Skip to content

Commit

Permalink
fix: Broken preferences (#267)
Browse files Browse the repository at this point in the history
This PR fixes the broken preferences. This issue occurs by #193, since
v0.5.0. Close #233 and #258.
  • Loading branch information
ueokande committed Nov 12, 2023
1 parent 6084379 commit 63c0b52
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 31 deletions.
5 changes: 3 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:prettier/recommended",
"plugin:prettier/recommended"
],
"plugins": [
"@typescript-eslint",
Expand All @@ -34,7 +34,8 @@
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"no-console": "error"
},
"overrides": [
{
Expand Down
1 change: 1 addition & 0 deletions src/background/clients/ConsoleMessageSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const newSender = (tabId: number, frameId?: number) => {
const sender = new Sender<Schema>((type: Key, args: Request) => {
if (process.env.NODE_ENV === "development") {
const style = "background-color: green; color: white; padding: 4px;";
// eslint-disable-next-line no-console
console.debug("%cSEND%c %s %o", style, "", type, args);
}

Expand Down
1 change: 1 addition & 0 deletions src/background/clients/ContentMessageSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const newSender = (tabId: number, frameId?: number) => {
if (process.env.NODE_ENV === "development") {
const style = "background-color: green; color: white; padding: 4px;";
const reset = "background-color: unset; color: unset; padding: unset;";
// eslint-disable-next-line no-console
console.debug("%cSEND%c %s %o", style, reset, type, args);
}

Expand Down
4 changes: 4 additions & 0 deletions src/background/messaging/BackgroundMessageListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export default class BackgroundMessageListener {
) => {
const ctx: RequestContext = { sender };
if (typeof message !== "object" && message !== null) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", message);
return;
}
Expand All @@ -94,19 +95,22 @@ export default class BackgroundMessageListener {
typeof type !== "string" ||
(typeof args !== "undefined" && typeof args !== "object")
) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", message);
return;
}

if (process.env.NODE_ENV === "development") {
const style = "background-color: purple; color: white; padding: 4px;";
// eslint-disable-next-line no-console
console.debug("%cRECEIVE%c %s %o", style, "", type, args);
}

Promise.resolve()
.then(() => this.receiver.receive(ctx, type, args))
.then(sendResponse)
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err);
if (!sender.tab || !sender.tab.id) {
return;
Expand Down
1 change: 1 addition & 0 deletions src/background/settings/PropertySettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class PropertySettingsImpl {
try {
def.validate(value);
} catch (e) {
// eslint-disable-next-line no-console
console.warn(`Property ${name} has invalid value: ${e.message}`);
return def.defaultValue();
}
Expand Down
10 changes: 6 additions & 4 deletions src/background/settings/SettingsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ export class PermanentSettingsRepository implements SettingsRepository {
try {
return deserialize(settings);
} catch (e) {
// eslint-disable-next-line no-console
console.warn("settings may be storage is broken:", e);
console.warn("loaded settings is:");
console.warn(settings);
// eslint-disable-next-line no-console
console.warn("loaded settings is:", settings);
return defaultSettings;
}
}
Expand All @@ -48,9 +49,10 @@ export class PermanentSettingsRepository implements SettingsRepository {
try {
settings = deserialize(changes.settings.newValue);
} catch (e) {
// eslint-disable-next-line no-console
console.warn("settings may be storage is broken:", e);
console.warn("loaded settings is:");
console.warn(changes.settings.newValue);
// eslint-disable-next-line no-console
console.warn("loaded settings is:", changes.settings.newValue);
return;
}

Expand Down
1 change: 1 addition & 0 deletions src/content/client/BackgroundMessageSender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const newSender = () => {
const sender = new Sender<Schema>((type: Key, args: Request) => {
if (process.env.NODE_ENV === "development") {
const style = "background-color: green; color: white; padding: 4px;";
// eslint-disable-next-line no-console
console.debug("%cSEND%c %s %o", style, "", type, args);
}

Expand Down
1 change: 1 addition & 0 deletions src/content/controllers/KeymapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default class KeymapController {
// identify to continue of abandon the event propagation.
this.operationUseCase
.exec(op.name, op.props, op.repeat)
// eslint-disable-next-line no-console
.catch(console.error);
return true;
}
Expand Down
1 change: 1 addition & 0 deletions src/content/controllers/SettingsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default class SettingsController {
}
} catch (e) {
// Sometime sendMessage fails when background script is not ready.
// eslint-disable-next-line no-console
console.warn(e);
setTimeout(() => this.initSettings(), 1000);
}
Expand Down
1 change: 1 addition & 0 deletions src/content/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const initDom = () => {
const app = container.resolve(Application);
await app.init();
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
})();
Expand Down
4 changes: 4 additions & 0 deletions src/content/messaging/ContentMessageListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export default class ContentMessageListener {
chrome.runtime.onMessage.addListener(
(message: unknown, _sender, sendResponse) => {
if (typeof message !== "object" && message !== null) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", message);
return;
}
Expand All @@ -151,19 +152,22 @@ export default class ContentMessageListener {
typeof type !== "string" ||
(typeof args !== "undefined" && typeof args !== "object")
) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", message);
return;
}

if (process.env.NODE_ENV === "development") {
const style = "background-color: purple; color: white; padding: 4px;";
// eslint-disable-next-line no-console
console.debug("%cRECEIVE%c %s %o", style, "", type, args);
}

const ret = this.receiver.receive(type, args);
Promise.resolve(ret)
.then(sendResponse)
.catch((err) => {
// eslint-disable-next-line no-console
console.error(err);
});
return true;
Expand Down
4 changes: 4 additions & 0 deletions src/content/messaging/WindowMessageListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ export default class WindowMessageListener {
try {
message = JSON.parse(event.data);
} catch (e) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", e);
return;
}

if (typeof message !== "object" && message !== null) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", message);
return;
}
Expand All @@ -56,6 +58,7 @@ export default class WindowMessageListener {
typeof type !== "string" ||
(typeof args !== "undefined" && typeof args !== "object")
) {
// eslint-disable-next-line no-console
console.warn("unexpected message format:", message);
return;
}
Expand All @@ -64,6 +67,7 @@ export default class WindowMessageListener {
try {
this.receiver.receive(ctx, type, args);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
});
Expand Down
89 changes: 64 additions & 25 deletions src/options/components/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import "prismjs/themes/prism-coy.css";
const Container = styled.div`
width: 100%;
height: 100%;
resize: both;
resize: none;
overflow: auto;
border: ButtonBorder 1px solid;
border-radius: 4px;
Expand All @@ -18,13 +18,14 @@ const Container = styled.div`

const Content = styled.div`
margin: 8px;
font: 14px monospace;
position: relative;
overflow: hidden;
`;

const StyledPre = styled.pre`
position: absolute;
font-size: 14px;
font: inherit;
width: 100%;
height: 100%;
resize: none;
Expand All @@ -34,7 +35,8 @@ const StyledPre = styled.pre`

const StyledTextarea = styled.textarea`
position: absolute;
font-size: 14px;
overflow: hidden;
font: inherit;
width: 100%;
height: 100%;
padding: 0;
Expand All @@ -47,53 +49,87 @@ const StyledTextarea = styled.textarea`
caret-color: CanvasText;
`;

const TextMeasure = styled.div`
font: inherit;
position: absolute;
visibility: hidden;
`;

type Props = React.TextareaHTMLAttributes<HTMLTextAreaElement>;

const TextArea: React.FC<Props> = (props) => {
const highlightContainer = React.useRef<HTMLDivElement>(null);
const container = React.useRef<HTMLDivElement>(null);
const content = React.useRef<HTMLDivElement>(null);
const textarea = React.useRef<HTMLTextAreaElement>(null);
const measure = React.useRef<HTMLDivElement>(null);
const [json, setJson] = React.useState(props.value as string);

React.useEffect(() => {
highlight(json);
}, []);

const onChange = React.useCallback(
(e: React.ChangeEvent<HTMLTextAreaElement>) => {
setJson(e.target.value);
highlight(e.target.value);
autoResize();
props.onChange?.(e);
},
[],
);

const highlight = React.useCallback((source: string) => {
if (!highlightContainer.current) {
return;
const [charWidth, charHeight] = React.useMemo(() => {
if (!measure.current) {
return [0, 0];
}
const { width, height } = measure.current.getBoundingClientRect();
return [width, height];
}, [measure.current]);

const highlighted = Prism.highlight(source, Prism.languages.json, "json");
highlightContainer.current.innerHTML = highlighted;
autoResize();
}, []);
const [cols, rows] = React.useMemo(() => {
const lines = json.split("\n");
const cols = Math.max(...lines.map((line) => line.length));
const rows = lines.length;
return [cols, rows];
}, [json]);

const autoResize = React.useCallback(() => {
if (!textarea.current || !content.current) {
if (!textarea.current || !content.current || !container.current) {
return;
}

// shrink scroll area to get the correct scroll area
content.current.style.width = "0";
content.current.style.height = "0";
// resize textarea
const parentWidth = container.current.getBoundingClientRect().width - 16;
content.current.style.width = `${Math.max(
parentWidth,
charWidth * cols,
)}px`;
content.current.style.height = `${charHeight * rows}px`;
}, [
textarea.current,
content.current,
container.current,
charWidth,
charHeight,
cols,
rows,
]);

const { scrollHeight, scrollWidth } = textarea.current;
console.log(scrollHeight, scrollWidth);
content.current.style.width = `${scrollWidth}px`;
content.current.style.height = `${scrollHeight}px`;
}, []);
React.useEffect(() => {
if (!highlightContainer.current) {
return;
}
const highlighted = Prism.highlight(json, Prism.languages.json, "json");
highlightContainer.current.innerHTML = highlighted;
autoResize();
}, [json]);

React.useEffect(() => {
setJson(props.value as string);
}, [props.value]);

React.useEffect(() => {
autoResize();
window.addEventListener("resize", autoResize);
return () => {
window.removeEventListener("resize", autoResize);
};
}, [autoResize]);

return (
<Container ref={container}>
Expand All @@ -104,11 +140,14 @@ const TextArea: React.FC<Props> = (props) => {
<StyledTextarea
{...props}
wrap="off"
cols={cols}
rows={rows}
ref={textarea}
onChange={onChange}
spellCheck={false}
value={json}
/>
<TextMeasure ref={measure}>@</TextMeasure>
</Content>
</Container>
);
Expand Down

0 comments on commit 63c0b52

Please sign in to comment.