summaryrefslogtreecommitdiff
path: root/src/gmdocument.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 17:14:06 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-05-04 17:14:06 +0300
commit347b4c1cb3482fd43251bf4d4ab7807360bbb938 (patch)
treea3a1ad51b392891f87ebd6ef438a1d16c5dd376e /src/gmdocument.c
parent6cbaa38d4ebf5a911e908b72bf721985bde87e44 (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.c42
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
92iDefineObjectConstruction(GmDocument) 94iDefineObjectConstruction(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
348static void updateOpenURLs_GmDocument_(iGmDocument *d) {
349 if (d->openURLs) {
350 iReleasePtr(&d->openURLs);
351 }
352 d->openURLs = listOpenURLs_App();
353}
354
343static void doLayout_GmDocument_(iGmDocument *d) { 355static 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
866void deinit_GmDocument(iGmDocument *d) { 880void 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
1404iBool 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
1384iLocalDef iBool isNormalizableSpace_(char ch) { 1420iLocalDef iBool isNormalizableSpace_(char ch) {
1385 return ch == ' ' || ch == '\t'; 1421 return ch == ' ' || ch == '\t';
1386} 1422}