MCPcopy Create free account
hub / github.com/violentmonkey/violentmonkey / prepareScript

Function prepareScript

src/background/utils/preinject.js:493–603  ·  view source on GitHub ↗

* @param {VMScript} script * @param {VMInjection.EnvStart} env * @return {VMInjection.Script}

(script, env)

Source from the content-addressed store, hash-verified

491 * @return {VMInjection.Script}
492 */
493function prepareScript(script, env) {
494 const { custom, meta, props } = script;
495 const { id } = props;
496 const { [S_REQUIRE]: require, [RUN_AT]: runAt } = env;
497 const code = env[S_CODE][id];
498 const dataKey = getUniqId();
499 const winKey = getUniqId();
500 const plantKey = { data: dataKey, win: winKey };
501 const displayName = getScriptName(script);
502 const pathMap = custom.pathMap || {};
503 const wrap = !meta[UNWRAP];
504 const wrapTryCatch = wrap && IS_FIREFOX; // FF doesn't show errors in content script's console
505 const { grant, [TL_AWAIT]: topLevelAwait } = meta;
506 const startIIFE = topLevelAwait ? 'await(async' : '(';
507 const grantNone = grant.includes('none');
508 const shouldUpdate = !!script.config.shouldUpdate;
509 // Storing slices separately to reuse JS-internalized strings for code in our storage cache
510 const injectedCode = [];
511 const metaCopy = meta::mapEntry(null, pluralizeMeta);
512 const metaStrMatch = METABLOCK_RE.exec(code);
513 let codeIndex;
514 let tmp;
515 for (const key of META_KEYS_TO_ENSURE) {
516 if (metaCopy[key] == null) metaCopy[key] = '';
517 }
518 for (const [key, from] of META_KEYS_TO_ENSURE_FROM) {
519 if (!metaCopy[key] && (tmp = metaCopy[from])) {
520 metaCopy[key] = tmp;
521 }
522 }
523 metaCopy.options = { // TM-compatibility
524 check_for_updates: shouldUpdate,
525 inject_into: custom[INJECT_INTO] || null,
526 noframes: custom.noframes ?? null,
527 override: {
528 merge_excludes: custom.origExclude,
529 merge_includes: custom.origInclude,
530 merge_matches: custom.origMatch,
531 merge_exclude_matches: custom.origExcludeMatch,
532 merge_tags: custom[kOrigTag],
533 use_excludes: custom.exclude || [],
534 use_includes: custom.include || [],
535 use_matches: custom.match || [],
536 use_exclude_matches: custom.excludeMatch || [],
537 },
538 run_at: custom[RUN_AT] || null,
539 tags: custom[kTag] || [],
540 user_modified: script.props.lastModified || 0,
541 };
542 if (wrap) {
543 // TODO: push winKey/dataKey as separate chunks so we can change them for each injection?
544 injectedCode.push('window.', winKey, '=',
545 wrapTryCatch && topLevelAwait ? 'async ' : '',
546 'function ', dataKey, '(',
547 // using a shadowed name to avoid scope pollution
548 grantNone ? GRANT_NONE_VARS : 'GM',
549 wrapTryCatch ? `,${dataKey}){try{` : '){',
550 grantNone ? '' : 'with(this)with(c)delete c,',

Callers 1

prepareScriptsFunction · 0.85

Calls 8

getUniqIdFunction · 0.90
getScriptNameFunction · 0.90
mapEntryFunction · 0.90
getScriptPrettyUrlFunction · 0.90
isUnsafeConcatFunction · 0.85
normalizeScriptRealmFunction · 0.85
filterMethod · 0.80
testMethod · 0.45

Tested by

no test coverage detected