Skip to content

Commit

Permalink
feat: Custom Style Support (#141)
Browse files Browse the repository at this point in the history
This is new feature: custom style. This feature is originally proposed
at ueokande/vim-vixen#161. This change
supports custom styles for hint and console.
  • Loading branch information
ueokande committed May 6, 2023
1 parent 14a070b commit 5f9da16
Show file tree
Hide file tree
Showing 49 changed files with 753 additions and 295 deletions.
2 changes: 2 additions & 0 deletions docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ <h1>Guide</h1>
<li><a href='./blacklist.html'>Blacklist</a></li>
<li><a href='./search_engines.html'>Search engines</a></li>
<li><a href='./properties.html'>Properties</a></li>
<li><a href='./styles.html'>Custom Styles</a></li>
</ul>
</aside>

Expand All @@ -53,6 +54,7 @@ <h1>Guide</h1>
<li><a href='./blacklist.html'>Blacklist</a></li>
<li><a href='./search_engines.html'>Search engines</a></li>
<li><a href='./properties.html'>Properties</a></li>
<li><a href='./styles.html'>Custom Styles</a></li>
<li class='separator'></li>
<li><a target="_blank" rel="noopener" href='https://github.com/ueokande/vimmatic'>GitHub</a></li>
<li><a target="_blank" rel="noopener" href='https://addons.mozilla.org/firefox/addon/vimmatic/'>Firefox Add-ons</a></li>
Expand Down
31 changes: 31 additions & 0 deletions docs/styles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: Custom Styles
---

# Custom Styles

Users can specify custom styles in CSS format for certain components.

```json
{
"styles": {
"hint": {
"background-color": "yellow",
"border": "1px solid gold",
"font-weight": "bold",
"font-size": "12px",
"color": "black"
},
"console": {
"font-family": "monospace",
"font-size": "12px"
}
}
}

```

Vimmatic supports the two types of components:

- `hint`: Hint tags in follow mode.
- `console`: Console at the bottom of the page.
1 change: 0 additions & 1 deletion script/build
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const buildScripts = async (browser) => {

const buildAssets = async (browser) => {
await fs.cp("resources/", `dist/${browser}/resources/`, { recursive: true });
await fs.copyFile(`src/console/index.css`, `dist/${browser}/lib/console.css`);
await fs.copyFile(
`src/console/index.html`,
`dist/${browser}/lib/console.html`
Expand Down
11 changes: 11 additions & 0 deletions src/background/controllers/SettingsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ export default class SettingsController {
return this.settingsUseCase.getProperty(name);
}

async getStyle(
_ctx: RequestContext,
{
name,
}: {
name: string;
}
): Promise<Record<string, string>> {
return this.settingsUseCase.getStyle(name);
}

async validate(
_ctx: RequestContext,
{ settings }: { settings: unknown }
Expand Down
2 changes: 2 additions & 0 deletions src/background/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
ChromeClipboardRepositoryImpl,
} from "./repositories/ClipboardRepository";
import { PropertySettingsImpl } from "./settings/PropertySettings";
import { StyleSettingsImpl } from "./settings/StyleSettings";
import { SearchEngineSettingsImpl } from "./settings/SearchEngineSettings";
import {
TransientSettingsRepository,
Expand Down Expand Up @@ -65,6 +66,7 @@ if (process.env.BROWSER === "firefox") {
.to(ChromeBrowserSettingRepositoryImpl);
}
container.bind("PropertySettings").to(PropertySettingsImpl);
container.bind("StyleSettings").to(StyleSettingsImpl);
container.bind("SearchEngineSettings").to(SearchEngineSettingsImpl);
container.bind("KeyCaptureClient").to(KeyCaptureClientImpl);
container.bind("MarkRepository").to(MarkRepositoryImpl);
Expand Down
3 changes: 3 additions & 0 deletions src/background/messaging/BackgroundMessageListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ export default class BackgroundMessageListener {
this.receiver
.route("settings.get.property")
.to(settingsController.getProperty.bind(settingsController));
this.receiver
.route("settings.get.style")
.to(settingsController.getStyle.bind(settingsController));
this.receiver
.route("settings.query")
.to(settingsController.getSettings.bind(settingsController));
Expand Down
25 changes: 25 additions & 0 deletions src/background/settings/StyleSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { injectable, inject } from "inversify";
import SettingsRepository from "./SettingsRepository";
import { ComponentName } from "../../shared/Styles";
import { defaultSettings } from "../../settings";

export default interface StyleSettings {
getStyle(name: string): Promise<Record<string, string>>;
}

@injectable()
export class StyleSettingsImpl {
constructor(
@inject("SettingsRepository")
private readonly settingsRepository: SettingsRepository
) {}

async getStyle(name: ComponentName): Promise<Record<string, string>> {
const settings = await this.settingsRepository.load();
const value = (settings.styles || {})[name];
if (typeof value === "undefined") {
return defaultSettings.styles![name]!;
}
return value;
}
}
7 changes: 7 additions & 0 deletions src/background/usecases/SettingsUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { injectable, inject } from "inversify";
import { serialize, deserialize } from "../../settings";
import SettingsRepository from "../settings/SettingsRepository";
import PropertySettings from "../settings/PropertySettings";
import StyleSettings from "../settings/StyleSettings";
import Validator from "../settings/Validator";

@injectable()
Expand All @@ -11,6 +12,8 @@ export default class SettingsUseCase {
private readonly settingsRepository: SettingsRepository,
@inject("PropertySettings")
private readonly propertySettings: PropertySettings,
@inject("StyleSettings")
private readonly styleSettings: StyleSettings,
@inject(Validator)
private readonly validator: Validator
) {}
Expand All @@ -23,6 +26,10 @@ export default class SettingsUseCase {
return this.propertySettings.getProperty(name);
}

async getStyle(name: string): Promise<Record<string, string>> {
return this.styleSettings.getStyle(name);
}

async validate(data: unknown): Promise<string | undefined> {
try {
this.validator.validate(deserialize(data));
Expand Down
73 changes: 67 additions & 6 deletions src/console/App.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,51 @@
import Console from "./components/Console";
import React from "react";
import Prompt from "./components/Prompt";
import InfoMessage from "./components/InfoMessage";
import ErrorMessage from "./components/ErrorMessage";
import { SimplexReceiver } from "../messaging";
import type { Schema as ConsoleMessageSchema } from "../messaging/schema/console";
import React from "react";
import { useConsoleMode, useVisibility } from "./app/hooks";
import { useColorSchemeRefresh } from "./colorscheme/hooks";
import {
useConsoleMode,
useVisibility,
useExecCommand,
useGetCommandCompletion,
useExecFind,
useGetFindCompletion,
} from "./app/hooks";
import { useInvalidateStyle } from "./styles/hooks";

// (10item + 1title) * sbc
const COMMAND_COMPLETION_MAX_ITEMS = 33;
const FIND_COMPLETION_MAX_ITEMS = 11;

const App: React.FC = () => {
const refreshColorScheme = useColorSchemeRefresh();
const refreshColorScheme = useInvalidateStyle();
const { hide, visible } = useVisibility();
const {
state,
showCommandPrompt,
showFindPrompt,
showInfoMessage,
showErrorMessage,
} = useConsoleMode();
const execCommand = useExecCommand();
const execFind = useExecFind();
const getCommandCompletions = useGetCommandCompletion();
const getFindCompletions = useGetFindCompletion();
const onExec = React.useCallback(
(cmd: string) => {
if (state.mode !== "prompt") {
return;
}
if (state.promptMode === "command") {
execCommand(cmd);
} else if (state.promptMode === "find") {
execFind(cmd);
}
hide();
},
[execCommand, execFind, state]
);

React.useEffect(() => {
if (visible) {
Expand Down Expand Up @@ -41,7 +73,36 @@ const App: React.FC = () => {
});
}, []);

return <Console />;
if (state.mode === "prompt") {
if (state.promptMode === "command") {
return (
<Prompt
prefix={":"}
maxLineHeight={COMMAND_COMPLETION_MAX_ITEMS}
onExec={onExec}
queryCompletions={getCommandCompletions}
initValue={state.initValue}
onBlur={hide}
/>
);
} else if (state.promptMode === "find") {
return (
<Prompt
prefix={"/"}
maxLineHeight={FIND_COMPLETION_MAX_ITEMS}
onExec={onExec}
queryCompletions={getFindCompletions}
initValue={state.initValue}
onBlur={hide}
/>
);
}
} else if (state.mode === "info_message") {
return <InfoMessage>{state.message}</InfoMessage>;
} else if (state.mode === "error_message") {
return <ErrorMessage>{state.message}</ErrorMessage>;
}
return null;
};

export default App;
7 changes: 7 additions & 0 deletions src/console/clients/SettingClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ export default class SettingClient {
});
return value as string;
}

async getConsoleStyle(): Promise<Record<string, string>> {
const value = await this.sender.send("settings.get.style", {
name: "console",
});
return value as Record<string, string>;
}
}
7 changes: 0 additions & 7 deletions src/console/colorscheme/contexts.tsx

This file was deleted.

17 changes: 0 additions & 17 deletions src/console/colorscheme/hooks.ts

This file was deleted.

30 changes: 0 additions & 30 deletions src/console/colorscheme/providers.tsx

This file was deleted.

47 changes: 0 additions & 47 deletions src/console/colorscheme/theme.ts

This file was deleted.

12 changes: 4 additions & 8 deletions src/console/completion/components/CompletionItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import styled from "../../colorscheme/styled";
import styled from "../../styles/styled";

const Container = styled.li<{
shown: boolean;
Expand All @@ -9,13 +9,9 @@ const Container = styled.li<{
background-image: ${({ icon }) =>
typeof icon !== "undefined" ? "url(" + icon + ")" : "unset"};
background-color: ${({ highlight, theme }) =>
highlight
? theme.completionSelectedBackground
: theme.completionItemBackground};
highlight ? theme.select?.background : theme.background};
color: ${({ highlight, theme }) =>
highlight
? theme.completionSelectedForeground
: theme.completionItemForeground};
highlight ? theme.select?.foreground : theme.foreground};
display: ${({ shown }) => (shown ? "block" : "none")};
padding-left: 1.8rem;
background-position: 0 center;
Expand All @@ -33,7 +29,7 @@ const Primary = styled.span`

const Secondary = styled.span`
display: inline-block;
color: ${({ theme }) => theme.completionItemDescriptionForeground};
color: ${({ theme }) => theme.secondaryForeground};
width: 60%;
text-overflow: ellipsis;
overflow: hidden;
Expand Down
Loading

0 comments on commit 5f9da16

Please sign in to comment.