Serenity Operating System
1/*
2 * Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "LocationEdit.h"
8#include "Utilities.h"
9#include <AK/URL.h>
10#include <QCoreApplication>
11#include <QPalette>
12#include <QTextLayout>
13
14LocationEdit::LocationEdit(QWidget* parent)
15 : QLineEdit(parent)
16{
17 connect(this, &QLineEdit::returnPressed, this, [&] {
18 clearFocus();
19 });
20
21 connect(this, &QLineEdit::textChanged, this, [&] {
22 highlight_location();
23 });
24}
25
26void LocationEdit::focusInEvent(QFocusEvent* event)
27{
28 QLineEdit::focusInEvent(event);
29 highlight_location();
30}
31
32void LocationEdit::focusOutEvent(QFocusEvent* event)
33{
34 QLineEdit::focusOutEvent(event);
35 highlight_location();
36}
37
38void LocationEdit::highlight_location()
39{
40 auto url = AK::URL::create_with_url_or_path(ak_deprecated_string_from_qstring(text()));
41
42 QList<QInputMethodEvent::Attribute> attributes;
43 if (url.is_valid() && !hasFocus()) {
44 if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "gemini") {
45 int host_start = (url.scheme().length() + 3) - cursorPosition();
46 auto host_length = url.host().length();
47
48 // FIXME: Maybe add a generator to use https://publicsuffix.org/list/public_suffix_list.dat
49 // for now just highlight the whole host
50
51 QTextCharFormat defaultFormat;
52 defaultFormat.setForeground(QPalette().color(QPalette::PlaceholderText));
53 attributes.append({
54 QInputMethodEvent::TextFormat,
55 -cursorPosition(),
56 static_cast<int>(text().length()),
57 defaultFormat,
58 });
59
60 QTextCharFormat hostFormat;
61 hostFormat.setForeground(QPalette().color(QPalette::Text));
62 attributes.append({
63 QInputMethodEvent::TextFormat,
64 host_start,
65 static_cast<int>(host_length),
66 hostFormat,
67 });
68 } else if (url.scheme() == "file") {
69 QTextCharFormat schemeFormat;
70 schemeFormat.setForeground(QPalette().color(QPalette::PlaceholderText));
71 attributes.append({
72 QInputMethodEvent::TextFormat,
73 -cursorPosition(),
74 static_cast<int>(url.scheme().length() + 3),
75 schemeFormat,
76 });
77 }
78 }
79
80 QInputMethodEvent event(QString(), attributes);
81 QCoreApplication::sendEvent(this, &event);
82}