mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 17:57:35 +00:00
LibWeb: Rename directory LibHTML => LibWeb
Let's rename this to LibWeb since it aims to provide more parts of the web platform than just HTML. :^)
This commit is contained in:
parent
7a6c4a72d5
commit
830a57c6b2
158 changed files with 360 additions and 360 deletions
3
Libraries/LibWeb/CSS/.gitignore
vendored
Normal file
3
Libraries/LibWeb/CSS/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
DefaultStyleSheetSource.cpp
|
||||
PropertyID.cpp
|
||||
PropertyID.h
|
139
Libraries/LibWeb/CSS/Default.css
Normal file
139
Libraries/LibWeb/CSS/Default.css
Normal file
|
@ -0,0 +1,139 @@
|
|||
html {
|
||||
font-family: Katica;
|
||||
}
|
||||
|
||||
head, link, meta, script, style, title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-left: 8;
|
||||
margin-top: 8;
|
||||
margin-right: 8;
|
||||
margin-bottom: 8;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
font-family: Pebbleton;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: Csilla;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 8;
|
||||
margin-top: 8;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: Csilla;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
u, ins {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
strong, b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
html, address,
|
||||
blockquote,
|
||||
body, dd, div,
|
||||
dl, dt, fieldset, form,
|
||||
frame, frameset,
|
||||
h1, h2, h3, h4,
|
||||
h5, h6, noframes,
|
||||
ol, p, ul, center,
|
||||
dir, hr, menu, pre,
|
||||
header, footer {
|
||||
display: block;
|
||||
}
|
||||
|
||||
center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
margin-top: 8;
|
||||
margin-bottom: 8;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
h4, p,
|
||||
blockquote, ul,
|
||||
fieldset, form,
|
||||
ol, dl, dir,
|
||||
menu {
|
||||
margin-top: 4;
|
||||
margin-bottom: 4;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
h5, h6 {
|
||||
margin-top: 2;
|
||||
margin-bottom: 2;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: list-item;
|
||||
margin-left: 8;
|
||||
margin-top: 2;
|
||||
margin-bottom: 2;
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: -libhtml-link;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: red;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin-top: 4;
|
||||
margin-bottom: 4;
|
||||
border-top-width: 1;
|
||||
border-left-width: 1;
|
||||
border-right-width: 1;
|
||||
border-bottom-width: 1;
|
||||
border-top-color: #888888;
|
||||
border-left-color: #888888;
|
||||
border-right-color: #888888;
|
||||
border-bottom-color: #888888;
|
||||
border-top-style: inset;
|
||||
border-left-style: inset;
|
||||
border-right-style: inset;
|
||||
border-bottom-style: inset;
|
||||
}
|
||||
|
||||
blink {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
table {
|
||||
display: table;
|
||||
}
|
||||
|
||||
tr {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
td {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
basefont {
|
||||
display: block;
|
||||
}
|
82
Libraries/LibWeb/CSS/Length.h
Normal file
82
Libraries/LibWeb/CSS/Length.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Length {
|
||||
public:
|
||||
enum class Type {
|
||||
Auto,
|
||||
Absolute,
|
||||
};
|
||||
|
||||
Length() {}
|
||||
Length(int value, Type type)
|
||||
: m_type(type)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
Length(float value, Type type)
|
||||
: m_type(type)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
~Length() {}
|
||||
|
||||
bool is_auto() const { return m_type == Type::Auto; }
|
||||
bool is_absolute() const { return m_type == Type::Absolute; }
|
||||
|
||||
float value() const { return m_value; }
|
||||
|
||||
String to_string() const
|
||||
{
|
||||
if (is_auto())
|
||||
return "[Length/auto]";
|
||||
return String::format("%g [Length/px]", m_value);
|
||||
}
|
||||
|
||||
float to_px() const
|
||||
{
|
||||
if (is_auto())
|
||||
return 0;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
private:
|
||||
Type m_type { Type::Auto };
|
||||
float m_value { 0 };
|
||||
};
|
||||
|
||||
inline const LogStream& operator<<(const LogStream& stream, const Length& value)
|
||||
{
|
||||
return stream << value.to_string();
|
||||
}
|
||||
|
||||
}
|
40
Libraries/LibWeb/CSS/LengthBox.h
Normal file
40
Libraries/LibWeb/CSS/LengthBox.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/CSS/Length.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
struct LengthBox {
|
||||
Length top;
|
||||
Length right;
|
||||
Length bottom;
|
||||
Length left;
|
||||
};
|
||||
|
||||
}
|
316
Libraries/LibWeb/CSS/Properties.json
Normal file
316
Libraries/LibWeb/CSS/Properties.json
Normal file
|
@ -0,0 +1,316 @@
|
|||
{
|
||||
"background-attachment": {
|
||||
"inherited": false,
|
||||
"initial": "scroll"
|
||||
},
|
||||
"background-color": {
|
||||
"inherited": false,
|
||||
"initial": "transparent"
|
||||
},
|
||||
"background-image": {
|
||||
"inherited": false,
|
||||
"initial": "none"
|
||||
},
|
||||
"background-position": {
|
||||
"inherited": false,
|
||||
"initial": "0% 0%"
|
||||
},
|
||||
"background-repeat": {
|
||||
"inherited": false,
|
||||
"initial": "repeat"
|
||||
},
|
||||
"border": {
|
||||
"longhands": [
|
||||
"border-width",
|
||||
"border-style",
|
||||
"border-color"
|
||||
]
|
||||
},
|
||||
"border-bottom-color": {
|
||||
"initial": "currentColor",
|
||||
"inherited": false
|
||||
},
|
||||
"border-bottom-style": {
|
||||
"initial": "none",
|
||||
"inherited": false
|
||||
},
|
||||
"border-bottom-width": {
|
||||
"initial": "medium",
|
||||
"inherited": false
|
||||
},
|
||||
"border-color": {
|
||||
"longhands": [
|
||||
"border-top-color",
|
||||
"border-right-color",
|
||||
"border-bottom-color",
|
||||
"border-left-color"
|
||||
]
|
||||
},
|
||||
"border-collapse": {
|
||||
"inherited": true,
|
||||
"initial": "separate"
|
||||
},
|
||||
"border-left-color": {
|
||||
"initial": "currentColor",
|
||||
"inherited": false
|
||||
},
|
||||
"border-left-style": {
|
||||
"initial": "none",
|
||||
"inherited": false
|
||||
},
|
||||
"border-left-width": {
|
||||
"initial": "medium",
|
||||
"inherited": false
|
||||
},
|
||||
"border-right-color": {
|
||||
"initial": "currentColor",
|
||||
"inherited": false
|
||||
},
|
||||
"border-right-style": {
|
||||
"initial": "none",
|
||||
"inherited": false
|
||||
},
|
||||
"border-right-width": {
|
||||
"initial": "medium",
|
||||
"inherited": false
|
||||
},
|
||||
"border-spacing": {
|
||||
"inherited": true,
|
||||
"initial": "0"
|
||||
},
|
||||
"border-style": {
|
||||
"longhands": [
|
||||
"border-top-style",
|
||||
"border-right-style",
|
||||
"border-bottom-style",
|
||||
"border-left-style"
|
||||
]
|
||||
},
|
||||
"border-top-color": {
|
||||
"initial": "currentColor",
|
||||
"inherited": false
|
||||
},
|
||||
"border-top-style": {
|
||||
"initial": "none",
|
||||
"inherited": false
|
||||
},
|
||||
"border-top-width": {
|
||||
"initial": "medium",
|
||||
"inherited": false
|
||||
},
|
||||
"border-width": {
|
||||
"longhands": [
|
||||
"border-top-width",
|
||||
"border-right-width",
|
||||
"border-bottom-width",
|
||||
"border-left-width"
|
||||
]
|
||||
},
|
||||
"bottom": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
},
|
||||
"caption-side": {
|
||||
"inherited": true,
|
||||
"initial": "top"
|
||||
},
|
||||
"clear": {
|
||||
"inherited": false,
|
||||
"initial": "none"
|
||||
},
|
||||
"clip": {
|
||||
"inherited": true,
|
||||
"initial": "auto"
|
||||
},
|
||||
"color": {
|
||||
"inherited": true,
|
||||
"initial": ""
|
||||
},
|
||||
"cursor": {
|
||||
"inherited": true,
|
||||
"initial": "auto"
|
||||
},
|
||||
"direction": {
|
||||
"inherited": true,
|
||||
"initial": "ltr"
|
||||
},
|
||||
"display": {
|
||||
"inherited": false,
|
||||
"initial": "inline"
|
||||
},
|
||||
"float": {
|
||||
"inherited": false,
|
||||
"initial": "none"
|
||||
},
|
||||
"font-family": {
|
||||
"inherited": true,
|
||||
"initial": "sans-serif"
|
||||
},
|
||||
"font-size": {
|
||||
"inherited": true,
|
||||
"initial": "medium"
|
||||
},
|
||||
"font-style": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"font-variant": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"font-weight": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"height": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
},
|
||||
"left": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
},
|
||||
"letter-spacing": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"line-height": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"list-style": {
|
||||
"longhands": [
|
||||
"list-style-type",
|
||||
"list-style-position",
|
||||
"list-style-image"
|
||||
]
|
||||
},
|
||||
"list-style-image": {
|
||||
"inherited": true,
|
||||
"initial": "none"
|
||||
},
|
||||
"list-style-position": {
|
||||
"inherited": true,
|
||||
"initial": "outside"
|
||||
},
|
||||
"list-style-type": {
|
||||
"inherited": true,
|
||||
"initial": "disc"
|
||||
},
|
||||
"margin": {
|
||||
"longhands": [
|
||||
"margin-top",
|
||||
"margin-right",
|
||||
"margin-bottom",
|
||||
"margin-left"
|
||||
]
|
||||
},
|
||||
"margin-bottom": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"margin-left": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"margin-right": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"margin-top": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"max-height": {
|
||||
"inherited": false,
|
||||
"initial": "none"
|
||||
},
|
||||
"max-width": {
|
||||
"inherited": false,
|
||||
"initial": "none"
|
||||
},
|
||||
"min-height": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"min-width": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"padding": {
|
||||
"longhands": [
|
||||
"padding-top",
|
||||
"padding-right",
|
||||
"padding-bottom",
|
||||
"padding-left"
|
||||
]
|
||||
},
|
||||
"padding-bottom": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"padding-left": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"padding-right": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"padding-top": {
|
||||
"inherited": false,
|
||||
"initial": "0"
|
||||
},
|
||||
"position": {
|
||||
"inherited": false,
|
||||
"initial": "static"
|
||||
},
|
||||
"right": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
},
|
||||
"text-align": {
|
||||
"inherited": true,
|
||||
"initial": "left"
|
||||
},
|
||||
"text-decoration": {
|
||||
"inherited": false,
|
||||
"initial": "none"
|
||||
},
|
||||
"text-indent": {
|
||||
"inherited": true,
|
||||
"initial": "0"
|
||||
},
|
||||
"text-transform": {
|
||||
"inherited": true,
|
||||
"initial": "none"
|
||||
},
|
||||
"top": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
},
|
||||
"vertical-align": {
|
||||
"inherited": false,
|
||||
"initial": "baseline"
|
||||
},
|
||||
"visibility": {
|
||||
"inherited": true,
|
||||
"initial": "visible"
|
||||
},
|
||||
"width": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
},
|
||||
"white-space": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"word-spacing": {
|
||||
"inherited": true,
|
||||
"initial": "normal"
|
||||
},
|
||||
"z-index": {
|
||||
"inherited": false,
|
||||
"initial": "auto"
|
||||
}
|
||||
}
|
67
Libraries/LibWeb/CSS/Selector.cpp
Normal file
67
Libraries/LibWeb/CSS/Selector.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Selector::Selector(Vector<ComplexSelector>&& component_lists)
|
||||
: m_complex_selectors(move(component_lists))
|
||||
{
|
||||
}
|
||||
|
||||
Selector::~Selector()
|
||||
{
|
||||
}
|
||||
|
||||
Specificity Selector::specificity() const
|
||||
{
|
||||
unsigned ids = 0;
|
||||
unsigned tag_names = 0;
|
||||
unsigned classes = 0;
|
||||
|
||||
for (auto& list : m_complex_selectors) {
|
||||
for (auto& simple_selector : list.compound_selector) {
|
||||
switch (simple_selector.type) {
|
||||
case SimpleSelector::Type::Id:
|
||||
++ids;
|
||||
break;
|
||||
case SimpleSelector::Type::Class:
|
||||
++classes;
|
||||
break;
|
||||
case SimpleSelector::Type::TagName:
|
||||
++tag_names;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { ids, classes, tag_names };
|
||||
}
|
||||
|
||||
}
|
96
Libraries/LibWeb/CSS/Selector.h
Normal file
96
Libraries/LibWeb/CSS/Selector.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/CSS/Specificity.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Selector {
|
||||
public:
|
||||
struct SimpleSelector {
|
||||
enum class Type {
|
||||
Invalid,
|
||||
Universal,
|
||||
TagName,
|
||||
Id,
|
||||
Class,
|
||||
};
|
||||
Type type { Type::Invalid };
|
||||
|
||||
enum class PseudoClass {
|
||||
None,
|
||||
Link,
|
||||
Hover,
|
||||
FirstChild,
|
||||
LastChild,
|
||||
OnlyChild,
|
||||
Empty,
|
||||
};
|
||||
PseudoClass pseudo_class { PseudoClass::None };
|
||||
|
||||
String value;
|
||||
|
||||
enum class AttributeMatchType {
|
||||
None,
|
||||
HasAttribute,
|
||||
ExactValueMatch,
|
||||
};
|
||||
|
||||
AttributeMatchType attribute_match_type { AttributeMatchType::None };
|
||||
String attribute_name;
|
||||
String attribute_value;
|
||||
};
|
||||
|
||||
struct ComplexSelector {
|
||||
enum class Relation {
|
||||
None,
|
||||
ImmediateChild,
|
||||
Descendant,
|
||||
AdjacentSibling,
|
||||
GeneralSibling,
|
||||
};
|
||||
Relation relation { Relation::None };
|
||||
|
||||
using CompoundSelector = Vector<SimpleSelector>;
|
||||
CompoundSelector compound_selector;
|
||||
};
|
||||
|
||||
explicit Selector(Vector<ComplexSelector>&&);
|
||||
~Selector();
|
||||
|
||||
const Vector<ComplexSelector>& complex_selectors() const { return m_complex_selectors; }
|
||||
|
||||
Specificity specificity() const;
|
||||
|
||||
private:
|
||||
Vector<ComplexSelector> m_complex_selectors;
|
||||
};
|
||||
|
||||
}
|
152
Libraries/LibWeb/CSS/SelectorEngine.cpp
Normal file
152
Libraries/LibWeb/CSS/SelectorEngine.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/SelectorEngine.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
namespace SelectorEngine {
|
||||
|
||||
static bool matches_hover_pseudo_class(const Element& element)
|
||||
{
|
||||
auto* hovered_node = element.document().hovered_node();
|
||||
if (!hovered_node)
|
||||
return false;
|
||||
if (&element == hovered_node)
|
||||
return true;
|
||||
return element.is_ancestor_of(*hovered_node);
|
||||
}
|
||||
|
||||
bool matches(const Selector::SimpleSelector& component, const Element& element)
|
||||
{
|
||||
switch (component.pseudo_class) {
|
||||
case Selector::SimpleSelector::PseudoClass::None:
|
||||
break;
|
||||
case Selector::SimpleSelector::PseudoClass::Link:
|
||||
if (!element.is_link())
|
||||
return false;
|
||||
break;
|
||||
case Selector::SimpleSelector::PseudoClass::Hover:
|
||||
if (!matches_hover_pseudo_class(element))
|
||||
return false;
|
||||
break;
|
||||
case Selector::SimpleSelector::PseudoClass::FirstChild:
|
||||
if (element.previous_element_sibling())
|
||||
return false;
|
||||
break;
|
||||
case Selector::SimpleSelector::PseudoClass::LastChild:
|
||||
if (element.next_element_sibling())
|
||||
return false;
|
||||
break;
|
||||
case Selector::SimpleSelector::PseudoClass::OnlyChild:
|
||||
if (element.previous_element_sibling() || element.next_element_sibling())
|
||||
return false;
|
||||
break;
|
||||
case Selector::SimpleSelector::PseudoClass::Empty:
|
||||
if (element.first_child_of_type<Element>() || element.first_child_of_type<Text>())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (component.attribute_match_type) {
|
||||
case Selector::SimpleSelector::AttributeMatchType::HasAttribute:
|
||||
if (!element.has_attribute(component.attribute_name))
|
||||
return false;
|
||||
break;
|
||||
case Selector::SimpleSelector::AttributeMatchType::ExactValueMatch:
|
||||
if (element.attribute(component.attribute_name) != component.attribute_value)
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (component.type) {
|
||||
case Selector::SimpleSelector::Type::Universal:
|
||||
return true;
|
||||
case Selector::SimpleSelector::Type::Id:
|
||||
return component.value == element.attribute("id");
|
||||
case Selector::SimpleSelector::Type::Class:
|
||||
return element.has_class(component.value);
|
||||
case Selector::SimpleSelector::Type::TagName:
|
||||
return component.value == element.tag_name();
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
bool matches(const Selector& selector, int component_list_index, const Element& element)
|
||||
{
|
||||
auto& component_list = selector.complex_selectors()[component_list_index];
|
||||
for (auto& component : component_list.compound_selector) {
|
||||
if (!matches(component, element))
|
||||
return false;
|
||||
}
|
||||
switch (component_list.relation) {
|
||||
case Selector::ComplexSelector::Relation::None:
|
||||
return true;
|
||||
case Selector::ComplexSelector::Relation::Descendant:
|
||||
ASSERT(component_list_index != 0);
|
||||
for (auto* ancestor = element.parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (!is<Element>(*ancestor))
|
||||
continue;
|
||||
if (matches(selector, component_list_index - 1, to<Element>(*ancestor)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Selector::ComplexSelector::Relation::ImmediateChild:
|
||||
ASSERT(component_list_index != 0);
|
||||
if (!element.parent() || !is<Element>(*element.parent()))
|
||||
return false;
|
||||
return matches(selector, component_list_index - 1, to<Element>(*element.parent()));
|
||||
case Selector::ComplexSelector::Relation::AdjacentSibling:
|
||||
ASSERT(component_list_index != 0);
|
||||
if (auto* sibling = element.previous_element_sibling())
|
||||
return matches(selector, component_list_index - 1, *sibling);
|
||||
return false;
|
||||
case Selector::ComplexSelector::Relation::GeneralSibling:
|
||||
ASSERT(component_list_index != 0);
|
||||
for (auto* sibling = element.previous_element_sibling(); sibling; sibling = sibling->previous_element_sibling()) {
|
||||
if (matches(selector, component_list_index - 1, *sibling))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
bool matches(const Selector& selector, const Element& element)
|
||||
{
|
||||
ASSERT(!selector.complex_selectors().is_empty());
|
||||
return matches(selector, selector.complex_selectors().size() - 1, element);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
41
Libraries/LibWeb/CSS/SelectorEngine.h
Normal file
41
Libraries/LibWeb/CSS/SelectorEngine.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Element;
|
||||
|
||||
namespace SelectorEngine {
|
||||
|
||||
bool matches(const Selector&, const Element&);
|
||||
|
||||
}
|
||||
|
||||
}
|
64
Libraries/LibWeb/CSS/Specificity.h
Normal file
64
Libraries/LibWeb/CSS/Specificity.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Specificity {
|
||||
public:
|
||||
Specificity(unsigned ids, unsigned classes, unsigned tag_names)
|
||||
: m_ids(ids)
|
||||
, m_classes(classes)
|
||||
, m_tag_names(tag_names)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned ids() const { return m_ids; }
|
||||
unsigned classes() const { return m_classes; }
|
||||
unsigned tag_names() const { return m_tag_names; }
|
||||
|
||||
bool operator<(const Specificity& other) const
|
||||
{
|
||||
return m_ids < other.m_ids
|
||||
|| m_classes < other.m_classes
|
||||
|| m_tag_names < other.m_tag_names;
|
||||
}
|
||||
|
||||
bool operator==(const Specificity& other) const
|
||||
{
|
||||
return m_ids == other.m_ids
|
||||
|| m_classes < other.m_classes
|
||||
|| m_tag_names < other.m_tag_names;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned m_ids { 0 };
|
||||
unsigned m_classes { 0 };
|
||||
unsigned m_tag_names { 0 };
|
||||
};
|
||||
|
||||
}
|
40
Libraries/LibWeb/CSS/StyleDeclaration.cpp
Normal file
40
Libraries/LibWeb/CSS/StyleDeclaration.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/StyleDeclaration.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
StyleDeclaration::StyleDeclaration(Vector<StyleProperty>&& properties)
|
||||
: m_properties(move(properties))
|
||||
{
|
||||
}
|
||||
|
||||
StyleDeclaration::~StyleDeclaration()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
58
Libraries/LibWeb/CSS/StyleDeclaration.h
Normal file
58
Libraries/LibWeb/CSS/StyleDeclaration.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
struct StyleProperty {
|
||||
CSS::PropertyID property_id;
|
||||
NonnullRefPtr<StyleValue> value;
|
||||
bool important { false };
|
||||
};
|
||||
|
||||
class StyleDeclaration : public RefCounted<StyleDeclaration> {
|
||||
public:
|
||||
static NonnullRefPtr<StyleDeclaration> create(Vector<StyleProperty>&& properties)
|
||||
{
|
||||
return adopt(*new StyleDeclaration(move(properties)));
|
||||
}
|
||||
|
||||
~StyleDeclaration();
|
||||
|
||||
const Vector<StyleProperty>& properties() const { return m_properties; }
|
||||
|
||||
public:
|
||||
explicit StyleDeclaration(Vector<StyleProperty>&&);
|
||||
|
||||
Vector<StyleProperty> m_properties;
|
||||
};
|
||||
|
||||
}
|
183
Libraries/LibWeb/CSS/StyleProperties.cpp
Normal file
183
Libraries/LibWeb/CSS/StyleProperties.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibCore/DirIterator.h>
|
||||
#include <LibWeb/CSS/StyleProperties.h>
|
||||
#include <LibWeb/FontCache.h>
|
||||
#include <ctype.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
StyleProperties::StyleProperties()
|
||||
{
|
||||
}
|
||||
|
||||
StyleProperties::StyleProperties(const StyleProperties& other)
|
||||
: m_property_values(*new HashMap(other.m_property_values))
|
||||
{
|
||||
if (other.m_font) {
|
||||
m_font = other.m_font->clone();
|
||||
} else {
|
||||
m_font = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NonnullRefPtr<StyleProperties> StyleProperties::clone() const
|
||||
{
|
||||
return adopt(*new StyleProperties(*this));
|
||||
}
|
||||
|
||||
void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue> value)
|
||||
{
|
||||
m_property_values.set((unsigned)id, move(value));
|
||||
}
|
||||
|
||||
Optional<NonnullRefPtr<StyleValue>> StyleProperties::property(CSS::PropertyID id) const
|
||||
{
|
||||
auto it = m_property_values.find((unsigned)id);
|
||||
if (it == m_property_values.end())
|
||||
return {};
|
||||
return it->value;
|
||||
}
|
||||
|
||||
Length StyleProperties::length_or_fallback(CSS::PropertyID id, const Length& fallback) const
|
||||
{
|
||||
auto value = property(id);
|
||||
if (!value.has_value())
|
||||
return fallback;
|
||||
return value.value()->to_length();
|
||||
}
|
||||
|
||||
String StyleProperties::string_or_fallback(CSS::PropertyID id, const StringView& fallback) const
|
||||
{
|
||||
auto value = property(id);
|
||||
if (!value.has_value())
|
||||
return fallback;
|
||||
return value.value()->to_string();
|
||||
}
|
||||
|
||||
Color StyleProperties::color_or_fallback(CSS::PropertyID id, const Document& document, Color fallback) const
|
||||
{
|
||||
auto value = property(id);
|
||||
if (!value.has_value())
|
||||
return fallback;
|
||||
return value.value()->to_color(document);
|
||||
}
|
||||
|
||||
void StyleProperties::load_font() const
|
||||
{
|
||||
auto font_family = string_or_fallback(CSS::PropertyID::FontFamily, "Katica");
|
||||
auto font_weight = string_or_fallback(CSS::PropertyID::FontWeight, "normal");
|
||||
|
||||
if (auto cached_font = FontCache::the().get({ font_family, font_weight })) {
|
||||
m_font = cached_font;
|
||||
return;
|
||||
}
|
||||
|
||||
String weight;
|
||||
if (font_weight == "lighter")
|
||||
weight = "Thin";
|
||||
else if (font_weight == "normal")
|
||||
weight = "";
|
||||
else if (font_weight == "bold")
|
||||
weight = "Bold";
|
||||
else {
|
||||
dbg() << "Unknown font-weight: " << font_weight;
|
||||
weight = "";
|
||||
}
|
||||
|
||||
auto look_for_file = [](const StringView& expected_name) -> String {
|
||||
// TODO: handle font sizes properly?
|
||||
Core::DirIterator it { "/res/fonts/", Core::DirIterator::Flags::SkipDots };
|
||||
while (it.has_next()) {
|
||||
String name = it.next_path();
|
||||
ASSERT(name.ends_with(".font"));
|
||||
if (!name.starts_with(expected_name))
|
||||
continue;
|
||||
|
||||
// Check that a numeric size immediately
|
||||
// follows the font name. This prevents,
|
||||
// for example, matching KaticaBold when
|
||||
// the regular Katica is requested.
|
||||
if (!isdigit(name[expected_name.length()]))
|
||||
continue;
|
||||
|
||||
return name;
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
String file_name = look_for_file(String::format("%s%s", font_family.characters(), weight.characters()));
|
||||
if (file_name.is_null() && weight == "")
|
||||
file_name = look_for_file(String::format("%sRegular", font_family.characters()));
|
||||
|
||||
if (file_name.is_null()) {
|
||||
dbg() << "Failed to find a font for family " << font_family << " weight " << font_weight;
|
||||
|
||||
if (font_weight == "bold")
|
||||
m_font = Gfx::Font::default_bold_font();
|
||||
else
|
||||
m_font = Gfx::Font::default_font();
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HTML_DEBUG
|
||||
dbg() << "Found font " << file_name << " for family " << font_family << " weight " << font_weight;
|
||||
#endif
|
||||
|
||||
m_font = Gfx::Font::load_from_file(String::format("/res/fonts/%s", file_name.characters()));
|
||||
FontCache::the().set({ font_family, font_weight }, *m_font);
|
||||
}
|
||||
|
||||
float StyleProperties::line_height() const
|
||||
{
|
||||
auto line_height_length = length_or_fallback(CSS::PropertyID::LineHeight, {});
|
||||
if (line_height_length.is_absolute())
|
||||
return (float)font().glyph_height() * line_height_length.to_px();
|
||||
return (float)font().glyph_height() * 1.4f;
|
||||
}
|
||||
|
||||
bool StyleProperties::operator==(const StyleProperties& other) const
|
||||
{
|
||||
if (m_property_values.size() != other.m_property_values.size())
|
||||
return false;
|
||||
|
||||
for (auto& it : m_property_values) {
|
||||
auto jt = other.m_property_values.find(it.key);
|
||||
if (jt == other.m_property_values.end())
|
||||
return false;
|
||||
auto& my_value = *it.value;
|
||||
auto& other_value = *jt->value;
|
||||
if (my_value.type() != other_value.type())
|
||||
return false;
|
||||
if (my_value.to_string() != other_value.to_string())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
81
Libraries/LibWeb/CSS/StyleProperties.h
Normal file
81
Libraries/LibWeb/CSS/StyleProperties.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class StyleProperties : public RefCounted<StyleProperties> {
|
||||
public:
|
||||
StyleProperties();
|
||||
|
||||
explicit StyleProperties(const StyleProperties&);
|
||||
|
||||
static NonnullRefPtr<StyleProperties> create() { return adopt(*new StyleProperties); }
|
||||
|
||||
NonnullRefPtr<StyleProperties> clone() const;
|
||||
|
||||
template<typename Callback>
|
||||
inline void for_each_property(Callback callback) const
|
||||
{
|
||||
for (auto& it : m_property_values)
|
||||
callback((CSS::PropertyID)it.key, *it.value);
|
||||
}
|
||||
|
||||
void set_property(CSS::PropertyID, NonnullRefPtr<StyleValue> value);
|
||||
Optional<NonnullRefPtr<StyleValue>> property(CSS::PropertyID) const;
|
||||
|
||||
Length length_or_fallback(CSS::PropertyID, const Length& fallback) const;
|
||||
String string_or_fallback(CSS::PropertyID, const StringView& fallback) const;
|
||||
Color color_or_fallback(CSS::PropertyID, const Document&, Color fallback) const;
|
||||
|
||||
const Gfx::Font& font() const
|
||||
{
|
||||
if (!m_font)
|
||||
load_font();
|
||||
return *m_font;
|
||||
}
|
||||
|
||||
float line_height() const;
|
||||
|
||||
bool operator==(const StyleProperties&) const;
|
||||
bool operator!=(const StyleProperties& other) const { return !(*this == other); }
|
||||
|
||||
private:
|
||||
HashMap<unsigned, NonnullRefPtr<StyleValue>> m_property_values;
|
||||
|
||||
void load_font() const;
|
||||
|
||||
mutable RefPtr<Gfx::Font> m_font;
|
||||
};
|
||||
|
||||
}
|
300
Libraries/LibWeb/CSS/StyleResolver.cpp
Normal file
300
Libraries/LibWeb/CSS/StyleResolver.cpp
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/SelectorEngine.h>
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/CSS/StyleSheet.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Parser/CSSParser.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
StyleResolver::StyleResolver(Document& document)
|
||||
: m_document(document)
|
||||
{
|
||||
}
|
||||
|
||||
StyleResolver::~StyleResolver()
|
||||
{
|
||||
}
|
||||
|
||||
static StyleSheet& default_stylesheet()
|
||||
{
|
||||
static StyleSheet* sheet;
|
||||
if (!sheet) {
|
||||
extern const char default_stylesheet_source[];
|
||||
String css = default_stylesheet_source;
|
||||
sheet = parse_css(css).leak_ref();
|
||||
}
|
||||
return *sheet;
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void StyleResolver::for_each_stylesheet(Callback callback) const
|
||||
{
|
||||
callback(default_stylesheet());
|
||||
for (auto& sheet : document().stylesheets()) {
|
||||
callback(sheet);
|
||||
}
|
||||
}
|
||||
|
||||
NonnullRefPtrVector<StyleRule> StyleResolver::collect_matching_rules(const Element& element) const
|
||||
{
|
||||
NonnullRefPtrVector<StyleRule> matching_rules;
|
||||
|
||||
for_each_stylesheet([&](auto& sheet) {
|
||||
for (auto& rule : sheet.rules()) {
|
||||
for (auto& selector : rule.selectors()) {
|
||||
if (SelectorEngine::matches(selector, element)) {
|
||||
matching_rules.append(rule);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
#ifdef HTML_DEBUG
|
||||
dbgprintf("Rules matching Element{%p}\n", &element);
|
||||
for (auto& rule : matching_rules) {
|
||||
dump_rule(rule);
|
||||
}
|
||||
#endif
|
||||
|
||||
return matching_rules;
|
||||
}
|
||||
|
||||
bool StyleResolver::is_inherited_property(CSS::PropertyID property_id)
|
||||
{
|
||||
static HashTable<CSS::PropertyID> inherited_properties;
|
||||
if (inherited_properties.is_empty()) {
|
||||
inherited_properties.set(CSS::PropertyID::BorderCollapse);
|
||||
inherited_properties.set(CSS::PropertyID::BorderSpacing);
|
||||
inherited_properties.set(CSS::PropertyID::Color);
|
||||
inherited_properties.set(CSS::PropertyID::FontFamily);
|
||||
inherited_properties.set(CSS::PropertyID::FontSize);
|
||||
inherited_properties.set(CSS::PropertyID::FontStyle);
|
||||
inherited_properties.set(CSS::PropertyID::FontVariant);
|
||||
inherited_properties.set(CSS::PropertyID::FontWeight);
|
||||
inherited_properties.set(CSS::PropertyID::LetterSpacing);
|
||||
inherited_properties.set(CSS::PropertyID::LineHeight);
|
||||
inherited_properties.set(CSS::PropertyID::ListStyle);
|
||||
inherited_properties.set(CSS::PropertyID::ListStyleImage);
|
||||
inherited_properties.set(CSS::PropertyID::ListStylePosition);
|
||||
inherited_properties.set(CSS::PropertyID::ListStyleType);
|
||||
inherited_properties.set(CSS::PropertyID::TextAlign);
|
||||
inherited_properties.set(CSS::PropertyID::TextIndent);
|
||||
inherited_properties.set(CSS::PropertyID::TextTransform);
|
||||
inherited_properties.set(CSS::PropertyID::Visibility);
|
||||
inherited_properties.set(CSS::PropertyID::WhiteSpace);
|
||||
inherited_properties.set(CSS::PropertyID::WordSpacing);
|
||||
|
||||
// FIXME: This property is not supposed to be inherited, but we currently
|
||||
// rely on inheritance to propagate decorations into line boxes.
|
||||
inherited_properties.set(CSS::PropertyID::TextDecoration);
|
||||
}
|
||||
return inherited_properties.contains(property_id);
|
||||
}
|
||||
|
||||
static Vector<String> split_on_whitespace(const StringView& string)
|
||||
{
|
||||
if (string.is_empty())
|
||||
return {};
|
||||
|
||||
Vector<String> v;
|
||||
size_t substart = 0;
|
||||
for (size_t i = 0; i < string.length(); ++i) {
|
||||
char ch = string.characters_without_null_termination()[i];
|
||||
if (isspace(ch)) {
|
||||
size_t sublen = i - substart;
|
||||
if (sublen != 0)
|
||||
v.append(string.substring_view(substart, sublen));
|
||||
substart = i + 1;
|
||||
}
|
||||
}
|
||||
size_t taillen = string.length() - substart;
|
||||
if (taillen != 0)
|
||||
v.append(string.substring_view(substart, taillen));
|
||||
return v;
|
||||
}
|
||||
|
||||
static void set_property_expanding_shorthands(StyleProperties& style, CSS::PropertyID property_id, const StyleValue& value)
|
||||
{
|
||||
if (property_id == CSS::PropertyID::BorderStyle) {
|
||||
style.set_property(CSS::PropertyID::BorderTopStyle, value);
|
||||
style.set_property(CSS::PropertyID::BorderRightStyle, value);
|
||||
style.set_property(CSS::PropertyID::BorderBottomStyle, value);
|
||||
style.set_property(CSS::PropertyID::BorderLeftStyle, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_id == CSS::PropertyID::BorderWidth) {
|
||||
style.set_property(CSS::PropertyID::BorderTopWidth, value);
|
||||
style.set_property(CSS::PropertyID::BorderRightWidth, value);
|
||||
style.set_property(CSS::PropertyID::BorderBottomWidth, value);
|
||||
style.set_property(CSS::PropertyID::BorderLeftWidth, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_id == CSS::PropertyID::BorderColor) {
|
||||
style.set_property(CSS::PropertyID::BorderTopColor, value);
|
||||
style.set_property(CSS::PropertyID::BorderRightColor, value);
|
||||
style.set_property(CSS::PropertyID::BorderBottomColor, value);
|
||||
style.set_property(CSS::PropertyID::BorderLeftColor, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_id == CSS::PropertyID::Margin) {
|
||||
if (value.is_length()) {
|
||||
style.set_property(CSS::PropertyID::MarginTop, value);
|
||||
style.set_property(CSS::PropertyID::MarginRight, value);
|
||||
style.set_property(CSS::PropertyID::MarginBottom, value);
|
||||
style.set_property(CSS::PropertyID::MarginLeft, value);
|
||||
return;
|
||||
}
|
||||
if (value.is_string()) {
|
||||
auto parts = split_on_whitespace(value.to_string());
|
||||
if (parts.size() == 2) {
|
||||
auto vertical = parse_css_value(parts[0]);
|
||||
auto horizontal = parse_css_value(parts[1]);
|
||||
style.set_property(CSS::PropertyID::MarginTop, vertical);
|
||||
style.set_property(CSS::PropertyID::MarginBottom, vertical);
|
||||
style.set_property(CSS::PropertyID::MarginLeft, horizontal);
|
||||
style.set_property(CSS::PropertyID::MarginRight, horizontal);
|
||||
return;
|
||||
}
|
||||
if (parts.size() == 3) {
|
||||
auto top = parse_css_value(parts[0]);
|
||||
auto horizontal = parse_css_value(parts[1]);
|
||||
auto bottom = parse_css_value(parts[2]);
|
||||
style.set_property(CSS::PropertyID::MarginTop, top);
|
||||
style.set_property(CSS::PropertyID::MarginBottom, bottom);
|
||||
style.set_property(CSS::PropertyID::MarginLeft, horizontal);
|
||||
style.set_property(CSS::PropertyID::MarginRight, horizontal);
|
||||
return;
|
||||
}
|
||||
if (parts.size() == 4) {
|
||||
auto top = parse_css_value(parts[0]);
|
||||
auto right = parse_css_value(parts[1]);
|
||||
auto bottom = parse_css_value(parts[2]);
|
||||
auto left = parse_css_value(parts[3]);
|
||||
style.set_property(CSS::PropertyID::MarginTop, top);
|
||||
style.set_property(CSS::PropertyID::MarginBottom, bottom);
|
||||
style.set_property(CSS::PropertyID::MarginLeft, left);
|
||||
style.set_property(CSS::PropertyID::MarginRight, right);
|
||||
return;
|
||||
}
|
||||
dbg() << "Unsure what to do with CSS margin value '" << value.to_string() << "'";
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (property_id == CSS::PropertyID::Padding) {
|
||||
if (value.is_length()) {
|
||||
style.set_property(CSS::PropertyID::PaddingTop, value);
|
||||
style.set_property(CSS::PropertyID::PaddingRight, value);
|
||||
style.set_property(CSS::PropertyID::PaddingBottom, value);
|
||||
style.set_property(CSS::PropertyID::PaddingLeft, value);
|
||||
return;
|
||||
}
|
||||
if (value.is_string()) {
|
||||
auto parts = split_on_whitespace(value.to_string());
|
||||
if (parts.size() == 2) {
|
||||
auto vertical = parse_css_value(parts[0]);
|
||||
auto horizontal = parse_css_value(parts[1]);
|
||||
style.set_property(CSS::PropertyID::PaddingTop, vertical);
|
||||
style.set_property(CSS::PropertyID::PaddingBottom, vertical);
|
||||
style.set_property(CSS::PropertyID::PaddingLeft, horizontal);
|
||||
style.set_property(CSS::PropertyID::PaddingRight, horizontal);
|
||||
return;
|
||||
}
|
||||
if (parts.size() == 3) {
|
||||
auto top = parse_css_value(parts[0]);
|
||||
auto horizontal = parse_css_value(parts[1]);
|
||||
auto bottom = parse_css_value(parts[2]);
|
||||
style.set_property(CSS::PropertyID::PaddingTop, top);
|
||||
style.set_property(CSS::PropertyID::PaddingBottom, bottom);
|
||||
style.set_property(CSS::PropertyID::PaddingLeft, horizontal);
|
||||
style.set_property(CSS::PropertyID::PaddingRight, horizontal);
|
||||
return;
|
||||
}
|
||||
if (parts.size() == 4) {
|
||||
auto top = parse_css_value(parts[0]);
|
||||
auto right = parse_css_value(parts[1]);
|
||||
auto bottom = parse_css_value(parts[2]);
|
||||
auto left = parse_css_value(parts[3]);
|
||||
style.set_property(CSS::PropertyID::PaddingTop, top);
|
||||
style.set_property(CSS::PropertyID::PaddingBottom, bottom);
|
||||
style.set_property(CSS::PropertyID::PaddingLeft, left);
|
||||
style.set_property(CSS::PropertyID::PaddingRight, right);
|
||||
return;
|
||||
}
|
||||
dbg() << "Unsure what to do with CSS padding value '" << value.to_string() << "'";
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
style.set_property(property_id, value);
|
||||
}
|
||||
|
||||
NonnullRefPtr<StyleProperties> StyleResolver::resolve_style(const Element& element, const StyleProperties* parent_style) const
|
||||
{
|
||||
auto style = StyleProperties::create();
|
||||
|
||||
if (parent_style) {
|
||||
parent_style->for_each_property([&](auto property_id, auto& value) {
|
||||
if (is_inherited_property(property_id))
|
||||
set_property_expanding_shorthands(style, property_id, value);
|
||||
});
|
||||
}
|
||||
|
||||
element.apply_presentational_hints(*style);
|
||||
|
||||
auto matching_rules = collect_matching_rules(element);
|
||||
for (auto& rule : matching_rules) {
|
||||
for (auto& property : rule.declaration().properties()) {
|
||||
set_property_expanding_shorthands(style, property.property_id, property.value);
|
||||
}
|
||||
}
|
||||
|
||||
auto style_attribute = element.attribute("style");
|
||||
if (!style_attribute.is_null()) {
|
||||
if (auto declaration = parse_css_declaration(style_attribute)) {
|
||||
for (auto& property : declaration->properties()) {
|
||||
set_property_expanding_shorthands(style, property.property_id, property.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
}
|
62
Libraries/LibWeb/CSS/StyleResolver.h
Normal file
62
Libraries/LibWeb/CSS/StyleResolver.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <LibWeb/CSS/StyleProperties.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Document;
|
||||
class Element;
|
||||
class ParentNode;
|
||||
class StyleRule;
|
||||
class StyleSheet;
|
||||
|
||||
class StyleResolver {
|
||||
public:
|
||||
explicit StyleResolver(Document&);
|
||||
~StyleResolver();
|
||||
|
||||
Document& document() { return m_document; }
|
||||
const Document& document() const { return m_document; }
|
||||
|
||||
NonnullRefPtr<StyleProperties> resolve_style(const Element&, const StyleProperties* parent_style) const;
|
||||
|
||||
NonnullRefPtrVector<StyleRule> collect_matching_rules(const Element&) const;
|
||||
|
||||
static bool is_inherited_property(CSS::PropertyID);
|
||||
|
||||
private:
|
||||
template<typename Callback>
|
||||
void for_each_stylesheet(Callback) const;
|
||||
|
||||
Document& m_document;
|
||||
};
|
||||
|
||||
}
|
41
Libraries/LibWeb/CSS/StyleRule.cpp
Normal file
41
Libraries/LibWeb/CSS/StyleRule.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/StyleRule.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
StyleRule::StyleRule(Vector<Selector>&& selectors, NonnullRefPtr<StyleDeclaration>&& declaration)
|
||||
: m_selectors(move(selectors))
|
||||
, m_declaration(move(declaration))
|
||||
{
|
||||
}
|
||||
|
||||
StyleRule::~StyleRule()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
54
Libraries/LibWeb/CSS/StyleRule.h
Normal file
54
Libraries/LibWeb/CSS/StyleRule.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWeb/CSS/StyleDeclaration.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class StyleRule : public RefCounted<StyleRule> {
|
||||
public:
|
||||
static NonnullRefPtr<StyleRule> create(Vector<Selector>&& selectors, NonnullRefPtr<StyleDeclaration>&& declaration)
|
||||
{
|
||||
return adopt(*new StyleRule(move(selectors), move(declaration)));
|
||||
}
|
||||
|
||||
~StyleRule();
|
||||
|
||||
const Vector<Selector>& selectors() const { return m_selectors; }
|
||||
const StyleDeclaration& declaration() const { return m_declaration; }
|
||||
|
||||
private:
|
||||
StyleRule(Vector<Selector>&&, NonnullRefPtr<StyleDeclaration>&&);
|
||||
|
||||
Vector<Selector> m_selectors;
|
||||
NonnullRefPtr<StyleDeclaration> m_declaration;
|
||||
};
|
||||
|
||||
}
|
40
Libraries/LibWeb/CSS/StyleSheet.cpp
Normal file
40
Libraries/LibWeb/CSS/StyleSheet.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/StyleSheet.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
StyleSheet::StyleSheet(NonnullRefPtrVector<StyleRule>&& rules)
|
||||
: m_rules(move(rules))
|
||||
{
|
||||
}
|
||||
|
||||
StyleSheet::~StyleSheet()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
51
Libraries/LibWeb/CSS/StyleSheet.h
Normal file
51
Libraries/LibWeb/CSS/StyleSheet.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <LibWeb/CSS/StyleRule.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class StyleSheet : public RefCounted<StyleSheet> {
|
||||
public:
|
||||
static NonnullRefPtr<StyleSheet> create(NonnullRefPtrVector<StyleRule>&& rules)
|
||||
{
|
||||
return adopt(*new StyleSheet(move(rules)));
|
||||
}
|
||||
|
||||
~StyleSheet();
|
||||
|
||||
const NonnullRefPtrVector<StyleRule>& rules() const { return m_rules; }
|
||||
|
||||
private:
|
||||
explicit StyleSheet(NonnullRefPtrVector<StyleRule>&&);
|
||||
|
||||
NonnullRefPtrVector<StyleRule> m_rules;
|
||||
};
|
||||
|
||||
}
|
82
Libraries/LibWeb/CSS/StyleValue.cpp
Normal file
82
Libraries/LibWeb/CSS/StyleValue.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/PNGLoader.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/ResourceLoader.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
StyleValue::StyleValue(Type type)
|
||||
: m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
StyleValue::~StyleValue()
|
||||
{
|
||||
}
|
||||
|
||||
String IdentifierStyleValue::to_string() const
|
||||
{
|
||||
switch (id()) {
|
||||
case CSS::ValueID::Invalid:
|
||||
return "(invalid)";
|
||||
case CSS::ValueID::VendorSpecificLink:
|
||||
return "-libhtml-link";
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
Color IdentifierStyleValue::to_color(const Document& document) const
|
||||
{
|
||||
if (id() == CSS::ValueID::VendorSpecificLink)
|
||||
return document.link_color();
|
||||
return {};
|
||||
}
|
||||
|
||||
ImageStyleValue::ImageStyleValue(const URL& url, Document& document)
|
||||
: StyleValue(Type::Image)
|
||||
, m_url(url)
|
||||
, m_document(document.make_weak_ptr())
|
||||
{
|
||||
NonnullRefPtr<ImageStyleValue> protector(*this);
|
||||
ResourceLoader::the().load(url, [this, protector](auto& data) {
|
||||
if (!m_document)
|
||||
return;
|
||||
m_bitmap = Gfx::load_png_from_memory(data.data(), data.size());
|
||||
if (!m_bitmap)
|
||||
return;
|
||||
// FIXME: Do less than a full repaint if possible?
|
||||
m_document->frame()->set_needs_display({});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
228
Libraries/LibWeb/CSS/StyleValue.h
Normal file
228
Libraries/LibWeb/CSS/StyleValue.h
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/URL.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <LibGfx/Color.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibWeb/CSS/Length.h>
|
||||
#include <LibWeb/CSS/PropertyID.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Document;
|
||||
|
||||
namespace CSS {
|
||||
enum class ValueID {
|
||||
Invalid,
|
||||
VendorSpecificLink,
|
||||
Center,
|
||||
Left,
|
||||
Right,
|
||||
Justify,
|
||||
};
|
||||
}
|
||||
|
||||
class StyleValue : public RefCounted<StyleValue> {
|
||||
public:
|
||||
virtual ~StyleValue();
|
||||
|
||||
enum class Type {
|
||||
Invalid,
|
||||
Inherit,
|
||||
Initial,
|
||||
String,
|
||||
Length,
|
||||
Color,
|
||||
Identifier,
|
||||
Image,
|
||||
};
|
||||
|
||||
Type type() const { return m_type; }
|
||||
|
||||
bool is_inherit() const { return type() == Type::Inherit; }
|
||||
bool is_initial() const { return type() == Type::Initial; }
|
||||
bool is_color() const { return type() == Type::Color; }
|
||||
bool is_identifier() const { return type() == Type::Identifier; }
|
||||
bool is_image() const { return type() == Type::Image; }
|
||||
bool is_string() const { return type() == Type::String; }
|
||||
bool is_length() const { return type() == Type::Length; }
|
||||
|
||||
virtual String to_string() const = 0;
|
||||
virtual Length to_length() const { return {}; }
|
||||
virtual Color to_color(const Document&) const { return {}; }
|
||||
|
||||
virtual bool is_auto() const { return false; }
|
||||
|
||||
protected:
|
||||
explicit StyleValue(Type);
|
||||
|
||||
private:
|
||||
Type m_type { Type::Invalid };
|
||||
};
|
||||
|
||||
class StringStyleValue : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<StringStyleValue> create(const String& string)
|
||||
{
|
||||
return adopt(*new StringStyleValue(string));
|
||||
}
|
||||
virtual ~StringStyleValue() override {}
|
||||
|
||||
String to_string() const override { return m_string; }
|
||||
|
||||
private:
|
||||
explicit StringStyleValue(const String& string)
|
||||
: StyleValue(Type::String)
|
||||
, m_string(string)
|
||||
{
|
||||
}
|
||||
|
||||
String m_string;
|
||||
};
|
||||
|
||||
class LengthStyleValue : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<LengthStyleValue> create(const Length& length)
|
||||
{
|
||||
return adopt(*new LengthStyleValue(length));
|
||||
}
|
||||
virtual ~LengthStyleValue() override {}
|
||||
|
||||
virtual String to_string() const override { return m_length.to_string(); }
|
||||
virtual Length to_length() const override { return m_length; }
|
||||
|
||||
const Length& length() const { return m_length; }
|
||||
|
||||
virtual bool is_auto() const override { return m_length.is_auto(); }
|
||||
|
||||
private:
|
||||
explicit LengthStyleValue(const Length& length)
|
||||
: StyleValue(Type::Length)
|
||||
, m_length(length)
|
||||
{
|
||||
}
|
||||
|
||||
Length m_length;
|
||||
};
|
||||
|
||||
class InitialStyleValue final : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<InitialStyleValue> create() { return adopt(*new InitialStyleValue); }
|
||||
virtual ~InitialStyleValue() override {}
|
||||
|
||||
String to_string() const override { return "initial"; }
|
||||
|
||||
private:
|
||||
InitialStyleValue()
|
||||
: StyleValue(Type::Initial)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class InheritStyleValue final : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<InheritStyleValue> create() { return adopt(*new InheritStyleValue); }
|
||||
virtual ~InheritStyleValue() override {}
|
||||
|
||||
String to_string() const override { return "inherit"; }
|
||||
|
||||
private:
|
||||
InheritStyleValue()
|
||||
: StyleValue(Type::Inherit)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ColorStyleValue : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<ColorStyleValue> create(Color color)
|
||||
{
|
||||
return adopt(*new ColorStyleValue(color));
|
||||
}
|
||||
virtual ~ColorStyleValue() override {}
|
||||
|
||||
Color color() const { return m_color; }
|
||||
String to_string() const override { return m_color.to_string(); }
|
||||
Color to_color(const Document&) const override { return m_color; }
|
||||
|
||||
private:
|
||||
explicit ColorStyleValue(Color color)
|
||||
: StyleValue(Type::Color)
|
||||
, m_color(color)
|
||||
{
|
||||
}
|
||||
|
||||
Color m_color;
|
||||
};
|
||||
|
||||
class IdentifierStyleValue final : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<IdentifierStyleValue> create(CSS::ValueID id)
|
||||
{
|
||||
return adopt(*new IdentifierStyleValue(id));
|
||||
}
|
||||
virtual ~IdentifierStyleValue() override {}
|
||||
|
||||
CSS::ValueID id() const { return m_id; }
|
||||
|
||||
virtual String to_string() const override;
|
||||
virtual Color to_color(const Document&) const override;
|
||||
|
||||
private:
|
||||
explicit IdentifierStyleValue(CSS::ValueID id)
|
||||
: StyleValue(Type::Identifier)
|
||||
, m_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
CSS::ValueID m_id { CSS::ValueID::Invalid };
|
||||
};
|
||||
|
||||
class ImageStyleValue final : public StyleValue {
|
||||
public:
|
||||
static NonnullRefPtr<ImageStyleValue> create(const URL& url, Document& document) { return adopt(*new ImageStyleValue(url, document)); }
|
||||
virtual ~ImageStyleValue() override {}
|
||||
|
||||
String to_string() const override { return String::format("Image{%s}", m_url.to_string().characters()); }
|
||||
|
||||
const Gfx::Bitmap* bitmap() const { return m_bitmap; }
|
||||
|
||||
private:
|
||||
ImageStyleValue(const URL&, Document&);
|
||||
|
||||
URL m_url;
|
||||
WeakPtr<Document> m_document;
|
||||
RefPtr<Gfx::Bitmap> m_bitmap;
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static String title_casify(const String& dashy_name)
|
||||
{
|
||||
auto parts = dashy_name.split('-');
|
||||
StringBuilder builder;
|
||||
for (auto& part : parts) {
|
||||
if (part.is_empty())
|
||||
continue;
|
||||
builder.append(toupper(part[0]));
|
||||
if (part.length() == 1)
|
||||
continue;
|
||||
builder.append(part.substring_view(1, part.length() - 1));
|
||||
}
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <path/to/CSS/Properties.json>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
auto file = Core::File::construct(argv[1]);
|
||||
if (!file->open(Core::IODevice::ReadOnly))
|
||||
return 1;
|
||||
|
||||
auto json = JsonValue::from_string(file->read_all());
|
||||
ASSERT(json.is_object());
|
||||
|
||||
dbg() << "#include <AK/Assertions.h>";
|
||||
dbg() << "#include <LibWeb/CSS/PropertyID.h>";
|
||||
dbg() << "namespace Web {";
|
||||
dbg() << "namespace CSS {";
|
||||
|
||||
dbg() << "PropertyID property_id_from_string(const StringView& string) {";
|
||||
|
||||
json.as_object().for_each_member([&](auto& name, auto& value) {
|
||||
ASSERT(value.is_object());
|
||||
dbg() << " if (string == \"" << name << "\")";
|
||||
dbg() << " return PropertyID::" << title_casify(name) << ";";
|
||||
});
|
||||
|
||||
dbg() << " return PropertyID::Invalid;";
|
||||
|
||||
dbg() << "}";
|
||||
|
||||
dbg() << "const char* string_from_property_id(PropertyID property_id) {";
|
||||
dbg() << " switch (property_id) {";
|
||||
json.as_object().for_each_member([&](auto& name, auto& value) {
|
||||
ASSERT(value.is_object());
|
||||
dbg() << " case PropertyID::" << title_casify(name) << ":";
|
||||
dbg() << " return \"" << name << "\";";
|
||||
});
|
||||
dbg() << " default:";
|
||||
dbg() << " return \"(invalid CSS::PropertyID)\";";
|
||||
dbg() << " }";
|
||||
dbg() << "}";
|
||||
dbg() << "}";
|
||||
dbg() << "}";
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
USE_HOST_CXX = 1
|
||||
|
||||
PROGRAM = Generate_CSS_PropertyID_cpp
|
||||
|
||||
OBJS = \
|
||||
Generate_CSS_PropertyID_cpp.o \
|
||||
../../../../AK/String.o \
|
||||
../../../../AK/StringImpl.o \
|
||||
../../../../AK/StringBuilder.o \
|
||||
../../../../AK/StringView.o \
|
||||
../../../../AK/StringUtils.o \
|
||||
../../../../AK/JsonValue.o \
|
||||
../../../../AK/JsonParser.o \
|
||||
../../../../AK/LogStream.o \
|
||||
../../../../Libraries/LibCore/IODevice.o \
|
||||
../../../../Libraries/LibCore/File.o \
|
||||
../../../../Libraries/LibCore/Object.o \
|
||||
../../../../Libraries/LibCore/Event.o \
|
||||
../../../../Libraries/LibCore/Socket.o \
|
||||
../../../../Libraries/LibCore/LocalSocket.o \
|
||||
../../../../Libraries/LibCore/Notifier.o \
|
||||
../../../../Libraries/LibCore/LocalServer.o \
|
||||
../../../../Libraries/LibCore/EventLoop.o
|
||||
|
||||
include ../../../../Makefile.common
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static String title_casify(const String& dashy_name)
|
||||
{
|
||||
auto parts = dashy_name.split('-');
|
||||
StringBuilder builder;
|
||||
for (auto& part : parts) {
|
||||
if (part.is_empty())
|
||||
continue;
|
||||
builder.append(toupper(part[0]));
|
||||
if (part.length() == 1)
|
||||
continue;
|
||||
builder.append(part.substring_view(1, part.length() - 1));
|
||||
}
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <path/to/CSS/Properties.json>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
auto file = Core::File::construct(argv[1]);
|
||||
if (!file->open(Core::IODevice::ReadOnly))
|
||||
return 1;
|
||||
|
||||
auto json = JsonValue::from_string(file->read_all());
|
||||
ASSERT(json.is_object());
|
||||
|
||||
dbg() << "#pragma once";
|
||||
dbg() << "#include <AK/StringView.h>";
|
||||
dbg() << "#include <AK/Traits.h>";
|
||||
|
||||
dbg() << "namespace Web {";
|
||||
dbg() << "namespace CSS {";
|
||||
dbg() << "enum class PropertyID {";
|
||||
dbg() << " Invalid,";
|
||||
|
||||
json.as_object().for_each_member([&](auto& name, auto& value) {
|
||||
ASSERT(value.is_object());
|
||||
dbg() << " " << title_casify(name) << ",";
|
||||
});
|
||||
|
||||
dbg() << "};\n\
|
||||
PropertyID property_id_from_string(const StringView&);\n\
|
||||
const char* string_from_property_id(PropertyID);\n\
|
||||
}\n\
|
||||
}\n\
|
||||
\n\
|
||||
namespace AK {\n\
|
||||
template<>\n\
|
||||
struct Traits<Web::CSS::PropertyID> : public GenericTraits<Web::CSS::PropertyID> {\n\
|
||||
static unsigned hash(Web::CSS::PropertyID property_id) { return int_hash((unsigned)property_id); }\n\
|
||||
};\n\
|
||||
}\n";
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
USE_HOST_CXX = 1
|
||||
|
||||
PROGRAM = Generate_CSS_PropertyID_h
|
||||
|
||||
OBJS = \
|
||||
Generate_CSS_PropertyID_h.o \
|
||||
../../../../AK/StringUtils.o \
|
||||
../../../../AK/String.o \
|
||||
../../../../AK/StringImpl.o \
|
||||
../../../../AK/StringBuilder.o \
|
||||
../../../../AK/StringView.o \
|
||||
../../../../AK/JsonValue.o \
|
||||
../../../../AK/JsonParser.o \
|
||||
../../../../AK/LogStream.o \
|
||||
../../../../Libraries/LibCore/IODevice.o \
|
||||
../../../../Libraries/LibCore/File.o \
|
||||
../../../../Libraries/LibCore/Object.o \
|
||||
../../../../Libraries/LibCore/Event.o \
|
||||
../../../../Libraries/LibCore/Socket.o \
|
||||
../../../../Libraries/LibCore/LocalSocket.o \
|
||||
../../../../Libraries/LibCore/Notifier.o \
|
||||
../../../../Libraries/LibCore/LocalServer.o \
|
||||
../../../../Libraries/LibCore/EventLoop.o
|
||||
|
||||
include ../../../../Makefile.common
|
3
Libraries/LibWeb/CodeGenerators/Makefile
Normal file
3
Libraries/LibWeb/CodeGenerators/Makefile
Normal file
|
@ -0,0 +1,3 @@
|
|||
SUBDIRS := $(wildcard */.)
|
||||
|
||||
include ../../../Makefile.subdir
|
41
Libraries/LibWeb/DOM/CharacterData.cpp
Normal file
41
Libraries/LibWeb/DOM/CharacterData.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/CharacterData.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
CharacterData::CharacterData(Document& document, NodeType type, const String& data)
|
||||
: Node(document, type)
|
||||
, m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
CharacterData::~CharacterData()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
55
Libraries/LibWeb/DOM/CharacterData.h
Normal file
55
Libraries/LibWeb/DOM/CharacterData.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class CharacterData : public Node {
|
||||
public:
|
||||
virtual ~CharacterData() override;
|
||||
|
||||
const String& data() const { return m_data; }
|
||||
|
||||
virtual String text_content() const override { return m_data; }
|
||||
|
||||
protected:
|
||||
explicit CharacterData(Document&, NodeType, const String&);
|
||||
|
||||
private:
|
||||
String m_data;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<CharacterData>(const Node& node)
|
||||
{
|
||||
return node.is_character_data();
|
||||
}
|
||||
|
||||
}
|
41
Libraries/LibWeb/DOM/Comment.cpp
Normal file
41
Libraries/LibWeb/DOM/Comment.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/Comment.h>
|
||||
#include <LibWeb/Layout/LayoutText.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Comment::Comment(Document& document, const String& data)
|
||||
: CharacterData(document, NodeType::COMMENT_NODE, data)
|
||||
{
|
||||
}
|
||||
|
||||
Comment::~Comment()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
48
Libraries/LibWeb/DOM/Comment.h
Normal file
48
Libraries/LibWeb/DOM/Comment.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/DOM/CharacterData.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Comment final : public CharacterData {
|
||||
public:
|
||||
explicit Comment(Document&, const String&);
|
||||
virtual ~Comment() override;
|
||||
|
||||
virtual String tag_name() const override { return "#comment"; }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<Comment>(const Node& node)
|
||||
{
|
||||
return node.is_comment();
|
||||
}
|
||||
|
||||
}
|
335
Libraries/LibWeb/DOM/Document.cpp
Normal file
335
Libraries/LibWeb/DOM/Document.cpp
Normal file
|
@ -0,0 +1,335 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/FileSystemPath.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/DocumentType.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/DOM/HTMLBodyElement.h>
|
||||
#include <LibWeb/DOM/HTMLHeadElement.h>
|
||||
#include <LibWeb/DOM/HTMLHtmlElement.h>
|
||||
#include <LibWeb/DOM/HTMLTitleElement.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/HtmlView.h>
|
||||
#include <LibWeb/Layout/LayoutDocument.h>
|
||||
#include <LibWeb/Layout/LayoutTreeBuilder.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Document::Document()
|
||||
: ParentNode(*this, NodeType::DOCUMENT_NODE)
|
||||
, m_style_resolver(make<StyleResolver>(*this))
|
||||
{
|
||||
m_style_update_timer = Core::Timer::construct();
|
||||
m_style_update_timer->set_single_shot(true);
|
||||
m_style_update_timer->set_interval(0);
|
||||
m_style_update_timer->on_timeout = [this] {
|
||||
update_style();
|
||||
};
|
||||
}
|
||||
|
||||
Document::~Document()
|
||||
{
|
||||
}
|
||||
|
||||
void Document::schedule_style_update()
|
||||
{
|
||||
if (m_style_update_timer->is_active())
|
||||
return;
|
||||
m_style_update_timer->start();
|
||||
}
|
||||
|
||||
bool Document::is_child_allowed(const Node& node) const
|
||||
{
|
||||
switch (node.type()) {
|
||||
case NodeType::DOCUMENT_NODE:
|
||||
case NodeType::TEXT_NODE:
|
||||
return false;
|
||||
case NodeType::COMMENT_NODE:
|
||||
return true;
|
||||
case NodeType::DOCUMENT_TYPE_NODE:
|
||||
return !first_child_of_type<DocumentType>();
|
||||
case NodeType::ELEMENT_NODE:
|
||||
return !first_child_of_type<Element>();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Document::fixup()
|
||||
{
|
||||
if (!first_child() || !is<DocumentType>(*first_child()))
|
||||
prepend_child(adopt(*new DocumentType(*this)));
|
||||
|
||||
if (is<HTMLHtmlElement>(first_child()->next_sibling()))
|
||||
return;
|
||||
|
||||
auto body = create_element(*this, "body");
|
||||
auto html = create_element(*this, "html");
|
||||
html->append_child(body);
|
||||
this->donate_all_children_to(body);
|
||||
this->append_child(html);
|
||||
}
|
||||
|
||||
const HTMLHtmlElement* Document::document_element() const
|
||||
{
|
||||
return first_child_of_type<HTMLHtmlElement>();
|
||||
}
|
||||
|
||||
const HTMLHeadElement* Document::head() const
|
||||
{
|
||||
auto* html = document_element();
|
||||
if (!html)
|
||||
return nullptr;
|
||||
return html->first_child_of_type<HTMLHeadElement>();
|
||||
}
|
||||
|
||||
const HTMLBodyElement* Document::body() const
|
||||
{
|
||||
auto* html = document_element();
|
||||
if (!html)
|
||||
return nullptr;
|
||||
return html->first_child_of_type<HTMLBodyElement>();
|
||||
}
|
||||
|
||||
String Document::title() const
|
||||
{
|
||||
auto* head_element = head();
|
||||
if (!head_element)
|
||||
return {};
|
||||
|
||||
auto* title_element = head_element->first_child_of_type<HTMLTitleElement>();
|
||||
if (!title_element)
|
||||
return {};
|
||||
|
||||
return title_element->text_content();
|
||||
}
|
||||
|
||||
void Document::attach_to_frame(Badge<Frame>, Frame& frame)
|
||||
{
|
||||
m_frame = frame.make_weak_ptr();
|
||||
layout();
|
||||
}
|
||||
|
||||
void Document::detach_from_frame(Badge<Frame>, Frame&)
|
||||
{
|
||||
m_layout_root = nullptr;
|
||||
m_frame = nullptr;
|
||||
}
|
||||
|
||||
Color Document::background_color(const Palette& palette) const
|
||||
{
|
||||
auto default_color = palette.base();
|
||||
auto* body_element = body();
|
||||
if (!body_element)
|
||||
return default_color;
|
||||
|
||||
auto* body_layout_node = body_element->layout_node();
|
||||
if (!body_layout_node)
|
||||
return default_color;
|
||||
|
||||
auto background_color = body_layout_node->style().property(CSS::PropertyID::BackgroundColor);
|
||||
if (!background_color.has_value() || !background_color.value()->is_color())
|
||||
return default_color;
|
||||
|
||||
return background_color.value()->to_color(*this);
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Bitmap> Document::background_image() const
|
||||
{
|
||||
auto* body_element = body();
|
||||
if (!body_element)
|
||||
return {};
|
||||
|
||||
auto* body_layout_node = body_element->layout_node();
|
||||
if (!body_layout_node)
|
||||
return {};
|
||||
|
||||
auto background_image = body_layout_node->style().property(CSS::PropertyID::BackgroundImage);
|
||||
if (!background_image.has_value() || !background_image.value()->is_image())
|
||||
return {};
|
||||
|
||||
auto& image_value = static_cast<const ImageStyleValue&>(*background_image.value());
|
||||
if (!image_value.bitmap())
|
||||
return {};
|
||||
|
||||
return *image_value.bitmap();
|
||||
}
|
||||
|
||||
URL Document::complete_url(const String& string) const
|
||||
{
|
||||
return m_url.complete_url(string);
|
||||
}
|
||||
|
||||
void Document::force_layout()
|
||||
{
|
||||
m_layout_root = nullptr;
|
||||
layout();
|
||||
}
|
||||
|
||||
void Document::layout()
|
||||
{
|
||||
if (!m_layout_root) {
|
||||
LayoutTreeBuilder tree_builder;
|
||||
m_layout_root = tree_builder.build(*this);
|
||||
}
|
||||
m_layout_root->layout();
|
||||
m_layout_root->set_needs_display();
|
||||
}
|
||||
|
||||
void Document::update_style()
|
||||
{
|
||||
for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (element.needs_style_update())
|
||||
element.recompute_style();
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
update_layout();
|
||||
}
|
||||
|
||||
void Document::update_layout()
|
||||
{
|
||||
if (!frame())
|
||||
return;
|
||||
|
||||
layout();
|
||||
if (on_layout_updated)
|
||||
on_layout_updated();
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> Document::create_layout_node(const StyleProperties*) const
|
||||
{
|
||||
return adopt(*new LayoutDocument(*this, StyleProperties::create()));
|
||||
}
|
||||
|
||||
void Document::set_link_color(Color color)
|
||||
{
|
||||
m_link_color = color;
|
||||
}
|
||||
|
||||
void Document::set_active_link_color(Color color)
|
||||
{
|
||||
m_active_link_color = color;
|
||||
}
|
||||
|
||||
void Document::set_visited_link_color(Color color)
|
||||
{
|
||||
m_visited_link_color = color;
|
||||
}
|
||||
|
||||
const LayoutDocument* Document::layout_node() const
|
||||
{
|
||||
return static_cast<const LayoutDocument*>(Node::layout_node());
|
||||
}
|
||||
|
||||
LayoutDocument* Document::layout_node()
|
||||
{
|
||||
return static_cast<LayoutDocument*>(Node::layout_node());
|
||||
}
|
||||
|
||||
void Document::set_inspected_node(Node* node)
|
||||
{
|
||||
if (m_inspected_node == node)
|
||||
return;
|
||||
|
||||
if (m_inspected_node && m_inspected_node->layout_node())
|
||||
m_inspected_node->layout_node()->set_needs_display();
|
||||
|
||||
m_inspected_node = node;
|
||||
|
||||
if (m_inspected_node && m_inspected_node->layout_node())
|
||||
m_inspected_node->layout_node()->set_needs_display();
|
||||
}
|
||||
|
||||
void Document::set_hovered_node(Node* node)
|
||||
{
|
||||
if (m_hovered_node == node)
|
||||
return;
|
||||
|
||||
RefPtr<Node> old_hovered_node = move(m_hovered_node);
|
||||
m_hovered_node = node;
|
||||
|
||||
invalidate_style();
|
||||
}
|
||||
|
||||
const Element* Document::get_element_by_id(const String& id) const
|
||||
{
|
||||
const Element* found_element = nullptr;
|
||||
for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (element.attribute("id") == id) {
|
||||
found_element = &element;
|
||||
return IterationDecision::Break;
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
return found_element;
|
||||
}
|
||||
|
||||
Vector<const Element*> Document::get_elements_by_name(const String& name) const
|
||||
{
|
||||
Vector<const Element*> elements;
|
||||
for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
if (element.attribute("name") == name)
|
||||
elements.append(&element);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
return elements;
|
||||
}
|
||||
|
||||
Color Document::link_color() const
|
||||
{
|
||||
if (m_link_color.has_value())
|
||||
return m_link_color.value();
|
||||
if (!frame())
|
||||
return Color::Blue;
|
||||
return frame()->html_view()->palette().link();
|
||||
}
|
||||
|
||||
Color Document::active_link_color() const
|
||||
{
|
||||
if (m_active_link_color.has_value())
|
||||
return m_active_link_color.value();
|
||||
if (!frame())
|
||||
return Color::Red;
|
||||
return frame()->html_view()->palette().active_link();
|
||||
}
|
||||
|
||||
Color Document::visited_link_color() const
|
||||
{
|
||||
if (m_visited_link_color.has_value())
|
||||
return m_visited_link_color.value();
|
||||
if (!frame())
|
||||
return Color::Magenta;
|
||||
return frame()->html_view()->palette().visited_link();
|
||||
}
|
||||
|
||||
}
|
150
Libraries/LibWeb/DOM/Document.h
Normal file
150
Libraries/LibWeb/DOM/Document.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/URL.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/CSS/StyleSheet.h>
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Frame;
|
||||
class HTMLBodyElement;
|
||||
class HTMLHtmlElement;
|
||||
class HTMLHeadElement;
|
||||
class LayoutDocument;
|
||||
class LayoutNode;
|
||||
class StyleResolver;
|
||||
class StyleSheet;
|
||||
|
||||
class Document : public ParentNode {
|
||||
public:
|
||||
Document();
|
||||
virtual ~Document() override;
|
||||
|
||||
void set_url(const URL& url) { m_url = url; }
|
||||
const URL& url() const { return m_url; }
|
||||
|
||||
URL complete_url(const String&) const;
|
||||
|
||||
void fixup();
|
||||
|
||||
StyleResolver& style_resolver() { return *m_style_resolver; }
|
||||
const StyleResolver& style_resolver() const { return *m_style_resolver; }
|
||||
|
||||
void add_sheet(const StyleSheet& sheet) { m_sheets.append(sheet); }
|
||||
const NonnullRefPtrVector<StyleSheet>& stylesheets() const { return m_sheets; }
|
||||
|
||||
virtual String tag_name() const override { return "#document"; }
|
||||
|
||||
void set_hovered_node(Node*);
|
||||
Node* hovered_node() { return m_hovered_node; }
|
||||
const Node* hovered_node() const { return m_hovered_node; }
|
||||
|
||||
void set_inspected_node(Node*);
|
||||
Node* inspected_node() { return m_inspected_node; }
|
||||
const Node* inspected_node() const { return m_inspected_node; }
|
||||
|
||||
const HTMLHtmlElement* document_element() const;
|
||||
const HTMLHeadElement* head() const;
|
||||
const HTMLBodyElement* body() const;
|
||||
|
||||
String title() const;
|
||||
|
||||
void attach_to_frame(Badge<Frame>, Frame&);
|
||||
void detach_from_frame(Badge<Frame>, Frame&);
|
||||
|
||||
Frame* frame() { return m_frame.ptr(); }
|
||||
const Frame* frame() const { return m_frame.ptr(); }
|
||||
|
||||
Color background_color(const Gfx::Palette&) const;
|
||||
RefPtr<Gfx::Bitmap> background_image() const;
|
||||
|
||||
Color link_color() const;
|
||||
void set_link_color(Color);
|
||||
|
||||
Color active_link_color() const;
|
||||
void set_active_link_color(Color);
|
||||
|
||||
Color visited_link_color() const;
|
||||
void set_visited_link_color(Color);
|
||||
|
||||
void layout();
|
||||
void force_layout();
|
||||
|
||||
void update_style();
|
||||
void update_layout();
|
||||
Function<void()> on_layout_updated;
|
||||
|
||||
virtual bool is_child_allowed(const Node&) const override;
|
||||
|
||||
const LayoutDocument* layout_node() const;
|
||||
LayoutDocument* layout_node();
|
||||
|
||||
void schedule_style_update();
|
||||
|
||||
const Element* get_element_by_id(const String&) const;
|
||||
Vector<const Element*> get_elements_by_name(const String&) const;
|
||||
|
||||
const String& source() const { return m_source; }
|
||||
void set_source(const String& source) { m_source = source; }
|
||||
|
||||
private:
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
|
||||
|
||||
OwnPtr<StyleResolver> m_style_resolver;
|
||||
NonnullRefPtrVector<StyleSheet> m_sheets;
|
||||
RefPtr<Node> m_hovered_node;
|
||||
RefPtr<Node> m_inspected_node;
|
||||
WeakPtr<Frame> m_frame;
|
||||
URL m_url;
|
||||
|
||||
RefPtr<LayoutDocument> m_layout_root;
|
||||
|
||||
Optional<Color> m_link_color;
|
||||
Optional<Color> m_active_link_color;
|
||||
Optional<Color> m_visited_link_color;
|
||||
|
||||
RefPtr<Core::Timer> m_style_update_timer;
|
||||
|
||||
String m_source;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<Document>(const Node& node)
|
||||
{
|
||||
return node.is_document();
|
||||
}
|
||||
|
||||
}
|
49
Libraries/LibWeb/DOM/DocumentFragment.h
Normal file
49
Libraries/LibWeb/DOM/DocumentFragment.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class DocumentFragment : public ParentNode {
|
||||
public:
|
||||
DocumentFragment(Document& document)
|
||||
: ParentNode(document, NodeType::DOCUMENT_FRAGMENT_NODE)
|
||||
{
|
||||
}
|
||||
|
||||
virtual String tag_name() const override { return "#document-fragment"; }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<DocumentFragment>(const Node& node)
|
||||
{
|
||||
return node.is_document_fragment();
|
||||
}
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/DocumentType.cpp
Normal file
40
Libraries/LibWeb/DOM/DocumentType.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/DocumentType.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
DocumentType::DocumentType(Document& document)
|
||||
: Node(document, NodeType::DOCUMENT_TYPE_NODE)
|
||||
{
|
||||
}
|
||||
|
||||
DocumentType::~DocumentType()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
47
Libraries/LibWeb/DOM/DocumentType.h
Normal file
47
Libraries/LibWeb/DOM/DocumentType.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class DocumentType final : public Node {
|
||||
public:
|
||||
explicit DocumentType(Document&);
|
||||
virtual ~DocumentType() override;
|
||||
|
||||
virtual String tag_name() const override { return "#doctype"; }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<DocumentType>(const Node& node)
|
||||
{
|
||||
return node.type() == NodeType::DOCUMENT_TYPE_NODE;
|
||||
}
|
||||
|
||||
}
|
221
Libraries/LibWeb/DOM/Element.cpp
Normal file
221
Libraries/LibWeb/DOM/Element.cpp
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/CSS/PropertyID.h>
|
||||
#include <LibWeb/CSS/Length.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutInline.h>
|
||||
#include <LibWeb/Layout/LayoutListItem.h>
|
||||
#include <LibWeb/Layout/LayoutTable.h>
|
||||
#include <LibWeb/Layout/LayoutTableCell.h>
|
||||
#include <LibWeb/Layout/LayoutTableRow.h>
|
||||
#include <LibWeb/Layout/LayoutTreeBuilder.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Element::Element(Document& document, const String& tag_name)
|
||||
: ParentNode(document, NodeType::ELEMENT_NODE)
|
||||
, m_tag_name(tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
Element::~Element()
|
||||
{
|
||||
}
|
||||
|
||||
Attribute* Element::find_attribute(const String& name)
|
||||
{
|
||||
for (auto& attribute : m_attributes) {
|
||||
if (attribute.name() == name)
|
||||
return &attribute;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Attribute* Element::find_attribute(const String& name) const
|
||||
{
|
||||
for (auto& attribute : m_attributes) {
|
||||
if (attribute.name() == name)
|
||||
return &attribute;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
String Element::attribute(const String& name) const
|
||||
{
|
||||
if (auto* attribute = find_attribute(name))
|
||||
return attribute->value();
|
||||
return {};
|
||||
}
|
||||
|
||||
void Element::set_attribute(const String& name, const String& value)
|
||||
{
|
||||
if (auto* attribute = find_attribute(name))
|
||||
attribute->set_value(value);
|
||||
else
|
||||
m_attributes.empend(name, value);
|
||||
|
||||
parse_attribute(name, value);
|
||||
}
|
||||
|
||||
void Element::set_attributes(Vector<Attribute>&& attributes)
|
||||
{
|
||||
m_attributes = move(attributes);
|
||||
|
||||
for (auto& attribute : m_attributes)
|
||||
parse_attribute(attribute.name(), attribute.value());
|
||||
}
|
||||
|
||||
bool Element::has_class(const StringView& class_name) const
|
||||
{
|
||||
auto value = attribute("class");
|
||||
if (value.is_empty())
|
||||
return false;
|
||||
auto parts = value.split_view(' ');
|
||||
for (auto& part : parts) {
|
||||
if (part == class_name)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> Element::create_layout_node(const StyleProperties* parent_style) const
|
||||
{
|
||||
auto style = document().style_resolver().resolve_style(*this, parent_style);
|
||||
const_cast<Element&>(*this).m_resolved_style = style;
|
||||
auto display = style->string_or_fallback(CSS::PropertyID::Display, "inline");
|
||||
|
||||
if (display == "none")
|
||||
return nullptr;
|
||||
if (display == "block")
|
||||
return adopt(*new LayoutBlock(this, move(style)));
|
||||
if (display == "inline")
|
||||
return adopt(*new LayoutInline(*this, move(style)));
|
||||
if (display == "list-item")
|
||||
return adopt(*new LayoutListItem(*this, move(style)));
|
||||
if (display == "table")
|
||||
return adopt(*new LayoutTable(*this, move(style)));
|
||||
if (display == "table-row")
|
||||
return adopt(*new LayoutTableRow(*this, move(style)));
|
||||
if (display == "table-cell")
|
||||
return adopt(*new LayoutTableCell(*this, move(style)));
|
||||
if (display == "inline-block")
|
||||
return adopt(*new LayoutBlock(this, move(style)));
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
void Element::parse_attribute(const String&, const String&)
|
||||
{
|
||||
}
|
||||
|
||||
enum class StyleDifference {
|
||||
None,
|
||||
NeedsRepaint,
|
||||
NeedsRelayout,
|
||||
};
|
||||
|
||||
static StyleDifference compute_style_difference(const StyleProperties& old_style, const StyleProperties& new_style, const Document& document)
|
||||
{
|
||||
if (old_style == new_style)
|
||||
return StyleDifference::None;
|
||||
|
||||
bool needs_repaint = false;
|
||||
bool needs_relayout = false;
|
||||
|
||||
if (new_style.color_or_fallback(CSS::PropertyID::Color, document, Color::Black) != old_style.color_or_fallback(CSS::PropertyID::Color, document, Color::Black))
|
||||
needs_repaint = true;
|
||||
else if (new_style.color_or_fallback(CSS::PropertyID::BackgroundColor, document, Color::Black) != old_style.color_or_fallback(CSS::PropertyID::BackgroundColor, document, Color::Black))
|
||||
needs_repaint = true;
|
||||
|
||||
if (needs_relayout)
|
||||
return StyleDifference::NeedsRelayout;
|
||||
if (needs_repaint)
|
||||
return StyleDifference::NeedsRepaint;
|
||||
return StyleDifference::None;
|
||||
}
|
||||
|
||||
void Element::recompute_style()
|
||||
{
|
||||
set_needs_style_update(false);
|
||||
ASSERT(parent());
|
||||
auto* parent_layout_node = parent()->layout_node();
|
||||
if (!parent_layout_node)
|
||||
return;
|
||||
ASSERT(parent_layout_node);
|
||||
auto style = document().style_resolver().resolve_style(*this, &parent_layout_node->style());
|
||||
m_resolved_style = style;
|
||||
if (!layout_node()) {
|
||||
if (style->string_or_fallback(CSS::PropertyID::Display, "inline") == "none")
|
||||
return;
|
||||
// We need a new layout tree here!
|
||||
LayoutTreeBuilder tree_builder;
|
||||
tree_builder.build(*this);
|
||||
return;
|
||||
}
|
||||
auto diff = compute_style_difference(layout_node()->style(), *style, document());
|
||||
if (diff == StyleDifference::None)
|
||||
return;
|
||||
layout_node()->set_style(*style);
|
||||
if (diff == StyleDifference::NeedsRelayout) {
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
if (diff == StyleDifference::NeedsRepaint) {
|
||||
layout_node()->set_needs_display();
|
||||
}
|
||||
}
|
||||
|
||||
NonnullRefPtr<StyleProperties> Element::computed_style()
|
||||
{
|
||||
auto properties = m_resolved_style->clone();
|
||||
if (layout_node() && layout_node()->has_style()) {
|
||||
CSS::PropertyID box_model_metrics[] = {
|
||||
CSS::PropertyID::MarginTop,
|
||||
CSS::PropertyID::MarginBottom,
|
||||
CSS::PropertyID::MarginLeft,
|
||||
CSS::PropertyID::MarginRight,
|
||||
CSS::PropertyID::PaddingTop,
|
||||
CSS::PropertyID::PaddingBottom,
|
||||
CSS::PropertyID::PaddingLeft,
|
||||
CSS::PropertyID::PaddingRight,
|
||||
CSS::PropertyID::BorderTopWidth,
|
||||
CSS::PropertyID::BorderBottomWidth,
|
||||
CSS::PropertyID::BorderLeftWidth,
|
||||
CSS::PropertyID::BorderRightWidth,
|
||||
};
|
||||
for (CSS::PropertyID id : box_model_metrics) {
|
||||
auto prop = layout_node()->style().property(id);
|
||||
if (prop.has_value())
|
||||
properties->set_property(id, prop.value());
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
108
Libraries/LibWeb/DOM/Element.h
Normal file
108
Libraries/LibWeb/DOM/Element.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class LayoutNodeWithStyle;
|
||||
|
||||
class Attribute {
|
||||
public:
|
||||
Attribute(const String& name, const String& value)
|
||||
: m_name(name)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
const String& name() const { return m_name; }
|
||||
const String& value() const { return m_value; }
|
||||
|
||||
void set_value(const String& value) { m_value = value; }
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
String m_value;
|
||||
};
|
||||
|
||||
class Element : public ParentNode {
|
||||
public:
|
||||
Element(Document&, const String& tag_name);
|
||||
virtual ~Element() override;
|
||||
|
||||
virtual String tag_name() const final { return m_tag_name; }
|
||||
|
||||
bool has_attribute(const String& name) const { return !attribute(name).is_null(); }
|
||||
String attribute(const String& name) const;
|
||||
void set_attribute(const String& name, const String& value);
|
||||
|
||||
void set_attributes(Vector<Attribute>&&);
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_attribute(Callback callback) const
|
||||
{
|
||||
for (auto& attribute : m_attributes)
|
||||
callback(attribute.name(), attribute.value());
|
||||
}
|
||||
|
||||
bool has_class(const StringView&) const;
|
||||
|
||||
virtual void apply_presentational_hints(StyleProperties&) const {}
|
||||
virtual void parse_attribute(const String& name, const String& value);
|
||||
|
||||
void recompute_style();
|
||||
|
||||
LayoutNodeWithStyle* layout_node() { return static_cast<LayoutNodeWithStyle*>(Node::layout_node()); }
|
||||
const LayoutNodeWithStyle* layout_node() const { return static_cast<const LayoutNodeWithStyle*>(Node::layout_node()); }
|
||||
|
||||
String name() const { return attribute("name"); }
|
||||
|
||||
const StyleProperties* resolved_style() const { return m_resolved_style.ptr(); }
|
||||
NonnullRefPtr<StyleProperties> computed_style();
|
||||
|
||||
private:
|
||||
RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
|
||||
|
||||
Attribute* find_attribute(const String& name);
|
||||
const Attribute* find_attribute(const String& name) const;
|
||||
|
||||
String m_tag_name;
|
||||
Vector<Attribute> m_attributes;
|
||||
|
||||
RefPtr<StyleProperties> m_resolved_style;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<Element>(const Node& node)
|
||||
{
|
||||
return node.is_element();
|
||||
}
|
||||
|
||||
}
|
88
Libraries/LibWeb/DOM/ElementFactory.cpp
Normal file
88
Libraries/LibWeb/DOM/ElementFactory.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/DOM/HTMLAnchorElement.h>
|
||||
#include <LibWeb/DOM/HTMLBRElement.h>
|
||||
#include <LibWeb/DOM/HTMLBlinkElement.h>
|
||||
#include <LibWeb/DOM/HTMLBodyElement.h>
|
||||
#include <LibWeb/DOM/HTMLFontElement.h>
|
||||
#include <LibWeb/DOM/HTMLFormElement.h>
|
||||
#include <LibWeb/DOM/HTMLHRElement.h>
|
||||
#include <LibWeb/DOM/HTMLHeadElement.h>
|
||||
#include <LibWeb/DOM/HTMLHeadingElement.h>
|
||||
#include <LibWeb/DOM/HTMLHtmlElement.h>
|
||||
#include <LibWeb/DOM/HTMLImageElement.h>
|
||||
#include <LibWeb/DOM/HTMLInputElement.h>
|
||||
#include <LibWeb/DOM/HTMLLinkElement.h>
|
||||
#include <LibWeb/DOM/HTMLStyleElement.h>
|
||||
#include <LibWeb/DOM/HTMLTitleElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
NonnullRefPtr<Element> create_element(Document& document, const String& tag_name)
|
||||
{
|
||||
auto lowercase_tag_name = tag_name.to_lowercase();
|
||||
if (lowercase_tag_name == "a")
|
||||
return adopt(*new HTMLAnchorElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "html")
|
||||
return adopt(*new HTMLHtmlElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "head")
|
||||
return adopt(*new HTMLHeadElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "body")
|
||||
return adopt(*new HTMLBodyElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "font")
|
||||
return adopt(*new HTMLFontElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "hr")
|
||||
return adopt(*new HTMLHRElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "style")
|
||||
return adopt(*new HTMLStyleElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "title")
|
||||
return adopt(*new HTMLTitleElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "link")
|
||||
return adopt(*new HTMLLinkElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "img")
|
||||
return adopt(*new HTMLImageElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "blink")
|
||||
return adopt(*new HTMLBlinkElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "form")
|
||||
return adopt(*new HTMLFormElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "input")
|
||||
return adopt(*new HTMLInputElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "br")
|
||||
return adopt(*new HTMLBRElement(document, lowercase_tag_name));
|
||||
if (lowercase_tag_name == "h1"
|
||||
|| lowercase_tag_name == "h2"
|
||||
|| lowercase_tag_name == "h3"
|
||||
|| lowercase_tag_name == "h4"
|
||||
|| lowercase_tag_name == "h5"
|
||||
|| lowercase_tag_name == "h6") {
|
||||
return adopt(*new HTMLHeadingElement(document, lowercase_tag_name));
|
||||
}
|
||||
return adopt(*new Element(document, lowercase_tag_name));
|
||||
}
|
||||
|
||||
}
|
35
Libraries/LibWeb/DOM/ElementFactory.h
Normal file
35
Libraries/LibWeb/DOM/ElementFactory.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
NonnullRefPtr<Element> create_element(Document&, const String& tag_name);
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLAnchorElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLAnchorElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLAnchorElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLAnchorElement::HTMLAnchorElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLAnchorElement::~HTMLAnchorElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
47
Libraries/LibWeb/DOM/HTMLAnchorElement.h
Normal file
47
Libraries/LibWeb/DOM/HTMLAnchorElement.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLAnchorElement : public HTMLElement {
|
||||
public:
|
||||
HTMLAnchorElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLAnchorElement() override;
|
||||
|
||||
String href() const { return attribute("href"); }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLAnchorElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "a";
|
||||
}
|
||||
|
||||
}
|
46
Libraries/LibWeb/DOM/HTMLBRElement.cpp
Normal file
46
Libraries/LibWeb/DOM/HTMLBRElement.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLBRElement.h>
|
||||
#include <LibWeb/Layout/LayoutBreak.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLBRElement::HTMLBRElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLBRElement::~HTMLBRElement()
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> HTMLBRElement::create_layout_node(const StyleProperties*) const
|
||||
{
|
||||
return adopt(*new LayoutBreak(*this));
|
||||
}
|
||||
|
||||
}
|
47
Libraries/LibWeb/DOM/HTMLBRElement.h
Normal file
47
Libraries/LibWeb/DOM/HTMLBRElement.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLBRElement final : public HTMLElement {
|
||||
public:
|
||||
HTMLBRElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLBRElement() override;
|
||||
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLBRElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "br";
|
||||
}
|
||||
|
||||
}
|
57
Libraries/LibWeb/DOM/HTMLBlinkElement.cpp
Normal file
57
Libraries/LibWeb/DOM/HTMLBlinkElement.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibWeb/CSS/StyleProperties.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
#include <LibWeb/DOM/HTMLBlinkElement.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLBlinkElement::HTMLBlinkElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
, m_timer(Core::Timer::construct())
|
||||
{
|
||||
m_timer->set_interval(500);
|
||||
m_timer->on_timeout = [this] { blink(); };
|
||||
m_timer->start();
|
||||
}
|
||||
|
||||
HTMLBlinkElement::~HTMLBlinkElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLBlinkElement::blink()
|
||||
{
|
||||
if (!layout_node())
|
||||
return;
|
||||
|
||||
layout_node()->set_visible(!layout_node()->is_visible());
|
||||
layout_node()->set_needs_display();
|
||||
}
|
||||
|
||||
}
|
45
Libraries/LibWeb/DOM/HTMLBlinkElement.h
Normal file
45
Libraries/LibWeb/DOM/HTMLBlinkElement.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLBlinkElement : public HTMLElement {
|
||||
public:
|
||||
HTMLBlinkElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLBlinkElement() override;
|
||||
|
||||
private:
|
||||
void blink();
|
||||
|
||||
NonnullRefPtr<Core::Timer> m_timer;
|
||||
};
|
||||
|
||||
}
|
77
Libraries/LibWeb/DOM/HTMLBodyElement.cpp
Normal file
77
Libraries/LibWeb/DOM/HTMLBodyElement.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/StyleProperties.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/HTMLBodyElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLBodyElement::HTMLBodyElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLBodyElement::~HTMLBodyElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLBodyElement::apply_presentational_hints(StyleProperties& style) const
|
||||
{
|
||||
for_each_attribute([&](auto& name, auto& value) {
|
||||
if (name.equals_ignoring_case("bgcolor")) {
|
||||
auto color = Color::from_string(value);
|
||||
if (color.has_value())
|
||||
style.set_property(CSS::PropertyID::BackgroundColor, ColorStyleValue::create(color.value()));
|
||||
} else if (name.equals_ignoring_case("text")) {
|
||||
auto color = Color::from_string(value);
|
||||
if (color.has_value())
|
||||
style.set_property(CSS::PropertyID::Color, ColorStyleValue::create(color.value()));
|
||||
} else if (name.equals_ignoring_case("background")) {
|
||||
style.set_property(CSS::PropertyID::BackgroundImage, ImageStyleValue::create(document().complete_url(value), const_cast<Document&>(document())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void HTMLBodyElement::parse_attribute(const String& name, const String& value)
|
||||
{
|
||||
if (name.equals_ignoring_case("link")) {
|
||||
auto color = Color::from_string(value);
|
||||
if (color.has_value())
|
||||
document().set_link_color(color.value());
|
||||
} else if (name.equals_ignoring_case("alink")) {
|
||||
auto color = Color::from_string(value);
|
||||
if (color.has_value())
|
||||
document().set_active_link_color(color.value());
|
||||
} else if (name.equals_ignoring_case("vlink")) {
|
||||
auto color = Color::from_string(value);
|
||||
if (color.has_value())
|
||||
document().set_visited_link_color(color.value());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
48
Libraries/LibWeb/DOM/HTMLBodyElement.h
Normal file
48
Libraries/LibWeb/DOM/HTMLBodyElement.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLBodyElement : public HTMLElement {
|
||||
public:
|
||||
HTMLBodyElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLBodyElement() override;
|
||||
|
||||
virtual void parse_attribute(const String&, const String&) override;
|
||||
virtual void apply_presentational_hints(StyleProperties&) const override;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLBodyElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "body";
|
||||
}
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLElement::HTMLElement(Document& document, const String& tag_name)
|
||||
: Element(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLElement::~HTMLElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
50
Libraries/LibWeb/DOM/HTMLElement.h
Normal file
50
Libraries/LibWeb/DOM/HTMLElement.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLElement : public Element {
|
||||
public:
|
||||
HTMLElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLElement() override;
|
||||
|
||||
String title() const { return attribute("title"); }
|
||||
|
||||
private:
|
||||
virtual bool is_html_element() const final { return true; }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLElement>(const Node& node)
|
||||
{
|
||||
return node.is_html_element();
|
||||
}
|
||||
|
||||
}
|
53
Libraries/LibWeb/DOM/HTMLFontElement.cpp
Normal file
53
Libraries/LibWeb/DOM/HTMLFontElement.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/StyleProperties.h>
|
||||
#include <LibWeb/CSS/StyleValue.h>
|
||||
#include <LibWeb/DOM/HTMLFontElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLFontElement::HTMLFontElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLFontElement::~HTMLFontElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLFontElement::apply_presentational_hints(StyleProperties& style) const
|
||||
{
|
||||
for_each_attribute([&](auto& name, auto& value) {
|
||||
if (name.equals_ignoring_case("color")) {
|
||||
auto color = Color::from_string(value);
|
||||
if (color.has_value())
|
||||
style.set_property(CSS::PropertyID::Color, ColorStyleValue::create(color.value()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
41
Libraries/LibWeb/DOM/HTMLFontElement.h
Normal file
41
Libraries/LibWeb/DOM/HTMLFontElement.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLFontElement : public HTMLElement {
|
||||
public:
|
||||
HTMLFontElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLFontElement() override;
|
||||
|
||||
virtual void apply_presentational_hints(StyleProperties&) const override;
|
||||
};
|
||||
|
||||
}
|
86
Libraries/LibWeb/DOM/HTMLFormElement.cpp
Normal file
86
Libraries/LibWeb/DOM/HTMLFormElement.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibWeb/DOM/HTMLFormElement.h>
|
||||
#include <LibWeb/DOM/HTMLInputElement.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/HtmlView.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLFormElement::HTMLFormElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLFormElement::~HTMLFormElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLFormElement::submit()
|
||||
{
|
||||
if (action().is_null()) {
|
||||
dbg() << "Unsupported form action ''";
|
||||
return;
|
||||
}
|
||||
|
||||
if (method().to_lowercase() != "get") {
|
||||
dbg() << "Unsupported form method '" << method() << "'";
|
||||
return;
|
||||
}
|
||||
|
||||
URL url(document().complete_url(action()));
|
||||
|
||||
struct NameAndValue {
|
||||
String name;
|
||||
String value;
|
||||
};
|
||||
|
||||
Vector<NameAndValue> parameters;
|
||||
|
||||
for_each_in_subtree_of_type<HTMLInputElement>([&](auto& node) {
|
||||
auto& input = to<HTMLInputElement>(node);
|
||||
if (!input.name().is_null())
|
||||
parameters.append({ input.name(), input.value() });
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||
builder.append(parameters[i].name);
|
||||
builder.append('=');
|
||||
builder.append(parameters[i].value);
|
||||
if (i != parameters.size() - 1)
|
||||
builder.append('&');
|
||||
}
|
||||
url.set_query(builder.to_string());
|
||||
|
||||
// FIXME: We shouldn't let the form just do this willy-nilly.
|
||||
document().frame()->html_view()->load(url);
|
||||
}
|
||||
|
||||
}
|
50
Libraries/LibWeb/DOM/HTMLFormElement.h
Normal file
50
Libraries/LibWeb/DOM/HTMLFormElement.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLFormElement : public HTMLElement {
|
||||
public:
|
||||
HTMLFormElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLFormElement() override;
|
||||
|
||||
String action() const { return attribute("action"); }
|
||||
String method() const { return attribute("method"); }
|
||||
|
||||
void submit();
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLFormElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "form";
|
||||
}
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLHRElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLHRElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLHRElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLHRElement::HTMLHRElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLHRElement::~HTMLHRElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
39
Libraries/LibWeb/DOM/HTMLHRElement.h
Normal file
39
Libraries/LibWeb/DOM/HTMLHRElement.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLHRElement : public HTMLElement {
|
||||
public:
|
||||
HTMLHRElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLHRElement() override;
|
||||
};
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLHeadElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLHeadElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLHeadElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLHeadElement::HTMLHeadElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLHeadElement::~HTMLHeadElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
45
Libraries/LibWeb/DOM/HTMLHeadElement.h
Normal file
45
Libraries/LibWeb/DOM/HTMLHeadElement.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLHeadElement : public HTMLElement {
|
||||
public:
|
||||
HTMLHeadElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLHeadElement() override;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLHeadElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "head";
|
||||
}
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLHeadingElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLHeadingElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLHeadingElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLHeadingElement::HTMLHeadingElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLHeadingElement::~HTMLHeadingElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
39
Libraries/LibWeb/DOM/HTMLHeadingElement.h
Normal file
39
Libraries/LibWeb/DOM/HTMLHeadingElement.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLHeadingElement : public HTMLElement {
|
||||
public:
|
||||
HTMLHeadingElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLHeadingElement() override;
|
||||
};
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLHtmlElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLHtmlElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLHtmlElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLHtmlElement::HTMLHtmlElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLHtmlElement::~HTMLHtmlElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
45
Libraries/LibWeb/DOM/HTMLHtmlElement.h
Normal file
45
Libraries/LibWeb/DOM/HTMLHtmlElement.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLHtmlElement : public HTMLElement {
|
||||
public:
|
||||
HTMLHtmlElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLHtmlElement() override;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLHtmlElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "html";
|
||||
}
|
||||
|
||||
}
|
127
Libraries/LibWeb/DOM/HTMLImageElement.cpp
Normal file
127
Libraries/LibWeb/DOM/HTMLImageElement.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/ImageDecoder.h>
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/HTMLImageElement.h>
|
||||
#include <LibWeb/Layout/LayoutImage.h>
|
||||
#include <LibWeb/ResourceLoader.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLImageElement::HTMLImageElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLImageElement::~HTMLImageElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLImageElement::parse_attribute(const String& name, const String& value)
|
||||
{
|
||||
if (name.equals_ignoring_case("src"))
|
||||
load_image(value);
|
||||
}
|
||||
|
||||
void HTMLImageElement::load_image(const String& src)
|
||||
{
|
||||
URL src_url = document().complete_url(src);
|
||||
ResourceLoader::the().load(src_url, [this, weak_element = make_weak_ptr()](auto data) {
|
||||
if (!weak_element) {
|
||||
dbg() << "HTMLImageElement: Load completed after element destroyed.";
|
||||
return;
|
||||
}
|
||||
if (data.is_null()) {
|
||||
dbg() << "HTMLImageElement: Failed to load " << this->src();
|
||||
return;
|
||||
}
|
||||
|
||||
m_encoded_data = data;
|
||||
m_image_decoder = Gfx::ImageDecoder::create(m_encoded_data.data(), m_encoded_data.size());
|
||||
document().update_layout();
|
||||
});
|
||||
}
|
||||
|
||||
int HTMLImageElement::preferred_width() const
|
||||
{
|
||||
bool ok = false;
|
||||
int width = attribute("width").to_int(ok);
|
||||
if (ok)
|
||||
return width;
|
||||
|
||||
if (m_image_decoder)
|
||||
return m_image_decoder->width();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HTMLImageElement::preferred_height() const
|
||||
{
|
||||
bool ok = false;
|
||||
int height = attribute("height").to_int(ok);
|
||||
if (ok)
|
||||
return height;
|
||||
|
||||
if (m_image_decoder)
|
||||
return m_image_decoder->height();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> HTMLImageElement::create_layout_node(const StyleProperties* parent_style) const
|
||||
{
|
||||
auto style = document().style_resolver().resolve_style(*this, parent_style);
|
||||
auto display = style->string_or_fallback(CSS::PropertyID::Display, "inline");
|
||||
if (display == "none")
|
||||
return nullptr;
|
||||
return adopt(*new LayoutImage(*this, move(style)));
|
||||
}
|
||||
|
||||
const Gfx::Bitmap* HTMLImageElement::bitmap() const
|
||||
{
|
||||
if (!m_image_decoder)
|
||||
return nullptr;
|
||||
return m_image_decoder->bitmap();
|
||||
}
|
||||
|
||||
void HTMLImageElement::set_volatile(Badge<LayoutDocument>, bool v)
|
||||
{
|
||||
if (!m_image_decoder)
|
||||
return;
|
||||
if (v) {
|
||||
m_image_decoder->set_volatile();
|
||||
return;
|
||||
}
|
||||
bool has_image = m_image_decoder->set_nonvolatile();
|
||||
if (has_image)
|
||||
return;
|
||||
m_image_decoder = Gfx::ImageDecoder::create(m_encoded_data.data(), m_encoded_data.size());
|
||||
}
|
||||
|
||||
}
|
63
Libraries/LibWeb/DOM/HTMLImageElement.h
Normal file
63
Libraries/LibWeb/DOM/HTMLImageElement.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class LayoutDocument;
|
||||
|
||||
class HTMLImageElement : public HTMLElement {
|
||||
public:
|
||||
HTMLImageElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLImageElement() override;
|
||||
|
||||
virtual void parse_attribute(const String& name, const String& value) override;
|
||||
|
||||
String alt() const { return attribute("alt"); }
|
||||
String src() const { return attribute("src"); }
|
||||
int preferred_width() const;
|
||||
int preferred_height() const;
|
||||
|
||||
const Gfx::Bitmap* bitmap() const;
|
||||
const Gfx::ImageDecoder* image_decoder() const { return m_image_decoder; }
|
||||
|
||||
void set_volatile(Badge<LayoutDocument>, bool);
|
||||
|
||||
private:
|
||||
void load_image(const String& src);
|
||||
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
|
||||
|
||||
RefPtr<Gfx::ImageDecoder> m_image_decoder;
|
||||
ByteBuffer m_encoded_data;
|
||||
};
|
||||
|
||||
}
|
82
Libraries/LibWeb/DOM/HTMLInputElement.cpp
Normal file
82
Libraries/LibWeb/DOM/HTMLInputElement.cpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibCore/ElapsedTimer.h>
|
||||
#include <LibGUI/Button.h>
|
||||
#include <LibGUI/TextBox.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/HTMLFormElement.h>
|
||||
#include <LibWeb/DOM/HTMLInputElement.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/HtmlView.h>
|
||||
#include <LibWeb/Layout/LayoutWidget.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLInputElement::HTMLInputElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLInputElement::~HTMLInputElement()
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> HTMLInputElement::create_layout_node(const StyleProperties*) const
|
||||
{
|
||||
ASSERT(document().frame());
|
||||
auto& frame = *document().frame();
|
||||
ASSERT(frame.html_view());
|
||||
auto& html_view = const_cast<HtmlView&>(*frame.html_view());
|
||||
|
||||
RefPtr<GUI::Widget> widget;
|
||||
if (type() == "submit") {
|
||||
auto& button = html_view.add<GUI::Button>(value());
|
||||
int text_width = Gfx::Font::default_font().width(value());
|
||||
button.set_relative_rect(0, 0, text_width + 20, 20);
|
||||
button.on_click = [this] {
|
||||
if (auto* form = first_ancestor_of_type<HTMLFormElement>()) {
|
||||
// FIXME: Remove this const_cast once we have a non-const first_ancestor_of_type.
|
||||
const_cast<HTMLFormElement*>(form)->submit();
|
||||
}
|
||||
};
|
||||
widget = button;
|
||||
} else {
|
||||
auto& text_box = html_view.add<GUI::TextBox>();
|
||||
text_box.set_text(value());
|
||||
text_box.on_change = [this] {
|
||||
auto& widget = to<LayoutWidget>(layout_node())->widget();
|
||||
const_cast<HTMLInputElement*>(this)->set_attribute("value", static_cast<const GUI::TextBox&>(widget).text());
|
||||
};
|
||||
int text_width = Gfx::Font::default_font().width(value());
|
||||
text_box.set_relative_rect(0, 0, text_width + 20, 20);
|
||||
widget = text_box;
|
||||
}
|
||||
|
||||
return adopt(*new LayoutWidget(*this, *widget));
|
||||
}
|
||||
|
||||
}
|
51
Libraries/LibWeb/DOM/HTMLInputElement.h
Normal file
51
Libraries/LibWeb/DOM/HTMLInputElement.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLInputElement : public HTMLElement {
|
||||
public:
|
||||
HTMLInputElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLInputElement() override;
|
||||
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
|
||||
|
||||
String type() const { return attribute("type"); }
|
||||
String value() const { return attribute("value"); }
|
||||
String name() const { return attribute("name"); }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLInputElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "input";
|
||||
}
|
||||
|
||||
}
|
66
Libraries/LibWeb/DOM/HTMLLinkElement.cpp
Normal file
66
Libraries/LibWeb/DOM/HTMLLinkElement.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/URL.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/HTMLLinkElement.h>
|
||||
#include <LibWeb/Parser/CSSParser.h>
|
||||
#include <LibWeb/ResourceLoader.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLLinkElement::HTMLLinkElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLLinkElement::~HTMLLinkElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLLinkElement::inserted_into(Node&)
|
||||
{
|
||||
if (rel() == "stylesheet") {
|
||||
URL url = document().complete_url(href());
|
||||
ResourceLoader::the().load(url, [&](auto data) {
|
||||
if (data.is_null()) {
|
||||
dbg() << "HTMLLinkElement: Failed to load stylesheet: " << href();
|
||||
return;
|
||||
}
|
||||
auto sheet = parse_css(data);
|
||||
if (!sheet) {
|
||||
dbg() << "HTMLLinkElement: Failed to parse stylesheet: " << href();
|
||||
return;
|
||||
}
|
||||
document().add_sheet(*sheet);
|
||||
document().update_style();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
51
Libraries/LibWeb/DOM/HTMLLinkElement.h
Normal file
51
Libraries/LibWeb/DOM/HTMLLinkElement.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLLinkElement final : public HTMLElement {
|
||||
public:
|
||||
HTMLLinkElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLLinkElement() override;
|
||||
|
||||
virtual void inserted_into(Node&) override;
|
||||
|
||||
String rel() const { return attribute("rel"); }
|
||||
String type() const { return attribute("type"); }
|
||||
String href() const { return attribute("href"); }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLLinkElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "link";
|
||||
}
|
||||
|
||||
}
|
65
Libraries/LibWeb/DOM/HTMLStyleElement.cpp
Normal file
65
Libraries/LibWeb/DOM/HTMLStyleElement.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/HTMLStyleElement.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Parser/CSSParser.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLStyleElement::HTMLStyleElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLStyleElement::~HTMLStyleElement()
|
||||
{
|
||||
}
|
||||
|
||||
void HTMLStyleElement::inserted_into(Node& new_parent)
|
||||
{
|
||||
StringBuilder builder;
|
||||
for_each_child([&](auto& child) {
|
||||
if (is<Text>(child))
|
||||
builder.append(to<Text>(child).text_content());
|
||||
});
|
||||
m_stylesheet = parse_css(builder.to_string());
|
||||
if (m_stylesheet)
|
||||
document().add_sheet(*m_stylesheet);
|
||||
HTMLElement::inserted_into(new_parent);
|
||||
}
|
||||
|
||||
void HTMLStyleElement::removed_from(Node& old_parent)
|
||||
{
|
||||
if (m_stylesheet) {
|
||||
// FIXME: Remove the sheet from the document
|
||||
}
|
||||
return HTMLElement::removed_from(old_parent);
|
||||
}
|
||||
|
||||
}
|
47
Libraries/LibWeb/DOM/HTMLStyleElement.h
Normal file
47
Libraries/LibWeb/DOM/HTMLStyleElement.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class StyleSheet;
|
||||
|
||||
class HTMLStyleElement : public HTMLElement {
|
||||
public:
|
||||
HTMLStyleElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLStyleElement() override;
|
||||
|
||||
virtual void inserted_into(Node&) override;
|
||||
virtual void removed_from(Node&) override;
|
||||
|
||||
private:
|
||||
RefPtr<StyleSheet> m_stylesheet;
|
||||
};
|
||||
|
||||
}
|
40
Libraries/LibWeb/DOM/HTMLTitleElement.cpp
Normal file
40
Libraries/LibWeb/DOM/HTMLTitleElement.cpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/HTMLTitleElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HTMLTitleElement::HTMLTitleElement(Document& document, const String& tag_name)
|
||||
: HTMLElement(document, tag_name)
|
||||
{
|
||||
}
|
||||
|
||||
HTMLTitleElement::~HTMLTitleElement()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
45
Libraries/LibWeb/DOM/HTMLTitleElement.h
Normal file
45
Libraries/LibWeb/DOM/HTMLTitleElement.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLElement.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class HTMLTitleElement : public HTMLElement {
|
||||
public:
|
||||
HTMLTitleElement(Document&, const String& tag_name);
|
||||
virtual ~HTMLTitleElement() override;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<HTMLTitleElement>(const Node& node)
|
||||
{
|
||||
return is<Element>(node) && to<Element>(node).tag_name().to_lowercase() == "title";
|
||||
}
|
||||
|
||||
}
|
120
Libraries/LibWeb/DOM/Node.cpp
Normal file
120
Libraries/LibWeb/DOM/Node.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/HTMLAnchorElement.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutDocument.h>
|
||||
#include <LibWeb/Layout/LayoutInline.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
#include <LibWeb/Layout/LayoutText.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Node::Node(Document& document, NodeType type)
|
||||
: m_document(document)
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
}
|
||||
|
||||
const HTMLAnchorElement* Node::enclosing_link_element() const
|
||||
{
|
||||
for (auto* node = this; node; node = node->parent()) {
|
||||
if (is<HTMLAnchorElement>(*node) && to<HTMLAnchorElement>(*node).has_attribute("href"))
|
||||
return to<HTMLAnchorElement>(node);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const HTMLElement* Node::enclosing_html_element() const
|
||||
{
|
||||
return first_ancestor_of_type<HTMLElement>();
|
||||
}
|
||||
|
||||
String Node::text_content() const
|
||||
{
|
||||
Vector<String> strings;
|
||||
StringBuilder builder;
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
auto text = child->text_content();
|
||||
if (!text.is_empty()) {
|
||||
builder.append(child->text_content());
|
||||
builder.append(' ');
|
||||
}
|
||||
}
|
||||
if (builder.length() > 1)
|
||||
builder.trim(1);
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
const Element* Node::next_element_sibling() const
|
||||
{
|
||||
for (auto* node = next_sibling(); node; node = node->next_sibling()) {
|
||||
if (node->is_element())
|
||||
return static_cast<const Element*>(node);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const Element* Node::previous_element_sibling() const
|
||||
{
|
||||
for (auto* node = previous_sibling(); node; node = node->previous_sibling()) {
|
||||
if (node->is_element())
|
||||
return static_cast<const Element*>(node);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> Node::create_layout_node(const StyleProperties*) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Node::invalidate_style()
|
||||
{
|
||||
for_each_in_subtree_of_type<Element>([&](auto& element) {
|
||||
element.set_needs_style_update(true);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
document().schedule_style_update();
|
||||
}
|
||||
|
||||
bool Node::is_link() const
|
||||
{
|
||||
auto* enclosing_link = enclosing_link_element();
|
||||
if (!enclosing_link)
|
||||
return false;
|
||||
return enclosing_link->has_attribute("href");
|
||||
}
|
||||
|
||||
}
|
191
Libraries/LibWeb/DOM/Node.h
Normal file
191
Libraries/LibWeb/DOM/Node.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Badge.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/TreeNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
enum class NodeType : unsigned {
|
||||
INVALID = 0,
|
||||
ELEMENT_NODE = 1,
|
||||
TEXT_NODE = 3,
|
||||
COMMENT_NODE = 8,
|
||||
DOCUMENT_NODE = 9,
|
||||
DOCUMENT_TYPE_NODE = 10,
|
||||
DOCUMENT_FRAGMENT_NODE = 11,
|
||||
};
|
||||
|
||||
class Document;
|
||||
class Element;
|
||||
class HTMLElement;
|
||||
class HTMLAnchorElement;
|
||||
class ParentNode;
|
||||
class LayoutNode;
|
||||
class StyleResolver;
|
||||
class StyleProperties;
|
||||
|
||||
class Node : public TreeNode<Node> {
|
||||
public:
|
||||
virtual ~Node();
|
||||
|
||||
NodeType type() const { return m_type; }
|
||||
bool is_element() const { return type() == NodeType::ELEMENT_NODE; }
|
||||
bool is_text() const { return type() == NodeType::TEXT_NODE; }
|
||||
bool is_document() const { return type() == NodeType::DOCUMENT_NODE; }
|
||||
bool is_document_type() const { return type() == NodeType::DOCUMENT_TYPE_NODE; }
|
||||
bool is_comment() const { return type() == NodeType::COMMENT_NODE; }
|
||||
bool is_character_data() const { return type() == NodeType::TEXT_NODE || type() == NodeType::COMMENT_NODE; }
|
||||
bool is_document_fragment() const { return type() == NodeType::DOCUMENT_FRAGMENT_NODE; }
|
||||
bool is_parent_node() const { return is_element() || is_document(); }
|
||||
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const;
|
||||
|
||||
virtual String tag_name() const = 0;
|
||||
|
||||
virtual String text_content() const;
|
||||
|
||||
Document& document() { return m_document; }
|
||||
const Document& document() const { return m_document; }
|
||||
|
||||
const HTMLAnchorElement* enclosing_link_element() const;
|
||||
const HTMLElement* enclosing_html_element() const;
|
||||
|
||||
virtual bool is_html_element() const { return false; }
|
||||
|
||||
template<typename T>
|
||||
const T* first_child_of_type() const;
|
||||
|
||||
template<typename T>
|
||||
const T* first_ancestor_of_type() const;
|
||||
|
||||
virtual void inserted_into(Node&) {}
|
||||
virtual void removed_from(Node&) {}
|
||||
|
||||
const LayoutNode* layout_node() const { return m_layout_node; }
|
||||
LayoutNode* layout_node() { return m_layout_node; }
|
||||
|
||||
void set_layout_node(Badge<LayoutNode>, LayoutNode* layout_node) const { m_layout_node = layout_node; }
|
||||
|
||||
const Element* previous_element_sibling() const;
|
||||
const Element* next_element_sibling() const;
|
||||
|
||||
virtual bool is_child_allowed(const Node&) const { return true; }
|
||||
|
||||
bool needs_style_update() const { return m_needs_style_update; }
|
||||
void set_needs_style_update(bool value) { m_needs_style_update = value; }
|
||||
|
||||
void invalidate_style();
|
||||
|
||||
bool is_link() const;
|
||||
|
||||
protected:
|
||||
Node(Document&, NodeType);
|
||||
|
||||
Document& m_document;
|
||||
mutable LayoutNode* m_layout_node { nullptr };
|
||||
NodeType m_type { NodeType::INVALID };
|
||||
bool m_needs_style_update { false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline bool is(const Node&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool is(const Node* node)
|
||||
{
|
||||
return !node || is<T>(*node);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool is<Node>(const Node&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool is<ParentNode>(const Node& node)
|
||||
{
|
||||
return node.is_parent_node();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T& to(const Node& node)
|
||||
{
|
||||
ASSERT(is<T>(node));
|
||||
return static_cast<const T&>(node);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* to(Node* node)
|
||||
{
|
||||
ASSERT(is<T>(node));
|
||||
return static_cast<T*>(node);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* to(const Node* node)
|
||||
{
|
||||
ASSERT(is<T>(node));
|
||||
return static_cast<const T*>(node);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T& to(Node& node)
|
||||
{
|
||||
ASSERT(is<T>(node));
|
||||
return static_cast<T&>(node);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* Node::first_child_of_type() const
|
||||
{
|
||||
for (auto* child = first_child(); child; child = child->next_sibling()) {
|
||||
if (is<T>(*child))
|
||||
return to<T>(child);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline const T* Node::first_ancestor_of_type() const
|
||||
{
|
||||
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
||||
if (is<T>(*ancestor))
|
||||
return to<T>(ancestor);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
28
Libraries/LibWeb/DOM/ParentNode.cpp
Normal file
28
Libraries/LibWeb/DOM/ParentNode.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
|
59
Libraries/LibWeb/DOM/ParentNode.h
Normal file
59
Libraries/LibWeb/DOM/ParentNode.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class ParentNode : public Node {
|
||||
public:
|
||||
template<typename F> void for_each_child(F) const;
|
||||
template<typename F> void for_each_child(F);
|
||||
|
||||
protected:
|
||||
explicit ParentNode(Document& document, NodeType type)
|
||||
: Node(document, type)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Callback>
|
||||
inline void ParentNode::for_each_child(Callback callback) const
|
||||
{
|
||||
for (auto* node = first_child(); node; node = node->next_sibling())
|
||||
callback(*node);
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
inline void ParentNode::for_each_child(Callback callback)
|
||||
{
|
||||
for (auto* node = first_child(); node; node = node->next_sibling())
|
||||
callback(*node);
|
||||
}
|
||||
|
||||
}
|
46
Libraries/LibWeb/DOM/Text.cpp
Normal file
46
Libraries/LibWeb/DOM/Text.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Layout/LayoutText.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Text::Text(Document& document, const String& data)
|
||||
: CharacterData(document, NodeType::TEXT_NODE, data)
|
||||
{
|
||||
}
|
||||
|
||||
Text::~Text()
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<LayoutNode> Text::create_layout_node(const StyleProperties*) const
|
||||
{
|
||||
return adopt(*new LayoutText(*this));
|
||||
}
|
||||
|
||||
}
|
51
Libraries/LibWeb/DOM/Text.h
Normal file
51
Libraries/LibWeb/DOM/Text.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <LibWeb/DOM/CharacterData.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Text final : public CharacterData {
|
||||
public:
|
||||
explicit Text(Document&, const String&);
|
||||
virtual ~Text() override;
|
||||
|
||||
virtual String tag_name() const override { return "#text"; }
|
||||
|
||||
private:
|
||||
virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<Text>(const Node& node)
|
||||
{
|
||||
return node.is_text();
|
||||
}
|
||||
|
||||
}
|
157
Libraries/LibWeb/DOMTreeModel.cpp
Normal file
157
Libraries/LibWeb/DOMTreeModel.cpp
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include "DOMTreeModel.h"
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
DOMTreeModel::DOMTreeModel(Document& document)
|
||||
: m_document(document)
|
||||
{
|
||||
m_document_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-html.png"));
|
||||
m_element_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/inspector-object.png"));
|
||||
m_text_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-unknown.png"));
|
||||
}
|
||||
|
||||
DOMTreeModel::~DOMTreeModel()
|
||||
{
|
||||
}
|
||||
|
||||
GUI::ModelIndex DOMTreeModel::index(int row, int column, const GUI::ModelIndex& parent) const
|
||||
{
|
||||
if (!parent.is_valid()) {
|
||||
return create_index(row, column, m_document.ptr());
|
||||
}
|
||||
auto& parent_node = *static_cast<Node*>(parent.internal_data());
|
||||
return create_index(row, column, parent_node.child_at_index(row));
|
||||
}
|
||||
|
||||
GUI::ModelIndex DOMTreeModel::parent_index(const GUI::ModelIndex& index) const
|
||||
{
|
||||
if (!index.is_valid())
|
||||
return {};
|
||||
auto& node = *static_cast<Node*>(index.internal_data());
|
||||
if (!node.parent())
|
||||
return {};
|
||||
|
||||
// No grandparent? Parent is the document!
|
||||
if (!node.parent()->parent()) {
|
||||
return create_index(0, 0, m_document.ptr());
|
||||
}
|
||||
|
||||
// Walk the grandparent's children to find the index of node's parent in its parent.
|
||||
// (This is needed to produce the row number of the GUI::ModelIndex corresponding to node's parent.)
|
||||
int grandparent_child_index = 0;
|
||||
for (auto* grandparent_child = node.parent()->parent()->first_child(); grandparent_child; grandparent_child = grandparent_child->next_sibling()) {
|
||||
if (grandparent_child == node.parent())
|
||||
return create_index(grandparent_child_index, 0, node.parent());
|
||||
++grandparent_child_index;
|
||||
}
|
||||
|
||||
ASSERT_NOT_REACHED();
|
||||
return {};
|
||||
}
|
||||
|
||||
int DOMTreeModel::row_count(const GUI::ModelIndex& index) const
|
||||
{
|
||||
if (!index.is_valid())
|
||||
return 1;
|
||||
auto& node = *static_cast<Node*>(index.internal_data());
|
||||
return node.child_count();
|
||||
}
|
||||
|
||||
int DOMTreeModel::column_count(const GUI::ModelIndex&) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static String with_whitespace_collapsed(const StringView& string)
|
||||
{
|
||||
StringBuilder builder;
|
||||
for (size_t i = 0; i < string.length(); ++i) {
|
||||
if (isspace(string[i])) {
|
||||
builder.append(' ');
|
||||
while (i < string.length()) {
|
||||
if (isspace(string[i])) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
builder.append(string[i]);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
builder.append(string[i]);
|
||||
}
|
||||
return builder.to_string();
|
||||
}
|
||||
|
||||
GUI::Variant DOMTreeModel::data(const GUI::ModelIndex& index, Role role) const
|
||||
{
|
||||
auto& node = *static_cast<Node*>(index.internal_data());
|
||||
if (role == Role::Icon) {
|
||||
if (node.is_document())
|
||||
return m_document_icon;
|
||||
if (node.is_element())
|
||||
return m_element_icon;
|
||||
// FIXME: More node type icons?
|
||||
return m_text_icon;
|
||||
}
|
||||
if (role == Role::Display) {
|
||||
if (node.is_text())
|
||||
return String::format("%s", with_whitespace_collapsed(to<Text>(node).data()).characters());
|
||||
if (!node.is_element())
|
||||
return node.tag_name();
|
||||
auto& element = to<Element>(node);
|
||||
StringBuilder builder;
|
||||
builder.append('<');
|
||||
builder.append(element.tag_name());
|
||||
element.for_each_attribute([&](auto& name, auto& value) {
|
||||
builder.append(' ');
|
||||
builder.append(name);
|
||||
builder.append('=');
|
||||
builder.append('"');
|
||||
builder.append(value);
|
||||
builder.append('"');
|
||||
});
|
||||
builder.append('>');
|
||||
return builder.to_string();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void DOMTreeModel::update()
|
||||
{
|
||||
did_update();
|
||||
}
|
||||
|
||||
}
|
61
Libraries/LibWeb/DOMTreeModel.h
Normal file
61
Libraries/LibWeb/DOMTreeModel.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGUI/Model.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Document;
|
||||
|
||||
class DOMTreeModel final : public GUI::Model {
|
||||
public:
|
||||
static NonnullRefPtr<DOMTreeModel> create(Document& document)
|
||||
{
|
||||
return adopt(*new DOMTreeModel(document));
|
||||
}
|
||||
|
||||
virtual ~DOMTreeModel() override;
|
||||
|
||||
virtual int row_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override;
|
||||
virtual int column_count(const GUI::ModelIndex& = GUI::ModelIndex()) const override;
|
||||
virtual GUI::Variant data(const GUI::ModelIndex&, Role = Role::Display) const override;
|
||||
virtual GUI::ModelIndex index(int row, int column, const GUI::ModelIndex& parent = GUI::ModelIndex()) const override;
|
||||
virtual GUI::ModelIndex parent_index(const GUI::ModelIndex&) const override;
|
||||
virtual void update() override;
|
||||
|
||||
private:
|
||||
explicit DOMTreeModel(Document&);
|
||||
|
||||
NonnullRefPtr<Document> m_document;
|
||||
|
||||
GUI::Icon m_document_icon;
|
||||
GUI::Icon m_element_icon;
|
||||
GUI::Icon m_text_icon;
|
||||
};
|
||||
|
||||
}
|
258
Libraries/LibWeb/Dump.cpp
Normal file
258
Libraries/LibWeb/Dump.cpp
Normal file
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibWeb/CSS/PropertyID.h>
|
||||
#include <LibWeb/CSS/StyleSheet.h>
|
||||
#include <LibWeb/DOM/Comment.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/DocumentType.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
#include <LibWeb/Layout/LayoutText.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
void dump_tree(const Node& node)
|
||||
{
|
||||
static int indent = 0;
|
||||
for (int i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
if (is<Document>(node)) {
|
||||
dbgprintf("*Document*\n");
|
||||
} else if (is<Element>(node)) {
|
||||
dbgprintf("<%s", to<Element>(node).tag_name().characters());
|
||||
to<Element>(node).for_each_attribute([](auto& name, auto& value) {
|
||||
dbgprintf(" %s=%s", name.characters(), value.characters());
|
||||
});
|
||||
dbgprintf(">\n");
|
||||
} else if (is<Text>(node)) {
|
||||
dbgprintf("\"%s\"\n", static_cast<const Text&>(node).data().characters());
|
||||
} else if (is<DocumentType>(node)) {
|
||||
dbgprintf("<!DOCTYPE>\n");
|
||||
} else if (is<Comment>(node)) {
|
||||
dbgprintf("<!--%s-->\n", to<Comment>(node).data().characters());
|
||||
}
|
||||
++indent;
|
||||
if (is<ParentNode>(node)) {
|
||||
static_cast<const ParentNode&>(node).for_each_child([](auto& child) {
|
||||
dump_tree(child);
|
||||
});
|
||||
}
|
||||
--indent;
|
||||
}
|
||||
|
||||
void dump_tree(const LayoutNode& layout_node)
|
||||
{
|
||||
static size_t indent = 0;
|
||||
for (size_t i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
|
||||
String tag_name;
|
||||
if (layout_node.is_anonymous())
|
||||
tag_name = "(anonymous)";
|
||||
else if (is<Text>(layout_node.node()))
|
||||
tag_name = "#text";
|
||||
else if (is<Document>(layout_node.node()))
|
||||
tag_name = "#document";
|
||||
else if (is<Element>(layout_node.node()))
|
||||
tag_name = to<Element>(*layout_node.node()).tag_name();
|
||||
else
|
||||
tag_name = "???";
|
||||
|
||||
if (!layout_node.is_box()) {
|
||||
dbgprintf("%s {%s}\n", layout_node.class_name(), tag_name.characters());
|
||||
} else {
|
||||
auto& layout_box = to<LayoutBox>(layout_node);
|
||||
dbgprintf("%s {%s} at (%g,%g) size %gx%g",
|
||||
layout_box.class_name(),
|
||||
tag_name.characters(),
|
||||
layout_box.x(),
|
||||
layout_box.y(),
|
||||
layout_box.width(),
|
||||
layout_box.height());
|
||||
|
||||
// Dump the horizontal box properties
|
||||
dbgprintf(" [%g+%g+%g %g %g+%g+%g]",
|
||||
layout_box.box_model().margin().left.to_px(),
|
||||
layout_box.box_model().border().left.to_px(),
|
||||
layout_box.box_model().padding().left.to_px(),
|
||||
layout_box.width(),
|
||||
layout_box.box_model().padding().right.to_px(),
|
||||
layout_box.box_model().border().right.to_px(),
|
||||
layout_box.box_model().margin().right.to_px());
|
||||
|
||||
// And the vertical box properties
|
||||
dbgprintf(" [%g+%g+%g %g %g+%g+%g]",
|
||||
layout_box.box_model().margin().top.to_px(),
|
||||
layout_box.box_model().border().top.to_px(),
|
||||
layout_box.box_model().padding().top.to_px(),
|
||||
layout_box.height(),
|
||||
layout_box.box_model().padding().bottom.to_px(),
|
||||
layout_box.box_model().border().bottom.to_px(),
|
||||
layout_box.box_model().margin().bottom.to_px());
|
||||
|
||||
dbgprintf("\n");
|
||||
}
|
||||
|
||||
if (layout_node.is_block() && static_cast<const LayoutBlock&>(layout_node).children_are_inline()) {
|
||||
auto& block = static_cast<const LayoutBlock&>(layout_node);
|
||||
for (size_t i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
dbgprintf(" Line boxes (%d):\n", block.line_boxes().size());
|
||||
for (size_t line_box_index = 0; line_box_index < block.line_boxes().size(); ++line_box_index) {
|
||||
auto& line_box = block.line_boxes()[line_box_index];
|
||||
for (size_t i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
dbgprintf(" [%d] width: %g\n", line_box_index, line_box.width());
|
||||
for (size_t fragment_index = 0; fragment_index < line_box.fragments().size(); ++fragment_index) {
|
||||
auto& fragment = line_box.fragments()[fragment_index];
|
||||
for (size_t i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
dbgprintf(" [%d] layout_node: %s{%p}, start: %d, length: %d, rect: %s\n",
|
||||
fragment_index,
|
||||
fragment.layout_node().class_name(),
|
||||
&fragment.layout_node(),
|
||||
fragment.start(),
|
||||
fragment.length(),
|
||||
fragment.rect().to_string().characters());
|
||||
if (fragment.layout_node().is_text()) {
|
||||
for (size_t i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
auto& layout_text = static_cast<const LayoutText&>(fragment.layout_node());
|
||||
auto fragment_text = layout_text.text_for_rendering().substring(fragment.start(), fragment.length());
|
||||
dbgprintf(" text: \"%s\"\n", fragment_text.characters());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layout_node.style().for_each_property([&](auto property_id, auto& value) {
|
||||
for (size_t i = 0; i < indent; ++i)
|
||||
dbgprintf(" ");
|
||||
dbgprintf(" (%s: %s)\n", CSS::string_from_property_id(property_id), value.to_string().characters());
|
||||
});
|
||||
|
||||
++indent;
|
||||
layout_node.for_each_child([](auto& child) {
|
||||
dump_tree(child);
|
||||
});
|
||||
--indent;
|
||||
}
|
||||
|
||||
void dump_rule(const StyleRule& rule)
|
||||
{
|
||||
dbgprintf("Rule:\n");
|
||||
for (auto& selector : rule.selectors()) {
|
||||
dbgprintf(" Selector:\n");
|
||||
|
||||
for (auto& complex_selector : selector.complex_selectors()) {
|
||||
dbgprintf(" ");
|
||||
|
||||
const char* relation_description = "";
|
||||
switch (complex_selector.relation) {
|
||||
case Selector::ComplexSelector::Relation::None:
|
||||
break;
|
||||
case Selector::ComplexSelector::Relation::ImmediateChild:
|
||||
relation_description = "ImmediateChild";
|
||||
break;
|
||||
case Selector::ComplexSelector::Relation::Descendant:
|
||||
relation_description = "Descendant";
|
||||
break;
|
||||
case Selector::ComplexSelector::Relation::AdjacentSibling:
|
||||
relation_description = "AdjacentSibling";
|
||||
break;
|
||||
case Selector::ComplexSelector::Relation::GeneralSibling:
|
||||
relation_description = "GeneralSibling";
|
||||
break;
|
||||
}
|
||||
|
||||
if (*relation_description)
|
||||
dbgprintf("{%s} ", relation_description);
|
||||
|
||||
for (size_t i = 0; i < complex_selector.compound_selector.size(); ++i) {
|
||||
auto& simple_selector = complex_selector.compound_selector[i];
|
||||
const char* type_description = "Unknown";
|
||||
switch (simple_selector.type) {
|
||||
case Selector::SimpleSelector::Type::Invalid:
|
||||
type_description = "Invalid";
|
||||
break;
|
||||
case Selector::SimpleSelector::Type::Universal:
|
||||
type_description = "Universal";
|
||||
break;
|
||||
case Selector::SimpleSelector::Type::Id:
|
||||
type_description = "Id";
|
||||
break;
|
||||
case Selector::SimpleSelector::Type::Class:
|
||||
type_description = "Class";
|
||||
break;
|
||||
case Selector::SimpleSelector::Type::TagName:
|
||||
type_description = "TagName";
|
||||
break;
|
||||
}
|
||||
const char* attribute_match_type_description = "";
|
||||
switch (simple_selector.attribute_match_type) {
|
||||
case Selector::SimpleSelector::AttributeMatchType::None:
|
||||
break;
|
||||
case Selector::SimpleSelector::AttributeMatchType::HasAttribute:
|
||||
attribute_match_type_description = "HasAttribute";
|
||||
break;
|
||||
case Selector::SimpleSelector::AttributeMatchType::ExactValueMatch:
|
||||
attribute_match_type_description = "ExactValueMatch";
|
||||
break;
|
||||
}
|
||||
|
||||
dbgprintf("%s:%s", type_description, simple_selector.value.characters());
|
||||
if (simple_selector.attribute_match_type != Selector::SimpleSelector::AttributeMatchType::None) {
|
||||
dbgprintf(" [%s, name='%s', value='%s']", attribute_match_type_description, simple_selector.attribute_name.characters(), simple_selector.attribute_value.characters());
|
||||
}
|
||||
|
||||
if (i != complex_selector.compound_selector.size() - 1)
|
||||
dbgprintf(", ");
|
||||
}
|
||||
dbgprintf("\n");
|
||||
}
|
||||
}
|
||||
dbgprintf(" Declarations:\n");
|
||||
for (auto& property : rule.declaration().properties()) {
|
||||
dbgprintf(" %s: '%s'\n", CSS::string_from_property_id(property.property_id), property.value->to_string().characters());
|
||||
}
|
||||
}
|
||||
|
||||
void dump_sheet(const StyleSheet& sheet)
|
||||
{
|
||||
dbgprintf("StyleSheet{%p}: %d rule(s)\n", &sheet, sheet.rules().size());
|
||||
|
||||
for (auto& rule : sheet.rules()) {
|
||||
dump_rule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
43
Libraries/LibWeb/Dump.h
Normal file
43
Libraries/LibWeb/Dump.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Node;
|
||||
class LayoutNode;
|
||||
class StyleRule;
|
||||
class StyleSheet;
|
||||
|
||||
void dump_tree(const Node&);
|
||||
void dump_tree(const LayoutNode&);
|
||||
void dump_sheet(const StyleSheet&);
|
||||
void dump_rule(const StyleRule&);
|
||||
|
||||
#undef HTML_DEBUG
|
||||
|
||||
}
|
47
Libraries/LibWeb/FontCache.cpp
Normal file
47
Libraries/LibWeb/FontCache.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibWeb/FontCache.h>
|
||||
|
||||
FontCache& FontCache::the()
|
||||
{
|
||||
static FontCache cache;
|
||||
return cache;
|
||||
}
|
||||
|
||||
RefPtr<Gfx::Font> FontCache::get(const FontSelector& font_selector) const
|
||||
{
|
||||
auto cached_font = m_fonts.get(font_selector);
|
||||
if (cached_font.has_value())
|
||||
return cached_font.value();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FontCache::set(const FontSelector& font_selector, NonnullRefPtr<Gfx::Font> font)
|
||||
{
|
||||
m_fonts.set(font_selector, move(font));
|
||||
}
|
59
Libraries/LibWeb/FontCache.h
Normal file
59
Libraries/LibWeb/FontCache.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
|
||||
struct FontSelector {
|
||||
String family;
|
||||
String weight;
|
||||
|
||||
bool operator==(const FontSelector& other) const
|
||||
{
|
||||
return family == other.family && weight == other.weight;
|
||||
}
|
||||
};
|
||||
|
||||
namespace AK {
|
||||
template<>
|
||||
struct Traits<FontSelector> : public GenericTraits<FontSelector> {
|
||||
static unsigned hash(const FontSelector& key) { return pair_int_hash(key.family.hash(), key.weight.hash()); }
|
||||
};
|
||||
}
|
||||
|
||||
class FontCache {
|
||||
public:
|
||||
static FontCache& the();
|
||||
RefPtr<Gfx::Font> get(const FontSelector&) const;
|
||||
void set(const FontSelector&, NonnullRefPtr<Gfx::Font>);
|
||||
|
||||
private:
|
||||
FontCache() {}
|
||||
mutable HashMap<FontSelector, NonnullRefPtr<Gfx::Font>> m_fonts;
|
||||
};
|
37
Libraries/LibWeb/Forward.h
Normal file
37
Libraries/LibWeb/Forward.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Document;
|
||||
class Element;
|
||||
class Frame;
|
||||
class HtmlView;
|
||||
class Node;
|
||||
|
||||
}
|
84
Libraries/LibWeb/Frame.cpp
Normal file
84
Libraries/LibWeb/Frame.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/HtmlView.h>
|
||||
#include <LibWeb/Layout/LayoutDocument.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
Frame::Frame(HtmlView& html_view)
|
||||
: m_html_view(html_view.make_weak_ptr())
|
||||
{
|
||||
}
|
||||
|
||||
Frame::~Frame()
|
||||
{
|
||||
}
|
||||
|
||||
void Frame::set_document(Document* document)
|
||||
{
|
||||
if (m_document == document)
|
||||
return;
|
||||
|
||||
if (m_document)
|
||||
m_document->detach_from_frame({}, *this);
|
||||
|
||||
m_document = document;
|
||||
|
||||
if (m_document)
|
||||
m_document->attach_to_frame({}, *this);
|
||||
}
|
||||
|
||||
void Frame::set_size(const Gfx::Size& size)
|
||||
{
|
||||
if (m_size == size)
|
||||
return;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
void Frame::set_viewport_rect(const Gfx::Rect& rect)
|
||||
{
|
||||
if (m_viewport_rect == rect)
|
||||
return;
|
||||
m_viewport_rect = rect;
|
||||
|
||||
if (m_document && m_document->layout_node())
|
||||
m_document->layout_node()->did_set_viewport_rect({}, rect);
|
||||
}
|
||||
|
||||
void Frame::set_needs_display(const Gfx::Rect& rect)
|
||||
{
|
||||
if (!m_viewport_rect.intersects(rect))
|
||||
return;
|
||||
|
||||
if (!on_set_needs_display)
|
||||
return;
|
||||
on_set_needs_display(rect);
|
||||
}
|
||||
|
||||
}
|
73
Libraries/LibWeb/Frame.h
Normal file
73
Libraries/LibWeb/Frame.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibWeb/TreeNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Document;
|
||||
class HtmlView;
|
||||
|
||||
class Frame : public TreeNode<Frame> {
|
||||
public:
|
||||
static NonnullRefPtr<Frame> create(HtmlView& html_view) { return adopt(*new Frame(html_view)); }
|
||||
~Frame();
|
||||
|
||||
const Document* document() const { return m_document; }
|
||||
Document* document() { return m_document; }
|
||||
|
||||
void set_document(Document*);
|
||||
|
||||
HtmlView* html_view() { return m_html_view; }
|
||||
const HtmlView* html_view() const { return m_html_view; }
|
||||
|
||||
const Gfx::Size& size() const { return m_size; }
|
||||
void set_size(const Gfx::Size&);
|
||||
|
||||
void set_needs_display(const Gfx::Rect&);
|
||||
Function<void(const Gfx::Rect&)> on_set_needs_display;
|
||||
|
||||
void set_viewport_rect(const Gfx::Rect&);
|
||||
Gfx::Rect viewport_rect() const { return m_viewport_rect; }
|
||||
|
||||
private:
|
||||
explicit Frame(HtmlView&);
|
||||
|
||||
WeakPtr<HtmlView> m_html_view;
|
||||
RefPtr<Document> m_document;
|
||||
Gfx::Size m_size;
|
||||
Gfx::Rect m_viewport_rect;
|
||||
};
|
||||
|
||||
}
|
417
Libraries/LibWeb/HtmlView.cpp
Normal file
417
Libraries/LibWeb/HtmlView.cpp
Normal file
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <AK/FileSystemPath.h>
|
||||
#include <AK/URL.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibGUI/ScrollBar.h>
|
||||
#include <LibGUI/Window.h>
|
||||
#include <LibGfx/PNGLoader.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/ElementFactory.h>
|
||||
#include <LibWeb/DOM/HTMLAnchorElement.h>
|
||||
#include <LibWeb/DOM/HTMLImageElement.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/HtmlView.h>
|
||||
#include <LibWeb/Layout/LayoutDocument.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
#include <LibWeb/Parser/HTMLParser.h>
|
||||
#include <LibWeb/RenderingContext.h>
|
||||
#include <LibWeb/ResourceLoader.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
HtmlView::HtmlView()
|
||||
: m_main_frame(Web::Frame::create(*this))
|
||||
{
|
||||
main_frame().on_set_needs_display = [this](auto& content_rect) {
|
||||
if (content_rect.is_empty()) {
|
||||
update();
|
||||
return;
|
||||
}
|
||||
Gfx::Rect adjusted_rect = content_rect;
|
||||
adjusted_rect.set_location(to_widget_position(content_rect.location()));
|
||||
update(adjusted_rect);
|
||||
};
|
||||
|
||||
set_should_hide_unnecessary_scrollbars(true);
|
||||
set_background_role(ColorRole::Base);
|
||||
}
|
||||
|
||||
HtmlView::~HtmlView()
|
||||
{
|
||||
}
|
||||
|
||||
void HtmlView::set_document(Document* new_document)
|
||||
{
|
||||
RefPtr<Document> old_document = document();
|
||||
|
||||
if (new_document == old_document)
|
||||
return;
|
||||
|
||||
if (old_document)
|
||||
old_document->on_layout_updated = nullptr;
|
||||
|
||||
main_frame().set_document(new_document);
|
||||
|
||||
if (new_document) {
|
||||
new_document->on_layout_updated = [this] {
|
||||
layout_and_sync_size();
|
||||
update();
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef HTML_DEBUG
|
||||
if (document != nullptr) {
|
||||
dbgprintf("\033[33;1mLayout tree before layout:\033[0m\n");
|
||||
::dump_tree(*layout_root());
|
||||
}
|
||||
#endif
|
||||
|
||||
layout_and_sync_size();
|
||||
update();
|
||||
}
|
||||
|
||||
void HtmlView::layout_and_sync_size()
|
||||
{
|
||||
if (!document())
|
||||
return;
|
||||
|
||||
bool had_vertical_scrollbar = vertical_scrollbar().is_visible();
|
||||
bool had_horizontal_scrollbar = horizontal_scrollbar().is_visible();
|
||||
|
||||
main_frame().set_size(available_size());
|
||||
document()->layout();
|
||||
set_content_size(enclosing_int_rect(layout_root()->rect()).size());
|
||||
|
||||
// NOTE: If layout caused us to gain or lose scrollbars, we have to lay out again
|
||||
// since the scrollbars now take up some of the available space.
|
||||
if (had_vertical_scrollbar != vertical_scrollbar().is_visible() || had_horizontal_scrollbar != horizontal_scrollbar().is_visible()) {
|
||||
main_frame().set_size(available_size());
|
||||
document()->layout();
|
||||
set_content_size(enclosing_int_rect(layout_root()->rect()).size());
|
||||
}
|
||||
|
||||
main_frame().set_viewport_rect(visible_content_rect());
|
||||
|
||||
#ifdef HTML_DEBUG
|
||||
dbgprintf("\033[33;1mLayout tree after layout:\033[0m\n");
|
||||
::dump_tree(*layout_root());
|
||||
#endif
|
||||
}
|
||||
|
||||
void HtmlView::resize_event(GUI::ResizeEvent& event)
|
||||
{
|
||||
GUI::ScrollableWidget::resize_event(event);
|
||||
layout_and_sync_size();
|
||||
}
|
||||
|
||||
void HtmlView::paint_event(GUI::PaintEvent& event)
|
||||
{
|
||||
GUI::Frame::paint_event(event);
|
||||
|
||||
GUI::Painter painter(*this);
|
||||
painter.add_clip_rect(widget_inner_rect());
|
||||
painter.add_clip_rect(event.rect());
|
||||
|
||||
if (!layout_root()) {
|
||||
painter.fill_rect(event.rect(), palette().color(background_role()));
|
||||
return;
|
||||
}
|
||||
|
||||
painter.fill_rect(event.rect(), document()->background_color(palette()));
|
||||
|
||||
if (auto background_bitmap = document()->background_image()) {
|
||||
painter.draw_tiled_bitmap(event.rect(), *background_bitmap);
|
||||
}
|
||||
|
||||
painter.translate(frame_thickness(), frame_thickness());
|
||||
painter.translate(-horizontal_scrollbar().value(), -vertical_scrollbar().value());
|
||||
|
||||
RenderingContext context(painter, palette());
|
||||
context.set_should_show_line_box_borders(m_should_show_line_box_borders);
|
||||
context.set_viewport_rect(visible_content_rect());
|
||||
layout_root()->render(context);
|
||||
}
|
||||
|
||||
void HtmlView::mousemove_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!layout_root())
|
||||
return GUI::ScrollableWidget::mousemove_event(event);
|
||||
|
||||
bool hovered_node_changed = false;
|
||||
bool is_hovering_link = false;
|
||||
bool was_hovering_link = document()->hovered_node() && document()->hovered_node()->is_link();
|
||||
auto result = layout_root()->hit_test(to_content_position(event.position()));
|
||||
const HTMLAnchorElement* hovered_link_element = nullptr;
|
||||
if (result.layout_node) {
|
||||
auto* node = result.layout_node->node();
|
||||
hovered_node_changed = node != document()->hovered_node();
|
||||
document()->set_hovered_node(const_cast<Node*>(node));
|
||||
if (node) {
|
||||
hovered_link_element = node->enclosing_link_element();
|
||||
if (hovered_link_element) {
|
||||
#ifdef HTML_DEBUG
|
||||
dbg() << "HtmlView: hovering over a link to " << hovered_link_element->href();
|
||||
#endif
|
||||
is_hovering_link = true;
|
||||
}
|
||||
}
|
||||
if (m_in_mouse_selection) {
|
||||
layout_root()->selection().set_end({ result.layout_node, result.index_in_node });
|
||||
dump_selection("MouseMove");
|
||||
update();
|
||||
}
|
||||
}
|
||||
if (window())
|
||||
window()->set_override_cursor(is_hovering_link ? GUI::StandardCursor::Hand : GUI::StandardCursor::None);
|
||||
if (hovered_node_changed) {
|
||||
update();
|
||||
auto* hovered_html_element = document()->hovered_node() ? document()->hovered_node()->enclosing_html_element() : nullptr;
|
||||
if (hovered_html_element && !hovered_html_element->title().is_null()) {
|
||||
auto screen_position = screen_relative_rect().location().translated(event.position());
|
||||
GUI::Application::the().show_tooltip(hovered_html_element->title(), screen_position.translated(4, 4));
|
||||
} else {
|
||||
GUI::Application::the().hide_tooltip();
|
||||
}
|
||||
}
|
||||
if (is_hovering_link != was_hovering_link) {
|
||||
if (on_link_hover) {
|
||||
on_link_hover(hovered_link_element ? document()->complete_url(hovered_link_element->href()).to_string() : String());
|
||||
}
|
||||
}
|
||||
event.accept();
|
||||
}
|
||||
|
||||
void HtmlView::mousedown_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!layout_root())
|
||||
return GUI::ScrollableWidget::mousemove_event(event);
|
||||
|
||||
bool hovered_node_changed = false;
|
||||
auto result = layout_root()->hit_test(to_content_position(event.position()));
|
||||
if (result.layout_node) {
|
||||
auto* node = result.layout_node->node();
|
||||
hovered_node_changed = node != document()->hovered_node();
|
||||
document()->set_hovered_node(const_cast<Node*>(node));
|
||||
if (node) {
|
||||
if (auto* link = node->enclosing_link_element()) {
|
||||
dbg() << "HtmlView: clicking on a link to " << link->href();
|
||||
if (on_link_click)
|
||||
on_link_click(link->href());
|
||||
} else {
|
||||
if (event.button() == GUI::MouseButton::Left) {
|
||||
layout_root()->selection().set({ result.layout_node, result.index_in_node }, {});
|
||||
dump_selection("MouseDown");
|
||||
m_in_mouse_selection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hovered_node_changed)
|
||||
update();
|
||||
event.accept();
|
||||
}
|
||||
|
||||
void HtmlView::mouseup_event(GUI::MouseEvent& event)
|
||||
{
|
||||
if (!layout_root())
|
||||
return GUI::ScrollableWidget::mouseup_event(event);
|
||||
|
||||
if (event.button() == GUI::MouseButton::Left) {
|
||||
dump_selection("MouseUp");
|
||||
m_in_mouse_selection = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HtmlView::keydown_event(GUI::KeyEvent& event)
|
||||
{
|
||||
if (event.modifiers() == 0) {
|
||||
switch (event.key()) {
|
||||
case Key_Home:
|
||||
vertical_scrollbar().set_value(0);
|
||||
break;
|
||||
case Key_End:
|
||||
vertical_scrollbar().set_value(vertical_scrollbar().max());
|
||||
break;
|
||||
case Key_Down:
|
||||
vertical_scrollbar().set_value(vertical_scrollbar().value() + vertical_scrollbar().step());
|
||||
break;
|
||||
case Key_Up:
|
||||
vertical_scrollbar().set_value(vertical_scrollbar().value() - vertical_scrollbar().step());
|
||||
break;
|
||||
case Key_Left:
|
||||
horizontal_scrollbar().set_value(horizontal_scrollbar().value() + horizontal_scrollbar().step());
|
||||
break;
|
||||
case Key_Right:
|
||||
horizontal_scrollbar().set_value(horizontal_scrollbar().value() - horizontal_scrollbar().step());
|
||||
break;
|
||||
case Key_PageDown:
|
||||
vertical_scrollbar().set_value(vertical_scrollbar().value() + frame_inner_rect().height());
|
||||
break;
|
||||
case Key_PageUp:
|
||||
vertical_scrollbar().set_value(vertical_scrollbar().value() - frame_inner_rect().height());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.accept();
|
||||
}
|
||||
|
||||
void HtmlView::reload()
|
||||
{
|
||||
load(main_frame().document()->url());
|
||||
}
|
||||
|
||||
static RefPtr<Document> create_image_document(const ByteBuffer& data, const URL& url)
|
||||
{
|
||||
auto document = adopt(*new Document);
|
||||
document->set_url(url);
|
||||
|
||||
auto bitmap = Gfx::load_png_from_memory(data.data(), data.size());
|
||||
ASSERT(bitmap);
|
||||
|
||||
auto html_element = create_element(document, "html");
|
||||
document->append_child(html_element);
|
||||
|
||||
auto head_element = create_element(document, "head");
|
||||
html_element->append_child(head_element);
|
||||
auto title_element = create_element(document, "title");
|
||||
head_element->append_child(title_element);
|
||||
|
||||
auto basename = FileSystemPath(url.path()).basename();
|
||||
auto title_text = adopt(*new Text(document, String::format("%s [%dx%d]", basename.characters(), bitmap->width(), bitmap->height())));
|
||||
title_element->append_child(title_text);
|
||||
|
||||
auto body_element = create_element(document, "body");
|
||||
html_element->append_child(body_element);
|
||||
|
||||
auto image_element = create_element(document, "img");
|
||||
image_element->set_attribute("src", url.to_string());
|
||||
body_element->append_child(image_element);
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
void HtmlView::load(const URL& url)
|
||||
{
|
||||
dbg() << "HtmlView::load: " << url.to_string();
|
||||
|
||||
if (window())
|
||||
window()->set_override_cursor(GUI::StandardCursor::None);
|
||||
|
||||
if (on_load_start)
|
||||
on_load_start(url);
|
||||
|
||||
ResourceLoader::the().load(url, [this, url](auto data) {
|
||||
if (data.is_null()) {
|
||||
dbg() << "Load failed!";
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
RefPtr<Document> document;
|
||||
if (url.path().ends_with(".png")) {
|
||||
document = create_image_document(data, url);
|
||||
} else {
|
||||
document = parse_html_document(data, url);
|
||||
}
|
||||
ASSERT(document);
|
||||
set_document(document);
|
||||
if (on_title_change)
|
||||
on_title_change(document->title());
|
||||
});
|
||||
}
|
||||
|
||||
const LayoutDocument* HtmlView::layout_root() const
|
||||
{
|
||||
return document() ? document()->layout_node() : nullptr;
|
||||
}
|
||||
|
||||
LayoutDocument* HtmlView::layout_root()
|
||||
{
|
||||
if (!document())
|
||||
return nullptr;
|
||||
return const_cast<LayoutDocument*>(document()->layout_node());
|
||||
}
|
||||
|
||||
void HtmlView::scroll_to_anchor(const StringView& name)
|
||||
{
|
||||
if (!document())
|
||||
return;
|
||||
|
||||
auto* element = document()->get_element_by_id(name);
|
||||
if (!element) {
|
||||
auto candidates = document()->get_elements_by_name(name);
|
||||
for (auto* candidate : candidates) {
|
||||
if (is<HTMLAnchorElement>(*candidate)) {
|
||||
element = to<HTMLAnchorElement>(candidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!element) {
|
||||
dbg() << "HtmlView::scroll_to_anchor(): Anchor not found: '" << name << "'";
|
||||
return;
|
||||
}
|
||||
if (!element->layout_node()) {
|
||||
dbg() << "HtmlView::scroll_to_anchor(): Anchor found but without layout node: '" << name << "'";
|
||||
return;
|
||||
}
|
||||
auto& layout_node = *element->layout_node();
|
||||
Gfx::FloatRect float_rect { layout_node.box_type_agnostic_position(), { (float)visible_content_rect().width(), (float)visible_content_rect().height() } };
|
||||
scroll_into_view(enclosing_int_rect(float_rect), true, true);
|
||||
window()->set_override_cursor(GUI::StandardCursor::None);
|
||||
}
|
||||
|
||||
Document* HtmlView::document()
|
||||
{
|
||||
return main_frame().document();
|
||||
}
|
||||
|
||||
const Document* HtmlView::document() const
|
||||
{
|
||||
return main_frame().document();
|
||||
}
|
||||
|
||||
void HtmlView::dump_selection(const char* event_name)
|
||||
{
|
||||
dbg() << event_name << " selection start: "
|
||||
<< layout_root()->selection().start().layout_node << ":" << layout_root()->selection().start().index_in_node << ", end: "
|
||||
<< layout_root()->selection().end().layout_node << ":" << layout_root()->selection().end().index_in_node;
|
||||
}
|
||||
|
||||
void HtmlView::did_scroll()
|
||||
{
|
||||
main_frame().set_viewport_rect(visible_content_rect());
|
||||
}
|
||||
|
||||
}
|
88
Libraries/LibWeb/HtmlView.h
Normal file
88
Libraries/LibWeb/HtmlView.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AK/URL.h>
|
||||
#include <LibGUI/ScrollableWidget.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Frame;
|
||||
|
||||
class HtmlView : public GUI::ScrollableWidget {
|
||||
C_OBJECT(HtmlView)
|
||||
public:
|
||||
virtual ~HtmlView() override;
|
||||
|
||||
Document* document();
|
||||
const Document* document() const;
|
||||
void set_document(Document*);
|
||||
|
||||
const LayoutDocument* layout_root() const;
|
||||
LayoutDocument* layout_root();
|
||||
|
||||
Web::Frame& main_frame() { return *m_main_frame; }
|
||||
const Web::Frame& main_frame() const { return *m_main_frame; }
|
||||
|
||||
void reload();
|
||||
void load(const URL&);
|
||||
void scroll_to_anchor(const StringView&);
|
||||
|
||||
URL url() const;
|
||||
|
||||
void set_should_show_line_box_borders(bool value) { m_should_show_line_box_borders = value; }
|
||||
|
||||
Function<void(const String&)> on_link_click;
|
||||
Function<void(const String&)> on_link_hover;
|
||||
Function<void(const String&)> on_title_change;
|
||||
Function<void(const URL&)> on_load_start;
|
||||
|
||||
virtual bool accepts_focus() const override { return true; }
|
||||
|
||||
protected:
|
||||
HtmlView();
|
||||
|
||||
virtual void resize_event(GUI::ResizeEvent&) override;
|
||||
virtual void paint_event(GUI::PaintEvent&) override;
|
||||
virtual void mousemove_event(GUI::MouseEvent&) override;
|
||||
virtual void mousedown_event(GUI::MouseEvent&) override;
|
||||
virtual void mouseup_event(GUI::MouseEvent&) override;
|
||||
virtual void keydown_event(GUI::KeyEvent&) override;
|
||||
|
||||
private:
|
||||
virtual void did_scroll() override;
|
||||
|
||||
void layout_and_sync_size();
|
||||
void dump_selection(const char* event_name);
|
||||
|
||||
RefPtr<Web::Frame> m_main_frame;
|
||||
|
||||
bool m_should_show_line_box_borders { false };
|
||||
bool m_in_mouse_selection { false };
|
||||
};
|
||||
|
||||
}
|
49
Libraries/LibWeb/Layout/BoxModelMetrics.cpp
Normal file
49
Libraries/LibWeb/Layout/BoxModelMetrics.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/Layout/BoxModelMetrics.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
BoxModelMetrics::BoxModelMetrics()
|
||||
{
|
||||
}
|
||||
|
||||
BoxModelMetrics::~BoxModelMetrics()
|
||||
{
|
||||
}
|
||||
|
||||
BoxModelMetrics::PixelBox BoxModelMetrics::full_margin() const
|
||||
{
|
||||
return {
|
||||
m_margin.top.to_px() + m_border.top.to_px() + m_padding.top.to_px(),
|
||||
m_margin.right.to_px() + m_border.right.to_px() + m_padding.right.to_px(),
|
||||
m_margin.bottom.to_px() + m_border.bottom.to_px() + m_padding.bottom.to_px(),
|
||||
m_margin.left.to_px() + m_border.left.to_px() + m_padding.left.to_px(),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
62
Libraries/LibWeb/Layout/BoxModelMetrics.h
Normal file
62
Libraries/LibWeb/Layout/BoxModelMetrics.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibWeb/CSS/LengthBox.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class BoxModelMetrics {
|
||||
public:
|
||||
BoxModelMetrics();
|
||||
~BoxModelMetrics();
|
||||
|
||||
LengthBox& margin() { return m_margin; }
|
||||
LengthBox& padding() { return m_padding; }
|
||||
LengthBox& border() { return m_border; }
|
||||
|
||||
const LengthBox& margin() const { return m_margin; }
|
||||
const LengthBox& padding() const { return m_padding; }
|
||||
const LengthBox& border() const { return m_border; }
|
||||
|
||||
struct PixelBox {
|
||||
float top;
|
||||
float right;
|
||||
float bottom;
|
||||
float left;
|
||||
};
|
||||
|
||||
PixelBox full_margin() const;
|
||||
|
||||
private:
|
||||
LengthBox m_margin;
|
||||
LengthBox m_padding;
|
||||
LengthBox m_border;
|
||||
};
|
||||
|
||||
}
|
390
Libraries/LibWeb/Layout/LayoutBlock.cpp
Normal file
390
Libraries/LibWeb/Layout/LayoutBlock.cpp
Normal file
|
@ -0,0 +1,390 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibWeb/CSS/StyleResolver.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutInline.h>
|
||||
#include <LibWeb/Layout/LayoutReplaced.h>
|
||||
#include <LibWeb/Layout/LayoutText.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
LayoutBlock::LayoutBlock(const Node* node, NonnullRefPtr<StyleProperties> style)
|
||||
: LayoutBox(node, move(style))
|
||||
{
|
||||
}
|
||||
|
||||
LayoutBlock::~LayoutBlock()
|
||||
{
|
||||
}
|
||||
|
||||
LayoutNode& LayoutBlock::inline_wrapper()
|
||||
{
|
||||
if (!last_child() || !last_child()->is_block() || last_child()->node() != nullptr) {
|
||||
append_child(adopt(*new LayoutBlock(nullptr, style_for_anonymous_block())));
|
||||
last_child()->set_children_are_inline(true);
|
||||
}
|
||||
return *last_child();
|
||||
}
|
||||
|
||||
void LayoutBlock::layout()
|
||||
{
|
||||
compute_width();
|
||||
compute_position();
|
||||
|
||||
if (children_are_inline())
|
||||
layout_inline_children();
|
||||
else
|
||||
layout_block_children();
|
||||
|
||||
compute_height();
|
||||
}
|
||||
|
||||
void LayoutBlock::layout_block_children()
|
||||
{
|
||||
ASSERT(!children_are_inline());
|
||||
float content_height = 0;
|
||||
for_each_child([&](auto& child) {
|
||||
// FIXME: What should we do here? Something like a <table> might have a bunch of useless text children..
|
||||
if (child.is_inline())
|
||||
return;
|
||||
auto& child_block = static_cast<LayoutBlock&>(child);
|
||||
child_block.layout();
|
||||
content_height = child_block.rect().bottom() + child_block.box_model().full_margin().bottom - rect().top();
|
||||
});
|
||||
rect().set_height(content_height);
|
||||
}
|
||||
|
||||
void LayoutBlock::layout_inline_children()
|
||||
{
|
||||
ASSERT(children_are_inline());
|
||||
m_line_boxes.clear();
|
||||
for_each_child([&](auto& child) {
|
||||
ASSERT(child.is_inline());
|
||||
child.split_into_lines(*this);
|
||||
});
|
||||
|
||||
for (auto& line_box : m_line_boxes) {
|
||||
line_box.trim_trailing_whitespace();
|
||||
}
|
||||
|
||||
float min_line_height = style().line_height();
|
||||
float line_spacing = min_line_height - style().font().glyph_height();
|
||||
float content_height = 0;
|
||||
|
||||
// FIXME: This should be done by the CSS parser!
|
||||
CSS::ValueID text_align = CSS::ValueID::Left;
|
||||
auto text_align_string = style().string_or_fallback(CSS::PropertyID::TextAlign, "left");
|
||||
if (text_align_string == "center")
|
||||
text_align = CSS::ValueID::Center;
|
||||
else if (text_align_string == "left")
|
||||
text_align = CSS::ValueID::Left;
|
||||
else if (text_align_string == "right")
|
||||
text_align = CSS::ValueID::Right;
|
||||
else if (text_align_string == "justify")
|
||||
text_align = CSS::ValueID::Justify;
|
||||
|
||||
for (auto& line_box : m_line_boxes) {
|
||||
float max_height = min_line_height;
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
max_height = max(max_height, fragment.rect().height());
|
||||
}
|
||||
|
||||
float x_offset = x();
|
||||
float excess_horizontal_space = (float)width() - line_box.width();
|
||||
|
||||
switch (text_align) {
|
||||
case CSS::ValueID::Center:
|
||||
x_offset += excess_horizontal_space / 2;
|
||||
break;
|
||||
case CSS::ValueID::Right:
|
||||
x_offset += excess_horizontal_space;
|
||||
break;
|
||||
case CSS::ValueID::Left:
|
||||
case CSS::ValueID::Justify:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
float excess_horizontal_space_including_whitespace = excess_horizontal_space;
|
||||
int whitespace_count = 0;
|
||||
if (text_align == CSS::ValueID::Justify) {
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
if (fragment.is_justifiable_whitespace()) {
|
||||
++whitespace_count;
|
||||
excess_horizontal_space_including_whitespace += fragment.rect().width();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float justified_space_width = whitespace_count ? (excess_horizontal_space_including_whitespace / (float)whitespace_count) : 0;
|
||||
|
||||
for (size_t i = 0; i < line_box.fragments().size(); ++i) {
|
||||
auto& fragment = line_box.fragments()[i];
|
||||
// Vertically align everyone's bottom to the line.
|
||||
// FIXME: Support other kinds of vertical alignment.
|
||||
fragment.rect().set_x(roundf(x_offset + fragment.rect().x()));
|
||||
fragment.rect().set_y(y() + content_height + (max_height - fragment.rect().height()) - (line_spacing / 2));
|
||||
|
||||
if (text_align == CSS::ValueID::Justify) {
|
||||
if (fragment.is_justifiable_whitespace()) {
|
||||
if (fragment.rect().width() != justified_space_width) {
|
||||
float diff = justified_space_width - fragment.rect().width();
|
||||
fragment.rect().set_width(justified_space_width);
|
||||
// Shift subsequent sibling fragments to the right to adjust for change in width.
|
||||
for (size_t j = i + 1; j < line_box.fragments().size(); ++j) {
|
||||
line_box.fragments()[j].rect().move_by(diff, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is<LayoutReplaced>(fragment.layout_node()))
|
||||
const_cast<LayoutReplaced&>(to<LayoutReplaced>(fragment.layout_node())).set_rect(fragment.rect());
|
||||
|
||||
float final_line_box_width = 0;
|
||||
for (auto& fragment : line_box.fragments())
|
||||
final_line_box_width += fragment.rect().width();
|
||||
line_box.m_width = final_line_box_width;
|
||||
}
|
||||
|
||||
content_height += max_height;
|
||||
}
|
||||
|
||||
rect().set_height(content_height);
|
||||
}
|
||||
|
||||
void LayoutBlock::compute_width()
|
||||
{
|
||||
auto& style = this->style();
|
||||
|
||||
auto auto_value = Length();
|
||||
auto zero_value = Length(0, Length::Type::Absolute);
|
||||
|
||||
Length margin_left;
|
||||
Length margin_right;
|
||||
Length border_left;
|
||||
Length border_right;
|
||||
Length padding_left;
|
||||
Length padding_right;
|
||||
|
||||
auto try_compute_width = [&](const auto& a_width) {
|
||||
Length width = a_width;
|
||||
#ifdef HTML_DEBUG
|
||||
dbg() << " Left: " << margin_left << "+" << border_left << "+" << padding_left;
|
||||
dbg() << "Right: " << margin_right << "+" << border_right << "+" << padding_right;
|
||||
#endif
|
||||
margin_left = style.length_or_fallback(CSS::PropertyID::MarginLeft, zero_value);
|
||||
margin_right = style.length_or_fallback(CSS::PropertyID::MarginRight, zero_value);
|
||||
border_left = style.length_or_fallback(CSS::PropertyID::BorderLeftWidth, zero_value);
|
||||
border_right = style.length_or_fallback(CSS::PropertyID::BorderRightWidth, zero_value);
|
||||
padding_left = style.length_or_fallback(CSS::PropertyID::PaddingLeft, zero_value);
|
||||
padding_right = style.length_or_fallback(CSS::PropertyID::PaddingRight, zero_value);
|
||||
|
||||
float total_px = 0;
|
||||
for (auto& value : { margin_left, border_left, padding_left, width, padding_right, border_right, margin_right }) {
|
||||
total_px += value.to_px();
|
||||
}
|
||||
|
||||
#ifdef HTML_DEBUG
|
||||
dbg() << "Total: " << total_px;
|
||||
#endif
|
||||
|
||||
// 10.3.3 Block-level, non-replaced elements in normal flow
|
||||
// If 'width' is not 'auto' and 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' (plus any of 'margin-left' or 'margin-right' that are not 'auto') is larger than the width of the containing block, then any 'auto' values for 'margin-left' or 'margin-right' are, for the following rules, treated as zero.
|
||||
if (width.is_auto() && total_px > containing_block()->width()) {
|
||||
if (margin_left.is_auto())
|
||||
margin_left = zero_value;
|
||||
if (margin_right.is_auto())
|
||||
margin_right = zero_value;
|
||||
}
|
||||
|
||||
// 10.3.3 cont'd.
|
||||
auto underflow_px = containing_block()->width() - total_px;
|
||||
|
||||
if (width.is_auto()) {
|
||||
if (margin_left.is_auto())
|
||||
margin_left = zero_value;
|
||||
if (margin_right.is_auto())
|
||||
margin_right = zero_value;
|
||||
if (underflow_px >= 0) {
|
||||
width = Length(underflow_px, Length::Type::Absolute);
|
||||
} else {
|
||||
width = zero_value;
|
||||
margin_right = Length(margin_right.to_px() + underflow_px, Length::Type::Absolute);
|
||||
}
|
||||
} else {
|
||||
if (!margin_left.is_auto() && !margin_right.is_auto()) {
|
||||
margin_right = Length(margin_right.to_px() + underflow_px, Length::Type::Absolute);
|
||||
} else if (!margin_left.is_auto() && margin_right.is_auto()) {
|
||||
margin_right = Length(underflow_px, Length::Type::Absolute);
|
||||
} else if (margin_left.is_auto() && !margin_right.is_auto()) {
|
||||
margin_left = Length(underflow_px, Length::Type::Absolute);
|
||||
} else { // margin_left.is_auto() && margin_right.is_auto()
|
||||
auto half_of_the_underflow = Length(underflow_px / 2, Length::Type::Absolute);
|
||||
margin_left = half_of_the_underflow;
|
||||
margin_right = half_of_the_underflow;
|
||||
}
|
||||
}
|
||||
return width;
|
||||
};
|
||||
|
||||
auto specified_width = style.length_or_fallback(CSS::PropertyID::Width, auto_value);
|
||||
|
||||
// 1. The tentative used width is calculated (without 'min-width' and 'max-width')
|
||||
auto used_width = try_compute_width(specified_width);
|
||||
|
||||
// 2. The tentative used width is greater than 'max-width', the rules above are applied again,
|
||||
// but this time using the computed value of 'max-width' as the computed value for 'width'.
|
||||
auto specified_max_width = style.length_or_fallback(CSS::PropertyID::MaxWidth, auto_value);
|
||||
if (!specified_max_width.is_auto()) {
|
||||
if (used_width.to_px() > specified_max_width.to_px()) {
|
||||
used_width = try_compute_width(specified_max_width);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. If the resulting width is smaller than 'min-width', the rules above are applied again,
|
||||
// but this time using the value of 'min-width' as the computed value for 'width'.
|
||||
auto specified_min_width = style.length_or_fallback(CSS::PropertyID::MinWidth, auto_value);
|
||||
if (!specified_min_width.is_auto()) {
|
||||
if (used_width.to_px() < specified_min_width.to_px()) {
|
||||
used_width = try_compute_width(specified_min_width);
|
||||
}
|
||||
}
|
||||
|
||||
rect().set_width(used_width.to_px());
|
||||
box_model().margin().left = margin_left;
|
||||
box_model().margin().right = margin_right;
|
||||
box_model().border().left = border_left;
|
||||
box_model().border().right = border_right;
|
||||
box_model().padding().left = padding_left;
|
||||
box_model().padding().right = padding_right;
|
||||
}
|
||||
|
||||
void LayoutBlock::compute_position()
|
||||
{
|
||||
auto& style = this->style();
|
||||
|
||||
auto auto_value = Length();
|
||||
auto zero_value = Length(0, Length::Type::Absolute);
|
||||
|
||||
auto width = style.length_or_fallback(CSS::PropertyID::Width, auto_value);
|
||||
|
||||
box_model().margin().top = style.length_or_fallback(CSS::PropertyID::MarginTop, zero_value);
|
||||
box_model().margin().bottom = style.length_or_fallback(CSS::PropertyID::MarginBottom, zero_value);
|
||||
box_model().border().top = style.length_or_fallback(CSS::PropertyID::BorderTopWidth, zero_value);
|
||||
box_model().border().bottom = style.length_or_fallback(CSS::PropertyID::BorderBottomWidth, zero_value);
|
||||
box_model().padding().top = style.length_or_fallback(CSS::PropertyID::PaddingTop, zero_value);
|
||||
box_model().padding().bottom = style.length_or_fallback(CSS::PropertyID::PaddingBottom, zero_value);
|
||||
rect().set_x(containing_block()->x() + box_model().margin().left.to_px() + box_model().border().left.to_px() + box_model().padding().left.to_px());
|
||||
|
||||
float top_border = -1;
|
||||
if (previous_sibling() != nullptr) {
|
||||
auto& previous_sibling_rect = previous_sibling()->rect();
|
||||
auto& previous_sibling_style = previous_sibling()->box_model();
|
||||
top_border = previous_sibling_rect.y() + previous_sibling_rect.height();
|
||||
top_border += previous_sibling_style.full_margin().bottom;
|
||||
} else {
|
||||
top_border = containing_block()->y();
|
||||
}
|
||||
rect().set_y(top_border + box_model().full_margin().top);
|
||||
}
|
||||
|
||||
void LayoutBlock::compute_height()
|
||||
{
|
||||
auto& style = this->style();
|
||||
|
||||
auto height_property = style.property(CSS::PropertyID::Height);
|
||||
if (!height_property.has_value())
|
||||
return;
|
||||
auto height_length = height_property.value()->to_length();
|
||||
if (height_length.is_absolute())
|
||||
rect().set_height(height_length.to_px());
|
||||
}
|
||||
|
||||
void LayoutBlock::render(RenderingContext& context)
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
|
||||
LayoutBox::render(context);
|
||||
|
||||
if (children_are_inline()) {
|
||||
for (auto& line_box : m_line_boxes) {
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
if (context.should_show_line_box_borders())
|
||||
context.painter().draw_rect(enclosing_int_rect(fragment.rect()), Color::Green);
|
||||
fragment.render(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HitTestResult LayoutBlock::hit_test(const Gfx::Point& position) const
|
||||
{
|
||||
if (!children_are_inline())
|
||||
return LayoutBox::hit_test(position);
|
||||
|
||||
HitTestResult result;
|
||||
for (auto& line_box : m_line_boxes) {
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
if (enclosing_int_rect(fragment.rect()).contains(position)) {
|
||||
return { fragment.layout_node(), fragment.text_index_at(position.x()) };
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
NonnullRefPtr<StyleProperties> LayoutBlock::style_for_anonymous_block() const
|
||||
{
|
||||
auto new_style = StyleProperties::create();
|
||||
|
||||
style().for_each_property([&](auto property_id, auto& value) {
|
||||
if (StyleResolver::is_inherited_property(property_id))
|
||||
new_style->set_property(property_id, value);
|
||||
});
|
||||
|
||||
return new_style;
|
||||
}
|
||||
|
||||
LineBox& LayoutBlock::ensure_last_line_box()
|
||||
{
|
||||
if (m_line_boxes.is_empty())
|
||||
m_line_boxes.append(LineBox());
|
||||
return m_line_boxes.last();
|
||||
}
|
||||
|
||||
LineBox& LayoutBlock::add_line_box()
|
||||
{
|
||||
m_line_boxes.append(LineBox());
|
||||
return m_line_boxes.last();
|
||||
}
|
||||
|
||||
}
|
109
Libraries/LibWeb/Layout/LayoutBlock.h
Normal file
109
Libraries/LibWeb/Layout/LayoutBlock.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Layout/LayoutBox.h>
|
||||
#include <LibWeb/Layout/LineBox.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class Element;
|
||||
|
||||
class LayoutBlock : public LayoutBox {
|
||||
public:
|
||||
LayoutBlock(const Node*, NonnullRefPtr<StyleProperties>);
|
||||
virtual ~LayoutBlock() override;
|
||||
|
||||
virtual const char* class_name() const override { return "LayoutBlock"; }
|
||||
|
||||
virtual void layout() override;
|
||||
virtual void render(RenderingContext&) override;
|
||||
|
||||
virtual LayoutNode& inline_wrapper() override;
|
||||
|
||||
Vector<LineBox>& line_boxes() { return m_line_boxes; }
|
||||
const Vector<LineBox>& line_boxes() const { return m_line_boxes; }
|
||||
|
||||
LineBox& ensure_last_line_box();
|
||||
LineBox& add_line_box();
|
||||
|
||||
virtual HitTestResult hit_test(const Gfx::Point&) const override;
|
||||
|
||||
LayoutBlock* previous_sibling() { return to<LayoutBlock>(LayoutNode::previous_sibling()); }
|
||||
const LayoutBlock* previous_sibling() const { return to<LayoutBlock>(LayoutNode::previous_sibling()); }
|
||||
LayoutBlock* next_sibling() { return to<LayoutBlock>(LayoutNode::next_sibling()); }
|
||||
const LayoutBlock* next_sibling() const { return to<LayoutBlock>(LayoutNode::next_sibling()); }
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_fragment(Callback);
|
||||
template<typename Callback>
|
||||
void for_each_fragment(Callback) const;
|
||||
|
||||
private:
|
||||
virtual bool is_block() const override { return true; }
|
||||
|
||||
NonnullRefPtr<StyleProperties> style_for_anonymous_block() const;
|
||||
|
||||
void layout_inline_children();
|
||||
void layout_block_children();
|
||||
|
||||
void compute_width();
|
||||
void compute_position();
|
||||
void compute_height();
|
||||
|
||||
Vector<LineBox> m_line_boxes;
|
||||
};
|
||||
|
||||
template<typename Callback>
|
||||
void LayoutBlock::for_each_fragment(Callback callback)
|
||||
{
|
||||
for (auto& line_box : line_boxes()) {
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
if (callback(fragment) == IterationDecision::Break)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Callback>
|
||||
void LayoutBlock::for_each_fragment(Callback callback) const
|
||||
{
|
||||
for (auto& line_box : line_boxes()) {
|
||||
for (auto& fragment : line_box.fragments()) {
|
||||
if (callback(fragment) == IterationDecision::Break)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool is<LayoutBlock>(const LayoutNode& node)
|
||||
{
|
||||
return node.is_block();
|
||||
}
|
||||
|
||||
}
|
244
Libraries/LibWeb/Layout/LayoutBox.cpp
Normal file
244
Libraries/LibWeb/Layout/LayoutBox.cpp
Normal file
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/DOM/HTMLBodyElement.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutBox.h>
|
||||
|
||||
//#define DRAW_BOXES_AROUND_LAYOUT_NODES
|
||||
//#define DRAW_BOXES_AROUND_HOVERED_NODES
|
||||
|
||||
namespace Web {
|
||||
|
||||
void LayoutBox::paint_border(RenderingContext& context, Edge edge, const Gfx::FloatRect& rect, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id)
|
||||
{
|
||||
auto border_width = style().property(width_property_id);
|
||||
if (!border_width.has_value())
|
||||
return;
|
||||
|
||||
auto border_style = style().property(style_property_id);
|
||||
float width = border_width.value()->to_length().to_px();
|
||||
|
||||
int int_width = max((int)width, 1);
|
||||
|
||||
Color color;
|
||||
auto border_color = style().property(color_property_id);
|
||||
if (border_color.has_value()) {
|
||||
color = border_color.value()->to_color(document());
|
||||
} else {
|
||||
// FIXME: This is basically CSS "currentColor" which should be handled elsewhere
|
||||
// in a much more reusable way.
|
||||
auto current_color = style().property(CSS::PropertyID::Color);
|
||||
if (current_color.has_value())
|
||||
color = current_color.value()->to_color(document());
|
||||
else
|
||||
color = Color::Black;
|
||||
}
|
||||
|
||||
auto first_point_for_edge = [](Edge edge, const Gfx::FloatRect& rect) {
|
||||
switch (edge) {
|
||||
case Edge::Top:
|
||||
return rect.top_left();
|
||||
case Edge::Right:
|
||||
return rect.top_right();
|
||||
case Edge::Bottom:
|
||||
return rect.bottom_left();
|
||||
case Edge::Left:
|
||||
default:
|
||||
return rect.top_left();
|
||||
}
|
||||
};
|
||||
|
||||
auto second_point_for_edge = [](Edge edge, const Gfx::FloatRect& rect) {
|
||||
switch (edge) {
|
||||
case Edge::Top:
|
||||
return rect.top_right();
|
||||
case Edge::Right:
|
||||
return rect.bottom_right();
|
||||
case Edge::Bottom:
|
||||
return rect.bottom_right();
|
||||
case Edge::Left:
|
||||
default:
|
||||
return rect.bottom_left();
|
||||
}
|
||||
};
|
||||
|
||||
auto p1 = first_point_for_edge(edge, rect);
|
||||
auto p2 = second_point_for_edge(edge, rect);
|
||||
|
||||
if (border_style.has_value() && border_style.value()->to_string() == "inset") {
|
||||
auto top_left_color = Color::from_rgb(0x5a5a5a);
|
||||
auto bottom_right_color = Color::from_rgb(0x888888);
|
||||
color = (edge == Edge::Left || edge == Edge::Top) ? top_left_color : bottom_right_color;
|
||||
} else if (border_style.has_value() && border_style.value()->to_string() == "outset") {
|
||||
auto top_left_color = Color::from_rgb(0x888888);
|
||||
auto bottom_right_color = Color::from_rgb(0x5a5a5a);
|
||||
color = (edge == Edge::Left || edge == Edge::Top) ? top_left_color : bottom_right_color;
|
||||
}
|
||||
|
||||
bool dotted = border_style.has_value() && border_style.value()->to_string() == "dotted";
|
||||
|
||||
auto draw_line = [&](auto& p1, auto& p2) {
|
||||
context.painter().draw_line({ (int)p1.x(), (int)p1.y() }, { (int)p2.x(), (int)p2.y() }, color, 1, dotted);
|
||||
};
|
||||
|
||||
auto width_for = [&](CSS::PropertyID property_id) -> float {
|
||||
auto width = style().property(property_id);
|
||||
if (!width.has_value())
|
||||
return 0;
|
||||
return width.value()->to_length().to_px();
|
||||
};
|
||||
|
||||
float p1_step = 0;
|
||||
float p2_step = 0;
|
||||
|
||||
switch (edge) {
|
||||
case Edge::Top:
|
||||
p1_step = width_for(CSS::PropertyID::BorderLeftWidth) / (float)int_width;
|
||||
p2_step = width_for(CSS::PropertyID::BorderRightWidth) / (float)int_width;
|
||||
for (int i = 0; i < int_width; ++i) {
|
||||
draw_line(p1, p2);
|
||||
p1.move_by(p1_step, 1);
|
||||
p2.move_by(-p2_step, 1);
|
||||
}
|
||||
break;
|
||||
case Edge::Right:
|
||||
p1_step = width_for(CSS::PropertyID::BorderTopWidth) / (float)int_width;
|
||||
p2_step = width_for(CSS::PropertyID::BorderBottomWidth) / (float)int_width;
|
||||
for (int i = int_width - 1; i >= 0; --i) {
|
||||
draw_line(p1, p2);
|
||||
p1.move_by(-1, p1_step);
|
||||
p2.move_by(-1, -p2_step);
|
||||
}
|
||||
break;
|
||||
case Edge::Bottom:
|
||||
p1_step = width_for(CSS::PropertyID::BorderLeftWidth) / (float)int_width;
|
||||
p2_step = width_for(CSS::PropertyID::BorderRightWidth) / (float)int_width;
|
||||
for (int i = int_width - 1; i >= 0; --i) {
|
||||
draw_line(p1, p2);
|
||||
p1.move_by(p1_step, -1);
|
||||
p2.move_by(-p2_step, -1);
|
||||
}
|
||||
break;
|
||||
case Edge::Left:
|
||||
p1_step = width_for(CSS::PropertyID::BorderTopWidth) / (float)int_width;
|
||||
p2_step = width_for(CSS::PropertyID::BorderBottomWidth) / (float)int_width;
|
||||
for (int i = 0; i < int_width; ++i) {
|
||||
draw_line(p1, p2);
|
||||
p1.move_by(1, p1_step);
|
||||
p2.move_by(1, -p2_step);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LayoutBox::render(RenderingContext& context)
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
|
||||
#ifdef DRAW_BOXES_AROUND_LAYOUT_NODES
|
||||
context.painter().draw_rect(m_rect, Color::Blue);
|
||||
#endif
|
||||
#ifdef DRAW_BOXES_AROUND_HOVERED_NODES
|
||||
if (!is_anonymous() && node() == document().hovered_node())
|
||||
context.painter().draw_rect(m_rect, Color::Red);
|
||||
#endif
|
||||
|
||||
if (node() && document().inspected_node() == node())
|
||||
context.painter().draw_rect(enclosing_int_rect(m_rect), Color::Magenta);
|
||||
|
||||
Gfx::FloatRect padded_rect;
|
||||
padded_rect.set_x(x() - box_model().padding().left.to_px());
|
||||
padded_rect.set_width(width() + box_model().padding().left.to_px() + box_model().padding().right.to_px());
|
||||
padded_rect.set_y(y() - box_model().padding().top.to_px());
|
||||
padded_rect.set_height(height() + box_model().padding().top.to_px() + box_model().padding().bottom.to_px());
|
||||
|
||||
if (!is_body()) {
|
||||
auto bgcolor = style().property(CSS::PropertyID::BackgroundColor);
|
||||
if (bgcolor.has_value() && bgcolor.value()->is_color()) {
|
||||
context.painter().fill_rect(enclosing_int_rect(padded_rect), bgcolor.value()->to_color(document()));
|
||||
}
|
||||
|
||||
auto bgimage = style().property(CSS::PropertyID::BackgroundImage);
|
||||
if (bgimage.has_value() && bgimage.value()->is_image()) {
|
||||
auto& image_value = static_cast<const ImageStyleValue&>(*bgimage.value());
|
||||
if (image_value.bitmap()) {
|
||||
context.painter().draw_tiled_bitmap(enclosing_int_rect(padded_rect), *image_value.bitmap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gfx::FloatRect bordered_rect;
|
||||
bordered_rect.set_x(padded_rect.x() - box_model().border().left.to_px());
|
||||
bordered_rect.set_width(padded_rect.width() + box_model().border().left.to_px() + box_model().border().right.to_px());
|
||||
bordered_rect.set_y(padded_rect.y() - box_model().border().top.to_px());
|
||||
bordered_rect.set_height(padded_rect.height() + box_model().border().top.to_px() + box_model().border().bottom.to_px());
|
||||
|
||||
paint_border(context, Edge::Left, bordered_rect, CSS::PropertyID::BorderLeftStyle, CSS::PropertyID::BorderLeftColor, CSS::PropertyID::BorderLeftWidth);
|
||||
paint_border(context, Edge::Right, bordered_rect, CSS::PropertyID::BorderRightStyle, CSS::PropertyID::BorderRightColor, CSS::PropertyID::BorderRightWidth);
|
||||
paint_border(context, Edge::Top, bordered_rect, CSS::PropertyID::BorderTopStyle, CSS::PropertyID::BorderTopColor, CSS::PropertyID::BorderTopWidth);
|
||||
paint_border(context, Edge::Bottom, bordered_rect, CSS::PropertyID::BorderBottomStyle, CSS::PropertyID::BorderBottomColor, CSS::PropertyID::BorderBottomWidth);
|
||||
|
||||
LayoutNodeWithStyleAndBoxModelMetrics::render(context);
|
||||
}
|
||||
|
||||
HitTestResult LayoutBox::hit_test(const Gfx::Point& position) const
|
||||
{
|
||||
// FIXME: It would be nice if we could confidently skip over hit testing
|
||||
// parts of the layout tree, but currently we can't just check
|
||||
// m_rect.contains() since inline text rects can't be trusted..
|
||||
HitTestResult result { m_rect.contains(position.x(), position.y()) ? this : nullptr };
|
||||
for_each_child([&](auto& child) {
|
||||
auto child_result = child.hit_test(position);
|
||||
if (child_result.layout_node)
|
||||
result = child_result;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void LayoutBox::set_needs_display()
|
||||
{
|
||||
auto* frame = document().frame();
|
||||
ASSERT(frame);
|
||||
|
||||
if (!is_inline()) {
|
||||
const_cast<Frame*>(frame)->set_needs_display(enclosing_int_rect(rect()));
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutNode::set_needs_display();
|
||||
}
|
||||
|
||||
bool LayoutBox::is_body() const
|
||||
{
|
||||
return node() && node() == document().body();
|
||||
}
|
||||
|
||||
}
|
80
Libraries/LibWeb/Layout/LayoutBox.h
Normal file
80
Libraries/LibWeb/Layout/LayoutBox.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGfx/FloatRect.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class LayoutBox : public LayoutNodeWithStyleAndBoxModelMetrics {
|
||||
public:
|
||||
const Gfx::FloatRect& rect() const { return m_rect; }
|
||||
Gfx::FloatRect& rect() { return m_rect; }
|
||||
void set_rect(const Gfx::FloatRect& rect) { m_rect = rect; }
|
||||
|
||||
float x() const { return rect().x(); }
|
||||
float y() const { return rect().y(); }
|
||||
float width() const { return rect().width(); }
|
||||
float height() const { return rect().height(); }
|
||||
Gfx::FloatSize size() const { return rect().size(); }
|
||||
Gfx::FloatPoint position() const { return rect().location(); }
|
||||
|
||||
virtual HitTestResult hit_test(const Gfx::Point& position) const override;
|
||||
virtual void set_needs_display() override;
|
||||
|
||||
bool is_body() const;
|
||||
|
||||
protected:
|
||||
LayoutBox(const Node* node, NonnullRefPtr<StyleProperties> style)
|
||||
: LayoutNodeWithStyleAndBoxModelMetrics(node, move(style))
|
||||
{
|
||||
}
|
||||
|
||||
virtual void render(RenderingContext&) override;
|
||||
|
||||
private:
|
||||
virtual bool is_box() const override { return true; }
|
||||
|
||||
enum class Edge {
|
||||
Top,
|
||||
Right,
|
||||
Bottom,
|
||||
Left,
|
||||
};
|
||||
void paint_border(RenderingContext&, Edge, const Gfx::FloatRect&, CSS::PropertyID style_property_id, CSS::PropertyID color_property_id, CSS::PropertyID width_property_id);
|
||||
|
||||
Gfx::FloatRect m_rect;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool is<LayoutBox>(const LayoutNode& node)
|
||||
{
|
||||
return node.is_box();
|
||||
}
|
||||
|
||||
}
|
47
Libraries/LibWeb/Layout/LayoutBreak.cpp
Normal file
47
Libraries/LibWeb/Layout/LayoutBreak.cpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
#include <LibWeb/Layout/LayoutBreak.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
LayoutBreak::LayoutBreak(const HTMLBRElement& element)
|
||||
: LayoutNodeWithStyleAndBoxModelMetrics(&element, StyleProperties::create())
|
||||
{
|
||||
set_inline(true);
|
||||
}
|
||||
|
||||
LayoutBreak::~LayoutBreak()
|
||||
{
|
||||
}
|
||||
|
||||
void LayoutBreak::split_into_lines(LayoutBlock& block)
|
||||
{
|
||||
block.add_line_box();
|
||||
}
|
||||
|
||||
}
|
46
Libraries/LibWeb/Layout/LayoutBreak.h
Normal file
46
Libraries/LibWeb/Layout/LayoutBreak.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/HTMLBRElement.h>
|
||||
#include <LibWeb/Layout/LayoutNode.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class LayoutBreak final : public LayoutNodeWithStyleAndBoxModelMetrics {
|
||||
public:
|
||||
explicit LayoutBreak(const HTMLBRElement&);
|
||||
virtual ~LayoutBreak() override;
|
||||
|
||||
const HTMLBRElement& node() const { return to<HTMLBRElement>(*LayoutNode::node()); }
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "LayoutBreak"; }
|
||||
virtual void split_into_lines(LayoutBlock&) override;
|
||||
};
|
||||
|
||||
}
|
71
Libraries/LibWeb/Layout/LayoutDocument.cpp
Normal file
71
Libraries/LibWeb/Layout/LayoutDocument.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibWeb/Dump.h>
|
||||
#include <LibWeb/Frame.h>
|
||||
#include <LibWeb/Layout/LayoutDocument.h>
|
||||
#include <LibWeb/Layout/LayoutImage.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
LayoutDocument::LayoutDocument(const Document& document, NonnullRefPtr<StyleProperties> style)
|
||||
: LayoutBlock(&document, move(style))
|
||||
{
|
||||
}
|
||||
|
||||
LayoutDocument::~LayoutDocument()
|
||||
{
|
||||
}
|
||||
|
||||
void LayoutDocument::layout()
|
||||
{
|
||||
ASSERT(document().frame());
|
||||
rect().set_width(document().frame()->size().width());
|
||||
|
||||
LayoutNode::layout();
|
||||
|
||||
ASSERT(!children_are_inline());
|
||||
|
||||
int lowest_bottom = 0;
|
||||
for_each_child([&](auto& child) {
|
||||
ASSERT(is<LayoutBlock>(child));
|
||||
auto& child_block = to<LayoutBlock>(child);
|
||||
if (child_block.rect().bottom() > lowest_bottom)
|
||||
lowest_bottom = child_block.rect().bottom();
|
||||
});
|
||||
rect().set_bottom(lowest_bottom);
|
||||
}
|
||||
|
||||
void LayoutDocument::did_set_viewport_rect(Badge<Frame>, const Gfx::Rect& a_viewport_rect)
|
||||
{
|
||||
Gfx::FloatRect viewport_rect(a_viewport_rect.x(), a_viewport_rect.y(), a_viewport_rect.width(), a_viewport_rect.height());
|
||||
for_each_in_subtree_of_type<LayoutImage>([&](auto& layout_image) {
|
||||
const_cast<HTMLImageElement&>(layout_image.node()).set_volatile({}, !viewport_rect.intersects(layout_image.rect()));
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
52
Libraries/LibWeb/Layout/LayoutDocument.h
Normal file
52
Libraries/LibWeb/Layout/LayoutDocument.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/Layout/LayoutBlock.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
class LayoutDocument final : public LayoutBlock {
|
||||
public:
|
||||
explicit LayoutDocument(const Document&, NonnullRefPtr<StyleProperties>);
|
||||
virtual ~LayoutDocument() override;
|
||||
|
||||
const Document& node() const { return static_cast<const Document&>(*LayoutNode::node()); }
|
||||
virtual const char* class_name() const override { return "LayoutDocument"; }
|
||||
virtual void layout() override;
|
||||
|
||||
const LayoutRange& selection() const { return m_selection; }
|
||||
LayoutRange& selection() { return m_selection; }
|
||||
|
||||
void did_set_viewport_rect(Badge<Frame>, const Gfx::Rect&);
|
||||
|
||||
private:
|
||||
LayoutRange m_selection;
|
||||
};
|
||||
|
||||
}
|
89
Libraries/LibWeb/Layout/LayoutImage.cpp
Normal file
89
Libraries/LibWeb/Layout/LayoutImage.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. 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.
|
||||
*/
|
||||
|
||||
#include <LibGfx/Font.h>
|
||||
#include <LibGfx/StylePainter.h>
|
||||
#include <LibGUI/Painter.h>
|
||||
#include <LibWeb/Layout/LayoutImage.h>
|
||||
|
||||
namespace Web {
|
||||
|
||||
LayoutImage::LayoutImage(const HTMLImageElement& element, NonnullRefPtr<StyleProperties> style)
|
||||
: LayoutReplaced(element, move(style))
|
||||
{
|
||||
}
|
||||
|
||||
LayoutImage::~LayoutImage()
|
||||
{
|
||||
}
|
||||
|
||||
void LayoutImage::layout()
|
||||
{
|
||||
if (node().preferred_width() && node().preferred_height()) {
|
||||
rect().set_width(node().preferred_width());
|
||||
rect().set_height(node().preferred_height());
|
||||
} else if (renders_as_alt_text()) {
|
||||
auto& font = Gfx::Font::default_font();
|
||||
auto alt = node().alt();
|
||||
if (alt.is_empty())
|
||||
alt = node().src();
|
||||
rect().set_width(font.width(alt) + 16);
|
||||
rect().set_height(font.glyph_height() + 16);
|
||||
} else {
|
||||
rect().set_width(16);
|
||||
rect().set_height(16);
|
||||
}
|
||||
|
||||
LayoutReplaced::layout();
|
||||
}
|
||||
|
||||
void LayoutImage::render(RenderingContext& context)
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
|
||||
// FIXME: This should be done at a different level. Also rect() does not include padding etc!
|
||||
if (!context.viewport_rect().intersects(enclosing_int_rect(rect())))
|
||||
return;
|
||||
|
||||
if (renders_as_alt_text()) {
|
||||
context.painter().set_font(Gfx::Font::default_font());
|
||||
Gfx::StylePainter::paint_frame(context.painter(), enclosing_int_rect(rect()), context.palette(), Gfx::FrameShape::Container, Gfx::FrameShadow::Sunken, 2);
|
||||
auto alt = node().alt();
|
||||
if (alt.is_empty())
|
||||
alt = node().src();
|
||||
context.painter().draw_text(enclosing_int_rect(rect()), alt, Gfx::TextAlignment::Center, style().color_or_fallback(CSS::PropertyID::Color, document(), Color::Black), Gfx::TextElision::Right);
|
||||
} else if (node().bitmap())
|
||||
context.painter().draw_scaled_bitmap(enclosing_int_rect(rect()), *node().bitmap(), node().bitmap()->rect());
|
||||
LayoutReplaced::render(context);
|
||||
}
|
||||
|
||||
bool LayoutImage::renders_as_alt_text() const
|
||||
{
|
||||
return !node().image_decoder();
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue