github-url-detection icon indicating copy to clipboard operation
github-url-detection copied to clipboard

Add `elementReady`-like helper for DOM detections

Open fregante opened this issue 4 years ago • 3 comments

Sometimes we want to test whether a page matches before it's done downloading, this can be done by passing a selector to element-ready.

I have 2 ideas:

Static definitions

Instead of being just a function, we can define the detections as a list of constraints like:

- const canUserEditOrg = (url) => isOrganizationProfile() && exists('.pagehead-tabs-item[href$="/settings/profile"]')
+ const canUserEditOrgDefinition = [isOrganizationProfile, '.pagehead-tabs-item[href$="/settings/profile"]']
+ export canUserEditOrg = solveConstraints(canUserEditOrgDefinition);
+ export canUserEditOrgAsync = solveConstraintsAsync(canUserEditOrgDefinition);

But this gets wordy FAST

Duplicate functions

  const canUserEditOrg = (url) => isOrganizationProfile() && exists('.pagehead-tabs-item[href$="/settings/profile"]')
+ const canUserEditOrgAsync = async (url) => isOrganizationProfile() && await existsReady('.pagehead-tabs-item[href$="/settings/profile"]')

fregante avatar Jul 09 '21 16:07 fregante

Wrapper idea

ElementReady is nothing but a requestAnimationFrame-based loop that calls querySelector until found. This means we can offer a simple wrapper that does this with any detection:

import {wait, canEditSidebar} from '';

function init() {
  if(!await wait(canEditSidebar)) 
    return false
}
  • Pure DOM-based detections would be perfect this way;
  • Pure URL-based detections wouldn’t need it;
  • Mixed detections would unnecessarily test the URL every time, but probably we don’t have to worry about the “performance impact” of this

Alternatively the detections could internally replace exists with an async version, but it would be impossible to effectively handle multiple checks in the same detection:

await canEditSidebar({async: true})

fregante avatar Jul 11 '22 16:07 fregante

Something like:

export async function wait(detection) {
	while (!detection() && document isn't ready) {
		await Promise(requestAnimationFrame)
	}

	return detection();
}

fregante avatar Jul 28 '22 08:07 fregante

Note that we moved these user-capability detections to the API in Refined GitHub:

  • https://github.com/refined-github/refined-github/pull/7798

However there are still other DOM-based detection like isOrganizationProfile that would benefit from this

fregante avatar Sep 25 '24 09:09 fregante