Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Annotate Gatherer APIs. - #79

Open
cpovirk wants to merge 4 commits into
mainfrom
gatherer
Open

Annotate Gatherer APIs.#79
cpovirk wants to merge 4 commits into
mainfrom
gatherer

Conversation

@cpovirk

Copy link
Copy Markdown
Collaborator

No description provided.

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These look like they were missed, but I don't know this API:

default <RR> Gatherer<T, ?, RR> andThen(Gatherer<? super R, ?, ? extends RR> that) on line 274 in Gatherer: shouldn't RR allow null?
static <A> Supplier<A> defaultInitializer() on line 289 and static <A> BinaryOperator<A> defaultCombiner() on line 304 in Gatherer: should A allow null?
static <A, R> BiConsumer<A, Downstream<? super R>> defaultFinisher() { on line 321 in Gatherer: A and R should be nullable?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks, I had totally missed those.

andThen looks straightforward, assuming that I haven't been missing anything big throughout this PR.

The others are more interesting. The implementations of default* methods all look capable of handling null—or, in the case of the BinaryOperator for combiner(), as incapable of handling null as of any other value (and I think this point is that the Gatherer infrastructure treats combiner() as a sentinel that says not to invoke the method). There are two things that make that interesting:

  • First, the initializer()returnsnull. I think that means that we actually want to return a Supplier<@Nullable A>.
  • Second, the Gatherer API doesn't do PECS. That means that we probably shouldn't force other methods (like defaultCombiner()) to return a more general type, which is to say BinaryOperator<@Nullable A> (since we can't change it to the fully general type BinaryOperator<@Nullable Object>, since that would require a change to the base type). So I think it makes sense to let callers pick their nullness, just as they can pick the base type.

I have never actually used these APIs, so I could well still be missing things. I would be OK with waiting to merge this until I can justify taking the time to investigate more deeply, or we could go for it and figure that we'll get feedback if users encounter actual problems.

@cpovirk
cpovirk requested a review from wmdietlOctober 7, 2024 16:54

@wmdietlwmdietl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I had missed that this was updated. I merged in main and things look good to me.

@msridhar

Copy link
Copy Markdown
Collaborator

@cpovirk are we good to merge this one? Or are we holding off until someone can do a deeper investigation?

@cpovirk

Copy link
Copy Markdown
CollaboratorAuthor

Thanks for checking. (And thanks for all the other reviews!) I have been holding off until we can take a closer look. At this point, I don't remember even the level of detail in my comment above. (That might be a good thing, since I could try annotating the API again someday with fresh eyes and then see if the results match my earlier attempt :)) I don't have any specific plans to come back to this, though.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@cpovirk@msridhar@wmdietl