This commit is contained in:
Face
2025-09-07 18:49:32 +03:00
parent b4639e80bc
commit 7220880e95
19 changed files with 1078 additions and 23 deletions

View File

@@ -0,0 +1,623 @@
[gd_scene load_steps=43 format=3 uid="uid://cs7kf3xvffcwu"]
[ext_resource type="Script" uid="uid://d4eh2nqg8r1ui" path="res://Scripts/Browser/settings.gd" id="1_settings"]
[ext_resource type="Theme" uid="uid://bn6rbmdy60lhr" path="res://Scenes/Styles/BrowserText.tres" id="2_theme"]
[ext_resource type="Texture2D" uid="uid://blskvfjswul1d" path="res://Assets/Icons/checkbox_white.svg" id="3_mdirl"]
[ext_resource type="Texture2D" uid="uid://bs414mrvwdmcn" path="res://Assets/Icons/radio_disabled.svg" id="4_dm5ls"]
[ext_resource type="Texture2D" uid="uid://bap17ryrkcyey" path="res://Assets/Icons/checkbox_disabled.svg" id="5_s7e1m"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_main"]
content_margin_left = 0.0
content_margin_top = 0.0
content_margin_right = 0.0
content_margin_bottom = 0.0
bg_color = Color(0.105882, 0.105882, 0.105882, 1)
corner_radius_top_left = 30
corner_radius_top_right = 30
corner_radius_bottom_right = 30
corner_radius_bottom_left = 30
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_sidebar"]
content_margin_left = 15.0
content_margin_top = 25.0
content_margin_right = 15.0
content_margin_bottom = 25.0
bg_color = Color(0.0784314, 0.0784314, 0.0784314, 1)
corner_radius_top_left = 30
corner_radius_bottom_left = 30
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_vkd6r"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tab_selected_hover"]
content_margin_left = 15.0
content_margin_top = 10.0
content_margin_right = 15.0
content_margin_bottom = 10.0
bg_color = Color(0.3, 0.55, 0.9, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tab_pressed"]
content_margin_left = 15.0
content_margin_top = 10.0
content_margin_right = 15.0
content_margin_bottom = 10.0
bg_color = Color(0.168627, 0.168627, 0.168627, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tab_selected"]
content_margin_left = 15.0
content_margin_top = 10.0
content_margin_right = 15.0
content_margin_bottom = 10.0
bg_color = Color(0.247059, 0.466667, 0.807843, 1)
draw_center = false
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[sub_resource type="ButtonGroup" id="ButtonGroup_tabs"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_dxen3"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tab_hover"]
content_margin_left = 15.0
content_margin_top = 10.0
content_margin_right = 15.0
content_margin_bottom = 10.0
bg_color = Color(0.168627, 0.168627, 0.168627, 1)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tab_normal"]
content_margin_left = 15.0
content_margin_top = 10.0
content_margin_right = 15.0
content_margin_bottom = 10.0
bg_color = Color(0.0784314, 0.0784314, 0.0784314, 0)
corner_radius_top_left = 10
corner_radius_top_right = 10
corner_radius_bottom_right = 10
corner_radius_bottom_left = 10
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_hxjif"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_3gdnt"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_hpjw2"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_content"]
content_margin_left = 25.0
content_margin_top = 25.0
content_margin_right = 25.0
content_margin_bottom = 25.0
bg_color = Color(0.127451, 0.127451, 0.127451, 1)
corner_radius_top_right = 30
corner_radius_bottom_right = 30
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_section"]
content_margin_left = 15.0
content_margin_top = 15.0
content_margin_right = 15.0
content_margin_bottom = 15.0
bg_color = Color(0.0980392, 0.0980392, 0.0980392, 1)
corner_radius_top_left = 15
corner_radius_top_right = 15
corner_radius_bottom_right = 15
corner_radius_bottom_left = 15
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_jyfhi"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_34gk8"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1xb48"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_mf3pd"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0linb"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_esroy"]
[sub_resource type="ButtonGroup" id="ButtonGroup_mdirl"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_mdirl"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_05lrc"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_jpip4"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_dm5ls"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_s7e1m"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_hcgcp"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_input"]
content_margin_left = 12.0
content_margin_top = 8.0
content_margin_right = 12.0
content_margin_bottom = 8.0
bg_color = Color(0.0784314, 0.0784314, 0.0784314, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_button_hover"]
content_margin_left = 15.0
content_margin_top = 8.0
content_margin_right = 15.0
content_margin_bottom = 8.0
bg_color = Color(0.3, 0.55, 0.9, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_button_pressed"]
content_margin_left = 15.0
content_margin_top = 8.0
content_margin_right = 15.0
content_margin_bottom = 8.0
bg_color = Color(0.2, 0.4, 0.7, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_button"]
content_margin_left = 15.0
content_margin_top = 8.0
content_margin_right = 15.0
content_margin_bottom = 8.0
bg_color = Color(0.247059, 0.466667, 0.807843, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_app81"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8jbl5"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_vt4mc"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_nnk28"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_yqiws"]
[node name="PopupPanel" type="PopupPanel"]
initial_position = 1
size = Vector2i(900, 700)
visible = true
theme_override_styles/panel = SubResource("StyleBoxFlat_main")
script = ExtResource("1_settings")
[node name="HSplitContainer" type="HSplitContainer" parent="."]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_right = 900.0
offset_bottom = 700.0
split_offset = 250
dragger_visibility = 2
[node name="Sidebar" type="PanelContainer" parent="HSplitContainer"]
custom_minimum_size = Vector2(250, 0)
layout_mode = 2
size_flags_horizontal = 0
theme_override_styles/panel = SubResource("StyleBoxFlat_sidebar")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Sidebar"]
layout_mode = 2
theme_override_constants/separation = 5
[node name="Title" type="Label" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 20
text = "Settings"
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 15
[node name="TabGeneral" type="Button" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_styles/focus = SubResource("StyleBoxEmpty_vkd6r")
theme_override_styles/hover = SubResource("StyleBoxFlat_tab_selected_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_tab_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_tab_selected")
toggle_mode = true
button_pressed = true
button_group = SubResource("ButtonGroup_tabs")
text = "General"
flat = true
alignment = 0
[node name="TabPrivacy" type="Button" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
theme_override_styles/focus = SubResource("StyleBoxEmpty_dxen3")
theme_override_styles/hover = SubResource("StyleBoxFlat_tab_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_tab_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_tab_normal")
toggle_mode = true
button_group = SubResource("ButtonGroup_tabs")
text = "Privacy"
flat = true
alignment = 0
[node name="TabDownloads" type="Button" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
theme_override_styles/focus = SubResource("StyleBoxEmpty_hxjif")
theme_override_styles/hover = SubResource("StyleBoxFlat_tab_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_tab_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_tab_normal")
toggle_mode = true
button_group = SubResource("ButtonGroup_tabs")
text = "Downloads"
flat = true
alignment = 0
[node name="TabAdvanced" type="Button" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
theme_override_styles/focus = SubResource("StyleBoxEmpty_3gdnt")
theme_override_styles/hover = SubResource("StyleBoxFlat_tab_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_tab_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_tab_normal")
toggle_mode = true
button_group = SubResource("ButtonGroup_tabs")
text = "Advanced"
flat = true
alignment = 0
[node name="TabAbout" type="Button" parent="HSplitContainer/Sidebar/VBoxContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
theme_override_styles/focus = SubResource("StyleBoxEmpty_hpjw2")
theme_override_styles/hover = SubResource("StyleBoxFlat_tab_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_tab_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_tab_normal")
toggle_mode = true
button_group = SubResource("ButtonGroup_tabs")
text = "About"
flat = true
alignment = 0
[node name="Content" type="PanelContainer" parent="HSplitContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/panel = SubResource("StyleBoxFlat_content")
[node name="ScrollContainer" type="ScrollContainer" parent="HSplitContainer/Content"]
layout_mode = 2
[node name="ContentStack" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_constants/separation = 0
[node name="GeneralPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
layout_mode = 2
theme_override_constants/separation = 20
[node name="GeneralTitle" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 24
text = "General"
[node name="StartupSection" type="PanelContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="Label" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16
text = "On startup"
[node name="StartupNewTab" type="CheckBox" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_constants/icon_max_width = 24
theme_override_styles/focus = SubResource("StyleBoxEmpty_jyfhi")
theme_override_styles/hover_pressed_mirrored = SubResource("StyleBoxEmpty_34gk8")
theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_1xb48")
theme_override_styles/hover = SubResource("StyleBoxEmpty_mf3pd")
theme_override_styles/pressed = SubResource("StyleBoxEmpty_0linb")
theme_override_styles/normal = SubResource("StyleBoxEmpty_esroy")
theme_override_icons/unchecked = ExtResource("3_mdirl")
theme_override_icons/radio_unchecked = ExtResource("4_dm5ls")
button_pressed = true
button_group = SubResource("ButtonGroup_mdirl")
text = " Open the new tab page"
flat = true
[node name="StartupSpecificPage" type="CheckBox" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_styles/focus = SubResource("StyleBoxEmpty_mdirl")
theme_override_styles/hover_pressed_mirrored = SubResource("StyleBoxEmpty_05lrc")
theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_jpip4")
theme_override_styles/hover = SubResource("StyleBoxEmpty_dm5ls")
theme_override_styles/pressed = SubResource("StyleBoxEmpty_s7e1m")
theme_override_styles/normal = SubResource("StyleBoxEmpty_hcgcp")
theme_override_icons/unchecked = ExtResource("3_mdirl")
theme_override_icons/radio_unchecked = ExtResource("4_dm5ls")
button_group = SubResource("ButtonGroup_mdirl")
text = " Open a specific page"
[node name="StartupURLContainer" type="HBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer"]
visible = false
layout_mode = 2
[node name="URLLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer/StartupURLContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
text = "URL:"
[node name="URLInput" type="LineEdit" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer/StartupURLContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxFlat_input")
placeholder_text = "https://example.com"
[node name="SearchEngineSection" type="PanelContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/SearchEngineSection"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="Label" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/SearchEngineSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16
text = "Search engine"
[node name="HBoxContainer" type="HBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/SearchEngineSection/VBoxContainer"]
layout_mode = 2
[node name="SearchLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/SearchEngineSection/VBoxContainer/HBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
text = "Default search URL:"
[node name="SearchInput" type="LineEdit" parent="HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/SearchEngineSection/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxFlat_input")
text = "gurt://search.web?q="
placeholder_text = "gurt://search.web?q="
[node name="PrivacyPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
visible = false
layout_mode = 2
theme_override_constants/separation = 20
[node name="PrivacyTitle" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 24
text = "Privacy and security"
[node name="ClearDataSection" type="PanelContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection"]
layout_mode = 2
theme_override_constants/separation = 15
[node name="Label" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16
text = "Clear browsing data"
[node name="Description" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1)
text = "Delete your browsing history, crumbs, and download history"
autowrap_mode = 3
[node name="ButtonsContainer" type="HBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="ClearHistoryButton" type="Button" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer/ButtonsContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_styles/hover = SubResource("StyleBoxFlat_button_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_button_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_button")
text = "Clear History"
[node name="ClearCookiesButton" type="Button" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer/ButtonsContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_styles/hover = SubResource("StyleBoxFlat_button_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_button_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_button")
text = "Clear Crumbs"
[node name="ClearDownloadsButton" type="Button" parent="HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer/ButtonsContainer"]
layout_mode = 2
mouse_default_cursor_shape = 2
theme = ExtResource("2_theme")
theme_override_styles/hover = SubResource("StyleBoxFlat_button_hover")
theme_override_styles/pressed = SubResource("StyleBoxFlat_button_pressed")
theme_override_styles/normal = SubResource("StyleBoxFlat_button")
text = "Clear Downloads"
[node name="DownloadsPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
visible = false
layout_mode = 2
theme_override_constants/separation = 20
[node name="DownloadsTitle" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 24
text = "Downloads"
[node name="DownloadConfirmSection" type="PanelContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel/DownloadConfirmSection"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="Label" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel/DownloadConfirmSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16
text = "Security"
[node name="ConfirmCheckBox" type="CheckBox" parent="HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel/DownloadConfirmSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_styles/focus = SubResource("StyleBoxEmpty_app81")
theme_override_styles/hover_pressed = SubResource("StyleBoxEmpty_8jbl5")
theme_override_styles/hover_mirrored = SubResource("StyleBoxEmpty_vt4mc")
theme_override_styles/pressed = SubResource("StyleBoxEmpty_nnk28")
theme_override_styles/normal = SubResource("StyleBoxEmpty_yqiws")
theme_override_icons/unchecked = ExtResource("5_s7e1m")
button_pressed = true
text = " Ask for confirmation for each download"
[node name="AdvancedPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
visible = false
layout_mode = 2
theme_override_constants/separation = 20
[node name="AdvancedTitle" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 24
text = "Advanced"
[node name="DNSSection" type="PanelContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel/DNSSection"]
layout_mode = 2
theme_override_constants/separation = 10
[node name="Label" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel/DNSSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 16
text = "DNS settings"
[node name="HBoxContainer" type="HBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel/DNSSection/VBoxContainer"]
layout_mode = 2
[node name="DNSLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel/DNSSection/VBoxContainer/HBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
text = "DNS Server URL:"
[node name="DNSInput" type="LineEdit" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel/DNSSection/VBoxContainer/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
theme_override_styles/normal = SubResource("StyleBoxFlat_input")
text = "135.125.163.131:4878"
placeholder_text = "135.125.163.131:4878"
[node name="AboutPanel" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack"]
visible = false
layout_mode = 2
theme_override_constants/separation = 20
[node name="AboutTitle" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 24
text = "About Flumi"
[node name="AboutSection" type="PanelContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel"]
layout_mode = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_section")
[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel/AboutSection"]
layout_mode = 2
theme_override_constants/separation = 15
[node name="FlumiBrand" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel/AboutSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(1, 1, 1, 1)
theme_override_font_sizes/font_size = 28
text = "Flumi"
[node name="VersionLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel/AboutSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.8, 0.8, 0.8, 1)
theme_override_font_sizes/font_size = 16
text = "Version 1.0.0"
[node name="DescriptionLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel/AboutSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1)
text = "The official browser for the GURT protocol"
autowrap_mode = 3
[node name="HSeparator" type="HSeparator" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel/AboutSection/VBoxContainer"]
layout_mode = 2
[node name="CopyrightLabel" type="Label" parent="HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel/AboutSection/VBoxContainer"]
layout_mode = 2
theme = ExtResource("2_theme")
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
theme_override_font_sizes/font_size = 12
text = "© 2025 Gurted under FaceDev. All rights reserved."

View File

@@ -240,6 +240,7 @@ item_1/id = 1
item_2/text = "New Incognito Window (CTRL SHIFT N)"
item_2/icon = ExtResource("14_u50mg")
item_2/id = 2
item_2/disabled = true
item_3/id = 3
item_3/separator = true
item_4/text = "History (CTRL H)"

View File

@@ -451,7 +451,7 @@ func _input(event: InputEvent) -> void:
func _handle_mousemove_event(mouse_event: InputEventMouseMotion, subscription: EventSubscription) -> void:
# TODO: pass reference instead of hardcoded path
var body_container = get_node("/root/Main").website_container
var body_container = Engine.get_main_loop().current_scene.website_container
if body_container.get_parent() is MarginContainer:
body_container = body_container.get_parent()
@@ -787,6 +787,10 @@ func _handle_text_setting(operation: Dictionary):
# If the element has a DOM node, update it directly without updating text_content
var element_id = get_or_assign_element_id(element)
var dom_node = dom_parser.parse_result.dom_nodes.get(element_id, null)
if not dom_node:
dom_node = dom_parser.parse_result.dom_nodes.get(element, null)
if dom_node:
if element.tag_name == "button":
var button_node = dom_node.get_node_or_null("ButtonNode")
@@ -806,6 +810,7 @@ func _handle_text_setting(operation: Dictionary):
var text_node = get_dom_node(dom_node, "text")
if text_node:
if text_node is RichTextLabel:
element.text_content = text
StyleManager.apply_styles_to_label(text_node, dom_parser.get_element_styles_with_inheritance(element, "", []), element, dom_parser, text)
try_apply_auto_resize(text_node)
elif text_node.has_method("set_text"):

View File

@@ -29,20 +29,26 @@ func _ensure_download_progress_container():
main_node.add_child(anchor_container)
func handle_download_request(download_data: Dictionary):
print("Download requested: ", download_data)
var active_tab = main_node.get_active_tab()
if active_tab and active_tab.current_url:
download_data["current_site"] = URLUtils.extract_domain(active_tab.current_url)
else:
download_data["current_site"] = "Unknown site"
var dialog = DOWNLOAD_DIALOG.instantiate()
main_node.add_child(dialog)
var settings_node = Engine.get_main_loop().current_scene
var skip_confirmation = !settings_node.get_download_confirmation_setting()
dialog.download_confirmed.connect(_on_download_confirmed)
dialog.download_cancelled.connect(_on_download_cancelled)
dialog.show_download_dialog(download_data)
if skip_confirmation:
var filename = download_data.get("filename", "download")
var default_path = OS.get_system_dir(OS.SYSTEM_DIR_DOWNLOADS) + "/" + filename
_on_download_confirmed(download_data, default_path)
else:
var dialog = DOWNLOAD_DIALOG.instantiate()
main_node.add_child(dialog)
dialog.download_confirmed.connect(_on_download_confirmed)
dialog.download_cancelled.connect(_on_download_cancelled)
dialog.show_download_dialog(download_data)
func _on_download_confirmed(download_data: Dictionary, save_path: String):
var download_id = download_data.get("id", "")

View File

@@ -74,3 +74,14 @@ func get_download_data_array() -> Array[Dictionary]:
for entry in download_entries:
data_array.append(entry.get_download_data())
return data_array
func clear_all_downloads():
for entry in download_entries:
entry.queue_free()
download_entries.clear()
var file = FileAccess.open(save_path, FileAccess.WRITE)
if file:
file.store_string("[]")
file.close()

View File

@@ -1,8 +1,17 @@
extends RefCounted
class_name GurtProtocol
const DNS_SERVER_IP: String = "135.125.163.131"
const DNS_SERVER_PORT: int = 4878
static var DNS_SERVER_IP: String = "135.125.163.131"
static var DNS_SERVER_PORT: int = 4878
static func set_dns_server(ip_port: String):
if ":" in ip_port:
var parts = ip_port.split(":")
DNS_SERVER_IP = parts[0]
DNS_SERVER_PORT = parts[1].to_int()
else:
DNS_SERVER_IP = ip_port
DNS_SERVER_PORT = 4878
static func is_gurt_domain(url: String) -> bool:
if url.begins_with("gurt://"):

View File

@@ -1,11 +1,13 @@
extends Button
const HISTORY = preload("res://Scenes/BrowserMenus/history.tscn")
const SETTINGS = preload("res://Scenes/BrowserMenus/settings.tscn")
@onready var tab_container: TabManager = $"../../TabContainer"
@onready var main: Main = $"../../../"
var history_scene: PopupPanel = null
var settings_scene: PopupPanel = null
func _on_pressed() -> void:
%OptionsMenu.show()
@@ -42,6 +44,8 @@ func _on_options_menu_id_pressed(id: int) -> void:
show_history()
if id == 5: # downloads
show_downloads()
if id == 9: # settings
show_settings()
if id == 10: # exit
get_tree().quit()
@@ -62,3 +66,16 @@ func _on_history_closed() -> void:
func show_downloads() -> void:
main.download_manager.show_downloads_history()
func show_settings() -> void:
if settings_scene == null:
settings_scene = SETTINGS.instantiate()
main.add_child(settings_scene)
settings_scene.connect("popup_hide", _on_settings_closed)
else:
settings_scene.show()
func _on_settings_closed() -> void:
if settings_scene:
settings_scene.hide()

View File

@@ -0,0 +1,114 @@
extends Node
const SETTINGS_FILE = "user://browser_settings.json"
var settings_data = {
"startup_new_tab": true,
"startup_specific_page": false,
"startup_url": "",
"search_engine_url": "gurt://search.web?q=",
"download_confirmation": true,
"dns_url": "135.125.163.131:4878"
}
var _loaded = false
func _ready():
load_settings()
func load_settings():
if _loaded:
return
if not FileAccess.file_exists(SETTINGS_FILE):
save_settings()
_loaded = true
return
var file = FileAccess.open(SETTINGS_FILE, FileAccess.READ)
if not file:
print("Failed to open settings file")
_loaded = true
return
var json_text = file.get_as_text()
file.close()
var json = JSON.new()
var parse_result = json.parse(json_text)
if parse_result != OK:
print("Failed to parse settings JSON")
_loaded = true
return
var loaded_data = json.data
if loaded_data is Dictionary:
# Merge loaded settings with defaults
for key in loaded_data:
if key in settings_data:
settings_data[key] = loaded_data[key]
_loaded = true
print("Settings loaded: ", settings_data)
func save_settings():
var file = FileAccess.open(SETTINGS_FILE, FileAccess.WRITE)
if not file:
print("Failed to open settings file for writing")
return
var json_text = JSON.stringify(settings_data)
file.store_string(json_text)
file.close()
print("Settings saved: ", settings_data)
func get_download_confirmation() -> bool:
return settings_data.download_confirmation
func get_search_engine_url() -> String:
return settings_data.search_engine_url
func get_dns_url() -> String:
return settings_data.dns_url
func get_startup_behavior() -> Dictionary:
return {
"new_tab": settings_data.startup_new_tab,
"specific_page": settings_data.startup_specific_page,
"url": settings_data.startup_url
}
func set_download_confirmation(value: bool):
settings_data.download_confirmation = value
save_settings()
func set_search_engine_url(value: String):
settings_data.search_engine_url = value
save_settings()
func set_dns_url(value: String):
settings_data.dns_url = value
save_settings()
# Update GurtProtocol immediately
GurtProtocol.set_dns_server(value)
func set_startup_new_tab(value: bool):
settings_data.startup_new_tab = value
if value:
settings_data.startup_specific_page = false
save_settings()
func set_startup_specific_page(value: bool):
settings_data.startup_specific_page = value
if value:
settings_data.startup_new_tab = false
save_settings()
func set_startup_url(value: String):
settings_data.startup_url = value
save_settings()
func get_setting(key: String, default_value = null):
if key in settings_data:
return settings_data[key]
return default_value

View File

@@ -0,0 +1 @@
uid://bksvvuqiuanw6

View File

@@ -229,8 +229,11 @@ func create_tab() -> void:
trigger_init_scene(tab)
# WARNING: temporary
main.render()
var startup_behavior = main.get_startup_behavior()
if startup_behavior.specific_page and not startup_behavior.url.is_empty():
main._on_search_submitted(startup_behavior.url, true)
else:
main.render()
func _input(_event: InputEvent) -> void:
if Input.is_action_just_pressed("NewTab"):

View File

@@ -0,0 +1,143 @@
extends PopupPanel
const SETTINGS_FILE = "user://browser_settings.json"
# Tab references
@onready var tab_general: Button = $HSplitContainer/Sidebar/VBoxContainer/TabGeneral
@onready var tab_privacy: Button = $HSplitContainer/Sidebar/VBoxContainer/TabPrivacy
@onready var tab_downloads: Button = $HSplitContainer/Sidebar/VBoxContainer/TabDownloads
@onready var tab_advanced: Button = $HSplitContainer/Sidebar/VBoxContainer/TabAdvanced
@onready var tab_about: Button = $HSplitContainer/Sidebar/VBoxContainer/TabAbout
# Panel references
@onready var general_panel: VBoxContainer = $HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel
@onready var privacy_panel: VBoxContainer = $HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel
@onready var downloads_panel: VBoxContainer = $HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel
@onready var advanced_panel: VBoxContainer = $HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel
@onready var about_panel: VBoxContainer = $HSplitContainer/Content/ScrollContainer/ContentStack/AboutPanel
# Settings controls - General
@onready var startup_new_tab: CheckBox = $HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer/StartupNewTab
@onready var startup_specific_page: CheckBox = $HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer/StartupSpecificPage
@onready var startup_url_container: HBoxContainer = $HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer/StartupURLContainer
@onready var startup_url_input: LineEdit = $HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/StartupSection/VBoxContainer/StartupURLContainer/URLInput
@onready var search_input: LineEdit = $HSplitContainer/Content/ScrollContainer/ContentStack/GeneralPanel/SearchEngineSection/VBoxContainer/HBoxContainer/SearchInput
# Settings controls - Privacy
@onready var clear_history_button: Button = $HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer/ButtonsContainer/ClearHistoryButton
@onready var clear_cookies_button: Button = $HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer/ButtonsContainer/ClearCookiesButton
@onready var clear_downloads_button: Button = $HSplitContainer/Content/ScrollContainer/ContentStack/PrivacyPanel/ClearDataSection/VBoxContainer/ButtonsContainer/ClearDownloadsButton
# Settings controls - Downloads
@onready var download_confirm_checkbox: CheckBox = $HSplitContainer/Content/ScrollContainer/ContentStack/DownloadsPanel/DownloadConfirmSection/VBoxContainer/ConfirmCheckBox
# Settings controls - Advanced
@onready var dns_input: LineEdit = $HSplitContainer/Content/ScrollContainer/ContentStack/AdvancedPanel/DNSSection/VBoxContainer/HBoxContainer/DNSInput
# Settings are now managed by SettingsManager singleton
var tab_buttons = []
var content_panels = []
func _ready():
tab_buttons = [tab_general, tab_privacy, tab_downloads, tab_advanced, tab_about]
content_panels = [general_panel, privacy_panel, downloads_panel, advanced_panel, about_panel]
tab_general.toggled.connect(_on_tab_toggled.bind("general"))
tab_privacy.toggled.connect(_on_tab_toggled.bind("privacy"))
tab_downloads.toggled.connect(_on_tab_toggled.bind("downloads"))
tab_advanced.toggled.connect(_on_tab_toggled.bind("advanced"))
tab_about.toggled.connect(_on_tab_toggled.bind("about"))
startup_new_tab.toggled.connect(_on_startup_new_tab_toggled)
startup_specific_page.toggled.connect(_on_startup_specific_page_toggled)
startup_url_input.text_changed.connect(_on_startup_url_changed)
search_input.text_changed.connect(_on_search_engine_changed)
download_confirm_checkbox.toggled.connect(_on_download_confirmation_changed)
dns_input.text_changed.connect(_on_dns_changed)
clear_history_button.pressed.connect(_on_clear_history_pressed)
clear_cookies_button.pressed.connect(_on_clear_cookies_pressed)
clear_downloads_button.pressed.connect(_on_clear_downloads_pressed)
apply_settings_to_ui()
_on_tab_toggled(true, "general")
func _on_tab_toggled(pressed: bool, tab_name: String):
if not pressed:
return
_update_tab_styles(tab_name)
for i in range(content_panels.size()):
var panel = content_panels[i]
match tab_name:
"general":
panel.visible = (i == 0)
"privacy":
panel.visible = (i == 1)
"downloads":
panel.visible = (i == 2)
"advanced":
panel.visible = (i == 3)
"about":
panel.visible = (i == 4)
func _update_tab_styles(selected_tab: String):
for i in range(tab_buttons.size()):
var button = tab_buttons[i]
var tab_names = ["general", "privacy", "downloads", "advanced", "about"]
var is_selected = (tab_names[i] == selected_tab)
if is_selected:
button.modulate = Color.WHITE
else:
button.modulate = Color(0.8, 0.8, 0.8)
func _on_startup_new_tab_toggled(pressed: bool):
if pressed:
SettingsManager.set_startup_new_tab(true)
startup_url_container.visible = false
func _on_startup_specific_page_toggled(pressed: bool):
if pressed:
SettingsManager.set_startup_specific_page(true)
startup_url_container.visible = true
func _on_startup_url_changed(new_url: String):
SettingsManager.set_startup_url(new_url)
func _on_search_engine_changed(new_url: String):
SettingsManager.set_search_engine_url(new_url)
func _on_download_confirmation_changed(enabled: bool):
SettingsManager.set_download_confirmation(enabled)
func _on_dns_changed(new_dns: String):
SettingsManager.set_dns_url(new_dns)
func _on_clear_history_pressed():
BrowserHistory.clear_all()
func _on_clear_cookies_pressed():
LuaCrumbsUtils.clear_all_crumbs()
func _on_clear_downloads_pressed():
var main = Engine.get_main_loop().current_scene
if main.download_manager.downloads_history_ui:
main.download_manager.downloads_history_ui.clear_all_downloads()
else:
main.download_manager._ensure_downloads_history_ui()
main.download_manager.downloads_history_ui.clear_all_downloads()
func apply_settings_to_ui():
var startup_behavior = SettingsManager.get_startup_behavior()
startup_new_tab.button_pressed = startup_behavior.new_tab
startup_specific_page.button_pressed = startup_behavior.specific_page
startup_url_container.visible = startup_behavior.specific_page
startup_url_input.text = startup_behavior.url
search_input.text = SettingsManager.get_search_engine_url()
download_confirm_checkbox.button_pressed = SettingsManager.get_download_confirmation()
dns_input.text = SettingsManager.get_dns_url()

View File

@@ -0,0 +1 @@
uid://d4eh2nqg8r1ui

View File

@@ -38,10 +38,20 @@ input[type="date"] { w-28 text-[16px] bg-[#1b1b1b] rounded-md text-white hover:b
var HTML_CONTENT = """
<head>
<title>New tab</title>
<script>
local items = {"Hi","Hello","Salut","Bonjour","Hola","Ciao","Hallo","Hej","Hei","Ola","Privet","Zdravstvuyte","Konnichiwa","Ni hao","Annyeonghaseyo","Merhaba","Selam","Habari","Shalom","Namaste","Marhaba","Geia","Sawasdee","Selamat","Halo","Kumusta","Sawubona","Jambo","Aloha","Goddag","Tere","Moikka","Sveiki"}
local h = gurt.select(".target")
local res = items[math.random(#items)] .. "!"
h.text = res
</script>
</head>
<body>
<p>Welcome to Flumi Browser!</p>
<img src="https://httpbin.org/image/png" alt="Test image" />
<p>This page includes a test image to verify network functionality.</p>
<body style="bg-[#323949] text-white font-sans">
<div style="flex flex-col items-center justify-center w-full mt-12">
<h1 style="target text-8xl font-bold mb-4 text-[#4a9eff] font-serif font-italic">Hello!</h1>
<p style="text-lg mb-8 text-[#cccccc]">Start browsing by typing in the omnibar.</p>
<p style="mb-2">Happy GURT:// exploration!</p>
</div>
</body>
""".to_utf8_buffer()

View File

@@ -13,6 +13,12 @@ func init(element, parser: HTMLParser) -> void:
size_flags_vertical = Control.SIZE_SHRINK_BEGIN
mouse_filter = Control.MOUSE_FILTER_PASS
var element_id = element.get_attribute("id")
if element_id.is_empty():
element.set_attribute("id", unique_id)
element_id = unique_id
parser.register_dom_node(element, self)
if get_child_count() > 0:
return
@@ -62,7 +68,6 @@ func create_styled_label(text: String, element, parser: HTMLParser) -> RichTextL
add_child(label)
parser.register_dom_node(element, label)
var styles = parser.get_element_styles_with_inheritance(element, "", [])
StyleManager.apply_styles_to_label(label, styles, element, parser, text)
@@ -140,6 +145,9 @@ func set_text(new_text: String) -> void:
remove_child(child)
child.queue_free()
if _element:
_element.text_content = new_text
if _element and _parser:
create_styled_label(new_text, _element, _parser)
else:
@@ -172,8 +180,6 @@ func create_label(text: String) -> RichTextLabel:
add_child(label)
if _element and _parser:
_parser.register_dom_node(_element, label)
call_deferred("_apply_auto_resize_to_label", label)
return label

View File

@@ -254,3 +254,15 @@ static func delete_crumb(domain: String, name: String) -> bool:
all_crumbs.erase(name)
save_all_crumbs(domain, all_crumbs)
return existed
static func clear_all_crumbs():
if DirAccess.dir_exists_absolute(CRUMBS_DIR_PATH):
var dir = DirAccess.open(CRUMBS_DIR_PATH)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if file_name.ends_with(".json"):
dir.remove(file_name)
file_name = dir.get_next()
dir.list_dir_end()

View File

@@ -507,7 +507,7 @@ static func is_same_element_visual_node(node1: Node, node2: Node) -> bool:
return false
static func render_new_element_at_position(element: HTMLParser.HTMLElement, parent_node: Node, position: int, dom_parser: HTMLParser) -> void:
var main_scene = Engine.get_main_loop().current_scene.get_node("/root/Main")
var main_scene = Engine.get_main_loop().current_scene.Engine.get_main_loop().current_scene
if not main_scene:
return
@@ -529,7 +529,7 @@ static func render_new_element_at_position(element: HTMLParser.HTMLElement, pare
container_node.move_child(element_node, position)
static func render_new_element_by_reference(element: HTMLParser.HTMLElement, parent_node: Node, reference_element_id: String, insert_before: bool, dom_parser: HTMLParser) -> void:
var main_scene = Engine.get_main_loop().current_scene.get_node("/root/Main")
var main_scene = Engine.get_main_loop().current_scene.Engine.get_main_loop().current_scene
if not main_scene:
return

View File

@@ -73,6 +73,7 @@ func _ready():
call_deferred("render")
call_deferred("update_navigation_buttons")
call_deferred("_handle_startup_behavior")
func _input(_event: InputEvent) -> void:
if Input.is_action_just_pressed("DevTools"):
@@ -114,7 +115,15 @@ func _on_search_submitted(url: String, add_to_history: bool = true) -> void:
await fetch_gurt_content_async(gurt_url, tab, url, add_to_history)
else:
print("Non-GURT URL entered: ", url)
print("Non-GURT URL entered, using search engine: ", url)
if url.begins_with("http://") or url.begins_with("https://"):
# It's already a web URL, open in system browser
OS.shell_open(url)
else:
var search_engine_url = get_search_engine_url()
var search_url = search_engine_url + url.uri_encode()
_on_search_submitted(search_url, add_to_history)
func fetch_gurt_content_async(gurt_url: String, tab: Tab, original_url: String, add_to_history: bool = true) -> void:
main_navigation_request = NetworkManager.start_request(gurt_url, "GET", false)
@@ -817,3 +826,18 @@ func update_navigation_buttons() -> void:
else:
back_button.disabled = true
forward_button.disabled = true
func get_download_confirmation_setting() -> bool:
return SettingsManager.get_download_confirmation()
func get_search_engine_url() -> String:
return SettingsManager.get_search_engine_url()
func get_startup_behavior() -> Dictionary:
return SettingsManager.get_startup_behavior()
func _handle_startup_behavior():
var startup_behavior = get_startup_behavior()
if startup_behavior.specific_page and not startup_behavior.url.is_empty():
_on_search_submitted(startup_behavior.url, true)

View File

@@ -24,6 +24,7 @@ Constants="*res://Scripts/Constants.gd"
Network="*res://Scripts/Network.gd"
NetworkManager="*res://Scripts/Browser/NetworkManager.gd"
BrowserHistory="*res://Scripts/Browser/BrowserHistory.gd"
SettingsManager="*res://Scripts/Browser/SettingsManager.gd"
[display]

View File

@@ -169,7 +169,75 @@ searchQuery:on('keydown', function(e)
if query and query ~= '' then
performSearch(query:trim())
end
elseif e.key == 'Escape' then
-- Clear search on Escape
searchQuery.value = ''
-- Clear results
local children = results.children
for i = #children, 1, -1 do
children[i]:remove()
end
stats.text = ''
loading.classList:add('hidden')
-- Update URL to remove query parameter
local baseUrl = gurt.location.pathname
if gurt.location.href ~= baseUrl then
gurt.location.goto(baseUrl)
end
end
end)
searchQuery:focus()
local function checkForQueryParam()
local url = gurt.location.href
local queryIndex = url:find('?')
if queryIndex then
local queryString = url:sub(queryIndex + 1)
local params = {}
-- Parse query parameters
for param in queryString:gmatch('([^&]+)') do
local key, value = param:match('([^=]+)=(.+)')
if key and value then
params[key] = urlDecode(value)
end
end
-- If 'q' parameter exists, populate search box and perform search
if params.q then
searchQuery.value = params.q
performSearch(params.q)
return
end
end
-- Focus search input if no query parameter
searchQuery:focus()
end
searchQuery:on('input', function()
local query = searchQuery.value:trim()
if query == '' then
-- Clear results when search box is empty
local children = results.children
for i = #children, 1, -1 do
children[i]:remove()
end
stats.text = ''
loading.classList:add('hidden')
-- Update URL to remove query parameter
local baseUrl = gurt.location.pathname
if gurt.location.href ~= baseUrl then
gurt.location.goto(baseUrl)
end
end
end)
checkForQueryParam()