Add every-page rules and trigger logging
This commit is contained in:
+24
-12
@@ -8,10 +8,10 @@
|
|||||||
const autoClickTimers = new Map(); // rule name -> setInterval id
|
const autoClickTimers = new Map(); // rule name -> setInterval id
|
||||||
const injectedStyles = new Map(); // rule name -> <style> element currently on the page
|
const injectedStyles = new Map(); // rule name -> <style> element currently on the page
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'complete') {
|
||||||
document.addEventListener('DOMContentLoaded', boot);
|
|
||||||
} else {
|
|
||||||
boot();
|
boot();
|
||||||
|
} else {
|
||||||
|
window.addEventListener('load', boot, { once: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function boot() {
|
function boot() {
|
||||||
@@ -41,25 +41,37 @@
|
|||||||
|
|
||||||
function ruleMatches(rule) {
|
function ruleMatches(rule) {
|
||||||
const currentUrl = window.location.href;
|
const currentUrl = window.location.href;
|
||||||
if (rule.matchType === 'url') {
|
if (rule.matchType === 'all') {
|
||||||
return currentUrl.includes(rule.urlPattern);
|
return { matched: true, elementCount: null };
|
||||||
} else if (rule.matchType === 'element') {
|
|
||||||
return !!document.querySelector(rule.elementSelector);
|
|
||||||
} else if (rule.matchType === 'both') {
|
|
||||||
return currentUrl.includes(rule.urlPattern) && !!document.querySelector(rule.elementSelector);
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
if (rule.matchType === 'url') {
|
||||||
|
return { matched: currentUrl.includes(rule.urlPattern), elementCount: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.matchType !== 'element' && rule.matchType !== 'both') {
|
||||||
|
return { matched: false, elementCount: null };
|
||||||
|
}
|
||||||
|
if (rule.matchType === 'both' && !currentUrl.includes(rule.urlPattern)) {
|
||||||
|
return { matched: false, elementCount: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
const elementCount = document.querySelectorAll(rule.elementSelector).length;
|
||||||
|
return { matched: elementCount > 0, elementCount };
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluateRule(rule) {
|
function evaluateRule(rule) {
|
||||||
if (!rule.enabled) return;
|
if (!rule.enabled) return;
|
||||||
|
|
||||||
const matched = ruleMatches(rule);
|
const { matched, elementCount } = ruleMatches(rule);
|
||||||
const wasMatched = ruleMatchState.get(rule.name) === true;
|
const wasMatched = ruleMatchState.get(rule.name) === true;
|
||||||
ruleMatchState.set(rule.name, matched);
|
ruleMatchState.set(rule.name, matched);
|
||||||
|
|
||||||
if (matched && !wasMatched) {
|
if (matched && !wasMatched) {
|
||||||
console.log(`[GreasyBoii] ✓ Executing rule: ${rule.name}`);
|
const elementLog = elementCount === null
|
||||||
|
? ''
|
||||||
|
: ` (${elementCount} element${elementCount === 1 ? '' : 's'} found for "${rule.elementSelector}")`;
|
||||||
|
console.log(`[GreasyBoii] Rule triggered: ${rule.name}${elementLog}`);
|
||||||
executeRule(rule);
|
executeRule(rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,7 @@
|
|||||||
<option value="url">URL contains string</option>
|
<option value="url">URL contains string</option>
|
||||||
<option value="element">Page contains element</option>
|
<option value="element">Page contains element</option>
|
||||||
<option value="both">Both URL and element</option>
|
<option value="both">Both URL and element</option>
|
||||||
|
<option value="all">Run on every page</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -77,6 +77,11 @@ function updateFieldVisibility(matchType) {
|
|||||||
elementGroup.style.display = 'block';
|
elementGroup.style.display = 'block';
|
||||||
urlInput.required = true;
|
urlInput.required = true;
|
||||||
elementInput.required = true;
|
elementInput.required = true;
|
||||||
|
} else if (matchType === 'all') {
|
||||||
|
urlGroup.style.display = 'none';
|
||||||
|
elementGroup.style.display = 'none';
|
||||||
|
urlInput.required = false;
|
||||||
|
elementInput.required = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +183,7 @@ function buildRuleCard(rule, index) {
|
|||||||
nameSpan.textContent = rule.name;
|
nameSpan.textContent = rule.name;
|
||||||
badgeGroup.appendChild(nameSpan);
|
badgeGroup.appendChild(nameSpan);
|
||||||
|
|
||||||
const matchTypeLabels = { url: 'URL', element: 'Element', both: 'URL + Element' };
|
const matchTypeLabels = { url: 'URL', element: 'Element', both: 'URL + Element', all: 'Every page' };
|
||||||
badgeGroup.appendChild(makeBadge(matchTypeLabels[rule.matchType] || rule.matchType, 'bg-secondary'));
|
badgeGroup.appendChild(makeBadge(matchTypeLabels[rule.matchType] || rule.matchType, 'bg-secondary'));
|
||||||
|
|
||||||
if (rule.javascript && rule.javascript.trim()) badgeGroup.appendChild(makeBadge('JS', 'bg-warning'));
|
if (rule.javascript && rule.javascript.trim()) badgeGroup.appendChild(makeBadge('JS', 'bg-warning'));
|
||||||
|
|||||||
+24
-12
@@ -8,10 +8,10 @@
|
|||||||
const autoClickTimers = new Map(); // rule name -> setInterval id
|
const autoClickTimers = new Map(); // rule name -> setInterval id
|
||||||
const injectedStyles = new Map(); // rule name -> <style> element currently on the page
|
const injectedStyles = new Map(); // rule name -> <style> element currently on the page
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'complete') {
|
||||||
document.addEventListener('DOMContentLoaded', boot);
|
|
||||||
} else {
|
|
||||||
boot();
|
boot();
|
||||||
|
} else {
|
||||||
|
window.addEventListener('load', boot, { once: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
function boot() {
|
function boot() {
|
||||||
@@ -41,25 +41,37 @@
|
|||||||
|
|
||||||
function ruleMatches(rule) {
|
function ruleMatches(rule) {
|
||||||
const currentUrl = window.location.href;
|
const currentUrl = window.location.href;
|
||||||
if (rule.matchType === 'url') {
|
if (rule.matchType === 'all') {
|
||||||
return currentUrl.includes(rule.urlPattern);
|
return { matched: true, elementCount: null };
|
||||||
} else if (rule.matchType === 'element') {
|
|
||||||
return !!document.querySelector(rule.elementSelector);
|
|
||||||
} else if (rule.matchType === 'both') {
|
|
||||||
return currentUrl.includes(rule.urlPattern) && !!document.querySelector(rule.elementSelector);
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
if (rule.matchType === 'url') {
|
||||||
|
return { matched: currentUrl.includes(rule.urlPattern), elementCount: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rule.matchType !== 'element' && rule.matchType !== 'both') {
|
||||||
|
return { matched: false, elementCount: null };
|
||||||
|
}
|
||||||
|
if (rule.matchType === 'both' && !currentUrl.includes(rule.urlPattern)) {
|
||||||
|
return { matched: false, elementCount: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
const elementCount = document.querySelectorAll(rule.elementSelector).length;
|
||||||
|
return { matched: elementCount > 0, elementCount };
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluateRule(rule) {
|
function evaluateRule(rule) {
|
||||||
if (!rule.enabled) return;
|
if (!rule.enabled) return;
|
||||||
|
|
||||||
const matched = ruleMatches(rule);
|
const { matched, elementCount } = ruleMatches(rule);
|
||||||
const wasMatched = ruleMatchState.get(rule.name) === true;
|
const wasMatched = ruleMatchState.get(rule.name) === true;
|
||||||
ruleMatchState.set(rule.name, matched);
|
ruleMatchState.set(rule.name, matched);
|
||||||
|
|
||||||
if (matched && !wasMatched) {
|
if (matched && !wasMatched) {
|
||||||
console.log(`[GreasyBoii] ✓ Executing rule: ${rule.name}`);
|
const elementLog = elementCount === null
|
||||||
|
? ''
|
||||||
|
: ` (${elementCount} element${elementCount === 1 ? '' : 's'} found for "${rule.elementSelector}")`;
|
||||||
|
console.log(`[GreasyBoii] Rule triggered: ${rule.name}${elementLog}`);
|
||||||
executeRule(rule);
|
executeRule(rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,7 @@
|
|||||||
<option value="url">URL contains string</option>
|
<option value="url">URL contains string</option>
|
||||||
<option value="element">Page contains element</option>
|
<option value="element">Page contains element</option>
|
||||||
<option value="both">Both URL and element</option>
|
<option value="both">Both URL and element</option>
|
||||||
|
<option value="all">Run on every page</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -77,6 +77,11 @@ function updateFieldVisibility(matchType) {
|
|||||||
elementGroup.style.display = 'block';
|
elementGroup.style.display = 'block';
|
||||||
urlInput.required = true;
|
urlInput.required = true;
|
||||||
elementInput.required = true;
|
elementInput.required = true;
|
||||||
|
} else if (matchType === 'all') {
|
||||||
|
urlGroup.style.display = 'none';
|
||||||
|
elementGroup.style.display = 'none';
|
||||||
|
urlInput.required = false;
|
||||||
|
elementInput.required = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +183,7 @@ function buildRuleCard(rule, index) {
|
|||||||
nameSpan.textContent = rule.name;
|
nameSpan.textContent = rule.name;
|
||||||
badgeGroup.appendChild(nameSpan);
|
badgeGroup.appendChild(nameSpan);
|
||||||
|
|
||||||
const matchTypeLabels = { url: 'URL', element: 'Element', both: 'URL + Element' };
|
const matchTypeLabels = { url: 'URL', element: 'Element', both: 'URL + Element', all: 'Every page' };
|
||||||
badgeGroup.appendChild(makeBadge(matchTypeLabels[rule.matchType] || rule.matchType, 'bg-secondary'));
|
badgeGroup.appendChild(makeBadge(matchTypeLabels[rule.matchType] || rule.matchType, 'bg-secondary'));
|
||||||
|
|
||||||
if (rule.javascript && rule.javascript.trim()) badgeGroup.appendChild(makeBadge('JS', 'bg-warning'));
|
if (rule.javascript && rule.javascript.trim()) badgeGroup.appendChild(makeBadge('JS', 'bg-warning'));
|
||||||
|
|||||||
Reference in New Issue
Block a user