Skip to content

Commit

Permalink
add ignoreReadonly
Browse files Browse the repository at this point in the history
  • Loading branch information
gdh1995 committed Jul 3, 2024
1 parent 2424776 commit 5fe08ad
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 18 deletions.
6 changes: 5 additions & 1 deletion background/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ export const updatePayload_ = function (shortKey: keyof SettingsNS.FrontendCompl
&& Build.OS & kBOS.MAC && (Build.OS === kBOS.MAC as number || !os_) ? kKeyLayout.ignoreCaps : 0)
break
case "d": value = value ? " D" : ""; break
case "p": case "y":
value = value.replace(":default", shortKey === "p" ? defaults_.passEsc : defaults_.ignoreReadonly)
break
default: if (0) { shortKey satisfies never } break // lgtm [js/unreachable-statement]
}
return obj ? (obj as Generalized<SettingsNS.FrontendSettingCache>)[shortKey] = value : value
Expand Down Expand Up @@ -357,6 +360,7 @@ [email protected]`
filterLinkHints: false,
grabBackFocus: false,
hideHud: false,
ignoreReadonly: "#read-only-cursor-text-area", // GitHub file content
keyLayout: kKeyLayout.Default,
keyboard: [560, 33],
keyupTime: 120,
Expand Down Expand Up @@ -505,7 +509,7 @@ export const frontUpdateAllowed_: ReadonlyArray<keyof SettingsNS.FrontUpdateAllo

export const valuesToLoad_ = {
__proto__: null as never,
filterLinkHints: "f", keyLayout: "l", keyboard: "k", keyupTime: "u",
filterLinkHints: "f", ignoreReadonly: "y", keyLayout: "l", keyboard: "k", keyupTime: "u",
linkHintCharacters: "c", linkHintNumbers: "n", mouseReachable: "e", passEsc: "p",
regexFindMode: "r", smoothScroll: "s", scrollStepSize: "t", waitForEnter: "w"
} satisfies SettingsNS.AutoSyncedNameMap & SafeObject as SettingsNS.AutoSyncedNameMap
Expand Down
11 changes: 9 additions & 2 deletions content/insert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import {
activeEl_unsafe_, getEditableType_, getEventPath, getSelection_, frameElement_, deepActiveEl_unsafe_, blur_unsafe,
SafeEl_not_ff_, MDW, fullscreenEl_unsafe_, removeEl_s, isNode_, BU, docHasFocus_, getRootNode_mounted, testMatch,
TryGetShadowRoot_
TryGetShadowRoot_, isAriaFalse_
} from "../lib/dom_utils"
import { post_, runFallbackKey, runtime_port, safePost } from "./port"
import { getParentVApi, ui_box, ui_root } from "./dom_ui"
Expand Down Expand Up @@ -256,9 +256,16 @@ export const onFocus = (event: Event | FocusEvent): void => {
}
}
lastWndFocusTime = 0;
if (getEditableType_<EventTarget>(target)) {
let match: boolean | void, readOnly: boolean, type: EditableType | boolean
if (type = getEditableType_<EventTarget>(target)) {
if (grabBackFocus) {
(grabBackFocus as Exclude<typeof grabBackFocus, boolean>)(event, target);
} else if (readOnly =
(type as number | boolean as EditableType) > EditableType.MaxNotTextBox && (target as TextElement).readOnly
|| (type as number | boolean as EditableType) > EditableType.MaxNotEditableElement
&& !isAriaFalse_(target, kAria.readOnly),
readOnly && (match = safeCall(testMatch, fgCache.y, [target]), match != null ? match : (fgCache.y = ""))) {
/* empty */
} else {
esc!(HandlerResult.Nothing)
lock_ = target
Expand Down
2 changes: 2 additions & 0 deletions i18n/zh/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@
"95": "如何在其它扩展程序的私有页面中使用 Vimium C?",
"95_2": "ESC 键兼容模式",
"95_3": "输入文字时,指定在哪些文本框上放行“ESC”键的按下事件并推迟移除焦点。默认值可便于在部分网站上收起搜索建议。",
"95_4": "要忽略的只读文本",
"95_5": "如果键盘焦点在只读文本上,指定在哪些文本框上要继续触发快捷键。",
"96": "定制搜索框页面",
"97": "例如:",
"98": "或",
Expand Down
2 changes: 2 additions & 0 deletions i18n/zh_TW/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@
"95": "如何在其他擴充程式的私有頁面中使用 Vimium C?",
"95_2": "ESC 鍵兼容模式",
"95_3": "輸入文字時,指定在哪些輸入框上放行“ESC”鍵的按下事件並推遲移除焦點。默認值可便於在部分網站上收起搜尋建議。",
"95_4": "要忽略的只讀文字",
"95_5": "如果鍵盤焦點在只讀文字上,指定在哪些文字方塊上要繼續觸發快速鍵。",
"96": "定制搜尋框頁面",
"97": "例如:",
"98": "或",
Expand Down
7 changes: 4 additions & 3 deletions lib/dom_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface kNodeToType {
export const DAC = "DOMActivate", MDW = "mousedown", CLK = "click", HDN = "hidden", NONE = "none"
export const INP = "input", BU = "blur", ALA = "aria-label", PGH = "pagehide"
export const kDir = ["backward", "forward"] as const, kGCh = "character"
export const AriaArray = ["aria-hidden", "aria-disabled", "aria-haspopup"] as const
export const AriaArray = ["aria-hidden", "aria-disabled", "aria-haspopup", "aria-readonly"] as const

//#region data and DOM-shortcut section

Expand Down Expand Up @@ -423,8 +423,9 @@ export const isRawStyleVisible = (style: CSSStyleDeclaration): boolean => style.

export const isAriaFalse_ = (element: SafeElement, ariaType: kAria): boolean => {
let s = Build.BTypes === BrowserType.Safari as number|| !(Build.BTypes & ~(BrowserType.Chrome | BrowserType.Safari))
&& Build.MinCVer >= BrowserVer.MinCorrectAriaSelected ? ariaType > kAria.disabled ? element.ariaHasPopup
: ariaType < kAria.disabled ? element.ariaHidden : element.ariaDisabled as string | null
&& Build.MinCVer >= BrowserVer.MinCorrectAriaSelected
? ariaType > kAria.disabled ? ariaType > kAria.hasPopup ? element.ariaReadOnly : element.ariaHasPopup
: ariaType < kAria.disabled ? element.ariaHidden : element.ariaDisabled as string | null
: element.getAttribute(AriaArray[ariaType])
return s === null || (!!s && Lower(s) === "false") || !!(evenHidden_ & (kHidden.BASE_ARIA << ariaType))
}
Expand Down
16 changes: 14 additions & 2 deletions pages/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -706,14 +706,26 @@
<tr>
<td class="caption" data-i="95_2">Compatibility of Escape</td>
<td>
<input id="passEsc" type="text" inputmode="text" lang="en" data-model="NonEmptyText" autocomplete="off" />
<input id="passEsc" type="text" inputmode="text" lang="en" data-model="CssSelector" autocomplete="off" />
<div class="info" data-i="nonEmpty">Delete all to reset this option.</div>
</td>
<td class="help"><div class="help-inner break-all" data-i="95_3">
<td class="help"><div class="help-inner" data-i="95_3">
In plain insert mode, specify when to pass <kbd>Escape</kbd> keydown events to pages and delay blurring.
The default value may collapse some search suggestions.
</div></td>
</tr>
<tr>
<td class="caption" data-i="95_4">Ignore list of readonly textbox</td>
<td>
<input id="ignoreReadonly" type="text" inputmode="text" lang="en" data-model="CssSelector"
autocomplete="off" />
<div class="info" data-i="nonEmpty">Delete all to reset this option.</div>
</td>
<td class="help"><div class="help-inner" data-i="95_5">
If a readonly textbox gets focused, specify if to keep a current normal mode,
or otherwise to enter insert mode.
</div></td>
</tr>
<tr>
<td class="caption" data-i="96">Preferred Vomnibar page</td>
<td>
Expand Down
4 changes: 2 additions & 2 deletions pages/options_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@ export const bgSettings_ = {
},
valuesToLoad_: {
__proto__: null as never,
filterLinkHints: "f", keyLayout: "l", mouseReachable: "e",
filterLinkHints: "f", ignoreReadonly: "y", keyLayout: "l", mouseReachable: "e",
keyboard: "k", keyupTime: "u", linkHintCharacters: "c", linkHintNumbers: "n", passEsc: "p",
regexFindMode: "r", smoothScroll: "s", scrollStepSize: "t", waitForEnter: "w"
} satisfies SettingsNS.AutoSyncedNameMap & SafeObject as SettingsNS.AutoSyncedNameMap,
complexValuesToLoad_: {
__proto__: null as never, c: 1, n: 1, l: 1, d: 1
__proto__: null as never, c: 1, n: 1, l: 1, d: 1, p: 1, y: 1
} satisfies TypedSafeEnum<SettingsNS.FrontendComplexSyncingItems>
}

Expand Down
23 changes: 17 additions & 6 deletions pages/options_defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,22 @@ export class NonEmptyTextOption_<T extends TextOptionNames> extends TextOption_<
}
}

const kPseudoDefault = ":default"

export class CssSelectorOption_ extends TextOption_<"passEsc" | "ignoreReadonly"> {
override readValueFromElement_(): string {
let value = super.readValueFromElement_()
value = value.replace(<RegExpOne> /:default\(.*?\)/, kPseudoDefault)
value = value !== kPseudoDefault ? value.replace(<RegExpG> /,\s+/g, ",") : bgSettings_.defaults_[this.field_]
return value
}
override formatValue_ (value: string): string {
value = value !== bgSettings_.defaults_[this.field_] ? value : kPseudoDefault
value = value.replace(kPseudoDefault, `${kPseudoDefault}(${bgSettings_.defaults_[this.field_]})`)
return value.replace(<RegExpG> /,/g, ", ")
}
}

export type JSONOptionNames = PossibleOptionNames<object>
export class JSONOption_<T extends JSONOptionNames> extends TextOption_<T> {
override formatValue_ (obj: AllowedOptions[T]): string {
Expand Down Expand Up @@ -537,7 +553,7 @@ export const createNewOption_ = ((): <T extends keyof AllowedOptions> (_element:
const types = {
Number: NumberOption_, Boolean: BooleanOption_,
Text: TextOption_, NonEmptyText: NonEmptyTextOption_, JSON: JSONOption_, MaskedText: MaskedText_,
ExclusionRules: ExclusionRulesOption_
ExclusionRules: ExclusionRulesOption_, CssSelector: CssSelectorOption_,
}
const createOption = <T extends keyof AllowedOptions> (element: HTMLElement): Option_<T> => {
const cls = types[(element.dataset as KnownOptionsDataset).model as "Text"]
Expand Down Expand Up @@ -777,11 +793,6 @@ Option_.all_.autoReduceMotion.onSave_ = function (): void {
})
}

Option_.all_.passEsc.readValueFromElement_ = function (): string {
return NonEmptyTextOption_.prototype.readValueFromElement_.call(this).replace(<RegExpG> /, /g, ",")
}
Option_.all_.passEsc.formatValue_ = (value: string): string => value.replace(<RegExpG> /,/g, ", ")

const onBeforeUnload = (): string => {
setTimeout((): void => { // wait until the confirmation dialog returning
setTimeout((): void => { // ensure the result is neither closing nor reloading
Expand Down
1 change: 1 addition & 0 deletions typings/base/base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ interface Element {
ariaDisabled?: boolean | string | null
ariaHasPopup?: string | null
ariaHidden?: string | null
ariaReadOnly?: string | null
}
interface HTMLElement {
focus (options?: { preventScroll?: boolean }): void
Expand Down
2 changes: 1 addition & 1 deletion typings/messages.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface ParsedSearch {
/** error */ e?: string | null;
}

declare const enum kAria { hidden = 0, disabled = 1, hasPopup = 2 }
declare const enum kAria { hidden = 0, disabled = 1, hasPopup = 2, readOnly = 3 }
declare const enum kHidden {
None = 0, VisibilityHidden = 1, OverflowHidden = 2, Size0 = 4,
BASE_ARIA = 16, AriaHidden = BASE_ARIA << kAria.hidden, AriaDisabled = BASE_ARIA << kAria.disabled,
Expand Down
3 changes: 2 additions & 1 deletion typings/vimium_c.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ declare const enum kKeyLayout {
}
declare namespace SettingsNS {
interface DirectlySyncedItems {
/** ignoreReadonly */ y: ["ignoreReadonly", string]
/** keyLayout */ l: ["keyLayout", kKeyLayout]
/** keyboard */ k: ["keyboard", [delay: number, interval: number, /** on Firefox */ screenRefreshRate?: number]]
/** linkHintCharacters */ c: ["linkHintCharacters", string];
Expand Down Expand Up @@ -351,7 +352,7 @@ declare namespace SettingsNS {

interface AutoSyncedItems extends DirectlySyncedItems {}
interface FrontendSettingsSyncingItems extends AutoSyncedItems, ManuallySyncedItems {}
type FrontendComplexSyncingItems = Pick<FrontendSettingsSyncingItems, "c" | "n" | "l" | "d">
type FrontendComplexSyncingItems = Pick<FrontendSettingsSyncingItems, "c" | "n" | "l" | "d" | "p" | "y">
interface DeclaredFrontendValues extends SelectValueType<ManuallySyncedItems & OneTimeItems>, DeclaredConstValues {
}
type AutoSyncedNameMap = SelectNameToKey<AutoSyncedItems>
Expand Down

0 comments on commit 5fe08ad

Please sign in to comment.