Skip to content

Commit

Permalink
Merge branch 'master' into fix/AG-18720
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamWr committed May 16, 2023
2 parents 5b79867 + b3a7f6c commit 0328992
Show file tree
Hide file tree
Showing 130 changed files with 859 additions and 354 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Expand Up @@ -37,6 +37,7 @@ module.exports = {
'scriptlet',
'trustedScriptlet',
'redirect',
'added',
'jest-environment',
],
}],
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

<!-- TODO: add @added tag to the files with specific version -->
<!-- during new scriptlets or redirects releasing -->

## [Unreleased]

### Added
Expand All @@ -12,13 +15,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- improved `prevent-fetch` — if `responseType` is not specified,
- `trusted-set-cookie` and `trusted-set-cookie-reload` scriptlets to not encode cookie name and value
[#311](https://github.com/AdguardTeam/Scriptlets/issues/311)
- improved `prevent-fetch`: if `responseType` is not specified,
original response type is returned instead of `default` [#297](https://github.com/AdguardTeam/Scriptlets/issues/291)

### Fixed

- website reloading if `$now$`/`$currentDate$` value is used
in `trusted-set-cookie-reload` scriptlet [#291](https://github.com/AdguardTeam/Scriptlets/issues/291)
- `getResponseHeader()` and `getAllResponseHeaders()` methods mock
in `prevent-xhr` scriptlet [#295](https://github.com/AdguardTeam/Scriptlets/issues/295)

## <a name="v1.9.7"></a> [v1.9.7] - 2023-03-14

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "@adguard/scriptlets",
"version": "1.9.11",
"version": "1.9.17",
"description": "AdGuard's JavaScript library of Scriptlets and Redirect resources",
"scripts": {
"build": "babel-node bundler.js",
Expand Down
69 changes: 43 additions & 26 deletions scripts/build-docs.js
Expand Up @@ -102,18 +102,21 @@ const getMarkdownData = (dataItems) => {
const output = dataItems.reduce((acc, {
name,
type,
versionAdded,
description,
source,
}) => {
// low case name should be used as anchor
// low case name should be used as an anchor in the table of content
acc.list.push(`* [${name}](#${name.toLowerCase()})${EOL}`);

const typeOfSrc = type.toLowerCase().includes('scriptlet') ? 'Scriptlet' : 'Redirect';

// low case name should be used as anchor
const body = `### <a id="${name.toLowerCase()}"></a> ⚡️ ${name}
// 1. Low case name should be used as an anchor
// 2. There is no EOL after 'version' string because `description` starts with `\n`
const body = `### <a id="${name.toLowerCase()}"></a> ⚡️ ${name}${EOL}
${versionAdded ? `> Added in ${versionAdded}` : '> Adding version is unknown.'}
${description}${EOL}
[${typeOfSrc} source](${source})
[${typeOfSrc} source](${source})${EOL}
* * *${EOL}${EOL}`;
acc.body.push(body);

Expand All @@ -135,18 +138,25 @@ const getMarkdownDataForStaticRedirects = () => {
const staticRedirects = fs.readFileSync(path.resolve(__dirname, staticRedirectsPath), { encoding: 'utf8' });
const parsedStaticRedirects = yaml.safeLoad(staticRedirects);

const output = parsedStaticRedirects.reduce((acc, { title, description }) => {
if (description) {
acc.list.push(`* [${title}](#${title})${EOL}`);
const output = parsedStaticRedirects.reduce((acc, { title, description, added }) => {
if (!title) {
throw new Error('No title for static redirect');
}
if (!description) {
throw new Error(`No description for static redirect '${title}'`);
}
if (!added) {
throw new Error(`No added version for static redirect '${title}'`);
}

acc.list.push(`* [${title}](#${title})${EOL}`);

const body = `### <a id="${title}"></a> ⚡️ ${title}
${description}
[Redirect source](${STATIC_REDIRECTS_RELATIVE_SOURCE})
const body = `### <a id="${title}"></a> ⚡️ ${title}${EOL}
${added ? `> Added in ${added}.` : '> Adding version is unknown.'}${EOL}
${description}${EOL}
[Redirect source](${STATIC_REDIRECTS_RELATIVE_SOURCE})${EOL}
* * *${EOL}${EOL}`;
acc.body.push(body);
} else {
throw new Error(`No description for ${title}`);
}
acc.body.push(body);

return acc;
}, { list: [], body: [] });
Expand All @@ -170,18 +180,25 @@ const getMarkdownDataForBlockingRedirects = () => {
const blockingRedirects = fs.readFileSync(blockingRedirectsPath, { encoding: 'utf8' });
const parsedBlockingRedirects = yaml.safeLoad(blockingRedirects);

const output = parsedBlockingRedirects.reduce((acc, { title, description }) => {
if (description) {
acc.list.push(`* [${title}](#${title})${EOL}`);
const output = parsedBlockingRedirects.reduce((acc, { title, description, added }) => {
if (!title) {
throw new Error('No title for blocking redirect');
}
if (!description) {
throw new Error(`No description for blocking redirect '${title}'`);
}
if (!added) {
throw new Error(`No added version for blocking redirect '${title}'`);
}

acc.list.push(`* [${title}](#${title})${EOL}`);

const body = `### <a id="${title}"></a> ⚡️ ${title}
${description}
[Redirect source](${BLOCKING_REDIRECTS_RELATIVE_SOURCE}/${title})
const body = `### <a id="${title}"></a> ⚡️ ${title}${EOL}
${added ? `> Added in ${added}.` : '> Adding version is unknown.'}${EOL}
${description}${EOL}
[Redirect source](${BLOCKING_REDIRECTS_RELATIVE_SOURCE}/${title})${EOL}
* * *${EOL}${EOL}`;
acc.body.push(body);
} else {
throw new Error(`No description for ${title}`);
}
acc.body.push(body);

return acc;
}, { list: [], body: [] });
Expand All @@ -206,8 +223,8 @@ const buildWikiAboutPages = () => {
const staticRedirectsMarkdownData = getMarkdownDataForStaticRedirects();
const blockingRedirectsMarkdownData = getMarkdownDataForBlockingRedirects();

const scriptletsPageContent = `## <a id="scriptlets"></a> Available Scriptlets
${scriptletsMarkdownData.list}* * *
const scriptletsPageContent = `## <a id="scriptlets"></a> Available Scriptlets${EOL}
${scriptletsMarkdownData.list}* * *${EOL}
${scriptletsMarkdownData.body}`;
fs.writeFileSync(
path.resolve(__dirname, aboutScriptletsPath),
Expand Down
5 changes: 1 addition & 4 deletions scripts/check-sources-updates.js
Expand Up @@ -84,10 +84,7 @@ const getDiff = (oldList, newList) => {
removed: [],
};

diff.removed = oldList.filter((item) => (
!newList.includes(item)
&& item.indexOf(REMOVED_MARKER) === -1
));
diff.removed = oldList.filter((item) => !newList.includes(item) && !item.includes(REMOVED_MARKER));
diff.added = newList.filter((item) => !oldList.includes(item));

return (diff.removed.length || diff.added.length) ? diff : null;
Expand Down
20 changes: 13 additions & 7 deletions scripts/helpers.js
Expand Up @@ -32,15 +32,15 @@ const getFilesList = (relativeDirPath) => {

/**
* @typedef {Object} CommentTag
* @property {string} type tag name
* @property {string} string text following the tag
* @property {string} type Tag name, e.g. `@scriptlet`, `@redirect`, `@added`.
* @property {string} string Text following the tag name.
*/

/**
* Returns parsed tags data which we use to describe the sources:
* - `@scriptlet`/`trustedScriptlet`/`@redirect` to describe the type and name of source;
* - `@description` actual description for scriptlet or redirect.
* required comments from file.
* - `@added` means version when scriptlet or redirect was implemented.
* In one file might be comments describing scriptlet and redirect as well.
*
* @param {string} filePath absolute path to file
Expand Down Expand Up @@ -95,11 +95,17 @@ Please add one OR edit the list of NON_SCRIPTLETS_FILES / NON_REDIRECTS_FILES.`)
* @returns {DescribingCommentData}
*/
const prepareCommentsData = (commentTags, source) => {
const [base, sup] = commentTags;
const [typeTag, descriptionTag, addedTag] = commentTags;
const name = typeTag.string;
const versionAdded = addedTag?.string;
if (!versionAdded) {
throw new Error(`No @added tag for ${name}`);
}
return {
type: base.type,
name: base.string,
description: sup.string,
type: typeTag.type,
name,
description: descriptionTag.string,
versionAdded,
source,
};
};
Expand Down
23 changes: 11 additions & 12 deletions src/helpers/converter.js
Expand Up @@ -128,7 +128,7 @@ const validateRemoveAttrClassArgs = (parsedArgs) => {
const lastArg = restArgs.pop();
let applying;
// check the last parsed arg for matching possible 'applying' vale
if (REMOVE_ATTR_CLASS_APPLYING.some((el) => lastArg.indexOf(el) > -1)) {
if (REMOVE_ATTR_CLASS_APPLYING.some((el) => lastArg.includes(el))) {
applying = lastArg;
} else {
restArgs.push(lastArg);
Expand Down Expand Up @@ -160,19 +160,18 @@ export const convertUboScriptletToAdg = (rule) => {
const domains = getBeforeRegExp(rule, validator.UBO_SCRIPTLET_MASK_REG);
const mask = rule.match(validator.UBO_SCRIPTLET_MASK_REG)[0];
let template;
if (mask.indexOf('@') > -1) {
if (mask.includes('@')) {
template = ADGUARD_SCRIPTLET_EXCEPTION_TEMPLATE;
} else {
template = ADGUARD_SCRIPTLET_TEMPLATE;
}
const argsStr = getStringInBraces(rule);
let parsedArgs = splitArgs(argsStr);
const scriptletName = parsedArgs[0].indexOf(UBO_SCRIPTLET_JS_ENDING) > -1
const scriptletName = parsedArgs[0].includes(UBO_SCRIPTLET_JS_ENDING)
? `ubo-${parsedArgs[0]}`
: `ubo-${parsedArgs[0]}${UBO_SCRIPTLET_JS_ENDING}`;

if (((REMOVE_ATTR_ALIASES.indexOf(scriptletName) > -1)
|| (REMOVE_CLASS_ALIASES.indexOf(scriptletName) > -1))) {
if (REMOVE_ATTR_ALIASES.includes(scriptletName) || REMOVE_CLASS_ALIASES.includes(scriptletName)) {
parsedArgs = validateRemoveAttrClassArgs(parsedArgs);
}

Expand Down Expand Up @@ -205,7 +204,7 @@ export const convertUboScriptletToAdg = (rule) => {
*/
export const convertAbpSnippetToAdg = (rule) => {
const SEMICOLON_DIVIDER = /;(?=(?:(?:[^"]*"){2})*[^"]*$)/g;
const mask = rule.indexOf(validator.ABP_SCRIPTLET_MASK) > -1
const mask = rule.includes(validator.ABP_SCRIPTLET_MASK)
? validator.ABP_SCRIPTLET_MASK
: validator.ABP_SCRIPTLET_EXCEPTION_MASK;
const template = mask === validator.ABP_SCRIPTLET_MASK
Expand Down Expand Up @@ -315,7 +314,7 @@ export const convertAdgScriptletToUbo = (rule) => {
|| parsedParams[0] === ADG_PREVENT_FETCH_EMPTY_STRING)) {
preparedParams = [UBO_NO_FETCH_IF_WILDCARD];
} else if ((parsedName === ADG_REMOVE_ATTR_NAME || parsedName === ADG_REMOVE_CLASS_NAME)
&& parsedParams[1] && parsedParams[1].indexOf(COMMA_SEPARATOR) > -1) {
&& parsedParams[1] && parsedParams[1].includes(COMMA_SEPARATOR)) {
preparedParams = [
parsedParams[0],
replaceAll(parsedParams[1], COMMA_SEPARATOR, ESCAPED_COMMA_SEPARATOR),
Expand All @@ -333,7 +332,7 @@ export const convertAdgScriptletToUbo = (rule) => {
return { name, aliases };
})
.find((el) => (el.name === parsedName
|| el.aliases.indexOf(parsedName) >= 0));
|| el.aliases.includes(parsedName)));

const { aliases } = adgScriptletObject;

Expand All @@ -345,7 +344,7 @@ export const convertAdgScriptletToUbo = (rule) => {
if (uboAlias) {
const mask = rule.match(ADGUARD_SCRIPTLET_MASK_REG)[0];
let template;
if (mask.indexOf('@') > -1) {
if (mask.includes('@')) {
template = UBO_SCRIPTLET_EXCEPTION_TEMPLATE;
} else {
template = UBO_SCRIPTLET_TEMPLATE;
Expand Down Expand Up @@ -445,11 +444,11 @@ export const isValidScriptletRule = (ruleText) => {
*/
const getMarkerData = (modifiers, redirectsData, rule) => {
let marker;
let index = modifiers.findIndex((m) => m.indexOf(redirectsData.redirectRuleMarker) > -1);
let index = modifiers.findIndex((m) => m.includes(redirectsData.redirectRuleMarker));
if (index > -1) {
marker = redirectsData.redirectRuleMarker;
} else {
index = modifiers.findIndex((m) => m.indexOf(redirectsData.redirectMarker) > -1);
index = modifiers.findIndex((m) => m.includes(redirectsData.redirectMarker));
if (index > -1) {
marker = redirectsData.redirectMarker;
} else {
Expand Down Expand Up @@ -501,7 +500,7 @@ export const convertAbpRedirectToAdg = (rule) => {
const abpModifiers = validator.parseModifiers(rule);
const adgModifiers = abpModifiers
.map((modifier) => {
if (modifier.indexOf(validator.REDIRECT_RULE_TYPES.ABP.redirectMarker) > -1) {
if (modifier.includes(validator.REDIRECT_RULE_TYPES.ABP.redirectMarker)) {
const abpName = substringAfter(
modifier,
validator.REDIRECT_RULE_TYPES.ABP.redirectMarker,
Expand Down
15 changes: 11 additions & 4 deletions src/helpers/cookie-utils.js
Expand Up @@ -30,11 +30,18 @@ export const getCookiePath = (rawPath) => {
* @param {string} rawName name argument of *set-cookie-* scriptlets
* @param {string} rawValue value argument of *set-cookie-* scriptlets
* @param {string} rawPath path argument of *set-cookie-* scriptlets
* @returns {string|null} string OR `null` if path is not supported
* @param {boolean} shouldEncode if cookie's name and value should be encoded
* @returns {string|null} string OR `null` if name or value is invalid
*/
export const concatCookieNameValuePath = (rawName, rawValue, rawPath) => {
// eslint-disable-next-line max-len
return `${encodeURIComponent(rawName)}=${encodeURIComponent(rawValue)}; ${getCookiePath(rawPath)};`;
export const concatCookieNameValuePath = (rawName, rawValue, rawPath, shouldEncode = true) => {
const COOKIE_BREAKER = ';';
// semicolon will cause the cookie to break
if (!shouldEncode && (rawName.includes(COOKIE_BREAKER) || `${rawValue}`.includes(COOKIE_BREAKER))) {
return null;
}
const name = shouldEncode ? encodeURIComponent(rawName) : rawName;
const value = shouldEncode ? encodeURIComponent(rawValue) : rawValue;
return `${name}=${value}; ${getCookiePath(rawPath)};`;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/create-on-error-handler.js
Expand Up @@ -9,7 +9,7 @@ export function createOnErrorHandler(rid) {
// eslint-disable-next-line consistent-return
const nativeOnError = window.onerror;
return function onError(error, ...args) {
if (typeof error === 'string' && error.indexOf(rid) !== -1) {
if (typeof error === 'string' && error.includes(rid)) {
return true;
}
if (nativeOnError instanceof Function) {
Expand Down
4 changes: 2 additions & 2 deletions src/helpers/hit.js
Expand Up @@ -22,9 +22,9 @@ export const hit = (source) => {
const AG_SCRIPTLET_MARKER = '#%#//';
const UBO_SCRIPTLET_MARKER = '##+js';
let ruleStartIndex;
if (source.ruleText.indexOf(AG_SCRIPTLET_MARKER) > -1) {
if (source.ruleText.includes(AG_SCRIPTLET_MARKER)) {
ruleStartIndex = source.ruleText.indexOf(AG_SCRIPTLET_MARKER);
} else if (source.ruleText.indexOf(UBO_SCRIPTLET_MARKER) > -1) {
} else if (source.ruleText.includes(UBO_SCRIPTLET_MARKER)) {
ruleStartIndex = source.ruleText.indexOf(UBO_SCRIPTLET_MARKER);
}
// delete all domains from ruleText and leave just rule part
Expand Down
14 changes: 1 addition & 13 deletions src/helpers/log-message.js
Expand Up @@ -12,7 +12,6 @@
export const logMessage = (source, message, forced = false, convertMessageToString = true) => {
const {
name,
ruleText,
verbose,
} = source;

Expand All @@ -31,16 +30,5 @@ export const logMessage = (source, message, forced = false, convertMessageToStri
return;
}

let messageStr = `${name}: ${message}`;

// Extract scriptlet part from rule text
if (ruleText) {
const RULE_MARKER = '#%#//scriptlet';
const markerIdx = ruleText.indexOf(RULE_MARKER);
if (markerIdx > -1) {
const ruleWithoutDomains = ruleText.slice(markerIdx, ruleText.length);
messageStr += `; cannot apply rule: ${ruleWithoutDomains}`;
}
}
nativeConsole(messageStr);
nativeConsole(`${name}: ${message}`);
};

0 comments on commit 0328992

Please sign in to comment.