Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
3308752
issue-66 playwright dependency and npm scripts
dhilt Nov 9, 2025
a499e20
issue-66 playwright configuration
dhilt Nov 9, 2025
748363e
issue-66 basic fixture entities
dhilt Nov 9, 2025
17a5f62
issue-66 global.d.ts for e2e
dhilt Nov 9, 2025
7e74a7b
issue-66 scroll-basic.spec
dhilt Nov 9, 2025
454683a
issue-66 new CI workflow
dhilt Nov 9, 2025
42c1c0e
issue-66 fix unit tests
dhilt Nov 9, 2025
6f2e0ab
issue-66 scroll-basic.spec | config type
dhilt Nov 9, 2025
eef5633
issue-66 Workflow.cyclesDone$
dhilt Nov 9, 2025
c96f1c9
issue-66 scroll-delay.spec
dhilt Nov 9, 2025
3c8ec1c
issue-66 devSettings.logColor
dhilt Nov 11, 2025
ec23b70
issue-66 detailed console output
dhilt Nov 11, 2025
ad0a25b
issue-66 add browser dev log for all tests
dhilt Nov 11, 2025
e01efb6
issue-66 Logger.getLogs()
dhilt Nov 11, 2025
d1b3b2c
issue-66 types
dhilt Nov 11, 2025
b28ea5d
issue-66 test.afterEach(afterEachLogs);
dhilt Nov 11, 2025
1a6eae7
issue-66 test.afterEach(afterEachLogs) | spec name in the log
dhilt Nov 11, 2025
ecbb780
issue-66 tests/unit, tests/e2e
dhilt Nov 11, 2025
4bca5d0
issue-66 own package.json for tests
dhilt Nov 11, 2025
fac56ac
issue-66 remove old CI workflow
dhilt Nov 11, 2025
211c123
issue-66 createFixture helper
dhilt Nov 11, 2025
174336f
issue-66 datasourceGet for createFixture
dhilt Nov 11, 2025
88a364a
issue-66 Routines.getWindowParams() fix
dhilt Nov 12, 2025
52af1f5
issue-66 scroll-fast.spec
dhilt Nov 12, 2025
6893215
issue-66 viewport.spec
dhilt Nov 12, 2025
e6163a7
issue-66 dispose, noRelaxOnStart
dhilt Nov 16, 2025
31aca48
issue-66 recreation.spec (1)
dhilt Nov 16, 2025
e7407a8
issue-66 makeDatasource -- getDefaultAdapterConfig
dhilt Nov 16, 2025
02217c6
issue-66 Workflow.isInitialized = false on dispose
dhilt Nov 16, 2025
3ff6e92
issue-66 no-adapter case refactoring
dhilt Nov 16, 2025
5a09b48
issue-66 manualRun and makeScroller
dhilt Nov 16, 2025
ff9bbee
issue-66 recreation.spec (2): should switch Adapter.init trice
dhilt Nov 16, 2025
715e6c0
issue-66 recreation.spec (2): should switch Adapter.init trice: wfIni…
dhilt Nov 17, 2025
8c243be
issue-66 recreation.spec (3): should re-render the viewport
dhilt Nov 20, 2025
d1f0d2d
issue-66 recreation.spec (4): should scroll and take firstVisible
dhilt Nov 21, 2025
92dc589
issue-66 recreation.spec: scrollTo refactoring
dhilt Nov 21, 2025
1fdcae2
issue-66 min-max-indexes.spec
dhilt Nov 22, 2025
54f1343
prettier husky lint-staged
dhilt Nov 22, 2025
96b4ffa
prettier husky lint-staged: configs are formatted
dhilt Nov 22, 2025
f891c44
prettier husky lint-staged: e2e tests are formatted
dhilt Nov 22, 2025
5aad76a
prettier husky lint-staged: unit tests are formatted
dhilt Nov 22, 2025
14a942c
issue-66 initial-load.spec: Fixed itemSize
dhilt Nov 23, 2025
78726a7
issue-66 initial-load.spec: Tuned itemSize (1)
dhilt Nov 23, 2025
b6580f8
issue-66 initial-load.spec: Tuned itemSize (2)
dhilt Nov 23, 2025
dce4e5d
issue-66 initial-load.spec: No itemSize
dhilt Nov 23, 2025
6b2e46e
issue-66 initial-load.spec: Lack of items after the 1st fetch
dhilt Nov 23, 2025
c6d7dd7
issue-66 initial-load.spec: finalization
dhilt Nov 23, 2025
18ede93
prettier husky lint-staged: core sources are formatted
dhilt Nov 27, 2025
bb5316e
Update npm dependencies
dhilt Nov 28, 2025
6898d02
Update tests npm dependencies
dhilt Nov 28, 2025
7c36a9f
vscroll v1.8.0
dhilt Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 0 additions & 39 deletions .github/workflows/build.yml

This file was deleted.

58 changes: 58 additions & 0 deletions .github/workflows/general.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: vscroll build and tests

on:
pull_request:
workflow_dispatch:
inputs:
cause:
description: "Reason"
required: true
default: "Manual triggering"

jobs:
build_and_tests:
runs-on: ubuntu-latest
steps:
- name: Dispatched?
if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo "This is dispatched"
echo "Test reason: ${{ github.event.inputs.cause }}"

- name: Checkout
uses: actions/checkout@v4

- name: Use Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 22.x

- name: Install root dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Build
run: npm run build

- name: Install test dependencies
run: cd tests && npm ci

- name: Run unit tests
run: npm run test:unit

- name: Install Playwright Browsers
run: cd tests && npx playwright install --with-deps chromium

- name: Run e2e tests
run: npm run test:e2e

- name: Upload Playwright Report
uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: tests/e2e/playwright-report/
retention-days: 30

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ node_modules
.vscode
*.tgz
.DS_Store
tests/e2e/playwright-report
tests/e2e/test-results
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx lint-staged
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"tabWidth": 2,
"singleQuote": true,
"arrowParens": "avoid",
"trailingComma": "none",
"printWidth": 100
}
2 changes: 1 addition & 1 deletion build.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const CONF_DIR = 'build';
const configJsonString = readFileSync('./package.json', { encoding: 'utf8' });
const config = JSON.parse(configJsonString);

// Package version
// Package version
shell.echo('Setup package version');
const versionContent = `export default {
name: '${config.name}',
Expand Down
184 changes: 184 additions & 0 deletions demo/window-test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<!doctype html>
<html>

<head>
<title>vscroll window viewport test</title>
<meta charset="utf-8">
<style>
body {
margin: 0;
padding: 0;
}

.item {
height: 20px;
line-height: 20px;
padding: 0 10px;
}

.item span {
font-size: small;
color: #666;
}

.info {
position: fixed;
top: 10px;
right: 10px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid #ccc;
padding: 10px;
font-size: 12px;
font-family: monospace;
z-index: 1000;
}

.info div {
margin: 2px 0;
}
</style>
<script src="../dist/bundles/vscroll.umd.js"></script>
</head>

<body>
<div class="info">
<div><strong>Window Viewport Test</strong></div>
<div id="info-html-height">html.clientHeight: -</div>
<div id="info-html-scroll">html.scrollHeight: -</div>
<div id="info-window-height">window.innerHeight: -</div>
<div id="info-buffer-size">Buffer size: -</div>
<div id="info-fetch-count">Fetches: 0</div>
</div>
<div id="vscroll">
<div data-padding-backward></div>
<div data-padding-forward></div>
</div>
<script>
(() => {

const MAX = 2000;
const MIN = 1;
let fetchCount = 0;

function updateInfo() {
document.getElementById('info-html-height').textContent =
'html.clientHeight: ' + document.documentElement.clientHeight;
document.getElementById('info-html-scroll').textContent =
'html.scrollHeight: ' + document.documentElement.scrollHeight;
document.getElementById('info-window-height').textContent =
'window.innerHeight: ' + window.innerHeight;
document.getElementById('info-buffer-size').textContent =
'Buffer size: ' + (window.workflow ? window.workflow.scroller.buffer.size : 0);
document.getElementById('info-fetch-count').textContent =
'Fetches: ' + fetchCount;
}

// virtual scroll engine params
const workflowParams = {
consumer: {
name: 'VScroll Window Test',
version: '1.0.0'
},
element: document.getElementById('vscroll'),
datasource: {
get: (index, count, success) => {
fetchCount++;
console.log(`[Fetch #${fetchCount}] Requesting [${index}..${index + count - 1}]`);

const start = Math.max(index, MIN);
const end = Math.min(index + count - 1, MAX);
const data = [];

if (start <= end) {
for (let i = start; i <= end; i++) {
data.push({ id: i, text: 'item #' + i });
}
}

console.log(`[Fetch #${fetchCount}] Resolved ${data.length} items`);
setTimeout(() => {
success(data);
updateInfo();
}, 25);
},
settings: {
startIndex: 100,
padding: 0.25,
bufferSize: 1,
itemSize: 20,
windowViewport: true
},
devSettings: {
debug: true,
immediateLog: true,
logProcessRun: true,
logColor: false
}
},
run: (newItems) => {
if (!newItems.length && !oldItems.length) {
return;
}
processItems(newItems, oldItems);
oldItems = newItems;
updateInfo();
},
};

// old items storage
let oldItems = [];

// the renderer
const processItems = (newItems, oldItems) => {
// remove elements not present
oldItems
.filter(item => !newItems.includes(item))
.forEach(item => item.element.remove());
// create and insert new elements
const elements = [];
let beforeElement =
workflowParams.element.querySelector('[data-padding-forward]');
for (let i = newItems.length - 1; i >= 0; i--) {
if (oldItems.includes(newItems[i])) {
if (!elements.length) {
beforeElement = newItems[i].element;
continue;
} else {
break;
}
}
elements.unshift(createItemElement(newItems[i]));
}
elements.forEach(elt =>
beforeElement.insertAdjacentElement('beforebegin', elt)
);
};

// creates single item HTML element
const createItemElement = item => {
const element = document.createElement('div');
element.setAttribute('data-sid', item.nodeId);
if (item.invisible) {
element.style.position = 'fixed';
element.style.top = '-99px';
}
element.innerHTML =
`<div class="item">
<span>${item.$index}</span>)
${item.data.text}
</div>`;
return element;
};

// run the VScroll Workflow
window.workflow = new VScroll.Workflow(workflowParams);

// Update info every second
setInterval(updateInfo, 1000);
setTimeout(updateInfo, 500);

})();
</script>
</body>

</html>
21 changes: 12 additions & 9 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ import globals from 'globals';
export default [
// Global ignores (replaces .eslintignore)
{
ignores: [
'node_modules/**',
'dist/**',
'build/**',
'demo/**'
]
ignores: ['node_modules/**', 'dist/**', 'build/**', 'demo/**']
},

// Base configuration for TypeScript files
Expand All @@ -37,10 +32,18 @@ export default [

// Custom rules from original config
'max-len': ['error', { code: 120 }],
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
quotes: ['error', 'single'],
semi: ['error', 'always'],
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': ['error', { ignoreRestArgs: true }],
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}
],

// Disable no-undef for TypeScript as TypeScript compiler handles this
'no-undef': 'off'
Expand Down Expand Up @@ -76,4 +79,4 @@ export default [
'@typescript-eslint/no-var-requires': 'off'
}
}
];
];
9 changes: 9 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default {
testMatch: ['**/tests/unit/**/*.spec.ts'],
transform: {
'^.+\\.ts$': 'babel-jest'
},
moduleFileExtensions: ['ts', 'js'],
collectCoverageFrom: ['src/**/*.ts'],
coveragePathIgnorePatterns: ['/node_modules/', '/tests/']
};
4 changes: 4 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default {
'*.ts': () => 'npm run lint',
'*.{ts,js,json}': 'prettier --write'
};
Loading