torn-pda icon indicating copy to clipboard operation
torn-pda copied to clipboard

@match handling doesn't follow script standard

Open xentac opened this issue 7 months ago • 2 comments
trafficstars

According to Tampermonkey you must include a protocol when defining a @match meta (https://www.tampermonkey.net/documentation.php?locale=en#meta:match).

The current code (https://github.com/Manuito83/torn-pda/blob/5788c5c9e5677e4ea9ea58db7f5bb0666162baad/lib/models/userscript_model.dart#L211) doesn't handle globs very well either. If you define a * anywhere in the middle of a URL, it will not match any URL you actually want it to.

I asked chatgpt to implement a @match handler and it suggested code like this:

function matchPattern(pattern, url) {
  // Escape regex special characters except * (we'll handle * ourselves)
  function escapeRegex(str) {
    return str.replace(/[$^+.?()[\]{}|\\]/g, '\\$&');
  }

  // Convert @match pattern to regex
  function patternToRegex(pattern) {
    const match = pattern.match(/^(https?|file|\*):\/\/([^\/]*)\/(.*)$/);
    if (!match) throw new Error('Invalid @match pattern: ' + pattern);

    const [, scheme, host, path] = match;

    // Scheme
    let schemeRegex = scheme === '*' ? 'https?' : escapeRegex(scheme);

    // Host
    let hostRegex = host
      .replace(/\./g, '\\.')
      .replace(/^\*\./, '(?:[^/]+\\.)?') // *.example.com => optional subdomain
      .replace(/\*/g, '[^/]*'); // wildcard in host (unusual)

    // Path
    let pathRegex = escapeRegex(path).replace(/\*/g, '.*');

    return new RegExp(`^${schemeRegex}://${hostRegex}/${pathRegex}$`);
  }

  const regex = patternToRegex(pattern);
  return regex.test(url);
}

Whether or not you want to break scripts that don't include the protocol in torn pda is up to you, but you could modify the final RegExp to make the scheme optional.

xentac avatar Apr 13 '25 22:04 xentac