Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ What gets stored (if allowed): cookies.
| Ability to remove window frame | ✅ | ❌ | |
| Minimalistic tabless design | ✅ | ❌ | |
| Fine zoom | ✅ | ❌ | |
| Search within the page | ❌ | ✅ | |
| Search within the page | ✅ | ✅ | Liquid keeps finding matches as pages change, and opens it as soon as you start typing |
| Permanently mute website | ✅ | ❌ | Browsers automatically unmute, Liquid remembers the state |
| Ability to go full-screen | ✅ | ✅ | |
| Full control over full-screen capabilities | ✅ | ❌ | Liquid acts more like a mobile device simulator when it comes to full-screen |
Expand Down Expand Up @@ -71,6 +71,7 @@ What gets stored (if allowed): cookies.
| Go back | `Ctrl`+`←` | `Backspace` |
| Go forward | `Ctrl`+`→` | |
| Open link using default web browser | `Ctrl`+_click_ | |
| Find on page | `Ctrl`+`F` | _start typing_ |
| Edit app settings | `Ctrl`+`,` | |

Most of these can also be found in the right-click menu.
Expand Down
116 changes: 116 additions & 0 deletions inc/liquidappfind.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once

#include <QLineEdit>
#include <QList>
#include <QObject>
#include <QPointF>
#include <QString>
#include <QWidget>

class QLabel;
class QTimer;
class QWebEngineView;

// Text input of the search, which also takes care of going from one match to another
class LiquidAppFindInput : public QLineEdit
{
Q_OBJECT

public:
explicit LiquidAppFindInput(QWidget* parent = Q_NULLPTR);

signals:
void nextRequested(void);
void previousRequested(void);

protected:
bool event(QEvent* event) override;
void keyPressEvent(QKeyEvent* event) override;
};

// Dots around the search box, where rays come out of (they're drawn on the page, see find.js): this is what makes them
// clickable. It covers the search box, but only its dots take the mouse, everything else goes through to what's below.
class LiquidAppFindDots : public QWidget
{
Q_OBJECT

public:
explicit LiquidAppFindDots(QWidget* parent = Q_NULLPTR);

// In the web view's coordinates (null ones are of matches that have no ray)
void setDots(const QList<QPointF>& dots, const QList<bool>& hasDot, const QRect& searchBoxGeometry);

signals:
void hovered(const int index);
void clicked(const int index);

protected:
void mouseMoveEvent(QMouseEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void leaveEvent(QEvent* event) override;

private:
int getDotAt(const QPointF& position) const;
void setHoveredIndex(const int index);

QList<QPointF> dots;
QList<bool> hasDot;
int hoveredIndex = -1;
};

// Find in page: a search box floating in the middle of the web view, with every match highlighted, and connected to it
// by a ray, all of which inverts the page underneath, like an X-ray. Keeps on looking for as long as it's open,
// so whatever shows up on the page later (including what gets typed into text inputs) gets found too.
class LiquidAppFind : public QObject
{
Q_OBJECT

public:
explicit LiquidAppFind(QWebEngineView* webView);

// Opens (or focuses) the search box; the text replaces the query, or gets added to it (for find-as-you-type)
void open(const QString& text = QString(), const bool append = false);
void close(void);
bool isOpen(void) const;

// Snapshots are of the page, not of the search (it stays open meanwhile)
void hideForSnapshot(void);
void showAfterSnapshot(void);

// The web view has been resized
void updateGeometry(void);

// Something may have moved (e.g. the page has been scrolled), find out where the matches are now
void scheduleUpdate(void);

// The search box itself: the input, and how many matches there are
static QWidget* createSearchBox(QWidget* parent, LiquidAppFindInput** input, QLabel** countLabel);

// Whether the search box (drawn by the page, inverting it) is light, and its text has to be dark
static void setSearchBoxLight(QWidget* searchBox, const bool isLight);

private:
void update(void);
void onUpdated(const QString& json, const qint64 duration);
void updateCountLabel(const int total, const int current);
void focusPage(void);
void setSearchBoxLight(const bool isLight);

QWebEngineView* webView;
QWidget* searchBox;
LiquidAppFindInput* input;
QLabel* countLabel;
LiquidAppFindDots* dots;
QTimer* pollTimer;
QTimer* scheduleTimer;
QString script;

bool isOpenBool = false;
bool isHiddenForSnapshot = false;
bool hadFocusBeforeSnapshot = false;
bool isUpdating = false;
bool isUpdatePending = false;
int pendingMove = 0;
int pendingGoTo = -1; // Match whose dot has been clicked
int hoveredIndex = -1;
};
8 changes: 8 additions & 0 deletions inc/liquidappwindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

class LiquidAppCookieJar;
class QLocalSocket;
class LiquidAppFind;
class LiquidAppIcon;
class LiquidAppIconFetcher;
class LiquidAppLocalStorage;
Expand Down Expand Up @@ -108,6 +109,12 @@ public slots:
LiquidAppCookieJar* liquidAppCookieJar = Q_NULLPTR;
bool iconFetchAttempted = false;

// Find in page (also opens upon typing while nothing that takes text is focused)
LiquidAppFind* find = Q_NULLPTR;
QString typedText;
QTimer* typeToFindTimer = Q_NULLPTR;
void onTypedOutsideOfInputs(QKeyEvent* event);

// Settings dialog, while it's open
QPointer<QDialog> settingsDialog;

Expand Down Expand Up @@ -142,6 +149,7 @@ public slots:
QAction* reloadAction2;
QAction* savePageAction;
QAction* editSettingsAction;
QAction* findAction;
QAction* stopLoadingOrExitFullScreenModeAction;
QAction* takeSnapshotAction;
QAction* takeSnapshotFullPageAction;
Expand Down
10 changes: 10 additions & 0 deletions inc/lqd.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,21 @@
#define LQD_UI_TOOLTIP_MAX_LENGTH 2000 // Characters of long values shown in tooltips
#define LQD_STORAGE_REFRESH_DELAY 300 // Milliseconds to wait for the .liquid file to settle before re-reading it in settings
#define LQD_LOCAL_STORAGE_QUIT_TIMEOUT 1000 // Milliseconds to wait for reading local storage before quitting
#define LQD_FIND_POLL_INTERVAL 150 // Milliseconds between looking for matches again (pages change)
#define LQD_FIND_HIDE_TIMEOUT 500 // Milliseconds to wait for the page to hide what it draws for the search
#define LQD_FIND_REPAINT_DELAY 50 // Milliseconds for the page to get repainted without it
#define LQD_FIND_DOT_HIT_RADIUS 7 // Pixels, how close to a dot clicking it counts
#define LQD_FIND_BOX_WIDTH 440 // Pixels
#define LQD_FIND_BOX_HEIGHT 42 // Pixels
#define LQD_FIND_BOX_MARGIN 16 // Pixels, between the search box and the edges of small windows
#define LQD_TYPE_TO_FIND_DELAY 50 // Milliseconds to wait for the page to handle typed keys first
#define LQD_INSTANCE_STOP_TIMEOUT 5000 // Milliseconds to wait for a Liquid app to quit

/* Names of scripts Liquid injects into web pages */
#define LQD_SCRIPT_NAME_ADDITIONAL_CSS "liquid-additional-css"
#define LQD_SCRIPT_NAME_ADDITIONAL_JS "liquid-additional-js"
#define LQD_SCRIPT_NAME_LOCAL_STORAGE "liquid-local-storage"
#define LQD_SCRIPT_NAME_KEY_RECORDER "liquid-key-recorder"

/* Textual icons */
#define LQD_ICON_ADD "➕"
Expand Down Expand Up @@ -140,6 +149,7 @@
#define LQD_KBD_SEQ_QUIT_2 "Ctrl+W"
#define LQD_KBD_SEQ_SAVE_PAGE "Ctrl+S"
#define LQD_KBD_SEQ_EDIT_SETTINGS "Ctrl+,"
#define LQD_KBD_SEQ_FIND "Ctrl+F"
#define LQD_KBD_SEQ_TAKE_SNAPSHOT_VECTOR "Ctrl+Shift+S"
#define LQD_KBD_SEQ_ZOOM_LVL_INC "Ctrl+="
#define LQD_KBD_SEQ_ZOOM_LVL_INC_FINE "Ctrl+Shift+="
Expand Down
2 changes: 2 additions & 0 deletions liquid.pro
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ INCLUDEPATH += $${INC_DIR}
HEADERS += inc/lqd.h \
inc/liquid.hpp \
inc/liquidappfile.hpp \
inc/liquidappfind.hpp \
inc/liquidappicon.hpp \
inc/liquidapplocalstorage.hpp \
inc/liquidappcookiejar.hpp \
Expand All @@ -37,6 +38,7 @@ HEADERS += inc/lqd.h \

SOURCES += src/liquid.cpp \
src/liquidappfile.cpp \
src/liquidappfind.cpp \
src/liquidappicon.cpp \
src/liquidapplocalstorage.cpp \
src/liquidappcookiejar.cpp \
Expand Down
1 change: 1 addition & 0 deletions res/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<qresource>
<file>images/checkers.svg</file>
<file>images/liquid.svg</file>
<file>scripts/find.js</file>
<file>scripts/html2svg.js</file>
<file>styles/base.qss</file>
<file>styles/dark.qss</file>
Expand Down
Loading
Loading