Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mod-box",
"private": true,
"version": "0.2.3",
"version": "0.2.4",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "ModBox – Modify headers, block requests",
"short_name": "ModBox",
"description": "Modify HTTP headers, block assets or domains & redirect requests. Organise rules by folder and tab, optionally scope to domains.",
"version": "0.2.3",
"version": "0.2.4",
"author": {
"email": "robertjamesphillips@googlemail.com"
},
Expand Down
2 changes: 0 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# ModBox
A compact and easy to use extension for modifying HTTP request & response headers and blocking HTTP requests.



## Features
- Create rules to modify HTTP request and response headers
- Create rules to block HTTP request & even block entire sites
Expand Down
17 changes: 15 additions & 2 deletions src/components/Editor.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="editor" :class="{'editor--align-right': aligned === 'right', 'editor--open': isEditing && aligned === 'right'}">
<button
v-if="!domains"
v-if="!domains && !icon"
@click="edit"
class="editor__trigger"
:class="{
Expand All @@ -14,6 +14,19 @@

</button>

<button
v-if="icon"
@click="edit"
class="editor__trigger editor__trigger--icon"
:title="model || ''"
>
<svg v-if="model" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0"/>
</svg>
<template v-else>-</template>
</button>

<div v-if="domains && splitDomains" class="editor__domains">
<button
v-if="splitDomains.length > 0"
Expand Down Expand Up @@ -77,7 +90,7 @@ import { cleanDomain } from "../utils";
import Tooltip from "./Tooltip.vue";

const model = defineModel<string>();
const props = defineProps(["placeholder", "locked", "fallback", "domains", "label", "aligned"]);
const props = defineProps(["placeholder", "locked", "fallback", "domains", "label", "aligned", "icon"]);

const input: Ref<HTMLTextAreaElement | null> = ref(null);
const isEditing = ref(false);
Expand Down
44 changes: 44 additions & 0 deletions src/components/Tab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@

<!-- <Tooltip> Single or comma separated domains </Tooltip> -->
</th>
<th>Note</th>
<th></th>
</tr>

Expand Down Expand Up @@ -181,6 +182,15 @@
:domains="true"
/>
</td>
<td class="table__short">
<Editor
v-model="header.note"
placeholder="Note"
:icon="true"
:aligned="'right'"
label="Note"
/>
</td>
<td class="table__short text-right">
<DropdownMenu :options="requestActions" :rule="header" />
</td>
Expand Down Expand Up @@ -217,6 +227,7 @@
Domains
<!-- <Tooltip>Single or comma separated domains</Tooltip> -->
</th>
<th>Note</th>
<th></th>
</tr>
<RuleDragger
Expand Down Expand Up @@ -264,6 +275,15 @@
:aligned="'right'"
/>
</td>
<td class="table__short">
<Editor
v-model="header.note"
placeholder="Note"
:icon="true"
:aligned="'right'"
label="Note"
/>
</td>
<td class="table__short text-right">
<DropdownMenu :options="responseActions" :rule="header" />
</td>
Expand Down Expand Up @@ -298,6 +318,7 @@
Domains
<!-- <Tooltip> Single or comma separated domains</Tooltip> -->
</th>
<th>Note</th>
<th class="table__short"></th>
</tr>
<RuleDragger
Expand Down Expand Up @@ -344,6 +365,15 @@
:aligned="'right'"
/>
</td>
<td class="table__short">
<Editor
v-model="request.note"
placeholder="Note"
:icon="true"
:aligned="'right'"
label="Note"
/>
</td>
<td class="table__short text-right">
<DropdownMenu :options="blockActions" :rule="request" />
</td>
Expand Down Expand Up @@ -381,6 +411,7 @@
Domains
<!-- <Tooltip> Single or comma separated domains</Tooltip> -->
</th>
<th>Note</th>
<th class="table__short"></th>
</tr>
<!-- <tr v-for="request in tab.redirectRequests"> -->
Expand Down Expand Up @@ -423,6 +454,15 @@
:aligned="'right'"
/>
</td>
<td class="table__short">
<Editor
v-model="request.note"
placeholder="Note"
:icon="true"
:aligned="'right'"
label="Note"
/>
</td>
<td class="table__short text-right">
<DropdownMenu :options="redirectActions" :rule="request" />
</td>
Expand Down Expand Up @@ -686,6 +726,7 @@ function addRequestHeader() {
active: true,
name: "",
value: "",
note: "",
condition: {
urlFilter: "",
requestDomains: "",
Expand All @@ -698,6 +739,7 @@ function addResponseHeader() {
active: true,
name: "",
value: "",
note: "",
condition: {
urlFilter: "",
requestDomains: "",
Expand All @@ -708,6 +750,7 @@ function addResponseHeader() {
function addBlockedRequest() {
tab.value.blockedRequests.push({
active: true,
note: "",
condition: {
urlFilter: "",
requestDomains: "",
Expand All @@ -724,6 +767,7 @@ function addRedirectRequest() {
tab.value.redirectRequests.push({
active: true,
url: "",
note: "",
condition: {
urlFilter: "",
requestDomains: "",
Expand Down
36 changes: 36 additions & 0 deletions src/interfaces.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ describe('Type Guards', () => {
it('returns false for invalid condition', () => {
expect(isValidHeaderRule({ ...validRule, condition: 'invalid' })).toBe(false);
});

it('returns true with a string note', () => {
expect(isValidHeaderRule({ ...validRule, note: 'some note' })).toBe(true);
});

it('returns true without note (undefined)', () => {
expect(isValidHeaderRule(validRule)).toBe(true);
});

it('returns false for non-string note', () => {
expect(isValidHeaderRule({ ...validRule, note: 123 })).toBe(false);
});
});

describe('isValidBlockedRequest', () => {
Expand All @@ -123,6 +135,18 @@ describe('Type Guards', () => {
it('returns false for missing condition', () => {
expect(isValidBlockedRequest({ active: true })).toBe(false);
});

it('returns true with a string note', () => {
expect(isValidBlockedRequest({ ...validBlock, note: 'block note' })).toBe(true);
});

it('returns true without note (undefined)', () => {
expect(isValidBlockedRequest(validBlock)).toBe(true);
});

it('returns false for non-string note', () => {
expect(isValidBlockedRequest({ ...validBlock, note: true })).toBe(false);
});
});

describe('isValidRedirectRequest', () => {
Expand All @@ -144,6 +168,18 @@ describe('Type Guards', () => {
it('returns false for non-string url', () => {
expect(isValidRedirectRequest({ ...validRedirect, url: 123 })).toBe(false);
});

it('returns true with a string note', () => {
expect(isValidRedirectRequest({ ...validRedirect, note: 'redirect note' })).toBe(true);
});

it('returns true without note (undefined)', () => {
expect(isValidRedirectRequest(validRedirect)).toBe(true);
});

it('returns false for non-string note', () => {
expect(isValidRedirectRequest({ ...validRedirect, note: 42 })).toBe(false);
});
});

describe('isValidTab', () => {
Expand Down
6 changes: 6 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ export interface HeaderRule {
name: string;
value: string;
operation?: 'set' | 'remove';
note?: string;
condition: RuleCondition;
}

export interface BlockedRequest {
active: boolean;
note?: string;
condition: RuleCondition;
}

export interface RedirectRequest {
active: boolean;
url: string;
note?: string;
condition: Omit<RuleCondition, 'document'>;
}

Expand Down Expand Up @@ -70,6 +73,7 @@ export function isValidHeaderRule(obj: unknown): obj is HeaderRule {
typeof rule.name === 'string' &&
typeof rule.value === 'string' &&
(rule.operation === undefined || rule.operation === 'set' || rule.operation === 'remove') &&
(rule.note === undefined || typeof rule.note === 'string') &&
isValidRuleCondition(rule.condition)
);
}
Expand All @@ -79,6 +83,7 @@ export function isValidBlockedRequest(obj: unknown): obj is BlockedRequest {
const rule = obj as Record<string, unknown>;
return (
typeof rule.active === 'boolean' &&
(rule.note === undefined || typeof rule.note === 'string') &&
isValidRuleCondition(rule.condition)
);
}
Expand All @@ -89,6 +94,7 @@ export function isValidRedirectRequest(obj: unknown): obj is RedirectRequest {
return (
typeof rule.active === 'boolean' &&
typeof rule.url === 'string' &&
(rule.note === undefined || typeof rule.note === 'string') &&
rule.condition !== null &&
typeof rule.condition === 'object' &&
typeof (rule.condition as Record<string, unknown>).urlFilter === 'string' &&
Expand Down
8 changes: 7 additions & 1 deletion src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1060,14 +1060,20 @@ hr {
}

svg {
width: 10px;
width: 12px;
vertical-align: middle;
display: inline-block;
opacity: 0;
}

&--icon svg {
opacity: 1;
// width: 16px;
}

&:hover svg {
opacity: 1;
fill: #000;
}
}

Expand Down
Loading