remove: v10
This commit is contained in:
parent
f959ccf448
commit
692c46e59d
32
v10/.github/ISSUE_TEMPLATE.md
vendored
32
v10/.github/ISSUE_TEMPLATE.md
vendored
@ -1,32 +0,0 @@
|
||||
<!-- Love ngx-infinite-scroll? Please consider supporting our collective:
|
||||
👉 https://opencollective.com/ngx-infinite-scroll/donate -->
|
||||
Your issue may already be reported!
|
||||
Please search on the [issue track](../) before creating one.
|
||||
|
||||
## Expected Behavior
|
||||
<!--- If you're describing a bug, tell us what should happen -->
|
||||
<!--- If you're suggesting a change/improvement, tell us how it should work -->
|
||||
|
||||
|
||||
## Actual Behavior
|
||||
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
|
||||
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
|
||||
|
||||
## Possible Solution
|
||||
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
|
||||
<!--- or ideas how to implement the addition or change -->
|
||||
|
||||
### Steps To Reproduce / Demo (if applicable)
|
||||
[ ] Please share a [stackblitz](https://stackblitz.com/) or [plunkr](https://plnkr.co/) demo reproducing this issue
|
||||
|
||||
|
||||
### Context
|
||||
<!--- How has this issue affected you? What are you trying to accomplish? -->
|
||||
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
|
||||
|
||||
### Your Environment
|
||||
<!--- Include as many relevant details about the environment you experienced the bug in -->
|
||||
- [ ] Version used:
|
||||
- [ ] Browser Name and version:
|
||||
- [ ] (Optional) Operating System and version (desktop or mobile):
|
||||
- [ ] (Optional) Link to your project:
|
||||
30
v10/.github/PULL_REQUEST_TEMPLATE.md
vendored
30
v10/.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,30 +0,0 @@
|
||||
A similar PR may already be submitted!
|
||||
Please search among the [Pull request](../) before creating one.
|
||||
|
||||
Thanks for submitting a pull request! Please provide enough information so that others can review your pull request.
|
||||
|
||||
**Summary**
|
||||
|
||||
<!-- Summary of the PR -->
|
||||
|
||||
This PR fixes/implements the following **bugs/features**
|
||||
|
||||
- [ ] #issue1
|
||||
- [ ] #issue2
|
||||
- [ ] #Feature1
|
||||
- [ ] #Feature2
|
||||
- [ ] Breaking changes
|
||||
|
||||
<!-- You can skip this if you're fixing a typo or adding an app to the Showcase. -->
|
||||
|
||||
Explain the **motivation** for making this change. What existing problem does the pull request solve?
|
||||
|
||||
<!-- Example: When "Adding a function to do X", explain why it is necessary to have a way to do X. -->
|
||||
|
||||
### Requirements
|
||||
Make sure these boxes are checked:
|
||||
- [ ] link to an issue
|
||||
- [ ] tests are updated (added/changed/removed)
|
||||
- [ ] tests run successfully (local)
|
||||
- [ ] tests run successfully (TravisCI)
|
||||
- [ ] please follow this [styleguide](https://gist.github.com/stephenparish/9941e89d80e2bc58a153#subject-line) for this pr title
|
||||
64
v10/.gitignore
vendored
64
v10/.gitignore
vendored
@ -1,64 +0,0 @@
|
||||
#################
|
||||
## Misc
|
||||
#################
|
||||
**/.DS_Store
|
||||
nbproject
|
||||
manifest.mf
|
||||
build.xml
|
||||
node_modules/*
|
||||
npm-debug.log
|
||||
coverage
|
||||
./*.js
|
||||
src/*.js
|
||||
angular2-infinite-scroll.js
|
||||
!karma.conf.js
|
||||
!karma-test-shim.js
|
||||
*.map
|
||||
*.d.ts
|
||||
!make.js
|
||||
!bundles/*.js
|
||||
__ivy_ngcc__
|
||||
|
||||
#################
|
||||
## JetBrains
|
||||
#################
|
||||
.idea
|
||||
.project
|
||||
.settings
|
||||
.idea/*
|
||||
*.iml
|
||||
|
||||
############
|
||||
## Windows
|
||||
############
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
############
|
||||
## Mac
|
||||
############
|
||||
|
||||
# Mac crap
|
||||
.DS_Store
|
||||
|
||||
.tmp
|
||||
typings
|
||||
.tags*
|
||||
|
||||
src/ngFactory
|
||||
*.metadata.json
|
||||
|
||||
$ cat .gitignore
|
||||
/node_modules
|
||||
/dist
|
||||
/documentation
|
||||
|
||||
*.log
|
||||
*.tgz
|
||||
|
||||
npm-debug.*
|
||||
package-lock.json
|
||||
@ -1,14 +0,0 @@
|
||||
# Node generated files
|
||||
node_modules
|
||||
npm-debug.log
|
||||
|
||||
# OS generated files
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
|
||||
# Ignored files
|
||||
*.ts
|
||||
!*.d.ts
|
||||
|
||||
# ngc generated files
|
||||
src/ngFactory
|
||||
@ -1 +0,0 @@
|
||||
package-lock=false
|
||||
@ -1,23 +0,0 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
# addons:
|
||||
# apt:
|
||||
# sources:
|
||||
# - google-chrome
|
||||
# packages:
|
||||
# - google-chrome-stable
|
||||
language: node_js
|
||||
node_js:
|
||||
- stable
|
||||
# before_install:
|
||||
# - npm i npm@^4 -g
|
||||
install:
|
||||
- npm install
|
||||
script:
|
||||
- npm test
|
||||
before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- sleep 3
|
||||
notifications:
|
||||
email: false
|
||||
17
v10/.vscode/launch.json
vendored
17
v10/.vscode/launch.json
vendored
@ -1,17 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "chrome",
|
||||
"request": "launch",
|
||||
"name": "Test In Chrome",
|
||||
"sourceMaps": true,
|
||||
"webRoot": "${workspaceRoot}/tests",
|
||||
"url": "http://localhost:9876/debug.html",
|
||||
"runtimeArgs": ["--headless"]
|
||||
}
|
||||
]
|
||||
}
|
||||
165
v10/CHANGELOG.md
165
v10/CHANGELOG.md
@ -1,165 +0,0 @@
|
||||
## v 10.0.1 (2020/12/09)
|
||||
|
||||
- [FIX] - throttle behavior refined - fixed issue #198
|
||||
|
||||
## v 10.0.0 (2020/11/07)
|
||||
|
||||
- [UPGRADE] - now using Angular 10
|
||||
|
||||
## v 9.1.0 (2020/09/09)
|
||||
|
||||
- [UPGRADE] - upgrading scarf
|
||||
|
||||
## v 9.0.0 (2020/05/12)
|
||||
|
||||
- [UPGRADE] - now using Angular 9
|
||||
|
||||
## v 8.0.2 (2020/05/10)
|
||||
|
||||
- [CHORE] - add @scarf
|
||||
|
||||
## v 8.0.1 (2019/10/15)
|
||||
|
||||
- [FIX] - solves issue with open collective postinstall #321
|
||||
|
||||
## v 8.0.0 (2019/07/26)
|
||||
|
||||
- [UPGRADE] - now using Angular 8
|
||||
- [BREAKING_CHANGE] - `InfiniteScrollEvent` is renamed to `IInfiniteScrollEvent`
|
||||
|
||||
## v 7.2.0 (2019/06/10)
|
||||
|
||||
- [FIX] - fixes #322 - fixing scrollDistance calculations to include it reach to definite bottom
|
||||
|
||||
## v 7.1.0 (2019/03/10)
|
||||
|
||||
- [FIX] - 'alwaysCallback' to trigger only when past distance point
|
||||
- [UPGRADE] - unit tests with puppeteer
|
||||
- [UPGRADE] - scorll state is now handled within a class
|
||||
- [FIX] - using now opencollective-postinstall #296
|
||||
|
||||
## v 7.0.1 (2019/01/04)
|
||||
|
||||
- [FIX] - build fix adding correct version of Typescript 3
|
||||
|
||||
## v 7.0.0 (2018/12/30)
|
||||
|
||||
- [UPGRADE] - now using Angular 7
|
||||
|
||||
## v 6.0.1 (2018/06/15)
|
||||
|
||||
- [FIX] - scroll up calculations issues #282
|
||||
- [CHORE] - more tests for "shouldFireScrollEvent()"
|
||||
- [CHORE] - added an "exmaples" instead "example" for development
|
||||
|
||||
## v 6.0.0 (2018/05/22)
|
||||
|
||||
- [UPGRADE] - upgrade to Angular 6 & rxjs 6
|
||||
- [CHORE] - demo now with https://stackblitz.com
|
||||
|
||||
## v 0.8.4 (2018/04/11)
|
||||
|
||||
- [FIX] - bug fixes
|
||||
- [UPGRADE] - rxjs 5.5.6 upgrade
|
||||
- [CHORE] - Add npm badges
|
||||
|
||||
## v 0.8.3 (2018/02/21)
|
||||
|
||||
- [FIX] - fix for #198 - takes a long time for onscroll to fire
|
||||
- [UPDATE] - default value for throttle changed to 150
|
||||
|
||||
## v 0.8.2 (2018/01/07)
|
||||
|
||||
- [FIX] - fix for #221 - action not fired on Windows scrolling
|
||||
- [FIX] - fix for #228 - scrolling back up to the top of the list and then scroll down doesn't trigger event
|
||||
- [REFACTOR] - shorten var names
|
||||
|
||||
## v 0.8.1 (2018/01/07)
|
||||
|
||||
- [REFACTOR] - performance optimization for scroll events
|
||||
|
||||
## v 0.8.0 (2018/01/02)
|
||||
|
||||
- [FIX] - now triggers only once when in or after target (#200)
|
||||
- [REFACTOR] - "distance" number has been refined to be the percentage point of the scroll nob.
|
||||
- [REFACTOR] - added more unit tests.
|
||||
|
||||
## v 0.7.2 (2017/12/07)
|
||||
|
||||
- [FIX] - fix for ie11 - fix #157
|
||||
|
||||
## v 0.7.1 (2017/11/27)
|
||||
|
||||
- [FIX] - use html container if passed in #217 - fix #216
|
||||
|
||||
## v 0.7.0 (2017/11/27)
|
||||
|
||||
- [ADD] - watch changes for: infiniteScrollDisabled - fix #196
|
||||
- [ADD] - watch changes for: infiniteScrollDistance - fix #202
|
||||
- [FIX] - fix for IE11 - fix #203
|
||||
- [REFACTOR] - "disable" now removes the scroll listener instead of rxjs/filter
|
||||
|
||||
## v 0.6.1 (2017/10/20)
|
||||
|
||||
- [REFACTOR] - updated code to be functional based
|
||||
- [FIX] - fix #67, fix #191, fix #190
|
||||
|
||||
## v 0.5.2 (2017/09/27)
|
||||
|
||||
- [FIX] - fix #157, fix #162, fix #171, fix #188
|
||||
- [DOCS] - added example for development
|
||||
|
||||
## v 0.5.1 (2017/04/25)
|
||||
|
||||
- [FIX] - fixes #156 - running scroll logics outside of angular's zone
|
||||
|
||||
## v 0.5.0 (2017/04/24)
|
||||
|
||||
- [MAINTAINANCE] - code refactor - removing factories to rely more pure functional methods in PositionResolver, AxisResolver
|
||||
|
||||
## v 0.4.2 (2017/04/19)
|
||||
|
||||
- [NEW] - added **'[infiniteScroll]'** by [Angular's styleguide](https://angular.io/docs/ts/latest/guide/style-guide.html#!#02-06). **[infinite-scroll]** will be deprecated in future version.
|
||||
- reduced bundle size with imports for RxJS Observable and Subscription objects #126.
|
||||
- removed old code directory from repo
|
||||
|
||||
## v 0.4.1 (2017/04/13)
|
||||
|
||||
- Fixes #147 - (**InfiniteScrollModule is not an NgModule**)
|
||||
|
||||
## v 0.4.0 (2017/04/12)
|
||||
|
||||
- Added Angular 4 support
|
||||
- New starter code base ([based on angular-library-starter](https://github.com/robisim74/angular-library-starter))
|
||||
|
||||
## v 0.3.3 (2017/03/01)
|
||||
|
||||
### Updates
|
||||
|
||||
- reverted the fix of #126
|
||||
|
||||
## v 0.3.2 (2017/03/01)
|
||||
|
||||
### Updates
|
||||
|
||||
- fixes [#126](https://github.com/orizens/angular2-infinite-scroll/issues/126)
|
||||
|
||||
## v 0.3.1 (2017/02/15)
|
||||
|
||||
### Updates
|
||||
|
||||
- added custom scrollable container from [#108](https://github.com/orizens/angular2-infinite-scroll/pull/108/files)
|
||||
|
||||
## v 0.3.0 (2017/01/31)
|
||||
|
||||
### Updates
|
||||
|
||||
- refactored infinite scroller to smaller modules with composition
|
||||
- added "models" - includes interfaces for development
|
||||
|
||||
## v 0.2.9 (2017/01/13)
|
||||
|
||||
### Updates
|
||||
|
||||
- added changelog.md
|
||||
- ([refactor(scroll): replaces throttle with debounce](https://github.com/orizens/angular2-infinite-scroll/pull/82))
|
||||
@ -1,67 +0,0 @@
|
||||
# Contribute
|
||||
|
||||
## Introduction
|
||||
|
||||
First, thank you for considering contributing to ngx-infinite-scroll! It's people like you that make the open source community such a great community! 😊
|
||||
|
||||
We welcome any type of contribution, not only code. You can help with
|
||||
- **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open)
|
||||
- **Marketing**: writing blog posts, howto's, printing stickers, ...
|
||||
- **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ...
|
||||
- **Code**: take a look at the [open issues](issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them.
|
||||
- **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/ngx-infinite-scroll).
|
||||
|
||||
## Your First Contribution
|
||||
|
||||
Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).
|
||||
|
||||
## Submitting code
|
||||
|
||||
Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests.
|
||||
|
||||
## Code review process
|
||||
|
||||
The bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge.
|
||||
It is also always helpful to have some context for your pull request. What was the purpose? Why does it matter to you?
|
||||
|
||||
## Financial contributions
|
||||
|
||||
We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/ngx-infinite-scroll).
|
||||
Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.
|
||||
|
||||
## Questions
|
||||
|
||||
If you have any questions, create an [issue](issue) (protip: do a quick search first to see if someone else didn't ask the same question before!).
|
||||
You can also reach us at hello@ngx-infinite-scroll.opencollective.com.
|
||||
|
||||
## Credits
|
||||
|
||||
### Contributors
|
||||
|
||||
Thank you to all the people who have already contributed to ngx-infinite-scroll!
|
||||
<a href="graphs/contributors"><img src="https://opencollective.com/ngx-infinite-scroll/contributors.svg?width=890" /></a>
|
||||
|
||||
|
||||
### Backers
|
||||
|
||||
Thank you to all our backers! [[Become a backer](https://opencollective.com/ngx-infinite-scroll#backer)]
|
||||
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll#backers" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/backers.svg?width=890"></a>
|
||||
|
||||
|
||||
### Sponsors
|
||||
|
||||
Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/ngx-infinite-scroll#sponsor))
|
||||
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/9/avatar.svg"></a>
|
||||
|
||||
<!-- This `CONTRIBUTING.md` is based on @nayafia's template https://github.com/nayafia/contributing-template -->
|
||||
@ -1,161 +0,0 @@
|
||||
# angular-library-starter
|
||||
[](https://travis-ci.org/robisim74/angular-library-starter)
|
||||
>Build an Angular library compatible with AoT compilation & Tree shaking.
|
||||
|
||||
This starter allows you to create a library for **Angular 2+** apps written in _TypeScript_, _ES6_ or _ES5_.
|
||||
The project is based on the official _Angular_ packages.
|
||||
|
||||
Get the [Changelog](https://github.com/robisim74/angular-library-starter/blob/master/CHANGELOG.md).
|
||||
|
||||
## Contents
|
||||
* [1 Project structure](#1)
|
||||
* [2 Customizing](#2)
|
||||
* [3 Unit testing](#3)
|
||||
* [4 Building](#4)
|
||||
* [5 Publishing](#5)
|
||||
* [6 Documentation](#6)
|
||||
* [7 Using the library](#7)
|
||||
* [8 What it is important to know](#8)
|
||||
|
||||
## <a name="1"></a>1 Project structure
|
||||
- Library:
|
||||
- **src** folder for the classes
|
||||
- **public-api.ts** entry point for all public APIs of the package
|
||||
- **package.json** _npm_ options
|
||||
- **rollup.config.js** _Rollup_ configuration for building the bundles
|
||||
- **tsconfig-build.json** _ngc_ compiler options for _AoT compilation_
|
||||
- **build.js** building process using _ShellJS_
|
||||
- Unit testing:
|
||||
- **tests** folder for unit tests
|
||||
- **karma.conf.js** _Karma_ configuration that uses _webpack_ to build the tests
|
||||
- **spec.bundle.js** defines the files used by _webpack_
|
||||
- **tsconfig.json** _TypeScript_ compiler options
|
||||
- Extra:
|
||||
- **tslint.json** _TypeScript_ linter rules with _Codelyzer_
|
||||
- **travis.yml** _Travis CI_ configuration
|
||||
|
||||
## <a name="2"></a>2 Customizing
|
||||
1. Update [Node & npm](https://docs.npmjs.com/getting-started/installing-node).
|
||||
|
||||
2. Rename `angular-library-starter` and `angularLibraryStarter` everywhere to `my-library` and `myLibrary`.
|
||||
|
||||
3. Update in `package.json` file:
|
||||
- version: [Semantic Versioning](http://semver.org/)
|
||||
- description
|
||||
- urls
|
||||
- packages
|
||||
|
||||
and run `npm install`.
|
||||
|
||||
4. Create your classes in `src` folder, and export public classes in `my-library.ts`.
|
||||
|
||||
5. You can create only one _module_ for the whole library:
|
||||
I suggest you create different _modules_ for different functions,
|
||||
so that the user can import only those he needs and optimize _Tree shaking_ of his app.
|
||||
|
||||
6. Update in `rollup.config.js` file `external` & `globals` libraries with those that actually you use.
|
||||
|
||||
7. Create unit tests in `tests` folder.
|
||||
_Karma_ is configured to use _webpack_ only for `*.ts` files: if you need to test different formats, you have to update it.
|
||||
|
||||
## <a name="3"></a>3 Unit testing
|
||||
```Shell
|
||||
npm test
|
||||
```
|
||||
|
||||
## <a name="4"></a>4 Building
|
||||
The following command:
|
||||
```Shell
|
||||
npm run build
|
||||
```
|
||||
- starts _TSLint_ with _Codelyzer_
|
||||
- starts _AoT compilation_ using _ngc_ compiler
|
||||
- creates `dist` folder with all the files of distribution
|
||||
|
||||
To test locally the npm package:
|
||||
```Shell
|
||||
npm run pack-lib
|
||||
```
|
||||
Then you can install it in an app to test it:
|
||||
```Shell
|
||||
npm install [path]my-library-[version].tgz
|
||||
```
|
||||
|
||||
## <a name="5"></a>5 Publishing
|
||||
Before publishing the first time:
|
||||
- you can register your library on [Travis CI](https://travis-ci.org/): you have already configured `.travis.yml` file
|
||||
- you must have a user on the _npm_ registry: [Publishing npm packages](https://docs.npmjs.com/getting-started/publishing-npm-packages)
|
||||
|
||||
```Shell
|
||||
npm run publish-lib
|
||||
```
|
||||
|
||||
## <a name="6"></a>6 Documentation
|
||||
To generate the documentation, this starter uses [compodoc](https://github.com/compodoc/compodoc):
|
||||
```Shell
|
||||
npm run compodoc
|
||||
npm run compodoc-serve
|
||||
```
|
||||
|
||||
## <a name="7"></a>7 Using the library
|
||||
### Installing
|
||||
```Shell
|
||||
npm install my-library --save
|
||||
```
|
||||
### Loading
|
||||
#### Using SystemJS configuration
|
||||
```JavaScript
|
||||
System.config({
|
||||
map: {
|
||||
'my-library': 'node_modules/my-library/bundles/my-library.umd.js'
|
||||
}
|
||||
});
|
||||
```
|
||||
#### Angular-CLI
|
||||
No need to set up anything, just import it in your code.
|
||||
#### Rollup or webpack
|
||||
No need to set up anything, just import it in your code.
|
||||
#### Plain JavaScript
|
||||
Include the `umd` bundle in your `index.html`:
|
||||
```Html
|
||||
<script src="node_modules/my-library/bundles/my-library.umd.js"></script>
|
||||
```
|
||||
and use global `ng.myLibrary` namespace.
|
||||
|
||||
### AoT compilation
|
||||
The library is compatible with _AoT compilation_.
|
||||
|
||||
## <a name="8"></a>8 What it is important to know
|
||||
1. `package.json`
|
||||
|
||||
* `"main": "./bundles/angular-library-starter.umd.js"` legacy module format
|
||||
* `"module": "./bundles/angular-library-starter.es5.js"` flat _ES_ module, for using module bundlers such as _Rollup_ or _webpack_:
|
||||
[package module](https://github.com/rollup/rollup/wiki/pkg.module)
|
||||
* `"es2015": "./bundles/angular-library-starter.js"` _ES2015_ flat _ESM_ format, experimental _ES2015_ build
|
||||
* `"peerDependencies"` the packages and their versions required by the library when it will be installed
|
||||
|
||||
2. `tsconfig-build.json` file used by _ngc_ compiler
|
||||
|
||||
* Compiler options:
|
||||
* `"declaration": true` to emit _TypeScript_ declaration files
|
||||
* `"module": "es2015"` & `"target": "es2015"` are used by _Rollup_ to create the _ES2015_ bundle
|
||||
|
||||
* Angular Compiler Options:
|
||||
* `"skipTemplateCodegen": true,` skips generating _AoT_ files
|
||||
* `"annotateForClosureCompiler": true` for compatibility with _Google Closure compiler_
|
||||
* `"strictMetadataEmit": true` without emitting metadata files, the library will not compatible with _AoT compilation_
|
||||
|
||||
3. `rollup.config.js` file used by _Rollup_
|
||||
|
||||
* `format: 'umd'` the _Universal Module Definition_ pattern is used by _Angular_ for its bundles
|
||||
* `moduleName: 'ng.angularLibraryStarter'` defines the global namespace used by _JavaScript_ apps
|
||||
* `external` & `globals` declare the external packages
|
||||
|
||||
4. Server-side prerendering
|
||||
|
||||
If you want the library will be compatible with server-side prerendering:
|
||||
* `window`, `document`, `navigator` and other browser types do not exist on the server
|
||||
* don't manipulate the _nativeElement_ directly
|
||||
|
||||
## License
|
||||
MIT
|
||||
21
v10/LICENSE
21
v10/LICENSE
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Roberto Simonetti
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
278
v10/README.md
278
v10/README.md
@ -1,278 +0,0 @@
|
||||
[](https://travis-ci.org/orizens/ngx-infinite-scroll) [](#backers) [](#sponsors)
|
||||
[](https://badge.fury.io/js/ngx-infinite-scroll)
|
||||
[](https://badge.fury.io/js/ngx-infinite-scroll)
|
||||
[](https://img.shields.io/npm/dm/ngx-infinite-scroll.svg)
|
||||
[](https://img.shields.io/npm/dt/ngx-infinite-scroll.svg)
|
||||
|
||||
## [Consider Becoming a sponsor](https://opencollective.com/ngx-infinite-scroll#sponsor)
|
||||
|
||||
# Angular Infinite Scroll
|
||||
|
||||
versions now follow Angular's version to easily reflect compatibility.
|
||||
Meaning, for **Angular 10**, use `ngx-infinite-scroll @ ^10.0.0`
|
||||
|
||||
## Angular - Older Versions Support
|
||||
|
||||
Starting **Angular 6 and Above** - `ngx-infinite-scroll@THE_VERSION.0.0`
|
||||
For **Angular 4** and **Angular = ^5.5.6** - use version `ngx-infinite-scroll@0.8.4`
|
||||
For **Angular 5.x** with **rxjs =<5.5.2** - use version `ngx-infinite-scroll@0.8.3`
|
||||
For Angular version **<= 2.3.1**, you can use `npm i angular2-infinite-scroll` (latest version is 0.3.42) - please notice **the angular2-infinite-scroll** package is deprecated
|
||||
|
||||
## Used By
|
||||
|
||||
- [Google](https://google.com)
|
||||
- [Apple](https://apple.com)
|
||||
- [Amazon](https://amazon.com)
|
||||
- [Microsoft](https://microsoft.com)
|
||||
- [Disney](https://disney.com)
|
||||
- [Sap](https://sap.com/)
|
||||
- [Cisco](https://cisco.com/)
|
||||
- [Yandex](https://yandex.com)
|
||||
- [Ancestry](https://www.ancestry.com/)
|
||||
|
||||
and much more.
|
||||
|
||||
> _These analytics are made available via the awesome [Scarf](https://www.npmjs.com/package/@scarf/scarf) package analytics library_
|
||||
|
||||
### Opt-Out Of Scarf
|
||||
|
||||
Scarf can be disabled by following [these directions](https://github.com/orizens/ngx-infinite-scroll/issues/352#issuecomment-742009046)
|
||||
|
||||
## Front End Consulting Services
|
||||
|
||||
I'm a Senior Front End Engineer & Consultant at [Orizens](https://orizens.com).
|
||||
My services include:
|
||||
|
||||
- Angular/React/Javascript Consulting
|
||||
- Front End Architecture Consulting
|
||||
- Project Code Review
|
||||
- Project Development
|
||||
|
||||
[Contact Here](http://orizens.com/contact)
|
||||
|
||||
<a href="https://orizens.com" target="_blank">
|
||||
<img src="https://cloud.githubusercontent.com/assets/878660/23353771/d0adbd12-fcd6-11e6-96be-7a236f8819d9.png" alt="Webpack and Angular" width="20%"/>
|
||||
</a>
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install ngx-infinite-scroll --save
|
||||
```
|
||||
|
||||
## Supported API
|
||||
|
||||
### Properties
|
||||
|
||||
| @Input() | Type | Required | Default | Description |
|
||||
| ------------------------ | -------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| infiniteScrollDistance | number | optional | 2 | the bottom percentage point of the scroll nob relatively to the infinite-scroll container (i.e, 2 (2 \* 10 = 20%) is event is triggered when 80% (100% - 20%) has been scrolled). if container.height is 900px, when the container is scrolled to or past the 720px, it will fire the scrolled event. |
|
||||
| infiniteScrollUpDistance | number | optional | 1.5 | should get a number |
|
||||
| infiniteScrollThrottle | number | optional | 150 | should get a number of **milliseconds** for throttle. The event will be triggered this many milliseconds after the user _stops_ scrolling. |
|
||||
| scrollWindow | boolean | optional | true | listens to the window scroll instead of the actual element scroll. this allows to invoke a callback function in the scope of the element while listenning to the window scroll. |
|
||||
| immediateCheck | boolean | optional | false | invokes the handler immediately to check if a scroll event has been already triggred when the page has been loaded (i.e. - when you refresh a page that has been scrolled) |
|
||||
| infiniteScrollDisabled | boolean | optional | false | doesn't invoke the handler if set to true |
|
||||
| horizontal | boolean | optional | false | sets the scroll to listen for horizontal events |
|
||||
| alwaysCallback | boolean | optional | false | instructs the scroller to always trigger events |
|
||||
| infiniteScrollContainer | string / HTMLElement | optional | null | should get a html element or css selector for a scrollable element; window or current element will be used if this attribute is empty. |
|
||||
| fromRoot | boolean | optional | false | if **infiniteScrollContainer** is set, this instructs the scroller to query the container selector from the root of the **document** object. |
|
||||
|
||||
### Events
|
||||
|
||||
| @Output() | Type | Event Type | Required | Description |
|
||||
| ---------- | ------------ | -------------------- | -------- | ------------------------------------------------------------------------------- |
|
||||
| scrolled | EventEmitter | IInfiniteScrollEvent | optional | this will callback if the distance threshold has been reached on a scroll down. |
|
||||
| scrolledUp | EventEmitter | IInfiniteScrollEvent | optional | this will callback if the distance threshold has been reached on a scroll up. |
|
||||
|
||||
## Behavior
|
||||
|
||||
By default, the directive listens to the **window scroll** event and invoked the callback.
|
||||
**To trigger the callback when the actual element is scrolled**, these settings should be configured:
|
||||
|
||||
- [scrollWindow]="false"
|
||||
- set an explict css "height" value to the element
|
||||
|
||||
## DEMO
|
||||
|
||||
[Try the Demo in StackBlitz](https://stackblitz.com/edit/ngx-infinite-scroll)
|
||||
|
||||
## Usage
|
||||
|
||||
First, import the InfiniteScrollModule to your module:
|
||||
|
||||
```typescript
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { AppComponent } from './app';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule, InfiniteScrollModule],
|
||||
declarations: [AppComponent],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
```
|
||||
|
||||
In this example, the **onScroll** callback will be invoked when the window is scrolled down:
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
template: `
|
||||
<div
|
||||
class="search-results"
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
[infiniteScrollThrottle]="50"
|
||||
(scrolled)="onScroll()"
|
||||
></div>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {
|
||||
onScroll() {
|
||||
console.log('scrolled!!');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
in this example, whenever the "search-results" is scrolled, the callback will be invoked:
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
styles: [
|
||||
`
|
||||
.search-results {
|
||||
height: 20rem;
|
||||
overflow: scroll;
|
||||
}
|
||||
`,
|
||||
],
|
||||
template: `
|
||||
<div
|
||||
class="search-results"
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
[infiniteScrollThrottle]="50"
|
||||
(scrolled)="onScroll()"
|
||||
[scrollWindow]="false"
|
||||
></div>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {
|
||||
onScroll() {
|
||||
console.log('scrolled!!');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the **onScrollDown** callback will be invoked when the window is scrolled down and the **onScrollUp** callback will be invoked when the window is scrolled up:
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
import { InfiniteScroll } from 'ngx-infinite-scroll';
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
directives: [InfiniteScroll],
|
||||
template: `
|
||||
<div
|
||||
class="search-results"
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
[infiniteScrollUpDistance]="1.5"
|
||||
[infiniteScrollThrottle]="50"
|
||||
(scrolled)="onScrollDown()"
|
||||
(scrolledUp)="onScrollUp()"
|
||||
></div>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {
|
||||
onScrollDown() {
|
||||
console.log('scrolled down!!');
|
||||
}
|
||||
|
||||
onScrollUp() {
|
||||
console.log('scrolled up!!');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the **infiniteScrollContainer** attribute is used to point directive to the scrollable container using a css selector. **fromRoot** is used to determine whether the scroll container has to be searched within the whole document (`[fromRoot]="true"`) or just inside the **infiniteScroll** directive (`[fromRoot]="false"`, default option).
|
||||
|
||||
```typescript
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app',
|
||||
styles: [
|
||||
`
|
||||
.main-panel {
|
||||
height: 100px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
`,
|
||||
],
|
||||
template: `
|
||||
<div class="main-panel">
|
||||
<div
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
[infiniteScrollThrottle]="50"
|
||||
[infiniteScrollContainer]="selector"
|
||||
[fromRoot]="true"
|
||||
(scrolled)="onScroll()"
|
||||
></div>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class AppComponent {
|
||||
selector: string = '.main-panel';
|
||||
|
||||
onScroll() {
|
||||
console.log('scrolled!!');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It is also possible to use **infiniteScrollContainer** without additional variable by using single quotes inside double quotes:
|
||||
|
||||
```
|
||||
[infiniteScrollContainer]="'.main-panel'"
|
||||
```
|
||||
|
||||
# Showcase Examples
|
||||
|
||||
- [Echoes Player - Developed with Angular, angular-cli and ngrx](http://orizens.github.io/echoes-player) ([github repo for echoes player](http://github.com/orizens/echoes-player))
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
<a href="graphs/contributors"><img src="https://opencollective.com/ngx-infinite-scroll/contributors.svg?width=890" /></a>
|
||||
|
||||
## Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/ngx-infinite-scroll#backer)]
|
||||
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll#backers" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/backers.svg?width=890"></a>
|
||||
|
||||
## Sponsors
|
||||
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ngx-infinite-scroll/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ngx-infinite-scroll/sponsor/9/avatar.svg"></a>
|
||||
61
v10/build.js
61
v10/build.js
@ -1,61 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
require('shelljs/global');
|
||||
const chalk = require('chalk');
|
||||
|
||||
const PACKAGE = `ngx-infinite-scroll`;
|
||||
const NPM_DIR = `dist`;
|
||||
const MODULES_DIR = `${NPM_DIR}/modules`;
|
||||
const BUNDLES_DIR = `${NPM_DIR}/bundles`;
|
||||
|
||||
echo('Start building...');
|
||||
|
||||
rm(`-Rf`, `${NPM_DIR}/*`);
|
||||
mkdir(`-p`, `./${MODULES_DIR}`);
|
||||
mkdir(`-p`, `./${BUNDLES_DIR}`);
|
||||
|
||||
/* TSLint with Codelyzer */
|
||||
// https://github.com/palantir/tslint/blob/master/src/configs/recommended.ts
|
||||
// https://github.com/mgechev/codelyzer
|
||||
echo(`Start TSLint`);
|
||||
exec(`tslint --project ./tsconfig.json --type-check ./src/**/*.ts`);
|
||||
echo(chalk.green(`TSLint completed`));
|
||||
|
||||
/* Aot compilation: ES2015 sources */
|
||||
echo(`Start AoT compilation`);
|
||||
exec(`ngc -p tsconfig-build.json`);
|
||||
echo(chalk.green(`AoT compilation completed`));
|
||||
|
||||
/* Creates bundles: ESM/ES5 and UMD bundles */
|
||||
echo(`Start bundling`);
|
||||
echo(`Rollup package`);
|
||||
exec(`rollup -i ${NPM_DIR}/${PACKAGE}.js -o ${MODULES_DIR}/${PACKAGE}.js --sourcemap`, {silent: true});
|
||||
exec(`node scripts/map-sources -f ${MODULES_DIR}/${PACKAGE}.js`);
|
||||
|
||||
echo(`Downleveling ES2015 to ESM/ES5`);
|
||||
cp(`${MODULES_DIR}/${PACKAGE}.js`, `${MODULES_DIR}/${PACKAGE}.es5.ts`);
|
||||
exec(`tsc ${MODULES_DIR}/${PACKAGE}.es5.ts --target es5 --module es2015 --noLib --sourceMap`, {silent: true});
|
||||
exec(`node scripts/map-sources -f ${MODULES_DIR}/${PACKAGE}.es5.js`);
|
||||
rm(`-f`, `${MODULES_DIR}/${PACKAGE}.es5.ts`);
|
||||
|
||||
echo(`Run Rollup conversion on package`);
|
||||
exec(`rollup -c rollup.config.js --sourcemap`, {silent: true});
|
||||
exec(`node scripts/map-sources -f ${BUNDLES_DIR}/${PACKAGE}.umd.js`);
|
||||
|
||||
echo(`Minifying`);
|
||||
cd(`${BUNDLES_DIR}`);
|
||||
exec(`uglifyjs -c --screw-ie8 --comments -o ${PACKAGE}.umd.min.js --source-map ${PACKAGE}.umd.min.js.map --source-map-include-sources ${PACKAGE}.umd.js`, {silent: true});
|
||||
exec(`node ../../scripts/map-sources -f ${PACKAGE}.umd.min.js`);
|
||||
cd(`..`);
|
||||
cd(`..`);
|
||||
|
||||
echo(chalk.green(`Bundling completed`));
|
||||
|
||||
rm(`-Rf`, `${NPM_DIR}/*.js`);
|
||||
rm(`-Rf`, `${NPM_DIR}/*.js.map`);
|
||||
rm(`-Rf`, `${NPM_DIR}/src/**/*.js`);
|
||||
rm(`-Rf`, `${NPM_DIR}/src/**/*.js.map`);
|
||||
|
||||
cp(`-Rf`, [`package.json`, `LICENSE`, `README.md`], `${NPM_DIR}`);
|
||||
|
||||
echo(chalk.green(`End building`));
|
||||
@ -1,13 +0,0 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
42
v10/examples/.gitignore
vendored
42
v10/examples/.gitignore
vendored
@ -1,42 +0,0 @@
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# e2e
|
||||
/e2e/*.js
|
||||
/e2e/*.map
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@ -1,27 +0,0 @@
|
||||
# NgxExamples
|
||||
|
||||
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.6.1.
|
||||
|
||||
## Development server
|
||||
|
||||
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
||||
|
||||
## Code scaffolding
|
||||
|
||||
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
|
||||
|
||||
## Build
|
||||
|
||||
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
||||
|
||||
## Running end-to-end tests
|
||||
|
||||
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
||||
|
||||
## Further help
|
||||
|
||||
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
||||
@ -1,142 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"ngx-examples": {
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"aot": true,
|
||||
"outputPath": "dist/example",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "6kb"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"browserTarget": "ngx-examples:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"browserTarget": "ngx-examples:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"browserTarget": "ngx-examples:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"karmaConfig": "./karma.conf.js",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"scripts": [],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ngx-examples-e2e": {
|
||||
"root": "",
|
||||
"sourceRoot": "",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "ngx-examples:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultProject": "ngx-examples",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "app",
|
||||
"style": "css"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
// import { AppPage } from './app.po';
|
||||
|
||||
// describe('ngx-examples App', () => {
|
||||
// let page: AppPage;
|
||||
|
||||
// beforeEach(() => {
|
||||
// page = new AppPage();
|
||||
// });
|
||||
|
||||
// it('should display welcome message', () => {
|
||||
// page.navigateTo();
|
||||
// expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||
// });
|
||||
// });
|
||||
@ -1,11 +0,0 @@
|
||||
import { browser, by, element } from 'protractor';
|
||||
|
||||
export class AppPage {
|
||||
navigateTo() {
|
||||
return browser.get('/');
|
||||
}
|
||||
|
||||
getParagraphText() {
|
||||
return element(by.css('app-root h1')).getText();
|
||||
}
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"jasminewd2",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
// Karma configuration file, see link for more information
|
||||
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
basePath: '',
|
||||
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-jasmine-html-reporter'),
|
||||
require('karma-coverage-istanbul-reporter'),
|
||||
require('@angular-devkit/build-angular/plugins/karma')
|
||||
],
|
||||
client:{
|
||||
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
|
||||
fixWebpackSourcePaths: true
|
||||
},
|
||||
angularCli: {
|
||||
environment: 'dev'
|
||||
},
|
||||
reporters: ['progress', 'kjhtml'],
|
||||
port: 9876,
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
browsers: ['Chrome'],
|
||||
singleRun: false
|
||||
});
|
||||
};
|
||||
@ -1,50 +0,0 @@
|
||||
{
|
||||
"name": "ngx-examples",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build --prod",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^10.1.6",
|
||||
"@angular/common": "^10.1.6",
|
||||
"@angular/compiler": "^10.1.6",
|
||||
"@angular/core": "^10.1.6",
|
||||
"@angular/forms": "^10.1.6",
|
||||
"@angular/platform-browser": "^10.1.6",
|
||||
"@angular/platform-browser-dynamic": "^10.1.6",
|
||||
"@angular/router": "^10.1.6",
|
||||
"core-js": "^2.4.1",
|
||||
"rxjs": "^6.6.3",
|
||||
"tslib": "^2.0.0",
|
||||
"zone.js": "~0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1001.7",
|
||||
"@angular/cli": "^10.1.6",
|
||||
"@angular/compiler-cli": "^10.1.6",
|
||||
"@angular/language-service": "^10.1.6",
|
||||
"@types/jasmine": "~2.5.53",
|
||||
"@types/jasminewd2": "~2.0.2",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^5.1.2",
|
||||
"jasmine-core": "~3.5.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "~5.0.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-cli": "~1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~3.2.0",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "^3.1.1"
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
// Protractor configuration file, see link for more information
|
||||
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||
|
||||
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||
|
||||
exports.config = {
|
||||
allScriptsTimeout: 11000,
|
||||
specs: [
|
||||
'./e2e/**/*.e2e-spec.ts'
|
||||
],
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:4200/',
|
||||
framework: 'jasmine',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000,
|
||||
print: function() {}
|
||||
},
|
||||
onPrepare() {
|
||||
require('ts-node').register({
|
||||
project: 'e2e/tsconfig.e2e.json'
|
||||
});
|
||||
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||
}
|
||||
};
|
||||
@ -1,74 +0,0 @@
|
||||
.search-results {
|
||||
height: 100%;
|
||||
}
|
||||
.title {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
width: 100%;
|
||||
}
|
||||
.title small {
|
||||
color: #eaeaea;
|
||||
}
|
||||
.fixed {
|
||||
height: 300px;
|
||||
width: 200px;
|
||||
overflow: scroll;
|
||||
display: block;
|
||||
position: fixed;
|
||||
transition: width 0.3s ease-out;
|
||||
}
|
||||
.fixed:hover {
|
||||
width: 350px;
|
||||
}
|
||||
.fixed .info {
|
||||
position: fixed;
|
||||
}
|
||||
.first {
|
||||
top: 0;
|
||||
right: 20px;
|
||||
background-color: tomato;
|
||||
}
|
||||
.second {
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
background-color: lime;
|
||||
}
|
||||
.dummy {
|
||||
bottom: 0;
|
||||
right: 200px;
|
||||
background-color: crimson;
|
||||
}
|
||||
.third {
|
||||
bottom: 0;
|
||||
right: 400px;
|
||||
background-color: darkslategrey;
|
||||
}
|
||||
|
||||
.with-error {
|
||||
top: 0;
|
||||
right: 220px;
|
||||
background-color: gray;
|
||||
}
|
||||
.inner {
|
||||
bottom: 0;
|
||||
right: 600px;
|
||||
background-color: goldenrod;
|
||||
}
|
||||
|
||||
.test1 {
|
||||
height: 300px;
|
||||
overflow: auto;
|
||||
width: 500px;
|
||||
}
|
||||
/* .test2 .content {
|
||||
display: flex;
|
||||
} */
|
||||
.modal-body {
|
||||
/* max-height: 200px; */
|
||||
height: 200px;
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
<!--The content below is only a placeholder and can be replaced.-->
|
||||
<test-inner className="fixed inner" [scrollWindow]="false" [selector]="'.content'" [fromRoot]="false" [info]="'selector inside: .content'">
|
||||
</test-inner>
|
||||
@ -1,27 +0,0 @@
|
||||
// import { TestBed, async } from '@angular/core/testing';
|
||||
// import { AppComponent } from './app.component';
|
||||
// describe('AppComponent', () => {
|
||||
// beforeEach(async(() => {
|
||||
// TestBed.configureTestingModule({
|
||||
// declarations: [
|
||||
// AppComponent
|
||||
// ],
|
||||
// }).compileComponents();
|
||||
// }));
|
||||
// it('should create the app', async(() => {
|
||||
// const fixture = TestBed.createComponent(AppComponent);
|
||||
// const app = fixture.debugElement.componentInstance;
|
||||
// expect(app).toBeTruthy();
|
||||
// }));
|
||||
// it(`should have as title 'app'`, async(() => {
|
||||
// const fixture = TestBed.createComponent(AppComponent);
|
||||
// const app = fixture.debugElement.componentInstance;
|
||||
// expect(app.title).toEqual('app');
|
||||
// }));
|
||||
// it('should render title in a h1 tag', async(() => {
|
||||
// const fixture = TestBed.createComponent(AppComponent);
|
||||
// fixture.detectChanges();
|
||||
// const compiled = fixture.debugElement.nativeElement;
|
||||
// expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||
// }));
|
||||
// });
|
||||
@ -1,71 +0,0 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { ListService } from "./list.service";
|
||||
import { ViewEncapsulation } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: "app-root",
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
providers: [ListService],
|
||||
// templateUrl: './app.component.html',
|
||||
// <test-inner className="inner test1"
|
||||
// [scrollWindow]="false"
|
||||
// [fromRoot]="false"
|
||||
// >
|
||||
// </test-inner>
|
||||
// <test-inner
|
||||
// [scrollWindow]="false"
|
||||
// className="inner test1"
|
||||
// ></test-inner>
|
||||
template: `
|
||||
|
||||
<test-inner
|
||||
className="inner test1"
|
||||
[scrollWindow]="false"
|
||||
></test-inner>
|
||||
|
||||
`,
|
||||
styleUrls: ["./app.component.css"]
|
||||
})
|
||||
export class AppComponent {
|
||||
title = "app";
|
||||
modalScrollDistance = 2;
|
||||
modalScrollDistanceUp = 3;
|
||||
modalScrollThrottle = 50;
|
||||
modalBody = [modalText];
|
||||
selector = null;
|
||||
|
||||
txt = modalText + modalText;
|
||||
array = [];
|
||||
|
||||
onModalScrollDown() {
|
||||
console.log("-> DOWN");
|
||||
this.modalBody = this.modalBody.concat(modalText);
|
||||
}
|
||||
|
||||
onScrollDown(ev) {
|
||||
this.array.push(modalText[0]);
|
||||
}
|
||||
|
||||
onScrollUp(ev) {
|
||||
console.log("=> UP");
|
||||
this.modalBody = [].concat(modalText, this.modalBody.concat());
|
||||
}
|
||||
}
|
||||
|
||||
const modalText = `Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
|
||||
|
||||
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
|
||||
|
||||
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.
|
||||
|
||||
Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
|
||||
|
||||
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
|
||||
|
||||
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.
|
||||
|
||||
Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
|
||||
|
||||
Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.
|
||||
|
||||
Aenean lacinia bibendum nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla.`;
|
||||
@ -1,24 +0,0 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { TestInnerComponent } from './test.inner';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
TestInnerComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
InfiniteScrollModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
@ -1,58 +0,0 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ListService {
|
||||
array = [];
|
||||
|
||||
sum = 40;
|
||||
direction = "";
|
||||
|
||||
constructor() {
|
||||
this.appendItems(0, this.sum);
|
||||
}
|
||||
|
||||
addItems(startIndex, endIndex, arrMethod) {
|
||||
// this._array = this._array.concat()
|
||||
// [;...Array(this.sum);].map((el, i) => {
|
||||
// this._array[arrMethod]([i, ' ', this.generateWord()].join(''));
|
||||
// });
|
||||
// this._array = this._array.slice();
|
||||
}
|
||||
|
||||
appendItems(startIndex, endIndex) {
|
||||
this.array = this.array.concat(
|
||||
Array(endIndex)
|
||||
.fill(0)
|
||||
.map((el, i) => `${i} -> ${this.generateWord()}`)
|
||||
);
|
||||
// this.addItems(startIndex, endIndex, 'push');
|
||||
}
|
||||
|
||||
prependItems(startIndex, endIndex) {
|
||||
this.array = Array(endIndex)
|
||||
.fill(0)
|
||||
.map((el, i) => `${i} -> ${this.generateWord()}`)
|
||||
.concat(this.array.concat());
|
||||
// this.addItems(startIndex, endIndex, 'unshift');
|
||||
}
|
||||
|
||||
setDirectionDown() {
|
||||
const start = this.sum;
|
||||
this.sum += 10;
|
||||
this.appendItems(start, this.sum);
|
||||
this.direction = "down";
|
||||
}
|
||||
|
||||
setDirectionUp() {
|
||||
const start = this.sum;
|
||||
this.sum += 10;
|
||||
this.prependItems(start, this.sum);
|
||||
this.direction = "up";
|
||||
}
|
||||
|
||||
generateWord() {
|
||||
return window["chance"].word();
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
|
||||
import { ListService } from "./list.service";
|
||||
|
||||
// our root app component
|
||||
@Component({
|
||||
selector: "test-inner",
|
||||
providers: [ListService],
|
||||
template: `
|
||||
<div class="{{className}}"
|
||||
[scrollWindow]="scrollWindow"
|
||||
infiniteScroll
|
||||
[infiniteScrollContainer]="selector"
|
||||
[fromRoot]="fromRoot"
|
||||
[infiniteScrollDistance]="scrollDistance"
|
||||
[infiniteScrollUpDistance]="scrollUpDistance"
|
||||
[infiniteScrollThrottle]="throttle"
|
||||
(scrolled)="onScrollDown()"
|
||||
(scrolledUp)="onUp()"
|
||||
>
|
||||
<section class="content">
|
||||
<div *ngFor="let i of array()">
|
||||
{{ i }}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class TestInnerComponent {
|
||||
@Input() scrollWindow = true;
|
||||
@Input() className = "";
|
||||
@Input() selector = null;
|
||||
@Input() fromRoot = false;
|
||||
@Input() info = "";
|
||||
|
||||
throttle = 300;
|
||||
scrollDistance = 2;
|
||||
scrollUpDistance = 2;
|
||||
|
||||
constructor(public listMaker: ListService) {}
|
||||
|
||||
array() {
|
||||
return this.listMaker.array;
|
||||
}
|
||||
onScrollDown(ev?: any) {
|
||||
// setTimeout(() => {
|
||||
console.log(`scrolled down, from ${this.className} ${this.info}`);
|
||||
this.listMaker.setDirectionDown();
|
||||
// }, 3000);
|
||||
}
|
||||
|
||||
onUp(ev?:any) {
|
||||
// setTimeout(() => {
|
||||
console.log(`scrolled up, from ${this.className} ${this.info}`);
|
||||
this.listMaker.setDirectionUp();
|
||||
// }, 3000);
|
||||
}
|
||||
|
||||
generateWord() {
|
||||
return window["chance"].word();
|
||||
}
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
};
|
||||
@ -1,8 +0,0 @@
|
||||
// The file contents for the current environment will overwrite these during build.
|
||||
// The build system defaults to the dev environment which uses `environment.ts`, but if you do
|
||||
// `ng build --env=prod` then `environment.prod.ts` will be used instead.
|
||||
// The list of which env maps to which file can be found in `.angular-cli.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB |
@ -1,19 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>NgxExamples</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chance/1.0.4/chance.min.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -1,12 +0,0 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.log(err));
|
||||
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||
* You can add your own extra polyfills to this file.
|
||||
*
|
||||
* This file is divided into 2 sections:
|
||||
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||
* file.
|
||||
*
|
||||
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||
*
|
||||
* Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
* BROWSER POLYFILLS
|
||||
*/
|
||||
|
||||
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
|
||||
// import 'core-js/es6/symbol';
|
||||
// import 'core-js/es6/object';
|
||||
// import 'core-js/es6/function';
|
||||
// import 'core-js/es6/parse-int';
|
||||
// import 'core-js/es6/parse-float';
|
||||
// import 'core-js/es6/number';
|
||||
// import 'core-js/es6/math';
|
||||
// import 'core-js/es6/string';
|
||||
// import 'core-js/es6/date';
|
||||
// import 'core-js/es6/array';
|
||||
// import 'core-js/es6/regexp';
|
||||
// import 'core-js/es6/map';
|
||||
// import 'core-js/es6/weak-map';
|
||||
// import 'core-js/es6/set';
|
||||
|
||||
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
|
||||
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||
|
||||
/** IE10 and IE11 requires the following for the Reflect API. */
|
||||
// import 'core-js/es6/reflect';
|
||||
|
||||
|
||||
/** Evergreen browsers require these. **/
|
||||
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
|
||||
import 'core-js/es7/reflect';
|
||||
|
||||
|
||||
/**
|
||||
* Required to support Web Animations `@angular/platform-browser/animations`.
|
||||
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
|
||||
**/
|
||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* APPLICATION IMPORTS
|
||||
*/
|
||||
@ -1 +0,0 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
@ -1,32 +0,0 @@
|
||||
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||
|
||||
import 'zone.js/dist/long-stack-trace-zone';
|
||||
import 'zone.js/dist/proxy.js';
|
||||
import 'zone.js/dist/sync-test';
|
||||
import 'zone.js/dist/jasmine-patch';
|
||||
import 'zone.js/dist/async-test';
|
||||
import 'zone.js/dist/fake-async-test';
|
||||
import { getTestBed } from '@angular/core/testing';
|
||||
import {
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting
|
||||
} from '@angular/platform-browser-dynamic/testing';
|
||||
|
||||
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
|
||||
declare const __karma__: any;
|
||||
declare const require: any;
|
||||
|
||||
// Prevent Karma from running prematurely.
|
||||
__karma__.loaded = function () {};
|
||||
|
||||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
// And load the modules.
|
||||
context.keys().map(context);
|
||||
// Finally, start Karma to run the tests.
|
||||
__karma__.start();
|
||||
@ -1,15 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"baseUrl": "./",
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"main.ts",
|
||||
"polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"baseUrl": "./",
|
||||
"target": "es5",
|
||||
"types": ["jasmine", "node"]
|
||||
},
|
||||
"files": ["test.ts", "polyfills.ts"],
|
||||
"include": ["**/*.spec.ts", "**/*.d.ts"]
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"module": "esnext",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
],
|
||||
"paths": {
|
||||
"ngx-infinite-scroll": ["../../public-api.ts"],
|
||||
"@angular/*": [ "../node_modules/@angular/*" ]
|
||||
},
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true
|
||||
}
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
{
|
||||
"rulesDirectory": [
|
||||
"node_modules/codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"arrow-return-shorthand": true,
|
||||
"callable-types": true,
|
||||
"class-name": true,
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": true,
|
||||
"deprecation": {
|
||||
"severity": "warn"
|
||||
},
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"import-spacing": true,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces"
|
||||
],
|
||||
"interface-over-type-literal": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-super": true,
|
||||
"no-empty": false,
|
||||
"no-empty-interface": true,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-misused-new": true,
|
||||
"no-non-null-assertion": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": false,
|
||||
"no-string-throw": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unnecessary-initializer": true,
|
||||
"no-unused-expression": true,
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"prefer-const": true,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}
|
||||
],
|
||||
"typeof-compare": true,
|
||||
"unified-signatures": true,
|
||||
"variable-name": false,
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
],
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"app",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"app",
|
||||
"kebab-case"
|
||||
],
|
||||
"no-output-on-prefix": true,
|
||||
"use-input-property-decorator": true,
|
||||
"use-output-property-decorator": true,
|
||||
"use-host-property-decorator": true,
|
||||
"no-input-rename": true,
|
||||
"no-output-rename": true,
|
||||
"use-life-cycle-interface": true,
|
||||
"use-pipe-transform-interface": true,
|
||||
"component-class-suffix": true,
|
||||
"directive-class-suffix": true
|
||||
}
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
// Karma configuration for Unit testing
|
||||
const puppeteer = require('puppeteer');
|
||||
process.env.CHROME_BIN = puppeteer.executablePath();
|
||||
|
||||
module.exports = function(config) {
|
||||
var configuration = {
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-webpack'),
|
||||
require('karma-sourcemap-loader'),
|
||||
require('karma-spec-reporter')
|
||||
],
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [{ pattern: 'spec.bundle.js', watched: false }],
|
||||
|
||||
// list of files to exclude
|
||||
exclude: [],
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
preprocessors: {
|
||||
'spec.bundle.js': ['webpack']
|
||||
},
|
||||
|
||||
// webpack
|
||||
webpack: {
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js']
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts/,
|
||||
loaders: ['ts-loader'],
|
||||
exclude: /node_modules/
|
||||
}
|
||||
],
|
||||
exprContextCritical: false
|
||||
},
|
||||
performance: { hints: false }
|
||||
},
|
||||
|
||||
webpackServer: {
|
||||
noInfo: true
|
||||
},
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
reporters: ['spec'],
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
||||
browsers: ['ChromeHeadlessNoSandbox'],
|
||||
customLaunchers: {
|
||||
ChromeHeadlessNoSandbox: {
|
||||
base: 'ChromeHeadless',
|
||||
flags: ['--no-sandbox']
|
||||
}
|
||||
},
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
singleRun: true
|
||||
};
|
||||
|
||||
config.set(configuration);
|
||||
};
|
||||
@ -1 +0,0 @@
|
||||
export * from './public-api';
|
||||
@ -1,87 +0,0 @@
|
||||
{
|
||||
"name": "ngx-infinite-scroll",
|
||||
"version": "10.0.1",
|
||||
"description": "An infinite scroll directive for Angular",
|
||||
"main": "./bundles/ngx-infinite-scroll.umd.js",
|
||||
"module": "./modules/ngx-infinite-scroll.es5.js",
|
||||
"es2015": "./modules/ngx-infinite-scroll.js",
|
||||
"scripts": {
|
||||
"build": "node build.js",
|
||||
"test": "karma start",
|
||||
"test:watch": "karma start --single-run=false",
|
||||
"pack-lib": "npm pack ./dist",
|
||||
"publish-lib": "npm publish ./dist",
|
||||
"publish:beta": "npm publish --tag next ./dist",
|
||||
"compodoc": "compodoc -p tsconfig.json",
|
||||
"compodoc:publish": "node scripts/gh-pages",
|
||||
"compodoc-serve": "compodoc -s",
|
||||
"transpile": "ngc -p ./tsconfig.json",
|
||||
"serve:prod": "npm run build && lite-server -c ./example/bs-config.json",
|
||||
"postinstall": "opencollective-postinstall || exit 0"
|
||||
},
|
||||
"typings": "./ngx-infinite-scroll.d.ts",
|
||||
"author": "Oren Farhi (orizens.com)",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/orizens/ngx-infinite-scroll.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/orizens/ngx-infinite-scroll/issues"
|
||||
},
|
||||
"homepage": "https://github.com/orizens/ngx-infinite-scroll",
|
||||
"keywords": [
|
||||
"angular",
|
||||
"javascript",
|
||||
"typescript"
|
||||
],
|
||||
"license": "MIT",
|
||||
"peerDependencies": {},
|
||||
"devDependencies": {
|
||||
"@angular/animations": "^10.1.6",
|
||||
"@angular/common": "^10.1.6",
|
||||
"@angular/compiler": "^10.1.6",
|
||||
"@angular/compiler-cli": "^10.1.6",
|
||||
"@angular/core": "^10.1.6",
|
||||
"@angular/platform-browser": "^10.1.6",
|
||||
"@angular/platform-browser-dynamic": "^10.1.6",
|
||||
"@angular/platform-server": "^10.1.6",
|
||||
"@compodoc/compodoc": "^1.1.2",
|
||||
"@types/jasmine": "3.3.9",
|
||||
"@types/node": "7.0.10",
|
||||
"chalk": "1.1.3",
|
||||
"codelyzer": "^6.0.1",
|
||||
"core-js": "2.4.1",
|
||||
"gh-pages": "3.1.0",
|
||||
"jasmine-core": "2.5.2",
|
||||
"karma": "1.5.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-jasmine": "1.1.0",
|
||||
"karma-sourcemap-loader": "0.3.7",
|
||||
"karma-spec-reporter": "0.0.30",
|
||||
"karma-webpack": "3.0.5",
|
||||
"puppeteer": "1.13.0",
|
||||
"reflect-metadata": "0.1.10",
|
||||
"rollup": "0.41.6",
|
||||
"rxjs": "^6.6.3",
|
||||
"shelljs": "0.7.7",
|
||||
"sorcery": "0.10.0",
|
||||
"ts-helpers": "1.1.2",
|
||||
"ts-loader": "2.0.3",
|
||||
"tsickle": "^0.39.1",
|
||||
"tslint": "~6.1.0",
|
||||
"typescript": "4.0.3",
|
||||
"uglify-js": "^2.8.15",
|
||||
"webpack": "2.3.1",
|
||||
"yargs": "7.0.2",
|
||||
"zone.js": "0.10.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@scarf/scarf": "^1.1.0",
|
||||
"opencollective-postinstall": "^2.0.2"
|
||||
},
|
||||
"collective": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ngx-infinite-scroll",
|
||||
"logo": "https://opencollective.com/ngx-infinite-scroll/logo.txt"
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
/**
|
||||
* Angular library starter.
|
||||
* Build an Angular library compatible with AoT compilation & Tree shaking.
|
||||
* Written by Roberto Simonetti.
|
||||
* MIT license.
|
||||
* https://github.com/robisim74/angular-library-starter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Entry point for all public APIs of the package.
|
||||
*/
|
||||
export * from './src/ngx-infinite-scroll';
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
export default {
|
||||
entry: './dist/modules/ngx-infinite-scroll.es5.js',
|
||||
dest: './dist/bundles/ngx-infinite-scroll.umd.js',
|
||||
format: 'umd',
|
||||
exports: 'named',
|
||||
moduleName: 'ng.ngxInfiniteScroll',
|
||||
external: [
|
||||
'@angular/core',
|
||||
'@angular/common',
|
||||
'rxjs/Observable',
|
||||
'rxjs/Observer'
|
||||
],
|
||||
globals: {
|
||||
'@angular/core': 'ng.core',
|
||||
'@angular/common': 'ng.common',
|
||||
'rxjs/Observable': 'Rx',
|
||||
'rxjs/Observer': 'Rx'
|
||||
},
|
||||
onwarn: () => { return }
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
const ghpages = require('gh-pages');
|
||||
|
||||
ghpages.publish('documentation', function (err) {
|
||||
console.log('error in publishing to Github Pages:', err);
|
||||
});
|
||||
@ -1,9 +0,0 @@
|
||||
const sorcery = require('sorcery');
|
||||
|
||||
var argv = require('yargs')
|
||||
.alias('f', 'file')
|
||||
.argv;
|
||||
|
||||
sorcery.load(argv.file).then(function(chain) {
|
||||
chain.write();
|
||||
});
|
||||
@ -1,28 +0,0 @@
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
require('core-js');
|
||||
require('ts-helpers');
|
||||
require('zone.js/dist/zone');
|
||||
require('zone.js/dist/long-stack-trace-zone');
|
||||
require('zone.js/dist/proxy');
|
||||
require('zone.js/dist/sync-test');
|
||||
require('zone.js/dist/jasmine-patch');
|
||||
require('zone.js/dist/async-test');
|
||||
require('zone.js/dist/fake-async-test');
|
||||
require('rxjs');
|
||||
|
||||
var testing = require('@angular/core/testing');
|
||||
var browser = require('@angular/platform-browser-dynamic/testing');
|
||||
|
||||
testing.TestBed.initTestEnvironment(
|
||||
browser.BrowserDynamicTestingModule,
|
||||
browser.platformBrowserDynamicTesting()
|
||||
);
|
||||
|
||||
var testContext = require.context('./tests', true, /\.spec\.ts/);
|
||||
|
||||
function requireAll(requireContext) {
|
||||
return requireContext.keys().map(requireContext);
|
||||
}
|
||||
|
||||
var modules = requireAll(testContext);
|
||||
@ -1,65 +0,0 @@
|
||||
import { ElementRef } from '@angular/core';
|
||||
|
||||
export type ContainerRef = Window | ElementRef | any;
|
||||
|
||||
export interface IInfiniteScrollEvent {
|
||||
currentScrollPosition: number;
|
||||
}
|
||||
|
||||
export interface IPositionElements {
|
||||
windowElement: ContainerRef;
|
||||
axis: any;
|
||||
}
|
||||
|
||||
export interface IPositionStats {
|
||||
height: number;
|
||||
scrolled: number;
|
||||
totalToScroll: number;
|
||||
isWindow?: boolean;
|
||||
}
|
||||
export interface IScrollerDistance {
|
||||
down?: number;
|
||||
up?: number;
|
||||
}
|
||||
|
||||
export interface IScrollState {
|
||||
lastTotalToScroll: number;
|
||||
totalToScroll: number;
|
||||
triggered: IScrollerDistance;
|
||||
lastScrollPosition: number;
|
||||
}
|
||||
|
||||
export interface IResolver {
|
||||
container: ContainerRef;
|
||||
isWindow: boolean;
|
||||
axis: any;
|
||||
}
|
||||
|
||||
export interface IScrollRegisterConfig {
|
||||
container: ContainerRef;
|
||||
throttle: number;
|
||||
}
|
||||
|
||||
export interface IScroller {
|
||||
fromRoot: boolean;
|
||||
horizontal: boolean;
|
||||
disable: boolean;
|
||||
throttle: number;
|
||||
scrollWindow: boolean;
|
||||
element: ElementRef;
|
||||
scrollContainer: string | ElementRef;
|
||||
alwaysCallback: boolean;
|
||||
downDistance: number;
|
||||
upDistance: number;
|
||||
}
|
||||
|
||||
export interface IScrollParams {
|
||||
scrollDown: boolean;
|
||||
fire: boolean;
|
||||
stats: IPositionStats;
|
||||
}
|
||||
|
||||
export interface IInfiniteScrollAction {
|
||||
type: string;
|
||||
payload: IInfiniteScrollEvent;
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Directive,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
Input,
|
||||
NgZone,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
Output,
|
||||
SimpleChanges
|
||||
} from '@angular/core';
|
||||
import {Subscription} from 'rxjs';
|
||||
|
||||
import { IInfiniteScrollEvent, IInfiniteScrollAction } from '../models';
|
||||
import { hasWindowDefined, inputPropChanged } from '../services/ngx-ins-utils';
|
||||
import { createScroller, InfiniteScrollActions } from '../services/scroll-register';
|
||||
|
||||
@Directive({
|
||||
selector: '[infiniteScroll], [infinite-scroll], [data-infinite-scroll]'
|
||||
})
|
||||
export class InfiniteScrollDirective
|
||||
implements OnDestroy, OnChanges, AfterViewInit {
|
||||
@Output() scrolled = new EventEmitter<IInfiniteScrollEvent>();
|
||||
@Output() scrolledUp = new EventEmitter<IInfiniteScrollEvent>();
|
||||
|
||||
@Input() infiniteScrollDistance: number = 2;
|
||||
@Input() infiniteScrollUpDistance: number = 1.5;
|
||||
@Input() infiniteScrollThrottle: number = 150;
|
||||
@Input() infiniteScrollDisabled: boolean = false;
|
||||
@Input() infiniteScrollContainer: any = null;
|
||||
@Input() scrollWindow: boolean = true;
|
||||
@Input() immediateCheck: boolean = false;
|
||||
@Input() horizontal: boolean = false;
|
||||
@Input() alwaysCallback: boolean = false;
|
||||
@Input() fromRoot: boolean = false;
|
||||
|
||||
private disposeScroller: Subscription;
|
||||
|
||||
constructor(private element: ElementRef, private zone: NgZone) { }
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (!this.infiniteScrollDisabled) {
|
||||
this.setup();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges({ infiniteScrollContainer, infiniteScrollDisabled, infiniteScrollDistance }: SimpleChanges) {
|
||||
const containerChanged = inputPropChanged(infiniteScrollContainer);
|
||||
const disabledChanged = inputPropChanged(infiniteScrollDisabled);
|
||||
const distanceChanged = inputPropChanged(infiniteScrollDistance);
|
||||
const shouldSetup = (!disabledChanged && !this.infiniteScrollDisabled) ||
|
||||
(disabledChanged && !infiniteScrollDisabled.currentValue) || distanceChanged;
|
||||
|
||||
if (containerChanged || disabledChanged || distanceChanged) {
|
||||
this.destroyScroller();
|
||||
if (shouldSetup) {
|
||||
this.setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup() {
|
||||
if (hasWindowDefined()) {
|
||||
this.zone.runOutsideAngular(() => {
|
||||
this.disposeScroller = createScroller({
|
||||
fromRoot: this.fromRoot,
|
||||
alwaysCallback: this.alwaysCallback,
|
||||
disable: this.infiniteScrollDisabled,
|
||||
downDistance: this.infiniteScrollDistance,
|
||||
element: this.element,
|
||||
horizontal: this.horizontal,
|
||||
scrollContainer: this.infiniteScrollContainer,
|
||||
scrollWindow: this.scrollWindow,
|
||||
throttle: this.infiniteScrollThrottle,
|
||||
upDistance: this.infiniteScrollUpDistance
|
||||
}).subscribe((payload: any) => this.zone.run(() => this.handleOnScroll(payload)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleOnScroll({ type, payload }: IInfiniteScrollAction) {
|
||||
switch (type) {
|
||||
case InfiniteScrollActions.DOWN:
|
||||
return this.scrolled.emit(payload);
|
||||
|
||||
case InfiniteScrollActions.UP:
|
||||
return this.scrolledUp.emit(payload);
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.destroyScroller();
|
||||
}
|
||||
|
||||
destroyScroller() {
|
||||
if (this.disposeScroller) {
|
||||
this.disposeScroller.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { InfiniteScrollDirective } from './infinite-scroll.directive';
|
||||
|
||||
@NgModule({
|
||||
declarations: [InfiniteScrollDirective],
|
||||
exports: [InfiniteScrollDirective],
|
||||
imports: [],
|
||||
providers: []
|
||||
})
|
||||
export class InfiniteScrollModule { }
|
||||
@ -1,11 +0,0 @@
|
||||
// Public classes.
|
||||
export {
|
||||
ContainerRef,
|
||||
IInfiniteScrollEvent,
|
||||
IPositionElements,
|
||||
IPositionStats,
|
||||
IResolver
|
||||
} from './models';
|
||||
|
||||
export { InfiniteScrollDirective } from './modules/infinite-scroll.directive';
|
||||
export { InfiniteScrollModule } from './modules/ngx-infinite-scroll.module';
|
||||
@ -1,48 +0,0 @@
|
||||
const VerticalProps = {
|
||||
clientHeight: "clientHeight",
|
||||
offsetHeight: "offsetHeight",
|
||||
scrollHeight: "scrollHeight",
|
||||
pageYOffset: "pageYOffset",
|
||||
offsetTop: "offsetTop",
|
||||
scrollTop: "scrollTop",
|
||||
top: "top"
|
||||
};
|
||||
|
||||
const HorizontalProps = {
|
||||
clientHeight: "clientWidth",
|
||||
offsetHeight: "offsetWidth",
|
||||
scrollHeight: "scrollWidth",
|
||||
pageYOffset: "pageXOffset",
|
||||
offsetTop: "offsetLeft",
|
||||
scrollTop: "scrollLeft",
|
||||
top: "left"
|
||||
};
|
||||
|
||||
export class AxisResolver {
|
||||
private propsMap: any;
|
||||
|
||||
constructor(private vertical: boolean = true) {
|
||||
this.propsMap = vertical ? VerticalProps : HorizontalProps;
|
||||
}
|
||||
clientHeightKey() {
|
||||
return this.propsMap.clientHeight;
|
||||
}
|
||||
offsetHeightKey() {
|
||||
return this.propsMap.offsetHeight;
|
||||
}
|
||||
scrollHeightKey() {
|
||||
return this.propsMap.scrollHeight;
|
||||
}
|
||||
pageYOffsetKey() {
|
||||
return this.propsMap.pageYOffset;
|
||||
}
|
||||
offsetTopKey() {
|
||||
return this.propsMap.offsetTop;
|
||||
}
|
||||
scrollTopKey() {
|
||||
return this.propsMap.scrollTop;
|
||||
}
|
||||
topKey() {
|
||||
return this.propsMap.top;
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
import { IInfiniteScrollEvent, IPositionStats } from '../models';
|
||||
|
||||
export interface IScrollerProps extends IDistanceRange {
|
||||
container: IPositionStats;
|
||||
alwaysCallback: boolean;
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
export interface ITriggerEvents {
|
||||
down: (event: any) => any;
|
||||
up: (event: any) => any;
|
||||
}
|
||||
|
||||
export interface IDistanceRange {
|
||||
down: number;
|
||||
up: number;
|
||||
}
|
||||
|
||||
export interface IScrollConfig {
|
||||
alwaysCallback: boolean;
|
||||
shouldFireScrollEvent: boolean;
|
||||
}
|
||||
|
||||
export function shouldTriggerEvents(
|
||||
alwaysCallback: boolean,
|
||||
shouldFireScrollEvent: boolean,
|
||||
isTriggeredCurrentTotal: boolean
|
||||
) {
|
||||
if (alwaysCallback && shouldFireScrollEvent) {
|
||||
return true;
|
||||
}
|
||||
if (!isTriggeredCurrentTotal && shouldFireScrollEvent) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1,39 +0,0 @@
|
||||
import { ElementRef, SimpleChange } from '@angular/core';
|
||||
|
||||
export function resolveContainerElement(
|
||||
selector: string | any,
|
||||
scrollWindow,
|
||||
defaultElement,
|
||||
fromRoot: boolean
|
||||
): any {
|
||||
const hasWindow = window && !!window.document && window.document.documentElement;
|
||||
let container = hasWindow && scrollWindow ? window : defaultElement;
|
||||
if (selector) {
|
||||
const containerIsString =
|
||||
selector && hasWindow && typeof selector === 'string';
|
||||
container = containerIsString
|
||||
? findElement(selector, defaultElement.nativeElement, fromRoot)
|
||||
: selector;
|
||||
if (!container) {
|
||||
throw new Error('ngx-infinite-scroll {resolveContainerElement()}: selector for');
|
||||
}
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
export function findElement(
|
||||
selector: string | any,
|
||||
customRoot: ElementRef | any,
|
||||
fromRoot: boolean
|
||||
) {
|
||||
const rootEl = fromRoot ? window.document : customRoot;
|
||||
return rootEl.querySelector(selector);
|
||||
}
|
||||
|
||||
export function inputPropChanged(prop: SimpleChange): boolean {
|
||||
return prop && !prop.firstChange;
|
||||
}
|
||||
|
||||
export function hasWindowDefined(): boolean {
|
||||
return typeof window !== 'undefined';
|
||||
}
|
||||
@ -1,152 +0,0 @@
|
||||
import { ElementRef } from '@angular/core';
|
||||
|
||||
import { ContainerRef, IPositionElements, IPositionStats, IResolver } from '../models';
|
||||
import { AxisResolver } from './axis-resolver';
|
||||
|
||||
export function createResolver({
|
||||
windowElement,
|
||||
axis
|
||||
}: IPositionElements): IResolver {
|
||||
return createResolverWithContainer(
|
||||
{ axis, isWindow: isElementWindow(windowElement) },
|
||||
windowElement
|
||||
);
|
||||
}
|
||||
|
||||
export function createResolverWithContainer(
|
||||
resolver,
|
||||
windowElement: ContainerRef
|
||||
) {
|
||||
const container =
|
||||
resolver.isWindow || (windowElement && !windowElement.nativeElement)
|
||||
? windowElement
|
||||
: windowElement.nativeElement;
|
||||
return { ...resolver, container };
|
||||
}
|
||||
|
||||
export function isElementWindow(windowElement: ContainerRef): boolean {
|
||||
const isWindow = ['Window', 'global'].some((obj: string) =>
|
||||
Object.prototype.toString.call(windowElement).includes(obj)
|
||||
);
|
||||
return isWindow;
|
||||
}
|
||||
|
||||
export function getDocumentElement(isContainerWindow: boolean, windowElement) {
|
||||
return isContainerWindow ? windowElement.document.documentElement : null;
|
||||
}
|
||||
|
||||
export function calculatePoints(element: ElementRef, resolver: IResolver) {
|
||||
const height = extractHeightForElement(resolver);
|
||||
return resolver.isWindow
|
||||
? calculatePointsForWindow(height, element, resolver)
|
||||
: calculatePointsForElement(height, element, resolver);
|
||||
}
|
||||
|
||||
export function calculatePointsForWindow(
|
||||
height: number,
|
||||
element: ElementRef,
|
||||
resolver: IResolver
|
||||
): IPositionStats {
|
||||
const { axis, container, isWindow } = resolver;
|
||||
const { offsetHeightKey, clientHeightKey } = extractHeightPropKeys(axis);
|
||||
// scrolled until now / current y point
|
||||
const scrolled =
|
||||
height +
|
||||
getElementPageYOffset(
|
||||
getDocumentElement(isWindow, container),
|
||||
axis,
|
||||
isWindow
|
||||
);
|
||||
// total height / most bottom y point
|
||||
const nativeElementHeight = getElementHeight(
|
||||
element.nativeElement,
|
||||
isWindow,
|
||||
offsetHeightKey,
|
||||
clientHeightKey
|
||||
);
|
||||
const totalToScroll =
|
||||
getElementOffsetTop(element.nativeElement, axis, isWindow) +
|
||||
nativeElementHeight;
|
||||
return { height, scrolled, totalToScroll, isWindow };
|
||||
}
|
||||
|
||||
export function calculatePointsForElement(
|
||||
height: number,
|
||||
element: ElementRef,
|
||||
resolver: IResolver
|
||||
): IPositionStats {
|
||||
const { axis, container } = resolver;
|
||||
// perhaps use container.offsetTop instead of 'scrollTop'
|
||||
const scrolled = container[axis.scrollTopKey()];
|
||||
const totalToScroll = container[axis.scrollHeightKey()];
|
||||
return { height, scrolled, totalToScroll, isWindow: false };
|
||||
}
|
||||
|
||||
export function extractHeightPropKeys(axis: AxisResolver) {
|
||||
return {
|
||||
offsetHeightKey: axis.offsetHeightKey(),
|
||||
clientHeightKey: axis.clientHeightKey()
|
||||
};
|
||||
}
|
||||
|
||||
export function extractHeightForElement({
|
||||
container,
|
||||
isWindow,
|
||||
axis
|
||||
}: IResolver) {
|
||||
const { offsetHeightKey, clientHeightKey } = extractHeightPropKeys(axis);
|
||||
return getElementHeight(
|
||||
container,
|
||||
isWindow,
|
||||
offsetHeightKey,
|
||||
clientHeightKey
|
||||
);
|
||||
}
|
||||
export function getElementHeight(
|
||||
elem: any,
|
||||
isWindow: boolean,
|
||||
offsetHeightKey: string,
|
||||
clientHeightKey: string
|
||||
) {
|
||||
if (isNaN(elem[offsetHeightKey])) {
|
||||
const docElem = getDocumentElement(isWindow, elem);
|
||||
return docElem ? docElem[clientHeightKey] : 0;
|
||||
} else {
|
||||
return elem[offsetHeightKey];
|
||||
}
|
||||
}
|
||||
|
||||
export function getElementOffsetTop(
|
||||
elem: ContainerRef,
|
||||
axis: AxisResolver,
|
||||
isWindow: boolean
|
||||
) {
|
||||
const topKey = axis.topKey();
|
||||
// elem = elem.nativeElement;
|
||||
if (!elem.getBoundingClientRect) {
|
||||
// || elem.css('none')) {
|
||||
return;
|
||||
}
|
||||
return (
|
||||
elem.getBoundingClientRect()[topKey] +
|
||||
getElementPageYOffset(elem, axis, isWindow)
|
||||
);
|
||||
}
|
||||
|
||||
export function getElementPageYOffset(
|
||||
elem: ContainerRef,
|
||||
axis: AxisResolver,
|
||||
isWindow: boolean
|
||||
) {
|
||||
const pageYOffset = axis.pageYOffsetKey();
|
||||
const scrollTop = axis.scrollTopKey();
|
||||
const offsetTop = axis.offsetTopKey();
|
||||
|
||||
if (isNaN(window.pageYOffset)) {
|
||||
return getDocumentElement(isWindow, elem)[scrollTop];
|
||||
} else if (elem.ownerDocument) {
|
||||
return elem.ownerDocument.defaultView[pageYOffset];
|
||||
} else {
|
||||
return elem[offsetTop];
|
||||
}
|
||||
}
|
||||
@ -1,110 +0,0 @@
|
||||
import { Observable, of, fromEvent } from 'rxjs';
|
||||
import { map, mergeMap, tap, throttleTime, filter } from 'rxjs/operators';
|
||||
|
||||
import * as Models from '../models';
|
||||
import { AxisResolver } from './axis-resolver';
|
||||
import { shouldTriggerEvents } from './event-trigger';
|
||||
import { resolveContainerElement } from './ngx-ins-utils';
|
||||
import { calculatePoints, createResolver } from './position-resolver';
|
||||
import * as ScrollResolver from './scroll-resolver';
|
||||
import { ScrollState } from './scroll-state';
|
||||
|
||||
export function createScroller(config: Models.IScroller) {
|
||||
const { scrollContainer, scrollWindow, element, fromRoot } = config;
|
||||
const resolver = createResolver({
|
||||
axis: new AxisResolver(!config.horizontal),
|
||||
windowElement: resolveContainerElement(
|
||||
scrollContainer,
|
||||
scrollWindow,
|
||||
element,
|
||||
fromRoot
|
||||
)
|
||||
});
|
||||
const scrollState = new ScrollState({
|
||||
totalToScroll: calculatePoints(element, resolver)
|
||||
});
|
||||
const options: Models.IScrollRegisterConfig = {
|
||||
container: resolver.container,
|
||||
throttle: config.throttle
|
||||
};
|
||||
const distance = {
|
||||
up: config.upDistance,
|
||||
down: config.downDistance
|
||||
};
|
||||
return attachScrollEvent(options).pipe(
|
||||
mergeMap(() => of(calculatePoints(element, resolver))),
|
||||
map((positionStats: Models.IPositionStats) =>
|
||||
toInfiniteScrollParams(
|
||||
scrollState.lastScrollPosition,
|
||||
positionStats,
|
||||
distance
|
||||
)
|
||||
),
|
||||
tap(({ stats }: Models.IScrollParams) =>
|
||||
scrollState.updateScroll(stats.scrolled, stats.totalToScroll)
|
||||
),
|
||||
filter(
|
||||
({ fire, scrollDown, stats: { totalToScroll } }: Models.IScrollParams) =>
|
||||
shouldTriggerEvents(
|
||||
config.alwaysCallback,
|
||||
fire,
|
||||
scrollState.isTriggeredScroll(totalToScroll, scrollDown)
|
||||
)
|
||||
),
|
||||
tap(({ scrollDown, stats: { totalToScroll } }: Models.IScrollParams) => {
|
||||
scrollState.updateTriggeredFlag(totalToScroll, scrollDown);
|
||||
}),
|
||||
map(toInfiniteScrollAction)
|
||||
);
|
||||
}
|
||||
|
||||
export function attachScrollEvent(
|
||||
options: Models.IScrollRegisterConfig
|
||||
): Observable<{}> {
|
||||
let obs = fromEvent(options.container, 'scroll');
|
||||
// For an unknown reason calling `sampleTime()` causes trouble for many users, even with `options.throttle = 0`.
|
||||
// Let's avoid calling the function unless needed.
|
||||
// Replacing with throttleTime seems to solve the problem
|
||||
// See https://github.com/orizens/ngx-infinite-scroll/issues/198
|
||||
if (options.throttle) {
|
||||
obs = obs.pipe(throttleTime(options.throttle));
|
||||
}
|
||||
return obs;
|
||||
}
|
||||
|
||||
export function toInfiniteScrollParams(
|
||||
lastScrollPosition: number,
|
||||
stats: Models.IPositionStats,
|
||||
distance: Models.IScrollerDistance
|
||||
): Models.IScrollParams {
|
||||
const { scrollDown, fire } = ScrollResolver.getScrollStats(
|
||||
lastScrollPosition,
|
||||
stats,
|
||||
distance
|
||||
);
|
||||
return {
|
||||
scrollDown,
|
||||
fire,
|
||||
stats
|
||||
};
|
||||
}
|
||||
|
||||
export const InfiniteScrollActions = {
|
||||
DOWN: '[NGX_ISE] DOWN',
|
||||
UP: '[NGX_ISE] UP'
|
||||
};
|
||||
|
||||
export function toInfiniteScrollAction(
|
||||
response: Models.IScrollParams
|
||||
): Models.IInfiniteScrollAction {
|
||||
const {
|
||||
scrollDown,
|
||||
stats: { scrolled: currentScrollPosition }
|
||||
} = response;
|
||||
return {
|
||||
type: scrollDown ? InfiniteScrollActions.DOWN : InfiniteScrollActions.UP,
|
||||
payload: {
|
||||
currentScrollPosition
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
import { IPositionStats, IScrollState, IScrollerDistance } from '../models';
|
||||
|
||||
export function shouldFireScrollEvent(
|
||||
container: IPositionStats,
|
||||
distance: IScrollerDistance,
|
||||
scrollingDown: boolean
|
||||
) {
|
||||
let remaining: number;
|
||||
let containerBreakpoint: number;
|
||||
if (container.totalToScroll <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const scrolledUntilNow = container.isWindow ? container.scrolled : container.height + container.scrolled;
|
||||
if (scrollingDown) {
|
||||
remaining =
|
||||
(container.totalToScroll - scrolledUntilNow) / container.totalToScroll;
|
||||
containerBreakpoint = distance.down / 10;
|
||||
} else {
|
||||
const totalHiddenContentHeight =
|
||||
container.scrolled + (container.totalToScroll - scrolledUntilNow);
|
||||
remaining = container.scrolled / totalHiddenContentHeight;
|
||||
containerBreakpoint = distance.up / 10;
|
||||
}
|
||||
|
||||
const shouldFireEvent: boolean = remaining <= containerBreakpoint;
|
||||
return shouldFireEvent;
|
||||
}
|
||||
|
||||
export function isScrollingDownwards(
|
||||
lastScrollPosition: number,
|
||||
container: IPositionStats
|
||||
) {
|
||||
return lastScrollPosition < container.scrolled;
|
||||
}
|
||||
|
||||
export function getScrollStats(
|
||||
lastScrollPosition: number,
|
||||
container: IPositionStats,
|
||||
distance: IScrollerDistance
|
||||
) {
|
||||
const scrollDown = isScrollingDownwards(lastScrollPosition, container);
|
||||
return {
|
||||
fire: shouldFireScrollEvent(container, distance, scrollDown),
|
||||
scrollDown
|
||||
};
|
||||
}
|
||||
|
||||
export function updateScrollPosition(
|
||||
position: number,
|
||||
scrollState: IScrollState
|
||||
) {
|
||||
return (scrollState.lastScrollPosition = position);
|
||||
}
|
||||
|
||||
export function updateTotalToScroll(
|
||||
totalToScroll: number,
|
||||
scrollState: IScrollState
|
||||
) {
|
||||
if (scrollState.lastTotalToScroll !== totalToScroll) {
|
||||
scrollState.lastTotalToScroll = scrollState.totalToScroll;
|
||||
scrollState.totalToScroll = totalToScroll;
|
||||
}
|
||||
}
|
||||
|
||||
export function isSameTotalToScroll(scrollState: IScrollState) {
|
||||
return scrollState.totalToScroll === scrollState.lastTotalToScroll;
|
||||
}
|
||||
|
||||
export function updateTriggeredFlag(
|
||||
scroll,
|
||||
scrollState: IScrollState,
|
||||
triggered: boolean,
|
||||
isScrollingDown: boolean
|
||||
) {
|
||||
if (isScrollingDown) {
|
||||
scrollState.triggered.down = scroll;
|
||||
} else {
|
||||
scrollState.triggered.up = scroll;
|
||||
}
|
||||
}
|
||||
|
||||
export function isTriggeredScroll(
|
||||
totalToScroll,
|
||||
scrollState: IScrollState,
|
||||
isScrollingDown: boolean
|
||||
) {
|
||||
return isScrollingDown
|
||||
? scrollState.triggered.down === totalToScroll
|
||||
: scrollState.triggered.up === totalToScroll;
|
||||
}
|
||||
|
||||
export function updateScrollState(
|
||||
scrollState: IScrollState,
|
||||
scrolledUntilNow: number,
|
||||
totalToScroll: number
|
||||
) {
|
||||
updateScrollPosition(scrolledUntilNow, scrollState);
|
||||
updateTotalToScroll(totalToScroll, scrollState);
|
||||
// const isSameTotal = isSameTotalToScroll(scrollState);
|
||||
// if (!isSameTotal) {
|
||||
// updateTriggeredFlag(scrollState, false, isScrollingDown);
|
||||
// }
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
import { IScrollState, IScrollerDistance } from '../models';
|
||||
|
||||
export class ScrollState implements IScrollState {
|
||||
lastScrollPosition = 0;
|
||||
lastTotalToScroll = 0;
|
||||
totalToScroll = 0;
|
||||
triggered: IScrollerDistance = {
|
||||
down: 0,
|
||||
up: 0
|
||||
};
|
||||
|
||||
constructor({ totalToScroll }) {
|
||||
this.totalToScroll = totalToScroll;
|
||||
}
|
||||
|
||||
updateScrollPosition(position: number) {
|
||||
return (this.lastScrollPosition = position);
|
||||
}
|
||||
|
||||
updateTotalToScroll(totalToScroll: number) {
|
||||
if (this.lastTotalToScroll !== totalToScroll) {
|
||||
this.lastTotalToScroll = this.totalToScroll;
|
||||
this.totalToScroll = totalToScroll;
|
||||
}
|
||||
}
|
||||
|
||||
updateScroll(scrolledUntilNow: number, totalToScroll: number) {
|
||||
this.updateScrollPosition(scrolledUntilNow);
|
||||
this.updateTotalToScroll(totalToScroll);
|
||||
}
|
||||
|
||||
updateTriggeredFlag(scroll, isScrollingDown: boolean) {
|
||||
if (isScrollingDown) {
|
||||
this.triggered.down = scroll;
|
||||
} else {
|
||||
this.triggered.up = scroll;
|
||||
}
|
||||
}
|
||||
|
||||
isTriggeredScroll(totalToScroll, isScrollingDown: boolean) {
|
||||
return isScrollingDown
|
||||
? this.triggered.down === totalToScroll
|
||||
: this.triggered.up === totalToScroll;
|
||||
}
|
||||
}
|
||||
@ -1,196 +0,0 @@
|
||||
/*
|
||||
import {
|
||||
async,
|
||||
inject
|
||||
} from '@angular/core/testing';
|
||||
import { InfiniteScrollDirective } from '../../src/modules/infinite-scroll.directive';
|
||||
import { ScrollRegister } from '../../src/services/scroll-register';
|
||||
import { ScrollResolver } from '../../src/services/scroll-resolver';
|
||||
|
||||
import { ElementRef, NgZone, SimpleChanges, SimpleChange } from '@angular/core';
|
||||
|
||||
describe('Infinite Scroll Directive', () => {
|
||||
// const zone = new NgZone({ enableLongStackTrace: false });
|
||||
let isScrollingDown = true;
|
||||
let zoneSpy: any, scrollResolverSpy: any, scrollRegisterSpy: any, positionResolverSpy: any;
|
||||
let directive: InfiniteScrollDirective;
|
||||
const positionFactoryMock: any = {
|
||||
create: () => positionResolverSpy
|
||||
};
|
||||
const createMockElement = () => {
|
||||
const mockedElement: ElementRef = new ElementRef(document.createElement('div'));
|
||||
return mockedElement;
|
||||
};
|
||||
const createInfiniteScroll = (mockedElement?: any) => {
|
||||
mockedElement = mockedElement || createMockElement();
|
||||
return new InfiniteScrollDirective(
|
||||
mockedElement,
|
||||
zoneSpy,
|
||||
positionFactoryMock,
|
||||
scrollRegisterSpy,
|
||||
scrollResolverSpy
|
||||
);
|
||||
};
|
||||
|
||||
beforeEach(() =>{
|
||||
zoneSpy = jasmine.createSpyObj('zone', ['run']);
|
||||
zoneSpy.runOutsideAngular = (fn) => fn();
|
||||
scrollResolverSpy = {
|
||||
getScrollStats: () => {
|
||||
return { shouldScroll: true, isScrollingDown };
|
||||
}
|
||||
};
|
||||
scrollRegisterSpy = jasmine.createSpyObj('register', ['attachEvent']);
|
||||
positionResolverSpy = jasmine.createSpyObj('pos', ['create', 'container']);
|
||||
directive = createInfiniteScroll();
|
||||
});
|
||||
|
||||
it('should create an instance of the directive', () => {
|
||||
const actual = directive;
|
||||
expect(actual).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have default @Input properties values', () => {
|
||||
const expectedInputs: Object = {
|
||||
alwaysCallback: false,
|
||||
horizontal: false,
|
||||
infiniteScrollContainer: null,
|
||||
infiniteScrollDisabled: false,
|
||||
infiniteScrollDistance: 2,
|
||||
infiniteScrollThrottle: 300,
|
||||
infiniteScrollUpDistance: 1.5,
|
||||
scrollWindow: true
|
||||
};
|
||||
|
||||
Object.keys(expectedInputs).forEach((input) =>
|
||||
expect(directive[input]).toEqual(expectedInputs[input]));
|
||||
});
|
||||
|
||||
it('should trigger the onScrollDown event when scroll has passed _distancedDown', () => {
|
||||
const container = {
|
||||
height: 0,
|
||||
scrolledUntilNow: 0,
|
||||
totalToScroll: 0,
|
||||
};
|
||||
spyOn(directive, 'onScrollDown');
|
||||
directive.ngOnInit();
|
||||
directive.handleOnScroll(container);
|
||||
const actual = directive.onScrollDown;
|
||||
expect(actual).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should trigger the onScrollUp event when scroll has passed _distanceUp', () => {
|
||||
const container = {
|
||||
height: 0,
|
||||
scrolledUntilNow: 0,
|
||||
totalToScroll: 0,
|
||||
};
|
||||
spyOn(directive, 'onScrollUp');
|
||||
directive.ngOnInit();
|
||||
isScrollingDown = false;
|
||||
directive.handleOnScroll(container);
|
||||
const actual = directive.onScrollUp;
|
||||
expect(actual).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should disable the scroller', () => {
|
||||
const container = {
|
||||
height: 0,
|
||||
scrolledUntilNow: 0,
|
||||
totalToScroll: 0,
|
||||
};
|
||||
spyOn(directive, 'onScrollDown');
|
||||
directive.ngOnInit();
|
||||
directive.infiniteScrollDisabled = true;
|
||||
directive.handleOnScroll(container);
|
||||
const actual = directive.onScrollDown;
|
||||
expect(actual).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('resolving container', () => {
|
||||
let directive: InfiniteScrollDirective;
|
||||
let mockedElement: ElementRef;
|
||||
const container = {
|
||||
height: 0,
|
||||
scrolledUntilNow: 0,
|
||||
totalToScroll: 0,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockedElement = createMockElement();
|
||||
directive = createInfiniteScroll(mockedElement);
|
||||
spyOn(positionFactoryMock, 'create').and.callThrough();
|
||||
});
|
||||
|
||||
describe('when container input is defined', () => {
|
||||
describe('when css selector is used', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(document, 'querySelector').and.returnValue(container);
|
||||
directive.infiniteScrollContainer = '.test';
|
||||
directive.ngOnInit();
|
||||
});
|
||||
|
||||
it('should find element in DOM', () => {
|
||||
expect(document.querySelector).toHaveBeenCalledWith('.test');
|
||||
});
|
||||
|
||||
it('should return container', () => {
|
||||
expect(positionFactoryMock.create)
|
||||
.toHaveBeenCalledWith(jasmine.objectContaining({windowElement: container}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when container is passed directly', () => {
|
||||
beforeEach(() => {
|
||||
directive.infiniteScrollContainer = container;
|
||||
directive.ngOnInit();
|
||||
});
|
||||
|
||||
it('should return container', () => {
|
||||
expect(positionFactoryMock.create)
|
||||
.toHaveBeenCalledWith(jasmine.objectContaining({windowElement: container}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when container input is not defined', () => {
|
||||
describe('when scrollWindow is true', () => {
|
||||
beforeEach(() => {
|
||||
directive.scrollWindow = true;
|
||||
directive.ngOnInit();
|
||||
});
|
||||
|
||||
it('should return window', () => {
|
||||
expect(positionFactoryMock.create)
|
||||
.toHaveBeenCalledWith(jasmine.objectContaining({windowElement: window}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when scrollWindow is false', () => {
|
||||
beforeEach(() => {
|
||||
directive.scrollWindow = false;
|
||||
directive.ngOnInit();
|
||||
});
|
||||
|
||||
it('should return current element', () => {
|
||||
expect(positionFactoryMock.create)
|
||||
.toHaveBeenCalledWith(jasmine.objectContaining({windowElement: mockedElement}));
|
||||
});
|
||||
|
||||
it('should initialize again when infiniteScrollContainer has changed', () => {
|
||||
const anotherContainer = {
|
||||
height: 0,
|
||||
scrolledUntilNow: 0,
|
||||
totalToScroll: 0,
|
||||
};
|
||||
directive.infiniteScrollContainer = anotherContainer;
|
||||
const change = new SimpleChange(container, anotherContainer, false);
|
||||
directive.ngOnChanges({ infiniteScrollContainer: change });
|
||||
expect(positionFactoryMock.create)
|
||||
.toHaveBeenCalledWith(jasmine.objectContaining({windowElement: anotherContainer}));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
*/
|
||||
@ -1,105 +0,0 @@
|
||||
import {
|
||||
IScrollerProps,
|
||||
shouldTriggerEvents
|
||||
} from '../../src/services/event-trigger';
|
||||
|
||||
const props = {
|
||||
alwaysCallback: true,
|
||||
container: {},
|
||||
disabled: false,
|
||||
down: 3,
|
||||
up: 2
|
||||
} as IScrollerProps;
|
||||
|
||||
describe('EventTrigger', () => {
|
||||
[
|
||||
{
|
||||
it: 'should return TRUE when alwaysCallback, shouldFireScrollEvent',
|
||||
params: {
|
||||
alwaysCallback: true,
|
||||
shouldFireScrollEvent: true,
|
||||
isTriggeredTotal: false
|
||||
},
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
it: 'should return FALSE when alwaysCallback, NOT shouldFireScrollEvent',
|
||||
params: {
|
||||
alwaysCallback: true,
|
||||
shouldFireScrollEvent: false,
|
||||
isTriggeredTotal: true
|
||||
},
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
it: 'should return FALSE when alwaysCallback',
|
||||
params: {
|
||||
alwaysCallback: true,
|
||||
shouldFireScrollEvent: false,
|
||||
isTriggeredTotal: false
|
||||
},
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
it:
|
||||
'should return TRUE when alwaysCallback, shouldFireScrollEvent, isTriggeredTotal',
|
||||
params: {
|
||||
alwaysCallback: true,
|
||||
shouldFireScrollEvent: true,
|
||||
isTriggeredTotal: true
|
||||
},
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
it: 'should return TRUE when shouldFireScrollEvent ONLY',
|
||||
params: {
|
||||
alwaysCallback: false,
|
||||
shouldFireScrollEvent: true,
|
||||
isTriggeredTotal: false
|
||||
},
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
it: 'should return FALSE when shouldFireScrollEvent, isTriggeredTotal',
|
||||
params: {
|
||||
alwaysCallback: false,
|
||||
shouldFireScrollEvent: true,
|
||||
isTriggeredTotal: true
|
||||
},
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
it:
|
||||
'should return FALSE when not alwaysCallback, shouldFireScrollEvent is false',
|
||||
params: {
|
||||
alwaysCallback: false,
|
||||
shouldFireScrollEvent: false,
|
||||
isTriggeredTotal: false
|
||||
},
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
it: 'should return FALSE when isTriggeredTotal ONLY',
|
||||
params: {
|
||||
alwaysCallback: false,
|
||||
shouldFireScrollEvent: false,
|
||||
isTriggeredTotal: true
|
||||
},
|
||||
expected: false
|
||||
}
|
||||
].forEach(spec => {
|
||||
it(spec.it, () => {
|
||||
const {
|
||||
isTriggeredTotal,
|
||||
alwaysCallback,
|
||||
shouldFireScrollEvent
|
||||
} = spec.params;
|
||||
const actual = shouldTriggerEvents(
|
||||
alwaysCallback,
|
||||
shouldFireScrollEvent,
|
||||
isTriggeredTotal
|
||||
);
|
||||
expect(actual).toBe(spec.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,96 +0,0 @@
|
||||
import { ElementRef } from "@angular/core";
|
||||
|
||||
import { ContainerRef } from "../../src/models";
|
||||
import { AxisResolver } from "../../src/services/axis-resolver";
|
||||
import {
|
||||
createResolver,
|
||||
createResolverWithContainer
|
||||
} from "../../src/services/position-resolver";
|
||||
|
||||
describe("Position Resolver", () => {
|
||||
let mockedElement: ElementRef;
|
||||
let mockedContainer: ElementRef;
|
||||
let axis: AxisResolver;
|
||||
let mockDom: ContainerRef;
|
||||
|
||||
const createMockDom = () => {
|
||||
const container = document.createElement("section");
|
||||
container.setAttribute("style", "height: 500px; overflow-y: scroll");
|
||||
const el = document.createElement("div");
|
||||
el.setAttribute("style", "height: 1000px;");
|
||||
container.appendChild(el);
|
||||
mockedElement = new ElementRef(el);
|
||||
mockedContainer = new ElementRef(container);
|
||||
return { element: mockedElement, container: mockedContainer };
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
axis = new AxisResolver(false);
|
||||
mockDom = createMockDom();
|
||||
});
|
||||
|
||||
describe("Resolver Maker", () => {
|
||||
it("should create an instance of position resolver", () => {
|
||||
const actual = createResolver({
|
||||
axis,
|
||||
windowElement: mockDom.element
|
||||
});
|
||||
expect(actual).toBeDefined();
|
||||
});
|
||||
|
||||
it("should return the native element if container is not window", () => {
|
||||
mockDom.element.nativeElement = { mocked: true };
|
||||
const resolver = createResolverWithContainer(
|
||||
{
|
||||
axis,
|
||||
isWindow: false
|
||||
},
|
||||
mockDom.element
|
||||
);
|
||||
const actual = resolver.container;
|
||||
const expected = mockDom.element.nativeElement;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
// describe('Points Calculation', () => {
|
||||
// it('should calculate points', () => {
|
||||
// const resolver: IResolver = {
|
||||
// isWindow: true,
|
||||
// axis,
|
||||
// container: {}
|
||||
// };
|
||||
// const points = calculatePoints(mockDom.element, resolver);
|
||||
// const actual = calculatePointsForWindow;
|
||||
// expect(actual).toHaveBeenCalledWith(mockDom.element, resolver);
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe("creating instance for non-window element", () => {
|
||||
// let service: IResolver;
|
||||
|
||||
// describe("when nativeElement is present", () => {
|
||||
// beforeEach(() => {
|
||||
// service = positionResolver.create({
|
||||
// axis,
|
||||
// windowElement: mockDom.element
|
||||
// });
|
||||
// });
|
||||
|
||||
// it("should use container as nativeElement", () => {
|
||||
// expect(service.container instanceof HTMLDivElement).toBeTruthy();
|
||||
// });
|
||||
// });
|
||||
|
||||
// describe('when nativeElement is not present', () => {
|
||||
// beforeEach(() => {
|
||||
// const mockDom = createMockDom();
|
||||
// service = createPositionResolver(mockDom.element, mockDom.container.nativeElement);
|
||||
// });
|
||||
|
||||
// it('should use container as nativeElement', () => {
|
||||
// expect(service.container instanceof HTMLDivElement).toBeTruthy();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
});
|
||||
@ -1,118 +0,0 @@
|
||||
import * as Models from '../../src/models';
|
||||
import { Observable } from 'rxjs';
|
||||
import * as ScrollRegister from '../../src/services/scroll-register';
|
||||
import * as ScrollResolver from '../../src/services/scroll-resolver';
|
||||
import { ElementRef } from '@angular/core';
|
||||
|
||||
describe('Scroll Regsiter', () => {
|
||||
let mockedElement: ElementRef;
|
||||
let mockedContainer: ElementRef;
|
||||
|
||||
const createMockDom = () => {
|
||||
const container = document.createElement('section');
|
||||
container.setAttribute('style', 'height: 500px; overflow-y: scroll');
|
||||
const el = document.createElement('div');
|
||||
el.setAttribute('style', 'height: 1000px;');
|
||||
container.appendChild(el);
|
||||
mockedElement = new ElementRef(el);
|
||||
mockedContainer = new ElementRef(container);
|
||||
return { element: mockedElement, container: mockedContainer };
|
||||
};
|
||||
|
||||
it('should create a Observable of scroll observable', () => {
|
||||
const mockDom = createMockDom();
|
||||
const scrollConfig: Models.IScrollRegisterConfig = {
|
||||
container: mockDom.container.nativeElement,
|
||||
throttle: 300,
|
||||
};
|
||||
const scroller$: Observable<{}> = ScrollRegister.attachScrollEvent(scrollConfig);
|
||||
const actual = scroller$;
|
||||
expect(actual).toBeDefined();
|
||||
});
|
||||
|
||||
[
|
||||
{
|
||||
it: 'should create a Observable of scroll observable with default 300 throttle',
|
||||
config: {
|
||||
throttle: 300,
|
||||
},
|
||||
expected: 300
|
||||
},
|
||||
{
|
||||
it: 'should create a Observable of scroll observable without a sampleTime if throttle is 0',
|
||||
config: {
|
||||
throttle: 0
|
||||
},
|
||||
expected: 0
|
||||
}
|
||||
].forEach((spec) => {
|
||||
it(spec.it, (done) => {
|
||||
const mockDom = createMockDom();
|
||||
const scrollConfig: Models.IScrollRegisterConfig = {
|
||||
container: mockDom.container.nativeElement,
|
||||
...spec.config
|
||||
};
|
||||
const scroller$: Observable<{}> = ScrollRegister.attachScrollEvent(scrollConfig);
|
||||
const start = new Date();
|
||||
scroller$.subscribe((result) => {
|
||||
const end = new Date();
|
||||
const actual = end.getTime() - start.getTime();
|
||||
expect(actual).toBeGreaterThanOrEqual(spec.expected);
|
||||
done();
|
||||
});
|
||||
mockDom.container.nativeElement.dispatchEvent(new Event('scroll'));
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a scroll params object', () => {
|
||||
const lastScrollPosition = 0;
|
||||
const positionStats = {} as Models.IPositionStats;
|
||||
const distance = {
|
||||
down: 2,
|
||||
up: 3,
|
||||
} as Models.IScrollerDistance;
|
||||
const scrollStats = {
|
||||
isScrollingDown: true,
|
||||
shouldFireScrollEvent: true
|
||||
};
|
||||
spyOn(ScrollResolver, 'getScrollStats').and.returnValue(scrollStats);
|
||||
const actual = ScrollRegister.toInfiniteScrollParams(lastScrollPosition, positionStats, distance);
|
||||
const expected = 3;
|
||||
expect(Object.keys(actual).length).toEqual(expected);
|
||||
});
|
||||
|
||||
describe('toInfiniteScrollAction', () => {
|
||||
let response;
|
||||
|
||||
beforeEach(() => {
|
||||
response = {
|
||||
stats: {
|
||||
scrolled: 100
|
||||
}
|
||||
} as Models.IScrollParams;
|
||||
});
|
||||
|
||||
[
|
||||
{
|
||||
it: 'should trigger down event when scrolling down',
|
||||
params: {
|
||||
scrollDown: true
|
||||
},
|
||||
expected: ScrollRegister.InfiniteScrollActions.DOWN
|
||||
},
|
||||
{
|
||||
it: 'should trigger up event when scrolling up',
|
||||
params: {
|
||||
scrollDown: false
|
||||
},
|
||||
expected: ScrollRegister.InfiniteScrollActions.UP
|
||||
}
|
||||
].forEach((spec) => {
|
||||
it(spec.it, () => {
|
||||
const params = { ...response, ...spec.params };
|
||||
const actual = ScrollRegister.toInfiniteScrollAction(params);
|
||||
expect(actual.type).toBe(spec.expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,192 +0,0 @@
|
||||
import * as Models from '../../src/models';
|
||||
import * as ScrollResolver from '../../src/services/scroll-resolver';
|
||||
|
||||
describe('Manage Scroll State', () => {
|
||||
it('should backup old Total and update the new one', () => {
|
||||
const state = {
|
||||
totalToScroll: 10,
|
||||
lastTotalToScroll: 0
|
||||
} as any;
|
||||
const newTotal = 20;
|
||||
ScrollResolver.updateTotalToScroll(newTotal, state);
|
||||
const actual = state.totalToScroll;
|
||||
const expected = newTotal;
|
||||
expect(actual).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should return false when total != lastTotal', () => {
|
||||
const state = {
|
||||
totalToScroll: 10,
|
||||
lastTotalToScroll: 0
|
||||
} as any;
|
||||
const actual = ScrollResolver.isSameTotalToScroll(state);
|
||||
expect(actual).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true total = lastTotal', () => {
|
||||
const state = {
|
||||
totalToScroll: 10,
|
||||
lastTotalToScroll: 10
|
||||
} as any;
|
||||
const actual = ScrollResolver.isSameTotalToScroll(state);
|
||||
expect(actual).toBeTruthy();
|
||||
});
|
||||
|
||||
[
|
||||
{
|
||||
it: 'should set the triggered to down',
|
||||
down: true,
|
||||
state: {
|
||||
triggered: { down: 0 }
|
||||
} as Models.IScrollState,
|
||||
prop: 'down'
|
||||
},
|
||||
{
|
||||
it: 'should set the triggered to up',
|
||||
down: false,
|
||||
state: {
|
||||
triggered: { up: 0 }
|
||||
} as Models.IScrollState,
|
||||
prop: 'up'
|
||||
}
|
||||
].forEach(spec => {
|
||||
it(spec.it, () => {
|
||||
const total = 1000;
|
||||
ScrollResolver.updateTriggeredFlag(total, spec.state, true, spec.down);
|
||||
const actual = spec.state.triggered[spec.prop];
|
||||
expect(actual).toBe(total);
|
||||
});
|
||||
});
|
||||
|
||||
describe('shouldFireScrollEvent() - DOWN', () => {
|
||||
const distance: Models.IScrollerDistance = {
|
||||
down: 2
|
||||
};
|
||||
const scrollingDown = true;
|
||||
it('should scroll when scrolled to the up', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 400,
|
||||
totalToScroll: 900
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = true;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
it('should NOT scroll when NOT scroll pass distance point', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 100,
|
||||
totalToScroll: 800
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = false;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
it('should NOT scroll when NOT scroll pass distance point', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 0,
|
||||
totalToScroll: 800
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = false;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
it('should NOT scroll when there is no scrollbar', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 0,
|
||||
totalToScroll: 0
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = false;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('shouldFireScrollEvent() - UP', () => {
|
||||
const distance: Models.IScrollerDistance = {
|
||||
up: 2
|
||||
};
|
||||
const scrollingDown = false;
|
||||
it('should scroll when scrolled upwards', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 50,
|
||||
totalToScroll: 900
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = true;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
it('should NOT scroll when scroll NOT pass up distance point', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 200,
|
||||
totalToScroll: 800
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = false;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
it('should scroll when at top zero point', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 0,
|
||||
totalToScroll: 800
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = true;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
|
||||
it('should NOT scroll when there is no scrollbar', () => {
|
||||
const container: Models.IPositionStats = {
|
||||
height: 500,
|
||||
scrolled: 0,
|
||||
totalToScroll: 0
|
||||
};
|
||||
const actual = ScrollResolver.shouldFireScrollEvent(
|
||||
container,
|
||||
distance,
|
||||
scrollingDown
|
||||
);
|
||||
const expected = false;
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,26 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"declaration": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "dist",
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
"inlineSources": false,
|
||||
"target": "es2015",
|
||||
"skipLibCheck": true,
|
||||
"lib": ["es2018", "dom"]
|
||||
},
|
||||
"exclude": ["node_modules", "examples", "dist"],
|
||||
"files": ["public-api.ts"],
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"annotateForClosureCompiler": true,
|
||||
"strictMetadataEmit": true,
|
||||
"flatModuleOutFile": "ngx-infinite-scroll.js",
|
||||
"flatModuleId": "ngx-infinite-scroll",
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": false,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"sourceMap": true,
|
||||
"rootDir": ".",
|
||||
"inlineSources": true,
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"target": "es5",
|
||||
"skipLibCheck": true,
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"example",
|
||||
"examples",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
100
v10/tslint.json
100
v10/tslint.json
@ -1,100 +0,0 @@
|
||||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rulesDirectory": ["node_modules/codelyzer"],
|
||||
"rules": {
|
||||
"align": {
|
||||
"options": [
|
||||
"parameters",
|
||||
"statements"
|
||||
]
|
||||
},
|
||||
"arrow-return-shorthand": true,
|
||||
"directive-selector": [true, "attribute", "camelCase"],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"kebab-case"
|
||||
],
|
||||
"curly": true,
|
||||
"no-inputs-metadata-property": true,
|
||||
"no-outputs-metadata-property": true,
|
||||
"eofline": true,
|
||||
"import-spacing": true,
|
||||
"indent": {
|
||||
"options": [
|
||||
"spaces"
|
||||
]
|
||||
},
|
||||
"no-host-metadata-property": true,
|
||||
"no-attribute-decorator": true,
|
||||
"no-input-rename": true,
|
||||
"no-output-rename": true,
|
||||
"no-forward-ref": true,
|
||||
"use-life-cycle-interface": true,
|
||||
"use-pipe-transform-interface": true,
|
||||
"no-unused-expression": true,
|
||||
"component-class-suffix": [true, "Component"],
|
||||
"directive-class-suffix": [true, "Directive"],
|
||||
"object-literal-sort-keys": false,
|
||||
"ordered-imports": [
|
||||
false
|
||||
],
|
||||
"semicolon": {
|
||||
"options": [
|
||||
"always"
|
||||
]
|
||||
},
|
||||
"space-before-function-paren": {
|
||||
"options": {
|
||||
"anonymous": "never",
|
||||
"asyncArrow": "always",
|
||||
"constructor": "never",
|
||||
"method": "never",
|
||||
"named": "never"
|
||||
}
|
||||
},
|
||||
"quotemark": [
|
||||
false
|
||||
],
|
||||
"typedef-whitespace": {
|
||||
"options": [
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
},
|
||||
{
|
||||
"call-signature": "onespace",
|
||||
"index-signature": "onespace",
|
||||
"parameter": "onespace",
|
||||
"property-declaration": "onespace",
|
||||
"variable-declaration": "onespace"
|
||||
}
|
||||
]
|
||||
},
|
||||
"trailing-comma": [false],
|
||||
"member-access": [
|
||||
false,
|
||||
"check-accessor"
|
||||
],
|
||||
"variable-name": {
|
||||
"options": [
|
||||
"ban-keywords",
|
||||
"check-format",
|
||||
"allow-pascal-case"
|
||||
]
|
||||
},
|
||||
"whitespace": {
|
||||
"options": [
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type",
|
||||
"check-typecast"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user