Skip to content

Commit

Permalink
AG-32457 Add new scriptlet — 'trusted-set-session-storage-item'. #426
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit 8edeb7a
Merge: 9bd05a6 b9c439e
Author: Adam Wróblewski <[email protected]>
Date:   Wed Jul 10 12:40:38 2024 +0200

    Merge branch 'master' into feature/AG-32457

commit 9bd05a6
Author: Adam Wróblewski <[email protected]>
Date:   Wed Jul 10 12:19:36 2024 +0200

    Fix docs

commit 5800e89
Author: Adam Wróblewski <[email protected]>
Date:   Wed Jul 10 11:48:37 2024 +0200

    Add trusted-set-session-storage-item scriptlet
  • Loading branch information
AdamWr committed Jul 10, 2024
1 parent b9c439e commit 3b06403
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 0 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
<!-- TODO: change `@added unknown` tag due to the actual version -->
<!-- during new scriptlets or redirects releasing -->

## [Unreleased]

### Added

- `trusted-set-session-storage-item` scriptlet [#426]

[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v1.11.6...HEAD
[#426]: https://github.com/AdguardTeam/Scriptlets/issues/426

## [v1.11.6] - 2024-07-08

### Added
Expand Down
1 change: 1 addition & 0 deletions src/scriptlets/scriptlets-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export * from './trusted-set-cookie';
export * from './trusted-set-cookie-reload';
export * from './trusted-replace-fetch-response';
export * from './trusted-set-local-storage-item';
export * from './trusted-set-session-storage-item';
export * from './trusted-set-constant';
export * from './inject-css-in-shadow-dom';
export * from './remove-node-text';
Expand Down
103 changes: 103 additions & 0 deletions src/scriptlets/trusted-set-session-storage-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {
hit,
logMessage,
nativeIsNaN,
setStorageItem,
parseKeywordValue,
} from '../helpers/index';

/* eslint-disable max-len */
/**
* @trustedScriptlet trusted-set-session-storage-item
*
* @description
* Adds item with arbitrary key and value to sessionStorage object, or updates the value of the key if it already exists.
* Scriptlet won't set item if storage is full.
*
* ### Syntax
*
* ```adblock
* example.com#%#//scriptlet('trusted-set-session-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 session storage item
*
* <!-- markdownlint-disable line-length -->
*
* ```adblock
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'player.live.current.mute', 'false')
*
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'COOKIE_CONSENTS', '{"preferences":3,"flag":false}')
*
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'providers', '[16364,88364]')
*
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'providers', '{"providers":[123,456],"consent":"all"}')
* ```
*
* <!-- markdownlint-enable line-length -->
*
* 1. Set item with current time since unix epoch in ms
*
* ```adblock
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'player.live.current.play', '$now$')
* ```
*
* 1. Set item with current date, e.g 'Tue Nov 08 2022 13:53:19 GMT+0300'
*
* ```adblock
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'player.live.current.play', '$currentDate$')
* ```
*
* 1. Set item without value
*
* ```adblock
* example.org#%#//scriptlet('trusted-set-session-storage-item', 'ppu_main_none', '')
* ```
*
* @added unknown.
*/
/* eslint-enable max-len */

export function trustedSetSessionStorageItem(
source: Source,
key: string,
value: string,
) {
if (typeof key === 'undefined') {
logMessage(source, 'Item key should be specified');
return;
}

if (typeof value === 'undefined') {
logMessage(source, 'Item value should be specified');
return;
}

const parsedValue = parseKeywordValue(value);

const { sessionStorage } = window;
setStorageItem(source, sessionStorage, key, parsedValue);
hit(source);
}

trustedSetSessionStorageItem.names = [
'trusted-set-session-storage-item',
// trusted scriptlets support no aliases
];

trustedSetSessionStorageItem.injections = [
hit,
logMessage,
nativeIsNaN,
setStorageItem,
parseKeywordValue,
];
1 change: 1 addition & 0 deletions tests/scriptlets/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import './trusted-click-element.test';
import './trusted-set-cookie.test';
import './trusted-replace-fetch-response.test';
import './trusted-set-local-storage-item.test';
import './trusted-set-session-storage-item.test';
import './trusted-set-constant.test';
import './inject-css-in-shadow-dom.test';
import './remove-node-text.test';
Expand Down
140 changes: 140 additions & 0 deletions tests/scriptlets/trusted-set-session-storage-item.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/* eslint-disable no-underscore-dangle */
import { runScriptlet, clearGlobalProps, isSafariBrowser } from '../helpers';

const { test, module } = QUnit;
const name = 'trusted-set-session-storage-item';

const beforeEach = () => {
window.__debug = () => {
window.hit = 'FIRED';
};
};

const afterEach = () => {
clearGlobalProps('hit', '__debug');
};

module(name, { beforeEach, afterEach });

const clearStorageItem = (iName) => {
window.sessionStorage.removeItem(iName);
};

if (isSafariBrowser()) {
test('unsupported', (assert) => {
assert.ok(true, 'does not work in Safari 10 while browserstack auto tests run');
});
} else {
test('Set sessionStorage item', (assert) => {
let iName = '__test-item_true';
let iValue = 'true';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), 'true', 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_false';
iValue = 'false';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), 'false', 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_null';
iValue = 'null';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), 'null', 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_undefined';
iValue = 'undefined';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), 'undefined', 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_emptyStr';
iValue = '';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), '', 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_object';
iValue = '{"preferences":3,"marketing":false}';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_array';
iValue = '[1, 2, "test"]';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_string';
iValue = 'some arbitrary item value 111';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_numbers';
iValue = '123123';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set');
clearStorageItem(iName);

iName = '__test-item_mix';
iValue = '123string_!!:;@#$';
runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');
assert.strictEqual(window.sessionStorage.getItem(iName), iValue, 'sessionStorage item has been set');
clearStorageItem(iName);
});

test('Set sessionStorage item with $now$ keyword value', (assert) => {
const iName = '__test-item_now';
const iValue = '$now$';

runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');

// Some time will pass between calling scriptlet
// and qunit running assertion
const tolerance = 20;
const itemValue = window.sessionStorage.getItem(iName);
const currentTime = Date.now();
const timeDiff = currentTime - itemValue;

assert.ok(timeDiff < tolerance, 'Item value has been set to current time');

clearStorageItem(iName);
});

test('Set sessionStorage item with $currentDate$ keyword value', (assert) => {
const iName = '__test-item_current_date';
const iValue = '$currentDate$';

runScriptlet(name, [iName, iValue]);
assert.strictEqual(window.hit, 'FIRED', 'Hit was fired');

const value = sessionStorage.getItem(iName);
const currentDate = new Date();
const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth();
const currentHour = currentDate.getHours();

const currentValue = new Date(value);

assert.strictEqual(currentValue.getFullYear(), currentYear, 'Year matched');
assert.strictEqual(currentValue.getMonth(), currentMonth, 'Month matched');
assert.strictEqual(currentValue.getHours(), currentHour, 'Hour matched');

clearStorageItem(iName);
});
}

0 comments on commit 3b06403

Please sign in to comment.