Lagrange [work/v1.11]

Working on site-specific settings dialog

=> 64eaaaac57fc909a9c9d47302f17f0801b7f2965

diff --git a/src/gmdocument.c b/src/gmdocument.c
index a3e233f3..bc0cc073 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -1292,7 +1292,7 @@ static void updateIconBasedOnUrl_GmDocument_(iGmDocument *d) {
     }
 }
 
-void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
+void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *paletteSeed, const iBlock *iconSeed) {
     const iPrefs *        prefs = prefs_App();
     enum iGmDocumentTheme theme = currentTheme_();
     static const iChar siteIcons[] = {
@@ -1303,6 +1303,16 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
         0x1f306, 0x1f308, 0x1f30a, 0x1f319, 0x1f31f, 0x1f320, 0x1f340, 0x1f4cd, 0x1f4e1, 0x1f531,
         0x1f533, 0x1f657, 0x1f659, 0x1f665, 0x1f668, 0x1f66b, 0x1f78b, 0x1f796, 0x1f79c,
     };
+    if (!iconSeed) {
+        iconSeed = paletteSeed;
+    }
+    if (iconSeed && !isEmpty_Block(iconSeed)) {
+        const uint32_t seedHash = themeHash_(iconSeed);
+        d->siteIcon = siteIcons[(seedHash >> 7) % iElemCount(siteIcons)];
+    }
+    else {
+        d->siteIcon = 0;        
+    }
     /* Default colors. These are used on "about:" pages and local files, for example. */ {
         /* Link colors are generally the same in all themes. */
         set_Color(tmBadLink_ColorId, get_Color(red_ColorId));
@@ -1504,13 +1514,11 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
             }
         }
     }
-    if (seed && !isEmpty_Block(seed)) {
-        d->themeSeed = themeHash_(seed);
-        d->siteIcon  = siteIcons[(d->themeSeed >> 7) % iElemCount(siteIcons)];
+    if (paletteSeed && !isEmpty_Block(paletteSeed)) {
+        d->themeSeed = themeHash_(paletteSeed);
     }
     else {
         d->themeSeed = 0;
-        d->siteIcon  = 0;
     }
     /* Set up colors. */
     if (d->themeSeed) {
@@ -1739,8 +1747,8 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
     /* Derived colors. */
     setDerivedThemeColors_(theme);
     /* Special exceptions. */
-    if (seed) {
-        if (equal_CStr(cstr_Block(seed), "gemini.circumlunar.space")) {
+    if (iconSeed) {
+        if (equal_CStr(cstr_Block(iconSeed), "gemini.circumlunar.space")) {
             d->siteIcon = 0x264a; /* gemini symbol */
         }
         updateIconBasedOnUrl_GmDocument_(d);
@@ -1761,7 +1769,8 @@ void setThemeSeed_GmDocument(iGmDocument *d, const iBlock *seed) {
 void makePaletteGlobal_GmDocument(const iGmDocument *d) {
     if (!d->isPaletteValid) {
         /* Recompute the palette since it's needed now. */
-        setThemeSeed_GmDocument((iGmDocument *) d, urlThemeSeed_String(&d->url));
+        setThemeSeed_GmDocument(
+            (iGmDocument *) d, urlPaletteSeed_String(&d->url), urlThemeSeed_String(&d->url));
     }
     iAssert(d->isPaletteValid);
     memcpy(get_Root()->tmPalette, d->palette, sizeof(d->palette));
@@ -1938,7 +1947,7 @@ static void normalize_GmDocument(iGmDocument *d) {
 void setUrl_GmDocument(iGmDocument *d, const iString *url) {
     url = canonicalUrl_String(url);
     set_String(&d->url, url);
-    setThemeSeed_GmDocument(d, urlThemeSeed_String(url));
+    setThemeSeed_GmDocument(d, urlPaletteSeed_String(url), urlThemeSeed_String(url));
     iUrl parts;
     init_Url(&parts, url);
     setRange_String(&d->localHost, parts.host);
diff --git a/src/gmdocument.h b/src/gmdocument.h
index 0969794c..6c25dd6f 100644
--- a/src/gmdocument.h
+++ b/src/gmdocument.h
@@ -181,7 +181,9 @@ enum iGmDocumentUpdate {
     final_GmDocumentUpdate,   /* process all lines, including the last one if not terminated */
 };
 
-void    setThemeSeed_GmDocument (iGmDocument *, const iBlock *seed);
+void    setThemeSeed_GmDocument (iGmDocument *,
+                                 const iBlock *paletteSeed,
+                                 const iBlock *iconSeed); /* seeds may be NULL; NULL iconSeed will use paletteSeed instead */
 void    setFormat_GmDocument    (iGmDocument *, enum iSourceFormat format);
 void    setWidth_GmDocument     (iGmDocument *, int width, int canvasWidth);
 iBool   updateWidth_GmDocument  (iGmDocument *, int width, int canvasWidth);
diff --git a/src/gmutil.c b/src/gmutil.c
index 0573aac1..9188091d 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -23,6 +23,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
 #include "gmutil.h"
 #include "fontpack.h"
 #include "lang.h"
+#include "sitespec.h"
 #include "ui/color.h"
 
 #include 
@@ -279,6 +280,19 @@ const iBlock *urlThemeSeed_String(const iString *url) {
     return collect_Block(newRange_Block(user));
 }
 
+const iBlock *urlPaletteSeed_String(const iString *url) {
+    if (equalCase_Rangecc(urlScheme_String(url), "file")) {
+        return urlThemeSeed_String(url);
+    }
+    /* Check for a site-specific setting. */
+    const iString *seed =
+        valueString_SiteSpec(collectNewRange_String(urlRoot_String(url)), paletteSeed_SiteSpecKey);
+    if (!isEmpty_String(seed)) {
+        return utf8_String(seed);
+    }
+    return urlThemeSeed_String(url);
+}
+
 static iBool isAbsolutePath_(iRangecc path) {
     return isAbsolute_Path(collect_String(urlDecode_String(collect_String(newRange_String(path)))));
 }
diff --git a/src/gmutil.h b/src/gmutil.h
index c9d7baae..01eb8e52 100644
--- a/src/gmutil.h
+++ b/src/gmutil.h
@@ -120,6 +120,7 @@ uint16_t        urlPort_String          (const iString *);
 iRangecc        urlUser_String          (const iString *);
 iRangecc        urlRoot_String          (const iString *);
 const iBlock *  urlThemeSeed_String     (const iString *);
+const iBlock *  urlPaletteSeed_String   (const iString *);
 
 const iString * absoluteUrl_String      (const iString *, const iString *urlMaybeRelative);
 iBool           isLikelyUrl_String      (const iString *);
diff --git a/src/sitespec.c b/src/sitespec.c
index fe80ad13..31094981 100644
--- a/src/sitespec.c
+++ b/src/sitespec.c
@@ -37,7 +37,8 @@ struct Impl_SiteParams {
     iString  titanIdentity; /* fingerprint */
     int      dismissWarnings;
     iStringArray usedIdentities; /* fingerprints; latest ones at the end */
-    /* TODO: theme seed, style settings */
+    iString  paletteSeed;
+    /* TODO: style settings */
 };
 
 void init_SiteParams(iSiteParams *d) {
@@ -45,9 +46,11 @@ void init_SiteParams(iSiteParams *d) {
     init_String(&d->titanIdentity);
     d->dismissWarnings = 0;
     init_StringArray(&d->usedIdentities);
+    init_String(&d->paletteSeed);
 }
 
 void deinit_SiteParams(iSiteParams *d) {
+    deinit_String(&d->paletteSeed);
     deinit_StringArray(&d->usedIdentities);
     deinit_String(&d->titanIdentity);
 }
@@ -149,6 +152,9 @@ static void handleIniKeyValue_SiteSpec_(void *context, const iString *table, con
             pushBack_StringArray(&d->loadParams->usedIdentities, collectNewRange_String(seg));
         }
     }
+    else if (!cmp_String(key, "paletteSeed") && value->type == string_TomlType) {
+        set_String(&d->loadParams->paletteSeed, value->value.string);
+    }
 }
 
 static iBool load_SiteSpec_(iSiteSpec *d) {
@@ -190,6 +196,11 @@ static void save_SiteSpec_(iSiteSpec *d) {
                     "usedIdentities = \"%s\"\n",
                     cstrCollect_String(joinCStr_StringArray(¶ms->usedIdentities, " ")));
             }
+            if (!isEmpty_String(¶ms->paletteSeed)) {
+                appendCStr_String(buf, "paletteSeed = \"");
+                append_String(buf, collect_String(quote_String(¶ms->paletteSeed, iFalse)));
+                appendCStr_String(buf, "\"\n");
+            }
             appendCStr_String(buf, "\n");
             write_File(f, utf8_String(buf));
             iEndCollect();
diff --git a/src/sitespec.h b/src/sitespec.h
index 11c40e3c..372e021e 100644
--- a/src/sitespec.h
+++ b/src/sitespec.h
@@ -31,6 +31,7 @@ enum iSiteSpecKey {
     titanIdentity_SiteSpecKey,   /* String */
     dismissWarnings_SiteSpecKey, /* int */
     usedIdentities_SiteSpecKey,  /* StringArray */
+    paletteSeed_SiteSpecKey,     /* String */
 };
 
 void    init_SiteSpec       (const char *saveDir);
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 293e4507..7d9ac154 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -3936,12 +3936,12 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
         const char *unchecked       = red_ColorEscape "\u2610";
         const char *checked         = green_ColorEscape "\u2611";
         const iBool haveFingerprint = (d->certFlags & haveFingerprint_GmCertFlag) != 0;
-        const int requiredForTrust = (available_GmCertFlag | haveFingerprint_GmCertFlag |
-                                      timeVerified_GmCertFlag);
+        const int   requiredForTrust =
+            (available_GmCertFlag | haveFingerprint_GmCertFlag | timeVerified_GmCertFlag);
         const iBool canTrust = ~d->certFlags & trusted_GmCertFlag &&
                                ((d->certFlags & requiredForTrust) == requiredForTrust);
         const iRecentUrl *recent = constMostRecentUrl_History(d->mod.history);
-        const iString *meta = &d->sourceMime;
+        const iString    *meta   = &d->sourceMime;
         if (recent && recent->cachedResponse) {
             meta = &recent->cachedResponse->meta;
         }
@@ -4006,6 +4006,10 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
         if (haveFingerprint) {
             pushBack_Array(items, &(iMenuItem){ "${dlg.cert.fingerprint}", 0, 0, "server.copycert" });
         }
+        const iRangecc root = urlRoot_String(d->mod.url);
+        if (!isEmpty_Range(&root)) {
+            pushBack_Array(items, &(iMenuItem){ "${pageinfo.settings}", 0, 0, "document.sitespec" });
+        }
         if (!isEmpty_Array(items)) {
             pushBack_Array(items, &(iMenuItem){ "---", 0, 0, 0 });
         }
@@ -4937,7 +4941,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e
                 for (size_t i = 0; i < 64; ++i) {
                     setByte_Block(seed, i, iRandom(0, 256));
                 }
-                setThemeSeed_GmDocument(view->doc, seed);
+                setThemeSeed_GmDocument(view->doc, seed, NULL);
                 delete_Block(seed);
                 invalidate_DocumentWidget_(d);
                 refresh_Widget(w);
diff --git a/src/ui/util.c b/src/ui/util.c
index befc2fd5..54715121 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -3169,15 +3169,14 @@ static iBool handleFeedSettingCommands_(iWidget *dlg, const char *cmd) {
 }
 
 iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) {
-    const char *headingText = bookmarkId ? uiHeading_ColorEscape "${heading.feedcfg}"
-                                         : uiHeading_ColorEscape "${heading.subscribe}";
-    const iMenuItem actions[] = { { "${cancel}" },
-                                  { bookmarkId ? uiTextCaution_ColorEscape "${dlg.feed.save}"
-                                               : uiTextCaution_ColorEscape "${dlg.feed.sub}",
-                                    SDLK_RETURN,
-                                    KMOD_PRIMARY,
-                                    format_CStr("feedcfg.accept bmid:%d", bookmarkId) } };
-    iWidget *dlg;
+    iWidget        *dlg;
+    const char     *headingText = bookmarkId ? "${heading.feedcfg}" : "${heading.subscribe}";
+    const iMenuItem actions[]   = { { "${cancel}" },
+                                    { bookmarkId ? uiTextCaution_ColorEscape "${dlg.feed.save}"
+                                                 : uiTextCaution_ColorEscape "${dlg.feed.sub}",
+                                      SDLK_RETURN,
+                                      KMOD_PRIMARY,
+                                      format_CStr("feedcfg.accept bmid:%d", bookmarkId) } };
     if (isUsingPanelLayout_Mobile()) {
         const iMenuItem typeItems[] = {
             { "button id:feedcfg.type.gemini label:dlg.feed.type.gemini", 0, 0, "feedcfg.type arg:0" },
@@ -3234,6 +3233,32 @@ iWidget *makeFeedSettings_Widget(uint32_t bookmarkId) {
     return dlg;
 }
 
+iWidget *makeSiteSpecificSettings_Widget(const iString *url) {
+    iWidget *dlg;
+    const iMenuItem actions[] = {
+        { "${cancel}" }, { "${sitespec.accept}", SDLK_RETURN, KMOD_PRIMARY, "sitespec.accept" }
+    };
+    if (isUsingPanelLayout_Mobile()) {
+        iAssert(iFalse);
+    }
+    else {
+        iWidget *headings, *values;
+        dlg = makeSheet_Widget("sitespec");
+        addDialogTitle_(dlg, "${heading.sitespec}", "heading.sitespec");
+        addChild_Widget(dlg, iClob(makeTwoColumns_Widget(&headings, &values)));
+        addDialogToggle_(headings, values, "${sitespec.ansi}", "sitespec.ansi");
+        iInputWidget *palInput = new_InputWidget(0);
+        addPrefsInputWithHeading_(headings, values, "sitespec.palette", iClob(palInput));
+        as_Widget(palInput)->rect.size.x = 80 * gap_UI;
+        addChild_Widget(dlg, iClob(makeDialogButtons_Widget(actions, iElemCount(actions))));
+    }
+    /* Initialize. */ {
+        const iRangecc root = urlRoot_String(url);
+        
+    }
+    return dlg;
+}
+
 iWidget *makeIdentityCreation_Widget(void) {
     const iMenuItem actions[] = { { "${dlg.newident.more}", 0, 0, "ident.showmore" },
                                   { "---" },
diff --git a/src/ui/util.h b/src/ui/util.h
index 0289d579..31c8cedc 100644
--- a/src/ui/util.h
+++ b/src/ui/util.h
@@ -336,13 +336,14 @@ iWidget *   makeQuestion_Widget     (const char *title, const char *msg,
 iWidget *   makePreferences_Widget          (void);
 void        updatePreferencesLayout_Widget  (iWidget *prefs);
 
-iWidget *   makeBookmarkEditor_Widget   (void);
-void        setBookmarkEditorFolder_Widget(iWidget *editor, uint32_t folderId);
-iWidget *   makeBookmarkCreation_Widget (const iString *url, const iString *title, iChar icon);
-iWidget *   makeIdentityCreation_Widget (void);
-iWidget *   makeFeedSettings_Widget     (uint32_t bookmarkId);
-iWidget *   makeTranslation_Widget      (iWidget *parent);
-iWidget *   makeGlyphFinder_Widget      (void);
+iWidget *   makeBookmarkEditor_Widget       (void);
+void        setBookmarkEditorFolder_Widget  (iWidget *editor, uint32_t folderId);
+iWidget *   makeBookmarkCreation_Widget     (const iString *url, const iString *title, iChar icon);
+iWidget *   makeIdentityCreation_Widget     (void);
+iWidget *   makeFeedSettings_Widget         (uint32_t bookmarkId);
+iWidget *   makeSiteSpecificSettings_Widget (const iString *url);
+iWidget *   makeTranslation_Widget          (iWidget *parent);
+iWidget *   makeGlyphFinder_Widget          (void);
 
 const char *    languageId_String   (const iString *menuItemLabel);
 int             languageIndex_CStr  (const char *langId);
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.11/cdiff/64eaaaac57fc909a9c9d47302f17f0801b7f2965
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
35.840312 milliseconds
Gemini-to-HTML Time
1.220294 milliseconds

This content has been proxied by September (3851b).