Discussions » Greasy Fork Feedback
Tighten the validity check of the userscript metablock comment?
FYI.
ScriptCat requires // ==UserScript==
to be placed in the beginning of the userscript. /* ..... */
cannot be inserted before // ==UserScript==
.
Tighten validity check should be necessary.
About 3% of user scripts on the site do not start with exactly // ==UserScript==
. The things these scripts start with include:
- A comment (licence)
- A closure
- A UTF-8 byte order mark
- "use strict"
- Whitespace
- A JS label statement
- Normal code
In the absence of a standard I'm leery of having a validation for this, especially since TM is OK with it and TM is the most popular. Maybe one of those skippable warnings...
Violentmonkey will allow malformed userscript metadata with a warning: https://github.com/violentmonkey/violentmonkey/commit/2dd34c3f729766ed49de190b6876fc43b3dfa84f
By ChatGPT,
function validateUserScriptMetaBlock(script) {
// Regular expression to match the full metablock
const metablockPattern = /^\/\/\s*==UserScript==\n([\s\S]*?)\n\/\/\s*==\/UserScript==/;
// Ensure no content appears before the metablock
const startsWithMetablock = metablockPattern.test(script);
// Extract the metablock if it exists, to validate contents inside
if (startsWithMetablock) {
const match = script.match(metablockPattern);
const metablockContent = match[1];
// Validate common userscript metadata (@name, @version, etc.)
const requiredFields = ['@name', '@version'];
for (const field of requiredFields) {
const fieldPattern = new RegExp(`^\\s*//\\s*${field}\\s+`, 'm');
if (!fieldPattern.test(metablockContent)) {
return false; // Missing required metadata field
}
}
return true;
}
return false;
}
// Example usage:
const userScript = `// ==UserScript==
// @name Example Script
// @version 1.0.0
// @description This is an example userscript
// ==/UserScript==
console.log('Hello, world!');
`;
if (validateUserScriptMetaBlock(userScript)) {
console.log("Valid UserScript meta block!");
} else {
console.log("Invalid UserScript meta block!");
}
def validate_user_script_meta_block(script)
# Regular expression to match the full metablock
metablock_pattern = /^\/\/\s*==UserScript==\n([\s\S]*?)\n\/\/\s*==\/UserScript==/m
# Check if the script starts with the metablock
if script =~ metablock_pattern
metablock_content = script.match(metablock_pattern)[1]
# Validate the presence of common userscript metadata
required_fields = ['@name', '@version']
required_fields.each do |field|
field_pattern = /^\/\/\s*#{field}\s+/
return false unless metablock_content =~ field_pattern
end
return true
end
return false
end
# Example usage:
user_script = <<-SCRIPT
// ==UserScript==
// @name Example Script
// @version 1.0.0
// @description This is an example userscript
// ==/UserScript==
puts 'Hello, world!'
SCRIPT
if validate_user_script_meta_block(user_script)
puts "Valid UserScript meta block!"
else
puts "Invalid UserScript meta block!"
end
ChatGPT can't help here because the task is something where one should think e.g. it anchors the pattern via ^
and uses \s
which includes \n
so it won't be a single line. You can see an example of how to detect validity in the commit I've linked above: it captures invalid input in (.*?)
I've added a skippable warning for any user.js that doesn't start with // ==UserScript==
.
Examples:
CODE: // ==UserScript==
/// ==UserScript==
(three slashes)Engines:
I think at the very least a skippable warning should be displayed when a broken metablock is uploaded, similarly to the warning when the same version is uploaded.