Merge branch 'state_in_bg_only'

This commit is contained in:
Oliver Blanthorn 2020-05-09 10:58:26 +01:00
commit 7e4da9c3ef
No known key found for this signature in database
GPG key ID: 2BB8C36BB504BFF3
9 changed files with 56 additions and 45 deletions

View file

@ -40,6 +40,7 @@ import { ExtensionsCompletionSource } from "@src/completions/Extensions"
import * as Messaging from "@src/lib/messaging"
import "@src/lib/number.clamp"
import state from "@src/state"
import * as State from "@src/state"
import Logger from "@src/lib/logging"
import { theme } from "@src/content/styling"
@ -256,14 +257,14 @@ export function clear(evlistener = false) {
commandline_state.clear = clear
/** @hidden **/
function history(n) {
async function history(n) {
history_called = true
if (!prev_cmd_called_history) {
HISTORY_SEARCH_STRING = commandline_state.clInput.value
}
const matches = state.cmdHistory.filter(key =>
const matches = (await State.getAsync("cmdHistory")).filter(key =>
key.startsWith(HISTORY_SEARCH_STRING),
)
if (commandline_state.cmdline_history_position === 0) {

View file

@ -131,6 +131,7 @@ import * as finding_content from "@src/content/finding"
import * as itertools from "@src/lib/itertools"
import * as messaging from "@src/lib/messaging"
import state from "@src/state"
import * as State from "@src/state"
import * as webext from "@src/lib/webext"
import Mark from "mark.js"
import * as perf from "@src/perf"
@ -162,6 +163,7 @@ import * as visual from "@src/lib/visual"
keyseq,
messaging,
state,
State,
scrolling,
visual,
webext,

View file

@ -2,6 +2,7 @@ import * as config from "@src/lib/config"
import * as DOM from "@src/lib/dom"
import { browserBg, activeTabId } from "@src/lib/webext"
import state from "@src/state"
import * as State from "@src/state"
// The host is the shadow root of a span used to contain all highlighting
// elements. This is the least disruptive way of highlighting text in a page.
@ -123,7 +124,7 @@ export async function jumpToMatch(searchQuery, reverse) {
}
}
if (lastHighlights.length < 1) {
throw new Error("Pattern not found: " + state.lastSearchQuery)
throw new Error("Pattern not found: " + searchQuery)
}
lastHighlights
.sort(reverse ? (a, b) => b.top - a.top : (a, b) => a.top - b.top)
@ -144,16 +145,17 @@ export function removeHighlighting() {
while (host.firstChild) host.removeChild(host.firstChild)
}
export function jumpToNextMatch(n: number) {
export async function jumpToNextMatch(n: number) {
const lastSearchQuery = await State.getAsync("lastSearchQuery")
if (!lastHighlights) {
return state.lastSearchQuery ? jumpToMatch(state.lastSearchQuery, n < 0) : undefined
return lastSearchQuery ? jumpToMatch(lastSearchQuery, n < 0) : undefined
}
if (!host.firstChild) {
drawHighlights(lastHighlights)
}
if (lastHighlights[selected] === undefined) {
removeHighlighting()
throw new Error("Pattern not found: " + state.lastSearchQuery)
throw new Error("Pattern not found: " + lastSearchQuery)
}
/* tslint:disable:no-useless-cast */
; (lastHighlights[selected] as any).unfocus()

View file

@ -2793,7 +2793,7 @@ async function getnexttabs(tabid: number, n?: number) {
It's difficult to execute this in the background script (`:jsb`, `:run_excmd`, `:autocmd TriStart`, `:source`), but if you you do, it will re-execute the last exstr that was executed in the background script. What this may have been is unpredictable and not precisely encouraged.
*/
//#both
//#background
export async function repeat(n = 1, ...exstr: string[]) {
let cmd = state.last_ex_str
if (exstr.length > 0) cmd = exstr.join(" ")

View file

@ -1,13 +1,14 @@
import { messageOwnTab } from "@src/lib/messaging"
import * as State from "@src/state"
export function getCommandlineFns(cmdline_state) {
return {
/**
* Insert the first command line history line that starts with the content of the command line in the command line.
*/
"complete": () => {
"complete": async () => {
const fragment = cmdline_state.clInput.value
const matches = cmdline_state.state.cmdHistory.filter(key => key.startsWith(fragment))
const matches = (await State.getAsync("cmdHistory")).filter(key => key.startsWith(fragment))
const mostrecent = matches[matches.length - 1]
if (mostrecent !== undefined) cmdline_state.clInput.value = mostrecent
return cmdline_state.refresh_completions(cmdline_state.clInput.value)
@ -121,7 +122,9 @@ export function getCommandlineFns(cmdline_state) {
!browser.extension.inIncognitoContext &&
!(func === "winopen" && args[0] === "-private")
) {
cmdline_state.state.cmdHistory = cmdline_state.state.cmdHistory.concat([command])
State.getAsync("cmdHistory").then(c => {
cmdline_state.state.cmdHistory = c.concat([command])
})
}
cmdline_state.cmdline_history_position = 0

View file

@ -1,5 +1,6 @@
import Logger from "@src/lib/logging"
import { parser as exmode_parser } from "@src/parsers/exmode"
import * as State from "@src/state"
import state from "@src/state"
const logger = new Logger("controller")
@ -15,7 +16,11 @@ export async function acceptExCmd(exstr: string): Promise<any> {
try {
const [func, args] = exmode_parser(exstr, stored_excmds)
// Stop the repeat excmd from recursing.
if (func !== stored_excmds[""].repeat && state.last_ex_str != exstr) state.last_ex_str = exstr
if (func !== stored_excmds[""].repeat){
State.getAsync("last_ex_str").then(last_ex_str => {
if (last_ex_str != exstr) state.last_ex_str = exstr
})
}
try {
return await func(...args)
} catch (e) {

View file

@ -7,6 +7,10 @@ export function inContentScript() {
return getContext() === "content"
}
export function notBackground() {
return getContext() !== "background"
}
/** WebExt code can be run from three contexts:
Content script

View file

@ -14,9 +14,10 @@
If this turns out to be expensive there are improvements available.
*/
import * as locks from "@src/lib/locks"
import Logger from "@src/lib/logging"
import * as messaging from "@src/lib/messaging"
import {notBackground} from "@src/lib/webext"
const logger = new Logger("state")
class State {
@ -49,6 +50,7 @@ browser.storage.local
const state = (new Proxy(overlay, {
/** Give defaults if overlay doesn't have the key */
get(target, property) {
if (notBackground()) throw "State object must be accessed with getAsync in content"
if (property in target) {
return target[property]
} else {
@ -58,31 +60,30 @@ const state = (new Proxy(overlay, {
/** Persist sets to storage "immediately" */
set(target, property, value) {
locks.withlock("state", async () => {
logger.debug("State changed!", property, value)
target[property] = value
if (notBackground()) {
browser.runtime.sendMessage({type: "state", command: "stateUpdate", args: [{state: target}]})
} else {
// Do we need a global storage lock?
browser.storage.local.set({ state: target } as any)
// Wait for reply from each script to say that they have updated their own state
await Promise.all([
// dispatch message to all content state.ts's
messaging.messageAllTabs("state", "stateUpdate", [{state: target}]),
// Ideally this V would use Farnoy's typed messages but
// I haven't had time to get my head around them
browser.runtime.sendMessage({type: "state", command: "stateUpdate", args: [{state: target}]}),
])
})
}
return true
},
}))
export async function getAsync(property) {
if (notBackground()) return browser.runtime.sendMessage({type: "state", command: "stateGet", args: [{prop: property}]})
else return state[property]
}
// Keep instances of state.ts synchronised with each other
messaging.addListener("state", (message, sender, sendResponse) => {
if (message.command !== "stateUpdate") throw("Unsupported message to state, type " + message.command)
if (message.command == "stateUpdate") {
Object.assign(overlay, message.args[0].state)
sendResponse(true)
} else if (message.command == "stateGet") {
sendResponse(state[message.args[0].prop])
} else throw("Unsupported message to state, type " + message.command)
})
export { state as default }

View file

@ -1,11 +1,17 @@
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin")
const CopyWebPackPlugin = require("copy-webpack-plugin")
// const WebpackShellPlugin = require('webpack-shell-plugin')
const fileExtensions = [".ts", ".tsx", ".js", ".json"]
module.exports = {
mode: "production",
mode: "development",
// mode: "production", // Uncomment me for more helpful error messages
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
// devtool: "inline-source-map", // Uncomment me for more helpful error messages
entry: {
background: "./src/background.ts",
content: "./src/content.ts",
@ -18,8 +24,6 @@ module.exports = {
path: __dirname + "/build",
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
@ -38,17 +42,6 @@ module.exports = {
},
plugins: [
// new UglifyJSPlugin({
// uglifyOptions: {
// ecma: 8
// }
// }),
// new WebpackShellPlugin({onBuildStart: [
// 'mkdir -p generated/static',
// 'scripts/excmds_macros.py',
// 'scripts/newtab.md.sh',
// 'scripts/make_docs.sh',
// ]}),
new CopyWebPackPlugin([
{ from: "src/manifest.json" },
{