mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
Browser+LibHTML: Add "Computed" styles to the DOM inspector
I though it would be nice to also show the style that the browser uses to display an element. In order to do that, in place of the styles table I've put a tab widget, with tabs for both element and computed element styles.
This commit is contained in:
parent
1da31ce8ae
commit
988d1deca8
Notes:
sideshowbarker
2024-07-19 10:20:33 +09:00
Author: https://github.com/Matrix89 🔰 Commit: https://github.com/SerenityOS/serenity/commit/988d1deca87 Pull-request: https://github.com/SerenityOS/serenity/pull/1006 Reviewed-by: https://github.com/awesomekling
@ -3,9 +3,11 @@
|
||||
#include <LibGUI/GSplitter.h>
|
||||
#include <LibGUI/GTableView.h>
|
||||
#include <LibGUI/GTreeView.h>
|
||||
#include <LibGUI/GTabWidget.h>
|
||||
#include <LibHTML/DOM/Document.h>
|
||||
#include <LibHTML/DOM/Element.h>
|
||||
#include <LibHTML/DOMElementStyleModel.h>
|
||||
#include <LibHTML/DOMComputedElementStyleModel.h>
|
||||
#include <LibHTML/DOMTreeModel.h>
|
||||
|
||||
InspectorWidget::InspectorWidget(GWidget* parent)
|
||||
@ -17,13 +19,24 @@ InspectorWidget::InspectorWidget(GWidget* parent)
|
||||
m_dom_tree_view->on_selection = [this](auto& index) {
|
||||
auto* node = static_cast<Node*>(index.internal_data());
|
||||
node->document().set_inspected_node(node);
|
||||
if (node->is_element())
|
||||
m_style_table_view->set_model(DOMElementStyleModel::create(to<Element>(*node)));
|
||||
else
|
||||
if (node->is_element()) {
|
||||
auto element = to<Element>(*node);
|
||||
m_style_table_view->set_model(DOMElementStyleModel::create(element));
|
||||
m_computed_style_table_view->set_model(DOMComputedElementStyleModel::create(element));
|
||||
} else {
|
||||
m_style_table_view->set_model(nullptr);
|
||||
m_computed_style_table_view->set_model(nullptr);
|
||||
}
|
||||
};
|
||||
m_style_table_view = GTableView::construct(splitter);
|
||||
m_style_table_view = GTableView::construct(nullptr);
|
||||
m_style_table_view->set_size_columns_to_fit_content(true);
|
||||
|
||||
m_computed_style_table_view = GTableView::construct(nullptr);
|
||||
m_computed_style_table_view->set_size_columns_to_fit_content(true);
|
||||
|
||||
auto tabwidget = GTabWidget::construct(splitter);
|
||||
tabwidget->add_widget("Styles", m_style_table_view);
|
||||
tabwidget->add_widget("Computed", m_computed_style_table_view);
|
||||
}
|
||||
|
||||
InspectorWidget::~InspectorWidget()
|
||||
|
@ -16,5 +16,6 @@ private:
|
||||
|
||||
RefPtr<GTreeView> m_dom_tree_view;
|
||||
RefPtr<GTableView> m_style_table_view;
|
||||
RefPtr<GTableView> m_computed_style_table_view;
|
||||
RefPtr<Document> m_document;
|
||||
};
|
||||
|
50
Libraries/LibHTML/DOMComputedElementStyleModel.cpp
Normal file
50
Libraries/LibHTML/DOMComputedElementStyleModel.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "DOMComputedElementStyleModel.h"
|
||||
#include <LibHTML/CSS/PropertyID.h>
|
||||
#include <LibHTML/DOM/Document.h>
|
||||
#include <LibHTML/DOM/Element.h>
|
||||
|
||||
DOMComputedElementStyleModel::DOMComputedElementStyleModel(const Element& element)
|
||||
: m_element(element)
|
||||
{
|
||||
if (element.layout_node() != nullptr && element.layout_node()->has_style()) {
|
||||
element.layout_node()->style().for_each_property([&](auto property_id, auto& property_value) {
|
||||
Value value;
|
||||
value.name = CSS::string_from_property_id(property_id);
|
||||
value.value = property_value.to_string();
|
||||
m_values.append(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int DOMComputedElementStyleModel::row_count(const GModelIndex&) const
|
||||
{
|
||||
return m_values.size();
|
||||
}
|
||||
|
||||
String DOMComputedElementStyleModel::column_name(int column_index) const
|
||||
{
|
||||
switch (column_index) {
|
||||
case Column::PropertyName:
|
||||
return "Name";
|
||||
case Column::PropertyValue:
|
||||
return "Value";
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
GVariant DOMComputedElementStyleModel::data(const GModelIndex& index, Role role) const
|
||||
{
|
||||
auto& value = m_values[index.row()];
|
||||
if (role == Role::Display) {
|
||||
if (index.column() == Column::PropertyName)
|
||||
return value.name;
|
||||
if (index.column() == Column::PropertyValue)
|
||||
return value.value;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void DOMComputedElementStyleModel::update()
|
||||
{
|
||||
did_update();
|
||||
}
|
33
Libraries/LibHTML/DOMComputedElementStyleModel.h
Normal file
33
Libraries/LibHTML/DOMComputedElementStyleModel.h
Normal file
@ -0,0 +1,33 @@
|
||||
#include <AK/NonnullRefPtrVector.h>
|
||||
#include <LibGUI/GModel.h>
|
||||
|
||||
class Element;
|
||||
|
||||
class DOMComputedElementStyleModel final : public GModel {
|
||||
public:
|
||||
enum Column {
|
||||
PropertyName,
|
||||
PropertyValue,
|
||||
__Count
|
||||
};
|
||||
|
||||
static NonnullRefPtr<DOMComputedElementStyleModel> create(const Element& element) { return adopt(*new DOMComputedElementStyleModel(element)); }
|
||||
|
||||
virtual int row_count(const GModelIndex& = GModelIndex()) const override;
|
||||
virtual int column_count(const GModelIndex& = GModelIndex()) const override { return Column::__Count; }
|
||||
virtual String column_name(int) const override;
|
||||
virtual GVariant data(const GModelIndex&, Role = Role::Display) const override;
|
||||
virtual void update() override;
|
||||
|
||||
private:
|
||||
explicit DOMComputedElementStyleModel(const Element&);
|
||||
const Element& element() const { return *m_element; }
|
||||
|
||||
NonnullRefPtr<Element> m_element;
|
||||
|
||||
struct Value {
|
||||
String name;
|
||||
String value;
|
||||
};
|
||||
Vector<Value> m_values;
|
||||
};
|
@ -35,6 +35,7 @@ LIBHTML_OBJS = \
|
||||
DOM/ParentNode.o \
|
||||
DOM/Text.o \
|
||||
DOMElementStyleModel.o \
|
||||
DOMComputedElementStyleModel.o \
|
||||
DOMTreeModel.o \
|
||||
Dump.o \
|
||||
FontCache.o \
|
||||
|
Loading…
Reference in New Issue
Block a user