Skip to content

Commit

Permalink
Fix #964; Slow/erratic edit behavior when main window isn't visible
Browse files Browse the repository at this point in the history
  • Loading branch information
mgmeyers committed May 31, 2024
1 parent fffc03b commit 10e8f35
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 4 deletions.
110 changes: 107 additions & 3 deletions esbuild.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,102 @@ import builtins from 'builtin-modules';
import esbuild from 'esbuild';
import { lessLoader } from 'esbuild-plugin-less';
import fs from 'fs';
import MagicString from 'magic-string';
import path from 'path';
import process from 'process';

const toFunction = (functionOrValue) => {
if (typeof functionOrValue === 'function') return functionOrValue;
return () => functionOrValue;
};

const escape = (str) => str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');

const longest = (a, b) => b.length - a.length;

const mapToFunctions = (options) => {
const values = options.values ? Object.assign({}, options.values) : Object.assign({}, options);
delete values.delimiters;
delete values.include;
delete values.exclude;

return Object.keys(values).reduce((fns, key) => {
const functions = Object.assign({}, fns);
functions[key] = toFunction(values[key]);
return functions;
}, {});
};

const generateFilter = (options) => {
let include = /.*/;
let exclude = null;
let hasValidInclude = false;

if (options.include) {
if (Object.prototype.toString.call(options.include) !== '[object RegExp]') {
console.warn(
`Options.include must be a RegExp object, but gets an '${typeof options.include}' type.`
);
} else {
hasValidInclude = true;
include = options.include;
}
}

if (options.exclude) {
if (Object.prototype.toString.call(options.exclude) !== '[object RegExp]') {
console.warn(
`Options.exclude must be a RegExp object, but gets an '${typeof options.exclude}' type.`
);
} else if (!hasValidInclude) {
// Only if `options.include` not set, take `options.exclude`
exclude = options.exclude;
}
}

return { include, exclude };
};

const replaceCode = (code, id, pattern, functionValues) => {
const magicString = new MagicString(code);
let match = null;

while ((match = pattern.exec(code))) {
const start = match.index;
if (code[start - 1] === '.') continue;
const end = start + match[0].length;
const replacement = String(functionValues[match[1]](id));
magicString.overwrite(start, end, replacement);
}
return magicString.toString();
};

// todo: add preventAssignment option & support sourceMap
const replace = (options = {}) => {
const { include, exclude } = generateFilter(options);
const functionValues = mapToFunctions(options);
const empty = Object.keys(functionValues).length === 0;
const keys = Object.keys(functionValues).sort(longest).map(escape);
const { delimiters } = options;
const pattern = delimiters
? new RegExp(`${escape(delimiters[0])}(${keys.join('|')})${escape(delimiters[1])}`, 'g')
: new RegExp(`\\b(${keys.join('|')})\\b`, 'g');
return {
name: 'replace',
setup(build) {
build.onLoad({ filter: include }, async (args) => {
// if match exclude, skip
if (exclude && args.path.match(exclude)) {
return;
}
const source = await fs.promises.readFile(args.path, 'utf8');
const contents = empty ? source : replaceCode(source, args.path, pattern, functionValues);
return { contents, loader: 'default' };
});
},
};
};

const isProd = process.argv[2] === 'production';
const renamePlugin = {
name: 'rename-styles',
Expand Down Expand Up @@ -39,8 +132,7 @@ function NodeModulesPolyfillPlugin(options = {}) {
async function loader(args) {
try {
const isCommonjs = args.namespace.endsWith('commonjs');
const resolved =
args.path === 'buffer' ? path.resolve('./buffer-es6.mjs') : null;
const resolved = args.path === 'buffer' ? path.resolve('./buffer-es6.mjs') : null;
const contents = (await fs.promises.readFile(resolved)).toString();

let resolveDir = path.dirname(resolved);
Expand Down Expand Up @@ -114,7 +206,19 @@ const context = await esbuild.context({
define: {
global: 'window',
},
plugins: [NodeModulesPolyfillPlugin(), lessLoader()],
plugins: [
NodeModulesPolyfillPlugin(),
lessLoader(),
replace({
include: /node_modules\/.*/,
values: {
setTimeout: 'activeWindow.setTimeout',
clearTimeout: 'activeWindow.clearTimeout',
requestAnimationFrame: 'activeWindow.requestAnimationFrame',
cancelAnimationFrame: 'activeWindow.cancelAnimationFrame',
},
}),
],
external: [
'obsidian',
'electron',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"esbuild-plugin-less": "^1.3.1",
"eslint": "^8.56.0",
"eslint-plugin-react": "^7.33.2",
"magic-string": "^0.30.10",
"obsidian": "^1.5.7-1",
"obsidian-dataview": "^0.5.66",
"obsidian-plugin-cli": "^0.9.0",
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==

"@jridgewell/sourcemap-codec@^1.4.14":
"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
Expand Down Expand Up @@ -2638,6 +2638,13 @@ luxon@^3.2.0:
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af"
integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==

magic-string@^0.30.10:
version "0.30.10"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e"
integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.15"

make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
Expand Down

0 comments on commit 10e8f35

Please sign in to comment.