diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-04 17:14:06 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-05-04 17:14:06 +0300 |
commit | 347b4c1cb3482fd43251bf4d4ab7807360bbb938 (patch) | |
tree | a3a1ad51b392891f87ebd6ef438a1d16c5dd376e /src/gmdocument.c | |
parent | 6cbaa38d4ebf5a911e908b72bf721985bde87e44 (diff) |
Highlight links opened in other tabs
The primary purpose is to aid navigation in split view, so one can see exactly which links have been opened.
Diffstat (limited to 'src/gmdocument.c')
-rw-r--r-- | src/gmdocument.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/src/gmdocument.c b/src/gmdocument.c index 47f629bd..b64e9ea7 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c | |||
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
33 | 33 | ||
34 | #include <the_Foundation/ptrarray.h> | 34 | #include <the_Foundation/ptrarray.h> |
35 | #include <the_Foundation/regexp.h> | 35 | #include <the_Foundation/regexp.h> |
36 | #include <the_Foundation/stringset.h> | ||
36 | 37 | ||
37 | #include <ctype.h> | 38 | #include <ctype.h> |
38 | 39 | ||
@@ -87,6 +88,7 @@ struct Impl_GmDocument { | |||
87 | uint32_t themeSeed; | 88 | uint32_t themeSeed; |
88 | iChar siteIcon; | 89 | iChar siteIcon; |
89 | iMedia * media; | 90 | iMedia * media; |
91 | iStringSet *openURLs; /* currently open URLs for highlighting links */ | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | iDefineObjectConstruction(GmDocument) | 94 | iDefineObjectConstruction(GmDocument) |
@@ -229,6 +231,9 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li | |||
229 | if (isValid_Time(&link->when)) { | 231 | if (isValid_Time(&link->when)) { |
230 | link->flags |= visited_GmLinkFlag; | 232 | link->flags |= visited_GmLinkFlag; |
231 | } | 233 | } |
234 | if (contains_StringSet(d->openURLs, &link->url)) { | ||
235 | link->flags |= isOpen_GmLinkFlag; | ||
236 | } | ||
232 | } | 237 | } |
233 | } | 238 | } |
234 | pushBack_PtrArray(&d->links, link); | 239 | pushBack_PtrArray(&d->links, link); |
@@ -340,6 +345,13 @@ static void alignDecoration_GmRun_(iGmRun *run, iBool isCentered) { | |||
340 | run->visBounds.size.x -= xAdjust; | 345 | run->visBounds.size.x -= xAdjust; |
341 | } | 346 | } |
342 | 347 | ||
348 | static void updateOpenURLs_GmDocument_(iGmDocument *d) { | ||
349 | if (d->openURLs) { | ||
350 | iReleasePtr(&d->openURLs); | ||
351 | } | ||
352 | d->openURLs = listOpenURLs_App(); | ||
353 | } | ||
354 | |||
343 | static void doLayout_GmDocument_(iGmDocument *d) { | 355 | static void doLayout_GmDocument_(iGmDocument *d) { |
344 | const iPrefs *prefs = prefs_App(); | 356 | const iPrefs *prefs = prefs_App(); |
345 | const iBool isMono = isForcedMonospace_GmDocument_(d); | 357 | const iBool isMono = isForcedMonospace_GmDocument_(d); |
@@ -405,6 +417,7 @@ static void doLayout_GmDocument_(iGmDocument *d) { | |||
405 | if (d->size.x <= 0 || isEmpty_String(&d->source)) { | 417 | if (d->size.x <= 0 || isEmpty_String(&d->source)) { |
406 | return; | 418 | return; |
407 | } | 419 | } |
420 | updateOpenURLs_GmDocument_(d); | ||
408 | const iRangecc content = range_String(&d->source); | 421 | const iRangecc content = range_String(&d->source); |
409 | iRangecc contentLine = iNullRange; | 422 | iRangecc contentLine = iNullRange; |
410 | iInt2 pos = zero_I2(); | 423 | iInt2 pos = zero_I2(); |
@@ -861,9 +874,11 @@ void init_GmDocument(iGmDocument *d) { | |||
861 | d->themeSeed = 0; | 874 | d->themeSeed = 0; |
862 | d->siteIcon = 0; | 875 | d->siteIcon = 0; |
863 | d->media = new_Media(); | 876 | d->media = new_Media(); |
877 | d->openURLs = NULL; | ||
864 | } | 878 | } |
865 | 879 | ||
866 | void deinit_GmDocument(iGmDocument *d) { | 880 | void deinit_GmDocument(iGmDocument *d) { |
881 | iReleasePtr(&d->openURLs); | ||
867 | delete_Media(d->media); | 882 | delete_Media(d->media); |
868 | deinit_String(&d->bannerText); | 883 | deinit_String(&d->bannerText); |
869 | deinit_String(&d->title); | 884 | deinit_String(&d->title); |
@@ -900,10 +915,15 @@ static void setDerivedThemeColors_(enum iGmDocumentTheme theme) { | |||
900 | set_Color(tmQuoteIcon_ColorId, | 915 | set_Color(tmQuoteIcon_ColorId, |
901 | mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f)); | 916 | mix_Color(get_Color(tmQuote_ColorId), get_Color(tmBackground_ColorId), 0.55f)); |
902 | set_Color(tmBannerSideTitle_ColorId, | 917 | set_Color(tmBannerSideTitle_ColorId, |
903 | mix_Color(get_Color(tmBannerTitle_ColorId), get_Color(tmBackground_ColorId), | 918 | mix_Color(get_Color(tmBannerTitle_ColorId), |
919 | get_Color(tmBackground_ColorId), | ||
904 | theme == colorfulDark_GmDocumentTheme ? 0.55f : 0)); | 920 | theme == colorfulDark_GmDocumentTheme ? 0.55f : 0)); |
905 | set_Color(tmAltTextBackground_ColorId, mix_Color(get_Color(tmQuoteIcon_ColorId), | 921 | set_Color(tmBackgroundAltText_ColorId, |
906 | get_Color(tmBackground_ColorId), 0.85f)); | 922 | mix_Color(get_Color(tmQuoteIcon_ColorId), get_Color(tmBackground_ColorId), 0.85f)); |
923 | set_Color(tmBackgroundOpenLink_ColorId, | ||
924 | mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.92f)); | ||
925 | set_Color(tmFrameOpenLink_ColorId, | ||
926 | mix_Color(get_Color(tmLinkText_ColorId), get_Color(tmBackground_ColorId), 0.78f)); | ||
907 | if (theme == colorfulDark_GmDocumentTheme) { | 927 | if (theme == colorfulDark_GmDocumentTheme) { |
908 | /* Ensure paragraph text and link text aren't too similarly colored. */ | 928 | /* Ensure paragraph text and link text aren't too similarly colored. */ |
909 | if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) { | 929 | if (delta_Color(get_Color(tmLinkText_ColorId), get_Color(tmParagraph_ColorId)) < 100) { |
@@ -1381,6 +1401,22 @@ void redoLayout_GmDocument(iGmDocument *d) { | |||
1381 | doLayout_GmDocument_(d); | 1401 | doLayout_GmDocument_(d); |
1382 | } | 1402 | } |
1383 | 1403 | ||
1404 | iBool updateOpenURLs_GmDocument(iGmDocument *d) { | ||
1405 | iBool wasChanged = iFalse; | ||
1406 | updateOpenURLs_GmDocument_(d); | ||
1407 | iForEach(PtrArray, i, &d->links) { | ||
1408 | iGmLink *link = i.ptr; | ||
1409 | if (!equal_String(&link->url, &d->url)) { | ||
1410 | const iBool isOpen = contains_StringSet(d->openURLs, &link->url); | ||
1411 | if (isOpen ^ ((link->flags & isOpen_GmLinkFlag) != 0)) { | ||
1412 | iChangeFlags(link->flags, isOpen_GmLinkFlag, isOpen); | ||
1413 | wasChanged = iTrue; | ||
1414 | } | ||
1415 | } | ||
1416 | } | ||
1417 | return wasChanged; | ||
1418 | } | ||
1419 | |||
1384 | iLocalDef iBool isNormalizableSpace_(char ch) { | 1420 | iLocalDef iBool isNormalizableSpace_(char ch) { |
1385 | return ch == ' ' || ch == '\t'; | 1421 | return ch == ' ' || ch == '\t'; |
1386 | } | 1422 | } |