From 134a31f0911513d137b29124400486c745030f6c Mon Sep 17 00:00:00 2001 From: Stanislav Atroschenko Date: Fri, 11 Nov 2022 19:21:54 +0300 Subject: [PATCH] add trusted scriptlets to readme AG-16962 Merge in ADGUARD-FILTERS/scriptlets from fix/AG-16962 to release/v1.7 Squashed commit of the following: commit 4f4e49c35bf72c183705530ab79f0a489d12acfd Author: Stanislav A Date: Fri Nov 11 18:34:29 2022 +0300 improve allowed sources description commit 0f7ffea31cb88f8683a992748d26464d00adc33c Author: Stanislav A Date: Fri Nov 11 15:54:27 2022 +0300 move tag types to helpers commit d337805993f891be5d398fd1d567aebfef65df4f Author: Stanislav A Date: Fri Nov 11 15:49:25 2022 +0300 fix quotes commit 9d78d55bbe74cbce7c3d8df2ef2b56a260f552cc Author: Stanislav A Date: Fri Nov 11 13:33:14 2022 +0300 update description & swap tag to trustedScriptlet commit 68ea2d854e0993046a5e2737aeaa74762a5cbdbf Author: Stanislav A Date: Thu Nov 10 15:50:28 2022 +0300 fix link commit 3b3dd16f4652d29e1fd94b78db068adc1dfdab0e Author: Stanislav A Date: Thu Nov 10 15:22:06 2022 +0300 improve readme commit 9354743af9360cdfd9cfec39c1ee7097106b7a89 Author: Stanislav A Date: Thu Nov 10 14:13:11 2022 +0300 update tag on all trusteds and update about-trusteds commit c252d85561e2188e3665842bdb9f002fc93d3972 Merge: 9863ab2 356dd0d Author: Stanislav A Date: Thu Nov 10 13:58:12 2022 +0300 Merge branch 'release/v1.7' into fix/AG-16962 commit 9863ab252e4769ef1ccdff1925ed38eb13d74ed0 Author: Stanislav A Date: Thu Nov 10 13:48:39 2022 +0300 add trustedscriptlet tag commit 69dc7c03463fea043acc53c0d9adf0ba49516d44 Author: Stanislav A Date: Thu Nov 10 01:50:02 2022 +0300 build separate wiki page for trusted scriptlets commit c4a87c6892e61d921f74a69ca40df3822a95e651 Merge: a93acba 0fb636b Author: Stanislav A Date: Thu Nov 10 00:14:33 2022 +0300 Merge branch 'release/v1.7' into fix/AG-16962 commit a93acbacbdc6dfca942cae9fa06f11d5ec88427c Author: Stanislav A Date: Thu Nov 10 00:05:54 2022 +0300 fix tables of contents back, fix typo commit a60a9c770a0cde15f7d158193777cb59913cb5fe Author: Stanislav A Date: Wed Oct 26 17:37:34 2022 +0300 move trusteds under Scriptlets commit 2adca6a0cc2d3ca37f89738fe088179df6637d8c Author: Stanislav A Date: Fri Oct 14 17:33:41 2022 +0300 add trusted scriptlets to readme --- README.md | 22 +- scripts/build-docs.js | 44 ++- scripts/constants.js | 12 +- scripts/helpers.js | 14 +- src/scriptlets/trusted-click-element.js | 2 +- .../trusted-replace-fetch-response.js | 2 +- .../trusted-replace-xhr-response.js | 2 +- src/scriptlets/trusted-set-cookie.js | 2 +- .../trusted-set-local-storage-item.js | 2 +- wiki/about-trusted-scriptlets.md | 276 ++++++++++++++++++ 10 files changed, 364 insertions(+), 14 deletions(-) create mode 100644 wiki/about-trusted-scriptlets.md diff --git a/README.md b/README.md index efd5b1f4b..37a11afba 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ AdGuard's Scriptlets and Redirect resources library which provides extended capa * [Syntax](#scriptlet-syntax) * [Available scriptlets](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#scriptlets) * [Scriptlets compatibility table](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/compatibility-table.md#scriptlets) + * [Trusted scriptlets](#trusted-scriptlets) + * [Restriction](#trusted-scriptlets-restriction) + * [Available trusted scriptlets](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-trusted-scriptlets.md#trusted-scriptlets) * [Redirect resources](#redirect-resources) * [Syntax](#redirect-syntax) * [Available redirect resources](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-redirects.md#redirect-resources) @@ -49,12 +52,29 @@ example.org#%#//scriptlet('abort-on-property-read', 'alert') example.org#%#//scriptlet('remove-class', 'branding', 'div[class^="inner"]') ``` -This rule applies the `abort-on-property-read` scriptlet on all pages of `example.org` and its subdomains, and passes one orgument to it (`alert`). +This rule applies the `abort-on-property-read` scriptlet on all pages of `example.org` and its subdomains, and passes one argument to it (`alert`). * **[Scriptlets list](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#scriptlets)** * **[Scriptlets compatibility table](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/compatibility-table.md#scriptlets)** +### Trusted scriptlets + +Trusted scriptlets are scriptlets with extended functionality. Their names are prefixed with `trusted-`, e.g `trusted-click-element`, to be easily distinguished from common scriptlets. + +#### Restriction + +Trusted scriptlets application must be restricted due to dangerous nature of their capabilities. +Allowed sources of trusted scriptlets are: +* filters created by AdGuard Team, +* custom filters which were installed as `trusted`, +* user rules. + +> Trusted scriptlets has no compatibility table as they are not compatible with any other blocker. + +**[Trusted scriptlets list](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-trusted-scriptlets.md#trusted-scriptlets)** + + ## Redirect resources AdGuard is able to redirect web requests to a local "resource". diff --git a/scripts/build-docs.js b/scripts/build-docs.js index ab67e62a5..480ed61c3 100644 --- a/scripts/build-docs.js +++ b/scripts/build-docs.js @@ -8,9 +8,13 @@ const { getDataFromFiles } = require('./helpers'); const { WIKI_DIR_PATH, scriptletsFilenames, + trustedScriptletsFilenames, redirectsFilenames, SCRIPTLETS_SRC_RELATIVE_DIR_PATH, REDIRECTS_SRC_RELATIVE_DIR_PATH, + SCRIPTLET_TYPE, + TRUSTED_SCRIPTLET_TYPE, + REDIRECT_TYPE, } = require('./constants'); const STATIC_REDIRECTS_FILENAME = 'static-redirects.yml'; @@ -28,10 +32,16 @@ const blockingRedirectsPath = path.resolve( ); const ABOUT_SCRIPTLETS_FILENAME = 'about-scriptlets.md'; +const ABOUT_TRUSTED_SCRIPTLETS_FILENAME = 'about-trusted-scriptlets.md'; const ABOUT_REDIRECTS_FILENAME = 'about-redirects.md'; const aboutScriptletsPath = path.resolve(__dirname, WIKI_DIR_PATH, ABOUT_SCRIPTLETS_FILENAME); const aboutRedirectsPath = path.resolve(__dirname, WIKI_DIR_PATH, ABOUT_REDIRECTS_FILENAME); +const aboutTrustedScriptletsPath = path.resolve( + __dirname, + WIKI_DIR_PATH, + ABOUT_TRUSTED_SCRIPTLETS_FILENAME, +); /** * Collects required comments from files and @@ -42,17 +52,31 @@ const manageDataFromFiles = () => { scriptletsFilenames, SCRIPTLETS_SRC_RELATIVE_DIR_PATH, ); + + const dataFromTrustedScriptletsFiles = getDataFromFiles( + trustedScriptletsFilenames, + SCRIPTLETS_SRC_RELATIVE_DIR_PATH, + ); + const dataFromRedirectsFiles = getDataFromFiles( redirectsFilenames, REDIRECTS_SRC_RELATIVE_DIR_PATH, ); - const fullData = dataFromScriptletsFiles.concat(dataFromRedirectsFiles).flat(Infinity); + const fullData = dataFromScriptletsFiles + .concat(dataFromTrustedScriptletsFiles) + .concat(dataFromRedirectsFiles) + .flat(Infinity); - const scriptletsData = fullData.filter(({ type }) => type === 'scriptlet'); - const redirectsData = fullData.filter(({ type }) => type === 'redirect'); + const scriptletsData = fullData.filter(({ type }) => type === SCRIPTLET_TYPE); + const trustedScriptletsData = fullData.filter(({ type }) => type === TRUSTED_SCRIPTLET_TYPE); + const redirectsData = fullData.filter(({ type }) => type === REDIRECT_TYPE); - return { scriptletsData, redirectsData }; + return { + scriptletsData, + trustedScriptletsData, + redirectsData, + }; }; /** @@ -171,6 +195,9 @@ const buildWikiAboutPages = () => { try { const filesData = manageDataFromFiles(); const scriptletsMarkdownData = getMarkdownData(filesData.scriptletsData); + + const trustedScriptletsMarkdownData = getMarkdownData(filesData.trustedScriptletsData); + const redirectsMarkdownData = getMarkdownData(filesData.redirectsData); const staticRedirectsMarkdownData = getMarkdownDataForStaticRedirects(); const blockingRedirectsMarkdownData = getMarkdownDataForBlockingRedirects(); @@ -183,6 +210,15 @@ ${scriptletsMarkdownData.body}`; scriptletsPageContent, ); + // eslint-disable-next-line max-len + const trustedScriptletsPageContent = `## Available Trusted Scriptlets +${trustedScriptletsMarkdownData.list}* * * +${trustedScriptletsMarkdownData.body}`; + fs.writeFileSync( + path.resolve(__dirname, aboutTrustedScriptletsPath), + trustedScriptletsPageContent, + ); + /* eslint-disable max-len */ const redirectsPageContent = `## Available Redirect resources ${staticRedirectsMarkdownData.list}${redirectsMarkdownData.list}${blockingRedirectsMarkdownData.list}* * * diff --git a/scripts/constants.js b/scripts/constants.js index 8f9c90c00..fac90690a 100644 --- a/scripts/constants.js +++ b/scripts/constants.js @@ -22,6 +22,8 @@ const SRC_REDIRECTS_SUB_DIR = 'redirects'; const SCRIPTLETS_SRC_RELATIVE_DIR_PATH = `${SRC_RELATIVE_DIR}/${SRC_SCRIPTLETS_SUB_DIR}`; const REDIRECTS_SRC_RELATIVE_DIR_PATH = `${SRC_RELATIVE_DIR}/${SRC_REDIRECTS_SUB_DIR}`; +const TRUSTED_SCRIPTLETS_PREFIX = 'trusted-'; + // files which are not scriptlets in the source directory const NON_SCRIPTLETS_FILES = [ 'index.js', @@ -30,8 +32,15 @@ const NON_SCRIPTLETS_FILES = [ 'scriptlets-wrapper.js', 'scriptlets-umd-wrapper.js', ]; + +const isUtilityFileName = (filename) => NON_SCRIPTLETS_FILES.includes(filename); +const isTrustedScriptletsFilename = (filename) => filename.startsWith(TRUSTED_SCRIPTLETS_PREFIX); + const scriptletsFilenames = getFilesList(SCRIPTLETS_SRC_RELATIVE_DIR_PATH) - .filter((el) => !NON_SCRIPTLETS_FILES.includes(el)); + .filter((el) => !isUtilityFileName(el) && !isTrustedScriptletsFilename(el)); + +const trustedScriptletsFilenames = getFilesList(SCRIPTLETS_SRC_RELATIVE_DIR_PATH) + .filter((el) => isTrustedScriptletsFilename(el)); // files which are not redirects in the source directory const NON_REDIRECTS_FILES = [ @@ -49,5 +58,6 @@ module.exports = { SCRIPTLETS_SRC_RELATIVE_DIR_PATH, REDIRECTS_SRC_RELATIVE_DIR_PATH, scriptletsFilenames, + trustedScriptletsFilenames, redirectsFilenames, }; diff --git a/scripts/helpers.js b/scripts/helpers.js index b3d126b64..6a75008bc 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -2,6 +2,10 @@ const path = require('path'); const fs = require('fs-extra'); const dox = require('dox'); +const SCRIPTLET_TYPE = 'scriptlet'; +const TRUSTED_SCRIPTLET_TYPE = 'trustedScriptlet'; +const REDIRECT_TYPE = 'redirect'; + /** * Asynchronously writes data to a file, replacing the file if it already exists. * @@ -33,7 +37,7 @@ const getFilesList = (relativeDirPath) => { /** * Returns parsed tags data which we use to describe the sources: - * - `@scriptlet`/`@redirect` to describe the type and name of source; + * - `@scriptlet`/`trustedScriptlet`/`@redirect` to describe the type and name of source; * - `@description` actual description for scriptlet or redirect. * required comments from file. * In one file might be comments describing scriptlet and redirect as well. @@ -54,8 +58,9 @@ const getDescribingCommentTags = (filePath) => { return false; } const [base] = tags; - return base?.type === 'scriptlet' - || base?.type === 'redirect'; + return base?.type === SCRIPTLET_TYPE + || base?.type === TRUSTED_SCRIPTLET_TYPE + || base?.type === REDIRECT_TYPE; }); if (describingComment.length === 0) { @@ -122,4 +127,7 @@ module.exports = { writeFile, getFilesList, getDataFromFiles, + SCRIPTLET_TYPE, + TRUSTED_SCRIPTLET_TYPE, + REDIRECT_TYPE, }; diff --git a/src/scriptlets/trusted-click-element.js b/src/scriptlets/trusted-click-element.js index c364c0dcb..f17972b85 100644 --- a/src/scriptlets/trusted-click-element.js +++ b/src/scriptlets/trusted-click-element.js @@ -6,7 +6,7 @@ import { /* eslint-disable max-len */ /** - * @scriptlet trusted-click-element + * @trustedScriptlet trusted-click-element * * @description * Clicks selected elements in a strict sequence, ordered by selectors passed, and waiting for them to render in the DOM first. diff --git a/src/scriptlets/trusted-replace-fetch-response.js b/src/scriptlets/trusted-replace-fetch-response.js index 7dc999643..84a56e852 100644 --- a/src/scriptlets/trusted-replace-fetch-response.js +++ b/src/scriptlets/trusted-replace-fetch-response.js @@ -20,7 +20,7 @@ import { /* eslint-disable max-len */ /** - * @scriptlet trusted-replace-fetch-response + * @trustedScriptlet trusted-replace-fetch-response * * @description * Replaces response text content of `fetch` requests if **all** given parameters match. diff --git a/src/scriptlets/trusted-replace-xhr-response.js b/src/scriptlets/trusted-replace-xhr-response.js index 99c3a6953..ba8b112bb 100644 --- a/src/scriptlets/trusted-replace-xhr-response.js +++ b/src/scriptlets/trusted-replace-xhr-response.js @@ -18,7 +18,7 @@ import { /* eslint-disable max-len */ /** - * @scriptlet trusted-replace-xhr-response + * @trustedScriptlet trusted-replace-xhr-response * * @description * Replaces response content of `xhr` requests if **all** given parameters match. diff --git a/src/scriptlets/trusted-set-cookie.js b/src/scriptlets/trusted-set-cookie.js index 693640b04..a4e6f52fa 100644 --- a/src/scriptlets/trusted-set-cookie.js +++ b/src/scriptlets/trusted-set-cookie.js @@ -12,7 +12,7 @@ import { /* eslint-disable max-len */ /** - * @scriptlet trusted-set-cookie + * @trustedScriptlet trusted-set-cookie * * @description * Sets a cookie with arbitrary name and value, with optional path diff --git a/src/scriptlets/trusted-set-local-storage-item.js b/src/scriptlets/trusted-set-local-storage-item.js index 9cd74cd99..082290d99 100644 --- a/src/scriptlets/trusted-set-local-storage-item.js +++ b/src/scriptlets/trusted-set-local-storage-item.js @@ -7,7 +7,7 @@ import { /* eslint-disable max-len */ /** - * @scriptlet trusted-set-local-storage-item + * @trustedScriptlet trusted-set-local-storage-item * * @description * Adds item with arbitrary key and value to localStorage object, or updates the value of the key if it already exists. diff --git a/wiki/about-trusted-scriptlets.md b/wiki/about-trusted-scriptlets.md new file mode 100644 index 000000000..01cd58be8 --- /dev/null +++ b/wiki/about-trusted-scriptlets.md @@ -0,0 +1,276 @@ +## Available Trusted Scriptlets +* [trusted-click-element](#trusted-click-element) +* [trusted-replace-fetch-response](#trusted-replace-fetch-response) +* [trusted-replace-xhr-response](#trusted-replace-xhr-response) +* [trusted-set-cookie](#trusted-set-cookie) +* [trusted-set-local-storage-item](#trusted-set-local-storage-item) +* * * +### ⚡️ trusted-click-element + +Clicks selected elements in a strict sequence, ordered by selectors passed, and waiting for them to render in the DOM first. +Deactivates after all elements have been clicked or by 10s timeout. + +**Syntax** +``` +example.com#%#//scriptlet('trusted-click-element', selectors[, extraMatch[, delay]]) +``` + +- `selectors` — required, string with query selectors delimited by comma +- `extraMatch` — optional, extra condition to check on a page; allows to match `cookie` and `localStorage`; can be set as `name:key[=value]` where `value` is optional. +Multiple conditions are allowed inside one `extraMatch` but they should be delimited by comma and each of them should match the syntax. Possible `name`s: + - `cookie` - test string or regex against cookies on a page + - `localStorage` - check if localStorage item is present +- 'delay' - optional, time in ms to delay scriptlet execution, defaults to instant execution. +**Examples** +1. Click single element by selector +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"]') +``` + +2. Delay click execution by 500ms +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"]', '', '500') +``` + +3. Click multiple elements by selector with a delay +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"], button[name='check"], input[type="submit"][value="akkoord"]', '', '500') +``` + +4. Match cookies by keys using regex and string +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"]', 'cookie:userConsentCommunity, cookie:/cmpconsent|cmp/') +``` + +5. Match by cookie key=value pairs using regex and string +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"]', 'cookie:userConsentCommunity=true, cookie:/cmpconsent|cmp/=/[a-z]{1,5}/') +``` + +6. Match by localStorage item 'promo' key +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"]', 'localStorage:promo') +``` + +7. Click multiple elements with delay and matching by both cookie string and localStorage item +``` +example.com#%#//scriptlet('trusted-click-element', 'button[name="agree"], input[type="submit"][value="akkoord"]', 'cookie:cmpconsent, localStorage:promo', '250') +``` + +[Redirect source](../src/scriptlets/trusted-click-element.js) +* * * + +### ⚡️ trusted-replace-fetch-response + +Replaces response text content of `fetch` requests if **all** given parameters match. + +**Syntax** +``` +example.org#%#//scriptlet('trusted-replace-fetch-response'[, pattern, replacement[, propsToMatch]]) +``` + +- pattern - optional, argument for matching contents of responseText that should be replaced. If set, `replacement` is required; +possible values: + - '*' to match all text content + - non-empty string + - regular expression +- replacement — optional, should be set if `pattern` is set. String to replace the response text content matched by `pattern`. +Empty string to remove content. Defaults to empty string. +- propsToMatch - optional, string of space-separated properties to match; possible props: + - string or regular expression for matching the URL passed to fetch call; empty string, wildcard `*` or invalid regular expression will match all fetch calls + - colon-separated pairs `name:value` where + - `name` is [`init` option name](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#parameters) + - `value` is string or regular expression for matching the value of the option passed to fetch call; invalid regular expression will cause any value matching + +> Usage with no arguments will log fetch calls to browser console; +which is useful for debugging but only allowed for production filter lists. + +> Scriptlet does nothing if response body can't be converted to text. + +**Examples** +1. Log all fetch calls + ``` + example.org#%#//scriptlet('trusted-replace-fetch-response') + ``` + +2. Replace response text content of fetch requests with specific url + ``` + example.org#%#//scriptlet('trusted-replace-fetch-response', 'adb_detect:true', 'adb_detect:false', 'example.org') + example.org#%#//scriptlet('trusted-replace-fetch-response', '/#EXT-X-VMAP-AD-BREAK[\s\S]*?/', '#EXT-X-ENDLIST', 'example.org') + ``` + +3. Remove all text content of fetch responses with specific request method + ``` + example.org#%#//scriptlet('trusted-replace-fetch-response', '*', '', 'method:GET') + ``` + +4. Replace response text content of fetch requests matching by URL regex and request methods + ``` + example.org#%#//scriptlet('trusted-replace-fetch-response', '/#EXT-X-VMAP-AD-BREAK[\s\S]*?/', '#EXT-X-ENDLIST', '/\.m3u8/ method:/GET|HEAD/') + ``` +5. Remove text content of all fetch responses for example.com + ``` + example.org#%#//scriptlet('trusted-replace-fetch-response', '*', '', 'example.com') + ``` + +[Redirect source](../src/scriptlets/trusted-replace-fetch-response.js) +* * * + +### ⚡️ trusted-replace-xhr-response + +Replaces response content of `xhr` requests if **all** given parameters match. + +**Syntax** +``` +example.org#%#//scriptlet('trusted-replace-xhr-response'[, pattern, replacement[, propsToMatch]]) +``` + +- pattern - optional, argument for matching contents of responseText that should be replaced. If set, `replacement` is required; +possible values: + - '*' to match all text content + - non-empty string + - regular expression +- replacement — optional, should be set if `pattern` is set. String to replace matched content with. Empty string to remove content. +- propsToMatch — optional, string of space-separated properties to match for extra condition; possible props: + - string or regular expression for matching the URL passed to `.open()` call; + - colon-separated pairs name:value where + - name - name is string or regular expression for matching XMLHttpRequest property name + - value is string or regular expression for matching the value of the option passed to `.open()` call + +> Usage with no arguments will log XMLHttpRequest objects to browser console; +which is useful for debugging but not permitted for production filter lists. + +**Examples** +1. Log all XMLHttpRequests + ``` + example.org#%#//scriptlet('trusted-replace-xhr-response') + ``` + +2. Replace text content of XMLHttpRequests with specific url + ``` + example.org#%#//scriptlet('trusted-replace-xhr-response', 'adb_detect:true', 'adb_detect:false', 'example.org') + example.org#%#//scriptlet('trusted-replace-xhr-response', '/#EXT-X-VMAP-AD-BREAK[\s\S]*?/', '#EXT-X-ENDLIST', 'example.org') + ``` + +3. Remove all text content of XMLHttpRequests with specific request method + ``` + example.org#%#//scriptlet('trusted-replace-xhr-response', '*', '', 'method:GET') + ``` + +4. Replace text content of XMLHttpRequests matching by URL regex and request methods + ``` + example.org#%#//scriptlet('trusted-replace-xhr-response', '/#EXT-X-VMAP-AD-BREAK[\s\S]*?/', '#EXT-X-ENDLIST', '/\.m3u8/ method:/GET|HEAD/') + ``` +5. Remove all text content of all XMLHttpRequests for example.com + ``` + example.org#%#//scriptlet('trusted-replace-xhr-response', '*', '', 'example.com') + ``` + +[Redirect source](../src/scriptlets/trusted-replace-xhr-response.js) +* * * + +### ⚡️ trusted-set-cookie + +Sets a cookie with arbitrary name and value, with optional path +and the ability to reload the page after cookie was set. + +**Syntax** +``` +example.org#%#//scriptlet('trusted-set-cookie', name, value[, offsetExpiresSec[, reload[, path]]]) +``` + +- `name` - required, cookie name to be set +- `value` - required, cookie value. Possible values: + - arbitrary value + - empty string for no value + - `$now$` keyword for setting current time +- 'offsetExpiresSec' - optional, offset from current time in seconds, after which cookie should expire; defaults to no offset +Possible values: + - positive integer in seconds + - `1year` keyword for setting expiration date to one year + - `1day` keyword for setting expiration date to one day +- 'reload' - optional, boolean. Argument for reloading page after cookie is set. Defaults to `false` +- `path` - optional, argument for setting cookie path, defaults to `/`; possible values: + - `/` — root path + - `none` — to set no path at all + +**Examples** +1. Set cookie +``` +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', 'accept') +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', '1-accept_1') +``` + +2. Set cookie with `new Date().getTime()` value +``` +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', '$now') +``` + +3. Set cookie which will expire in 3 days +``` +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', 'accept', '259200') +``` + +4. Set cookie which will expire in one year +``` +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', 'accept', '1year') +``` +5. Reload the page if cookie was successfully set +``` +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', 'decline', '', 'true') +``` + +6. Set cookie with no path +``` +example.org#%#//scriptlet('trusted-set-cookie', 'cmpconsent', 'decline', '', '', 'none') +``` + +[Redirect source](../src/scriptlets/trusted-set-cookie.js) +* * * + +### ⚡️ trusted-set-local-storage-item + +Adds item with arbitrary key and value to localStorage object, or updates the value of the key if it already exists. +Scriptlet won't set item if storage is full. + +**Syntax** +``` +example.com#%#//scriptlet('trusted-set-local-storage-item', 'key', 'value') +``` + +- `key` — required, key name to be set. +- `value` - required, key value; possible values: + - arbitrary value + - `$now$` keyword for setting current time in ms, corresponds to `Date.now()` and `(new Date).getTime()` calls + - `$currentDate$` keyword for setting string representation of the current date and time, corresponds to `Date()` and `(new Date).toString()` calls + +**Examples** +1. Set local storage item +``` +example.org#%#//scriptlet('trusted-set-local-storage-item', 'player.live.current.mute', 'false') + +example.org#%#//scriptlet('trusted-set-local-storage-item', 'COOKIE_CONSENTS', '{"preferences":3,"marketing":false}') + +example.org#%#//scriptlet('trusted-set-local-storage-item', 'providers', '[16364,88364]') + +example.org#%#//scriptlet('trusted-set-local-storage-item', 'providers', '{"providers":[16364,88364],"consent":"all"}') +``` + +2. Set item with current time since unix epoch in ms +``` +example.org#%#//scriptlet('trusted-set-local-storage-item', 'player.live.current.play', '$now$') +``` + +3. Set item with current date, e.g 'Tue Nov 08 2022 13:53:19 GMT+0300' +``` +example.org#%#//scriptlet('trusted-set-local-storage-item', 'player.live.current.play', '$currentDate$') +``` + +4. Set item without value +``` +example.org#%#//scriptlet('trusted-set-local-storage-item', 'ppu_main_none', '') +``` + +[Redirect source](../src/scriptlets/trusted-set-local-storage-item.js) +* * * +