├── projects └── aem-angular-core-spa-wcm-components │ ├── core │ ├── tslint.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ ├── ng-package.json │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── public-api.ts │ │ ├── core.module.ts │ │ ├── test.ts │ │ ├── common.ts │ │ ├── AbstractContainerComponent.ts │ │ └── AbstractContainerComponent.spec.ts │ ├── karma.conf.js │ ├── common.ts │ └── README.md │ ├── containers │ ├── tabs │ │ └── v1 │ │ │ ├── tslint.json │ │ │ ├── tsconfig.lib.prod.json │ │ │ ├── tsconfig.lib.json │ │ │ ├── tsconfig.spec.json │ │ │ ├── ng-package.json │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── public-api.ts │ │ │ ├── test.ts │ │ │ ├── tabs.v1.module.ts │ │ │ ├── tabs.v1.component.html │ │ │ ├── tabs.v1.component.ts │ │ │ └── tabs.v1.component.spec.ts │ │ │ ├── karma.conf.js │ │ │ └── README.md │ ├── accordion │ │ └── v1 │ │ │ ├── tslint.json │ │ │ ├── tsconfig.lib.prod.json │ │ │ ├── tsconfig.lib.json │ │ │ ├── tsconfig.spec.json │ │ │ ├── ng-package.json │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── public-api.ts │ │ │ ├── test.ts │ │ │ ├── accordion.v1.module.ts │ │ │ ├── accordion.v1.component.html │ │ │ ├── accordion.v1.component.ts │ │ │ └── accordion.v1.component.spec.ts │ │ │ ├── karma.conf.js │ │ │ └── README.md │ ├── carousel │ │ └── v1 │ │ │ ├── tslint.json │ │ │ ├── tsconfig.lib.prod.json │ │ │ ├── tsconfig.lib.json │ │ │ ├── tsconfig.spec.json │ │ │ ├── ng-package.json │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── src │ │ │ ├── public-api.ts │ │ │ ├── test.ts │ │ │ ├── carousel.v1.module.ts │ │ │ ├── carousel.v1.component.html │ │ │ ├── carousel.v1.component.ts │ │ │ └── carousel.v1.component.spec.ts │ │ │ ├── karma.conf.js │ │ │ └── README.md │ └── container │ │ └── v1 │ │ ├── tslint.json │ │ ├── tsconfig.lib.prod.json │ │ ├── tsconfig.lib.json │ │ ├── tsconfig.spec.json │ │ ├── ng-package.json │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ ├── public-api.ts │ │ ├── test.ts │ │ ├── container.v1.module.ts │ │ ├── container.v1.component.html │ │ ├── container.v1.component.ts │ │ └── container.v1.spec.ts │ │ ├── karma.conf.js │ │ └── README.md │ ├── src │ ├── randomCode.ts │ ├── randomCode.spec.ts │ ├── public-api.ts │ ├── test.ts │ └── aem-angular-core-spa-wcm-components.module.ts │ ├── tsconfig.lib.prod.json │ ├── tslint.json │ ├── ng-package.json │ ├── tsconfig.spec.json │ ├── test │ ├── data │ │ ├── experience-fragment-empty.json │ │ ├── carousel.json │ │ ├── tabs.json │ │ ├── accordion.json │ │ ├── experience-fragment.json │ │ ├── container.json │ │ └── layout.json │ ├── test-comp1.component.ts │ ├── test-comp2.component.ts │ ├── test-comp3.component.ts │ └── mapping.ts │ ├── package-lock.json │ ├── package.json │ ├── tsconfig.lib.json │ ├── karma.conf.js │ └── README.md ├── .npmignore ├── .gitignore ├── .github ├── workflows │ ├── security.yml │ ├── ci.yml │ └── release.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── renovate.json ├── update-version.js ├── README.md ├── combine-coverage.js ├── tsconfig.json ├── karma-conf-generator.local.js ├── karma-conf-generator.js ├── tslint.json ├── package.json ├── pom.xml ├── angular.json └── LICENSE /projects/aem-angular-core-spa-wcm-components/core/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json" 3 | } 4 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tslint.json" 3 | } 4 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tslint.json" 3 | } 4 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tslint.json" 3 | } 4 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tslint.json" 3 | } 4 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/src/randomCode.ts: -------------------------------------------------------------------------------- 1 | export const something = () => { 2 | return 5 + 2; 3 | }; 4 | 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | config 2 | node 3 | node_modules 4 | .eslintignore 5 | .gitignore 6 | *.iml 7 | jest.config.js 8 | pom.xml 9 | tsconfig.json -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "exclude": [ 4 | "src/test.ts", 5 | "**/*.spec.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "angularCompilerOptions": { 4 | "enableIvy": false 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.lib.json", 3 | "exclude": [ 4 | "src/test.ts", 5 | "**/*.spec.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.lib.json", 3 | "exclude": [ 4 | "src/test.ts", 5 | "**/*.spec.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.lib.json", 3 | "exclude": [ 4 | "src/test.ts", 5 | "**/*.spec.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.lib.json", 3 | "exclude": [ 4 | "src/test.ts", 5 | "**/*.spec.ts" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.spec.json", 3 | "files": [ 4 | "src/test.ts" 5 | ], 6 | "include": [ 7 | "**/*.spec.ts", 8 | "**/*.d.ts" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "files": [ 4 | "src/test.ts" 5 | ], 6 | "include": [ 7 | "**/*.spec.ts", 8 | "**/*.d.ts" 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "files": [ 4 | "src/test.ts" 5 | ], 6 | "include": [ 7 | "**/*.spec.ts", 8 | "**/*.d.ts" 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "files": [ 4 | "src/test.ts" 5 | ], 6 | "include": [ 7 | "**/*.spec.ts", 8 | "**/*.d.ts" 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.spec.json", 3 | "files": [ 4 | "src/test.ts" 5 | ], 6 | "include": [ 7 | "**/*.spec.ts", 8 | "**/*.d.ts" 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/src/randomCode.spec.ts: -------------------------------------------------------------------------------- 1 | import {something} from "./randomCode"; 2 | 3 | describe('something', () => { 4 | 5 | it('should create placeholder', () => { 6 | const someNumber:number = something(); 7 | 8 | expect(someNumber).toBe(7) 9 | }); 10 | 11 | 12 | }); -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../dist/aem-angular-core-spa-wcm-components/core", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "." 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "lib", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "lib", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../../../dist/aem-angular-core-spa-wcm-components/containers/tabs/v1", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "." 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/aem-angular-core-spa-wcm-components", 4 | "lib": { 5 | "entryFile": "src/public-api.ts", 6 | "umdModuleIds": { 7 | "@adobe/aem-angular-editable-components": "aemAngularEditableComponents" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/experience-fragment-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "localizedFragmentVariationPath": "/content/experience-fragments/angulartest/master/jcr:content", 3 | "pathConfigured": false, 4 | ":items": { 5 | }, 6 | ":itemsOrder": [], 7 | "classNames": "aem-xf", 8 | ":type": "core/wcm/components/experiencefragment/v2/experiencefragment" 9 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../../../dist/aem-angular-core-spa-wcm-components/containers/accordion/v1", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "." 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../../../dist/aem-angular-core-spa-wcm-components/containers/carousel/v1", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "." 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../../../../dist/aem-angular-core-spa-wcm-components/containers/container/v1", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | }, 7 | "whitelistedNonPeerDependencies": [ 8 | "." 9 | ] 10 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .idea 3 | .classpath 4 | .metadata 5 | .project 6 | .settings 7 | .externalToolBuilders 8 | maven-eclipse.xml 9 | *.swp 10 | *.iml 11 | *.ipr 12 | *.iws 13 | *.bak 14 | .vlt 15 | .DS_Store 16 | jcr.log 17 | atlassian-ide-plugin.xml 18 | .vlt-sync.log 19 | .vlt-sync-config.properties 20 | node 21 | node_modules 22 | 23 | dist 24 | coverage 25 | 26 | **/clientlibs/angular-spacomponents/resources/**/* 27 | **/clientlibs/angular-webcomponents/resources/**/* -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa", 3 | "version": "1.0.4", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "tslib": { 8 | "version": "1.13.0", 9 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 10 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-core", 3 | "version": "0.0.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "tslib": { 8 | "version": "1.14.1", 9 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 10 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-tabs-v1", 3 | "version": "0.0.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "tslib": { 8 | "version": "1.14.1", 9 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 10 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-carousel-v1", 3 | "version": "0.0.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "tslib": { 8 | "version": "1.14.1", 9 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 10 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/security.yml: -------------------------------------------------------------------------------- 1 | name: Vulnerability check 2 | on: 3 | push: 4 | branches: 5 | - master 6 | pull_request_target: 7 | 8 | jobs: 9 | security: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout source code 13 | uses: actions/checkout@master 14 | - name: Run Snyk to check for vulnerabilities 15 | uses: snyk/actions/node@master 16 | env: 17 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} 18 | with: 19 | command: monitor --all-projects --exclude=examples,pom.xml 20 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-accordion-v1", 3 | "version": "0.0.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "tslib": { 8 | "version": "1.14.1", 9 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 10 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-container-v1", 3 | "version": "0.0.6", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "tslib": { 8 | "version": "1.14.1", 9 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 10 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-core", 3 | "version": "0.0.6", 4 | "author": "Adobe Systems Inc.", 5 | "license": "Apache-2.0", 6 | "peerDependencies": { 7 | "@adobe/aem-angular-editable-components": "^1.0.3", 8 | "@adobe/aem-spa-component-mapping": "^1.0.5", 9 | "@adobe/aem-spa-page-model-manager": "^1.0.3", 10 | "@angular/common": "^9.1.12", 11 | "@angular/core": "^9.1.12" 12 | }, 13 | "dependencies": { 14 | "tslib": "^1.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-tabs-v1", 3 | "version": "0.0.6", 4 | "author": "Adobe Systems Inc.", 5 | "license": "Apache-2.0", 6 | "peerDependencies": { 7 | "@adobe/aem-angular-editable-components": "^1.0.3", 8 | "@adobe/aem-spa-component-mapping": "^1.0.5", 9 | "@adobe/aem-spa-page-model-manager": "^1.0.3", 10 | "@angular/common": "^9.1.12", 11 | "@angular/core": "^9.1.12" 12 | }, 13 | "dependencies": { 14 | "tslib": "^1.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /update-version.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const generatedPackageJson = require('./dist/aem-angular-core-spa-wcm-components/package.json'); 5 | 6 | const sourcePackageJson = require('./projects/aem-angular-core-spa-wcm-components/package.json'); 7 | 8 | const destPath = path.join('projects', 'aem-angular-core-spa-wcm-components', 'package.json'); 9 | 10 | sourcePackageJson['version'] = generatedPackageJson['version']; 11 | 12 | const data = JSON.stringify(sourcePackageJson,null, 4); 13 | fs.writeFileSync(destPath,data,{encoding:'utf8',flag:'w'}) -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-accordion-v1", 3 | "version": "0.0.6", 4 | "author": "Adobe Systems Inc.", 5 | "license": "Apache-2.0", 6 | "peerDependencies": { 7 | "@adobe/aem-angular-editable-components": "^1.0.3", 8 | "@adobe/aem-spa-component-mapping": "^1.0.5", 9 | "@adobe/aem-spa-page-model-manager": "^1.0.3", 10 | "@angular/common": "^9.1.12", 11 | "@angular/core": "^9.1.12" 12 | }, 13 | "dependencies": { 14 | "tslib": "^1.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-carousel-v1", 3 | "version": "0.0.6", 4 | "author": "Adobe Systems Inc.", 5 | "license": "Apache-2.0", 6 | "peerDependencies": { 7 | "@adobe/aem-angular-editable-components": "^1.0.3", 8 | "@adobe/aem-spa-component-mapping": "^1.0.5", 9 | "@adobe/aem-spa-page-model-manager": "^1.0.3", 10 | "@angular/common": "^9.1.12", 11 | "@angular/core": "^9.1.12" 12 | }, 13 | "dependencies": { 14 | "tslib": "^1.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa-container-v1", 3 | "version": "0.0.6", 4 | "author": "Adobe Systems Inc.", 5 | "license": "Apache-2.0", 6 | "peerDependencies": { 7 | "@adobe/aem-angular-editable-components": "^1.0.3", 8 | "@adobe/aem-spa-component-mapping": "^1.0.5", 9 | "@adobe/aem-spa-page-model-manager": "^1.0.3", 10 | "@angular/common": "^9.1.12", 11 | "@angular/core": "^9.1.12" 12 | }, 13 | "dependencies": { 14 | "tslib": "^1.10.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@adobe/aem-core-components-angular-spa", 3 | "version": "1.0.8", 4 | "author": "Adobe Systems Inc.", 5 | "license": "Apache-2.0", 6 | "peerDependencies": { 7 | "@adobe/aem-angular-editable-components": "^1.0.3", 8 | "@adobe/aem-spa-component-mapping": "^1.0.5", 9 | "@adobe/aem-spa-page-model-manager": "^1.0.3", 10 | "@angular/common": "^9.1.12", 11 | "@angular/core": "^9.1.12" 12 | }, 13 | "dependencies": { 14 | "tslib": "^1.10.0" 15 | } 16 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "declaration": true, 7 | "inlineSources": true, 8 | "types": [], 9 | "lib": [ 10 | "dom", 11 | "es2018" 12 | ] 13 | }, 14 | "angularCompilerOptions": { 15 | "skipTemplateCodegen": true, 16 | "strictMetadataEmit": true, 17 | "enableResourceInlining": true, 18 | "enableIvy": false 19 | }, 20 | "exclude": [ 21 | "test.ts", 22 | "**/*.spec.ts" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | on: pull_request_target 3 | 4 | jobs: 5 | test-angular-base-components: 6 | name: test angular-base-components 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout source code 10 | uses: actions/checkout@v2 11 | - name: Setup Node.js 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: '12' 15 | - name: Install dependencies 16 | run: npm ci 17 | - name: Build the project 18 | run: npm run build-prod 19 | - name: Run tests and do code coverage check 20 | run: npm run test -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[feature] " 5 | labels: feature-request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[bug]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Package version** 14 | Provide a package version where the bug occurs. 15 | 16 | **To Reproduce** 17 | Steps to reproduce the behavior: 18 | 1. Go to '...' 19 | 2. Click on '....' 20 | 3. Scroll down to '....' 21 | 4. See error 22 | 23 | **Expected behavior** 24 | A clear and concise description of what you expected to happen. 25 | 26 | **Screenshots** 27 | If applicable, add screenshots to help explain your problem. 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | release: 8 | name: Release and publish module 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout source code 12 | uses: actions/checkout@v2 13 | with: 14 | fetch-depth: 0 15 | - name: Setup Node.js 16 | uses: actions/setup-node@v2 17 | with: 18 | node-version: 12 19 | - name: Install dependencies 20 | run: npm ci 21 | - name: Build the project 22 | run: npm run build-prod 23 | - name: Run tests and do code coverage check 24 | run: npm run test 25 | - name: Release module and publish it in github.com and npmjs.com 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 28 | NPM_TOKEN: ${{ secrets.ADOBE_BOT_NPM_TOKEN }} 29 | run: npm run semantic-release 30 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | export * from "./tabs.v1.component"; 18 | export * from "./tabs.v1.module"; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/carousel.json: -------------------------------------------------------------------------------- 1 | { 2 | ":items": 3 | { 4 | "component1": 5 | { 6 | "cq:panelTitle": "Tab1", 7 | "title": "Component1", 8 | ":type": "app/components/comp1" 9 | 10 | }, 11 | "component2": 12 | { 13 | "cq:panelTitle": "Tab2", 14 | "title": "Component2", 15 | ":type": "app/components/comp2" 16 | }, 17 | "component3": 18 | { 19 | "cq:panelTitle": "Tab3", 20 | "title": "Component3", 21 | ":type": "app/components/comp3" 22 | }, 23 | "component4": 24 | { 25 | "cq:panelTitle": "Tab4", 26 | "title": "Component4", 27 | ":type": "app/components/comp2" 28 | }, 29 | "component5": 30 | { 31 | "cq:panelTitle": "Tab5", 32 | "title": "Component5", 33 | ":type": "app/components/comp1" 34 | } 35 | }, 36 | ":itemsOrder": ["component1", "component3", "component5", "component2", "component4"] 37 | } 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/tabs.json: -------------------------------------------------------------------------------- 1 | { 2 | ":items": 3 | { 4 | "component1": 5 | { 6 | "cq:panelTitle": "Tab1", 7 | "title": "Component1", 8 | ":type": "app/components/comp1" 9 | 10 | }, 11 | "component2": 12 | { 13 | "cq:panelTitle": "Tab2", 14 | "title": "Component2", 15 | ":type": "app/components/comp2" 16 | }, 17 | "component3": 18 | { 19 | "cq:panelTitle": "Tab3", 20 | "title": "Component3", 21 | ":type": "app/components/comp3" 22 | }, 23 | "component4": 24 | { 25 | "cq:panelTitle": "Tab4", 26 | "title": "Component4", 27 | ":type": "app/components/comp2" 28 | }, 29 | "component5": 30 | { 31 | "cq:panelTitle": "Tab5", 32 | "title": "Component5", 33 | ":type": "app/components/comp1" 34 | } 35 | }, 36 | ":itemsOrder": ["component1", "component3", "component5", "component2", "component4"] 37 | } 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | export * from "./carousel.v1.component"; 18 | export * from "./carousel.v1.module"; 19 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | export * from "./accordion.v1.component"; 18 | export * from "./accordion.v1.module"; 19 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | export * from "./container.v1.component"; 18 | export * from "./container.v1.module"; 19 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | export * from "./core.module"; 18 | export * from "./AbstractContainerComponent"; 19 | export * from "./common"; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/accordion.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "testaccordion", 3 | ":items": 4 | { 5 | "component1": 6 | { 7 | "cq:panelTitle": "Tab1", 8 | "title": "Component1", 9 | ":type": "app/components/comp1" 10 | 11 | }, 12 | "component2": 13 | { 14 | "cq:panelTitle": "Tab2", 15 | "title": "Component2", 16 | ":type": "app/components/comp2" 17 | }, 18 | "component3": 19 | { 20 | "cq:panelTitle": "Tab3", 21 | "title": "Component3", 22 | ":type": "app/components/comp3" 23 | }, 24 | "component4": 25 | { 26 | "cq:panelTitle": "Tab4", 27 | "title": "Component4", 28 | ":type": "app/components/comp2" 29 | }, 30 | "component5": 31 | { 32 | "cq:panelTitle": "Tab5", 33 | "title": "Component5", 34 | ":type": "app/components/comp1" 35 | } 36 | }, 37 | ":itemsOrder": ["component1", "component3", "component5", "component2", "component4"] 38 | } 39 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "timezone": "Europe/Zurich", 3 | "masterIssue": true, 4 | "packageRules": [ 5 | { 6 | "groupName": "@adobe fixes", 7 | "updateTypes": ["patch", "pin", "digest", "minor"], 8 | "automerge": true, 9 | "packagePatterns": ["^@adobe/"], 10 | "schedule": ["at any time"] 11 | }, 12 | { 13 | "groupName": "@adobe major", 14 | "updateTypes": ["major"], 15 | "packagePatterns": ["^@adobe/"], 16 | "automerge": false, 17 | "schedule": ["at any time"] 18 | }, 19 | { 20 | "groupName": "external fixes", 21 | "updateTypes": ["patch", "pin", "digest", "minor"], 22 | "automerge": false, 23 | "schedule": ["after 1pm on Monday"], 24 | "packagePatterns": ["^.+"], 25 | "excludePackagePatterns": ["^@adobe/"] 26 | }, 27 | { 28 | "groupName": "external major", 29 | "updateTypes": ["major"], 30 | "automerge": false, 31 | "packagePatterns": ["^.+"], 32 | "excludePackagePatterns": ["^@adobe/"], 33 | "schedule": ["after 1pm on Monday"] 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AngularCore 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.8. 4 | 5 | ## Development server 6 | 7 | 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. 8 | 9 | ## Code scaffolding 10 | 11 | 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`. 12 | 13 | ## Build 14 | 15 | 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. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | 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). 28 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/experience-fragment.json: -------------------------------------------------------------------------------- 1 | { 2 | "localizedFragmentVariationPath": "/content/experience-fragments/angulartest/master/jcr:content", 3 | "pathConfigured": true, 4 | ":items": { 5 | "component1": { 6 | "title": "Component1", 7 | ":type": "app/components/comp1" 8 | }, 9 | "component2": { 10 | "title": "Component2", 11 | ":type": "app/components/comp2" 12 | }, 13 | "component3": { 14 | "title": "Component3", 15 | ":type": "app/components/comp3" 16 | }, 17 | "component4": { 18 | "title": "Component4", 19 | ":type": "app/components/comp2" 20 | }, 21 | "component5": { 22 | "title": "Component5", 23 | ":type": "app/components/comp1" 24 | } 25 | }, 26 | ":itemsOrder": [ 27 | "component1", 28 | "component3", 29 | "component5", 30 | "component2", 31 | "component4" 32 | ], 33 | "classNames": "aem-xf myCustomCssClass", 34 | ":type": "core/wcm/components/experiencefragment/v2/experiencefragment" 35 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/test-comp1.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import { Component, Input } from '@angular/core'; 19 | 20 | @Component({ 21 | selector: 'test-comp1', 22 | host: { 23 | '[attr.data-title]': 'title' 24 | }, 25 | template: `
{{ title }}
` 26 | }) 27 | 28 | export class Component1 { 29 | @Input() title:any; 30 | 31 | constructor() {} 32 | } 33 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/test-comp2.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import { Component, Input } from '@angular/core'; 19 | 20 | @Component({ 21 | selector: 'test-comp2', 22 | host: { 23 | '[attr.data-title]': 'title' 24 | }, 25 | template: `
{{ title }}
` 26 | }) 27 | 28 | export class Component2 { 29 | @Input() title:any; 30 | 31 | constructor() {} 32 | } 33 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/test-comp3.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | 19 | import { Component, Input } from '@angular/core'; 20 | 21 | @Component({ 22 | selector: 'test-comp3', 23 | host: { 24 | '[attr.data-title]': 'title' 25 | }, 26 | template: `
{{ title }}
` 27 | }) 28 | 29 | export class Component3 { 30 | @Input() title:any; 31 | constructor() {} 32 | } 33 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | 20 | const karmaConfigGenerator = require('../../karma-conf-generator'); 21 | 22 | module.exports = function (config) { 23 | return karmaConfigGenerator(config, 'aem-angular-core-spa-wcm-components'); 24 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | 20 | const karmaConfigGenerator = require('../../../karma-conf-generator'); 21 | 22 | module.exports = function (config) { 23 | return karmaConfigGenerator(config, 'aem-angular-core-spa-wcm-components-core'); 24 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/common.ts: -------------------------------------------------------------------------------- 1 | import {ComponentMapping} from "@adobe/aem-angular-editable-components"; 2 | 3 | export interface ContainerProperties { 4 | componentMapping?: typeof ComponentMapping; 5 | cqItems: {[key: string]: Model}; 6 | cqItemsOrder: string[]; 7 | baseCssClass: string; 8 | } 9 | 10 | export interface ContainerModel extends Model{ 11 | 12 | } 13 | 14 | 15 | export interface Model extends Object { 16 | ":hierarchyType"?: string; 17 | /** 18 | * Path of the item/page 19 | */ 20 | ":path"?: string; 21 | /** 22 | * Child pages (only present on page's itself, not on items) 23 | */ 24 | ":children"?: {[key: string]: Model}; 25 | 26 | /** 27 | * Items under the page / item 28 | */ 29 | ":items"?: {[key: string]: Model}; 30 | 31 | /** 32 | * Order of the items under the page / item 33 | * Can be used as keys for the :items property to iterate items in the proper order 34 | */ 35 | ":itemsOrder"?: string[]; 36 | 37 | /** 38 | * Resource type of the page / item 39 | */ 40 | ":type"?: string; 41 | } 42 | 43 | export interface LabelledModel extends Model{ 44 | "cq:panelTitle": string 45 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | const karmaConfigGenerator = require('../../../../../karma-conf-generator'); 20 | 21 | module.exports = function (config) { 22 | return karmaConfigGenerator(config, 'aem-angular-core-spa-wcm-components-carousel-v1'); 23 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | 20 | const karmaConfigGenerator = require('../../../../../karma-conf-generator'); 21 | 22 | module.exports = function (config) { 23 | return karmaConfigGenerator(config, 'aem-angular-core-spa-wcm-components-tabs-v1'); 24 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | const karmaConfigGenerator = require('../../../../../karma-conf-generator'); 20 | 21 | module.exports = function (config) { 22 | return karmaConfigGenerator(config, 'aem-angular-core-spa-wcm-components-accordion-v1'); 23 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/karma.conf.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | 20 | const karmaConfigGenerator = require('../../../../../karma-conf-generator'); 21 | 22 | module.exports = function (config) { 23 | return karmaConfigGenerator(config, 'aem-angular-core-spa-wcm-components-container-v1'); 24 | }; -------------------------------------------------------------------------------- /combine-coverage.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | const createReporter = require('istanbul-api').createReporter; 19 | const istanbulCoverage = require('istanbul-lib-coverage'); 20 | const coverage = require('./coverage/coverage-final.json'); 21 | 22 | const map = istanbulCoverage.createCoverageMap(); 23 | Object.keys(coverage).forEach(filename => map.addFileCoverage(coverage[filename])); 24 | 25 | const reporter = createReporter(); 26 | reporter.addAll(['html', 'lcovonly', 'text-summary']); 27 | reporter.write(map); -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/README.md: -------------------------------------------------------------------------------- 1 | # AemAngularCoreSpaWcmComponents 2 | 3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.12. 4 | 5 | ## Code scaffolding 6 | 7 | Run `ng generate component component-name --project aem-angular-core-spa-wcm-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project aem-angular-core-spa-wcm-components`. 8 | > Note: Don't forget to add `--project aem-angular-core-spa-wcm-components` or else it will be added to the default project in your `angular.json` file. 9 | 10 | ## Build 11 | 12 | Run `ng build aem-angular-core-spa-wcm-components` to build the project. The build artifacts will be stored in the `dist/` directory. 13 | 14 | ## Publishing 15 | 16 | After building your library with `ng build aem-angular-core-spa-wcm-components`, go to the dist folder `cd dist/aem-angular-core-spa-wcm-components` and run `npm publish`. 17 | 18 | ## Running unit tests 19 | 20 | Run `ng test aem-angular-core-spa-wcm-components` to execute the unit tests via [Karma](https://karma-runner.github.io). 21 | 22 | ## Further help 23 | 24 | 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). 25 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/src/public-api.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | export * from './aem-angular-core-spa-wcm-components.module'; 18 | 19 | export * from "@adobe/aem-core-components-angular-spa/core"; 20 | export * from "@adobe/aem-core-components-angular-spa/containers/accordion/v1"; 21 | export * from "@adobe/aem-core-components-angular-spa/containers/carousel/v1"; 22 | export * from "@adobe/aem-core-components-angular-spa/containers/container/v1"; 23 | export * from "@adobe/aem-core-components-angular-spa/containers/tabs/v1"; 24 | 25 | 26 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/README.md: -------------------------------------------------------------------------------- 1 | # AemAngularCoreSpaWcmComponents 2 | 3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.12. 4 | 5 | ## Code scaffolding 6 | 7 | Run `ng generate component component-name --project aem-angular-core-spa-wcm-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project aem-angular-core-spa-wcm-components`. 8 | > Note: Don't forget to add `--project aem-angular-core-spa-wcm-components` or else it will be added to the default project in your `angular.json` file. 9 | 10 | ## Build 11 | 12 | Run `ng build aem-angular-core-spa-wcm-components` to build the project. The build artifacts will be stored in the `dist/` directory. 13 | 14 | ## Publishing 15 | 16 | After building your library with `ng build aem-angular-core-spa-wcm-components`, go to the dist folder `cd dist/aem-angular-core-spa-wcm-components` and run `npm publish`. 17 | 18 | ## Running unit tests 19 | 20 | Run `ng test aem-angular-core-spa-wcm-components` to execute the unit tests via [Karma](https://karma-runner.github.io). 21 | 22 | ## Further help 23 | 24 | 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). 25 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/README.md: -------------------------------------------------------------------------------- 1 | # AemAngularCoreSpaWcmComponents 2 | 3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.12. 4 | 5 | ## Code scaffolding 6 | 7 | Run `ng generate component component-name --project aem-angular-core-spa-wcm-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project aem-angular-core-spa-wcm-components`. 8 | > Note: Don't forget to add `--project aem-angular-core-spa-wcm-components` or else it will be added to the default project in your `angular.json` file. 9 | 10 | ## Build 11 | 12 | Run `ng build aem-angular-core-spa-wcm-components` to build the project. The build artifacts will be stored in the `dist/` directory. 13 | 14 | ## Publishing 15 | 16 | After building your library with `ng build aem-angular-core-spa-wcm-components`, go to the dist folder `cd dist/aem-angular-core-spa-wcm-components` and run `npm publish`. 17 | 18 | ## Running unit tests 19 | 20 | Run `ng test aem-angular-core-spa-wcm-components` to execute the unit tests via [Karma](https://karma-runner.github.io). 21 | 22 | ## Further help 23 | 24 | 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). 25 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/README.md: -------------------------------------------------------------------------------- 1 | # AemAngularCoreSpaWcmComponents 2 | 3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.12. 4 | 5 | ## Code scaffolding 6 | 7 | Run `ng generate component component-name --project aem-angular-core-spa-wcm-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project aem-angular-core-spa-wcm-components`. 8 | > Note: Don't forget to add `--project aem-angular-core-spa-wcm-components` or else it will be added to the default project in your `angular.json` file. 9 | 10 | ## Build 11 | 12 | Run `ng build aem-angular-core-spa-wcm-components` to build the project. The build artifacts will be stored in the `dist/` directory. 13 | 14 | ## Publishing 15 | 16 | After building your library with `ng build aem-angular-core-spa-wcm-components`, go to the dist folder `cd dist/aem-angular-core-spa-wcm-components` and run `npm publish`. 17 | 18 | ## Running unit tests 19 | 20 | Run `ng test aem-angular-core-spa-wcm-components` to execute the unit tests via [Karma](https://karma-runner.github.io). 21 | 22 | ## Further help 23 | 24 | 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). 25 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/README.md: -------------------------------------------------------------------------------- 1 | # AemAngularCoreSpaWcmComponents 2 | 3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.1.12. 4 | 5 | ## Code scaffolding 6 | 7 | Run `ng generate component component-name --project aem-angular-core-spa-wcm-components` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project aem-angular-core-spa-wcm-components`. 8 | > Note: Don't forget to add `--project aem-angular-core-spa-wcm-components` or else it will be added to the default project in your `angular.json` file. 9 | 10 | ## Build 11 | 12 | Run `ng build aem-angular-core-spa-wcm-components` to build the project. The build artifacts will be stored in the `dist/` directory. 13 | 14 | ## Publishing 15 | 16 | After building your library with `ng build aem-angular-core-spa-wcm-components`, go to the dist folder `cd dist/aem-angular-core-spa-wcm-components` and run `npm publish`. 17 | 18 | ## Running unit tests 19 | 20 | Run `ng test aem-angular-core-spa-wcm-components` to execute the unit tests via [Karma](https://karma-runner.github.io). 21 | 22 | ## Further help 23 | 24 | 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). 25 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/mapping.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | 19 | import { MapTo, AEMResponsiveGridComponent } from "@adobe/aem-angular-editable-components"; 20 | 21 | import { Component1 } from "./test-comp1.component"; 22 | import { Component2 } from "./test-comp2.component"; 23 | import { Component3 } from "./test-comp3.component"; 24 | 25 | MapTo("app/components/comp1")(Component1); 26 | MapTo("app/components/comp2")(Component2); 27 | MapTo("app/components/comp3")(Component3); 28 | MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent); 29 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/src/core.module.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {NgModule} from '@angular/core'; 18 | import {CommonModule} from "@angular/common"; 19 | import {BrowserModule} from "@angular/platform-browser"; 20 | import {RouterModule} from "@angular/router"; 21 | import {AbstractContainerComponent} from "./AbstractContainerComponent"; 22 | 23 | @NgModule({ 24 | imports: [CommonModule, RouterModule], 25 | declarations: [AbstractContainerComponent], 26 | exports: [AbstractContainerComponent], 27 | entryComponents: [AbstractContainerComponent], 28 | }) 29 | export class AemAngularCoreSpaWcmComponentsCore { 30 | } 31 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/container.json: -------------------------------------------------------------------------------- 1 | { 2 | "gridClassNames": "aem-Grid-root-responsivegrid", 3 | "columnClassNames": { 4 | "component1": "aem-GridColumn-root-responsivegrid-component1", 5 | "component2": "aem-GridColumn-root-responsivegrid-component2", 6 | "component3": "aem-GridColumn-root-responsivegrid-component3", 7 | "component4": "aem-GridColumn-root-responsivegrid-component4", 8 | "component5": "aem-GridColumn-root-responsivegrid-component5" 9 | }, 10 | "columnCount": 12, 11 | ":items": { 12 | "component1": { 13 | "title": "Component1", 14 | ":type": "app/components/comp1" 15 | }, 16 | "component2": { 17 | "title": "Component2", 18 | ":type": "app/components/comp2" 19 | }, 20 | "component3": { 21 | "title": "Component3", 22 | ":type": "app/components/comp3" 23 | }, 24 | "component4": { 25 | "title": "Component4", 26 | ":type": "app/components/comp2" 27 | }, 28 | "component5": { 29 | "title": "Component5", 30 | ":type": "app/components/comp1" 31 | } 32 | }, 33 | ":itemsOrder": [ 34 | "component1", 35 | "component3", 36 | "component5", 37 | "component2", 38 | "component4" 39 | ], 40 | ":type": "wcm/foundation/components/responsivegrid" 41 | } 42 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "emitDecoratorMetadata": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "importHelpers": true, 14 | "target": "es2015", 15 | "lib": [ 16 | "es2020", 17 | "dom" 18 | ], 19 | "paths": { 20 | "@angular/*": ["./node_modules/@angular/*"], 21 | "@adobe/aem-core-components-angular-spa": [ 22 | "./dist/aem-angular-core-spa-wcm-components" 23 | ], 24 | "@adobe/aem-core-components-angular-spa/*": [ 25 | "./dist/aem-angular-core-spa-wcm-components/*" 26 | ], 27 | "@adobe/aem-core-components-angular-base": [ 28 | "./dist/aem-angular-core-wcm-components" 29 | ], 30 | "@adobe/aem-core-components-angular-base/*": [ 31 | "./dist/aem-angular-core-wcm-components/*" 32 | ], 33 | "@adobe/aem-angular-editable-components":[ 34 | "./node_modules/@adobe/aem-angular-editable-components" 35 | ] 36 | } 37 | }, 38 | "angularCompilerOptions": { 39 | "enableIvy": false, 40 | "fullTemplateTypeCheck": true, 41 | "strictInjectionParameters": true 42 | } 43 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/src/test.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import 'core-js/features/reflect'; 19 | import 'zone.js/dist/zone'; 20 | import 'zone.js/dist/zone-testing'; 21 | import { getTestBed } from '@angular/core/testing'; 22 | import { 23 | BrowserDynamicTestingModule, 24 | platformBrowserDynamicTesting 25 | } from '@angular/platform-browser-dynamic/testing'; 26 | 27 | declare const require: any; 28 | 29 | // First, initialize the Angular testing environment. 30 | getTestBed().initTestEnvironment( 31 | BrowserDynamicTestingModule, 32 | platformBrowserDynamicTesting() 33 | ); 34 | // Then we find all the tests. 35 | const context = require.context('./../', true, /\.spec\.ts$/); 36 | // And load the modules. 37 | context.keys().map(context); 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/test.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import 'core-js/features/reflect'; 19 | import 'zone.js/dist/zone'; 20 | import 'zone.js/dist/zone-testing'; 21 | import { getTestBed } from '@angular/core/testing'; 22 | import { 23 | BrowserDynamicTestingModule, 24 | platformBrowserDynamicTesting 25 | } from '@angular/platform-browser-dynamic/testing'; 26 | 27 | declare const require: any; 28 | 29 | // First, initialize the Angular testing environment. 30 | getTestBed().initTestEnvironment( 31 | BrowserDynamicTestingModule, 32 | platformBrowserDynamicTesting() 33 | ); 34 | // Then we find all the tests. 35 | const context = require.context('./../', true, /\.spec\.ts$/); 36 | // And load the modules. 37 | context.keys().map(context); 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/test.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import 'core-js/features/reflect'; 19 | import 'zone.js/dist/zone'; 20 | import 'zone.js/dist/zone-testing'; 21 | import { getTestBed } from '@angular/core/testing'; 22 | import { 23 | BrowserDynamicTestingModule, 24 | platformBrowserDynamicTesting 25 | } from '@angular/platform-browser-dynamic/testing'; 26 | 27 | declare const require: any; 28 | 29 | // First, initialize the Angular testing environment. 30 | getTestBed().initTestEnvironment( 31 | BrowserDynamicTestingModule, 32 | platformBrowserDynamicTesting() 33 | ); 34 | // Then we find all the tests. 35 | const context = require.context('./../', true, /\.spec\.ts$/); 36 | // And load the modules. 37 | context.keys().map(context); 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/test.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import 'core-js/features/reflect'; 19 | import 'zone.js/dist/zone'; 20 | import 'zone.js/dist/zone-testing'; 21 | import { getTestBed } from '@angular/core/testing'; 22 | import { 23 | BrowserDynamicTestingModule, 24 | platformBrowserDynamicTesting 25 | } from '@angular/platform-browser-dynamic/testing'; 26 | 27 | declare const require: any; 28 | 29 | // First, initialize the Angular testing environment. 30 | getTestBed().initTestEnvironment( 31 | BrowserDynamicTestingModule, 32 | platformBrowserDynamicTesting() 33 | ); 34 | // Then we find all the tests. 35 | const context = require.context('./../', true, /\.spec\.ts$/); 36 | // And load the modules. 37 | context.keys().map(context); 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/test.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import 'core-js/features/reflect'; 19 | import 'zone.js/dist/zone'; 20 | import 'zone.js/dist/zone-testing'; 21 | import { getTestBed } from '@angular/core/testing'; 22 | import { 23 | BrowserDynamicTestingModule, 24 | platformBrowserDynamicTesting 25 | } from '@angular/platform-browser-dynamic/testing'; 26 | 27 | declare const require: any; 28 | 29 | // First, initialize the Angular testing environment. 30 | getTestBed().initTestEnvironment( 31 | BrowserDynamicTestingModule, 32 | platformBrowserDynamicTesting() 33 | ); 34 | // Then we find all the tests. 35 | const context = require.context('./../', true, /\.spec\.ts$/); 36 | // And load the modules. 37 | context.keys().map(context); 38 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/accordion.v1.module.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | import {NgModule} from '@angular/core'; 17 | import {CommonModule} from "@angular/common"; 18 | import {RouterModule} from "@angular/router"; 19 | import {AccordionV1Component} from "./accordion.v1.component"; 20 | import {SpaAngularEditableComponentsModule} from "@adobe/aem-angular-editable-components"; 21 | import {AemAngularCoreSpaWcmComponentsCore} from "@adobe/aem-core-components-angular-spa/core"; 22 | 23 | @NgModule({ 24 | imports: [CommonModule, RouterModule,SpaAngularEditableComponentsModule,AemAngularCoreSpaWcmComponentsCore], 25 | declarations: [ 26 | AccordionV1Component 27 | ], 28 | exports: [ 29 | AccordionV1Component 30 | ] 31 | }) 32 | export class AemAngularCoreWcmComponentsAccordionV1 { 33 | } 34 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/tabs.v1.module.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import {NgModule} from '@angular/core'; 19 | import {CommonModule} from "@angular/common"; 20 | import {BrowserModule} from "@angular/platform-browser"; 21 | import {RouterModule} from "@angular/router"; 22 | import {TabsV1Component} from "./tabs.v1.component"; 23 | import {SpaAngularEditableComponentsModule} from "@adobe/aem-angular-editable-components"; 24 | import {AemAngularCoreSpaWcmComponentsCore} from "@adobe/aem-core-components-angular-spa/core"; 25 | 26 | @NgModule({ 27 | imports: [CommonModule, BrowserModule, RouterModule,SpaAngularEditableComponentsModule,AemAngularCoreSpaWcmComponentsCore], 28 | declarations: [ 29 | TabsV1Component 30 | ], 31 | exports: [ 32 | TabsV1Component 33 | ], 34 | entryComponents: [ 35 | TabsV1Component, 36 | ], 37 | }) 38 | export class AemAngularCoreWcmComponentsTabsV1 {} -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/src/test.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 18 | 19 | import 'zone.js/dist/zone'; 20 | import 'zone.js/dist/zone-testing'; 21 | import { getTestBed } from '@angular/core/testing'; 22 | import { 23 | BrowserDynamicTestingModule, 24 | platformBrowserDynamicTesting 25 | } from '@angular/platform-browser-dynamic/testing'; 26 | 27 | declare const require: { 28 | context(path: string, deep?: boolean, filter?: RegExp): { 29 | keys(): string[]; 30 | (id: string): T; 31 | }; 32 | }; 33 | 34 | // First, initialize the Angular testing environment. 35 | getTestBed().initTestEnvironment( 36 | BrowserDynamicTestingModule, 37 | platformBrowserDynamicTesting() 38 | ); 39 | // Then we find all the tests. 40 | const context = require.context('./../', true, /\.spec\.ts$/); 41 | // And load the modules. 42 | context.keys().map(context); 43 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/carousel.v1.module.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | import {NgModule} from '@angular/core'; 17 | import {CommonModule} from "@angular/common"; 18 | import {BrowserModule} from "@angular/platform-browser"; 19 | import {RouterModule} from "@angular/router"; 20 | import {CarouselV1Component} from "./carousel.v1.component"; 21 | import {SpaAngularEditableComponentsModule} from "@adobe/aem-angular-editable-components"; 22 | import {AemAngularCoreSpaWcmComponentsCore} from "@adobe/aem-core-components-angular-spa/core"; 23 | 24 | @NgModule({ 25 | imports: [CommonModule, BrowserModule, RouterModule,SpaAngularEditableComponentsModule,AemAngularCoreSpaWcmComponentsCore], 26 | declarations: [ 27 | CarouselV1Component 28 | ], 29 | exports: [ 30 | CarouselV1Component 31 | ], 32 | entryComponents: [ 33 | CarouselV1Component, 34 | ], 35 | }) 36 | export class AemAngularCoreWcmComponentsCarouselV1 {} -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/container.v1.module.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {NgModule} from '@angular/core'; 18 | import {CommonModule} from "@angular/common"; 19 | import {BrowserModule} from "@angular/platform-browser"; 20 | import {RouterModule} from "@angular/router"; 21 | import {ContainerV1Component} from "./container.v1.component"; 22 | import {SpaAngularEditableComponentsModule} from "@adobe/aem-angular-editable-components"; 23 | import {AemAngularCoreSpaWcmComponentsCore} from "@adobe/aem-core-components-angular-spa/core"; 24 | 25 | @NgModule({ 26 | imports: [CommonModule, BrowserModule, RouterModule,SpaAngularEditableComponentsModule,AemAngularCoreSpaWcmComponentsCore], 27 | declarations: [ 28 | ContainerV1Component 29 | ], 30 | exports: [ 31 | ContainerV1Component 32 | ], 33 | entryComponents: [ 34 | ContainerV1Component, 35 | ], 36 | }) 37 | export class AemAngularCoreWcmComponentsContainerV1 {} -------------------------------------------------------------------------------- /karma-conf-generator.local.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | 20 | module.exports = function (config, projectName) { 21 | config.set({ 22 | basePath: '', 23 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 24 | plugins: [ 25 | require('karma-jasmine'), 26 | require('karma-chrome-launcher'), 27 | require('karma-jasmine-html-reporter'), 28 | require('karma-coverage-istanbul-reporter'), 29 | require('@angular-devkit/build-angular/plugins/karma') 30 | ], 31 | client: { 32 | clearContext: false // leave Jasmine Spec Runner output visible in browser 33 | }, 34 | coverageIstanbulReporter: { 35 | dir: require('path').join(__dirname, '/coverage/' + projectName), 36 | reports: ['json'], 37 | fixWebpackSourcePaths: true 38 | }, 39 | reporters: ['progress', 'kjhtml'], 40 | port: 9876, 41 | colors: true, 42 | logLevel: config.LOG_INFO, 43 | failOnEmptyTestSuite: false, 44 | autoWatch: true, 45 | browsers: ['Chrome'], 46 | singleRun: false, 47 | restartOnFileChange: true 48 | }); 49 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/test/data/layout.json: -------------------------------------------------------------------------------- 1 | { 2 | ":items": 3 | { 4 | "root": 5 | { 6 | "gridClassNames": "aem-Grid/root", 7 | "classNames": "test-class-names", 8 | "columnClassNames": { 9 | "responsivegrid": "aem-GridColumn/root/responsivegrid" 10 | }, 11 | "columnCount": 12, 12 | ":items": 13 | { 14 | "responsivegrid": 15 | { 16 | "gridClassNames": "aem-Grid/root/responsivegrid", 17 | "columnClassNames": { 18 | "component1": "aem-GridColumn/root/responsivegrid/component1", 19 | "component2": "aem-GridColumn/root/responsivegrid/component2", 20 | "component3": "aem-GridColumn/root/responsivegrid/component3", 21 | "component4": "aem-GridColumn/root/responsivegrid/component4", 22 | "component5": "aem-GridColumn/root/responsivegrid/component5" 23 | }, 24 | "columnCount": 12, 25 | ":items": 26 | { 27 | "component1": 28 | { 29 | "title": "Component1", 30 | ":type": "app/components/comp1" 31 | }, 32 | "component2": 33 | { 34 | "title": "Component2", 35 | ":type": "app/components/comp2" 36 | }, 37 | "component3": 38 | { 39 | "title": "Component3", 40 | ":type": "app/components/comp3" 41 | }, 42 | "component4": 43 | { 44 | "title": "Component4", 45 | ":type": "app/components/comp2" 46 | }, 47 | "component5": 48 | { 49 | "title": "Component5", 50 | ":type": "app/components/comp1" 51 | } 52 | }, 53 | ":itemsOrder": ["component1", "component3", "component5", "component2", "component4"], 54 | ":type": "wcm/foundation/components/responsivegrid" 55 | } 56 | }, 57 | ":itemsOrder": ["responsivegrid"], 58 | ":type": "wcm/foundation/components/responsivegrid" 59 | } 60 | }, 61 | ":itemsOrder": ["root"] 62 | } 63 | -------------------------------------------------------------------------------- /karma-conf-generator.js: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | // Karma configuration file, see link for more information 18 | // https://karma-runner.github.io/1.0/config/configuration-file.html 19 | const puppeteer = require('puppeteer'); 20 | process.env.CHROME_BIN = puppeteer.executablePath(); 21 | 22 | 23 | module.exports = function (config, projectName) { 24 | config.set({ 25 | basePath: '', 26 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 27 | plugins: [ 28 | require('karma-jasmine'), 29 | require('karma-chrome-launcher'), 30 | require('karma-jasmine-html-reporter'), 31 | require('karma-coverage-istanbul-reporter'), 32 | require('@angular-devkit/build-angular/plugins/karma') 33 | ], 34 | client: { 35 | clearContext: false // leave Jasmine Spec Runner output visible in browser 36 | }, 37 | coverageIstanbulReporter: { 38 | dir: require('path').join(__dirname, '/coverage/' + projectName), 39 | reports: ['json'], 40 | fixWebpackSourcePaths: true 41 | }, 42 | reporters: ['progress', 'kjhtml'], 43 | port: 9876, 44 | colors: true, 45 | logLevel: config.LOG_INFO, 46 | failOnEmptyTestSuite: false, 47 | autoWatch: true, 48 | browsers: ['ChromeHeadless'], 49 | singleRun: true, 50 | restartOnFileChange: true 51 | }); 52 | }; -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/README.md: -------------------------------------------------------------------------------- 1 | # AEM WCM Components - Spa editor - Angular Core implementation 2 | 3 | This module provides a Angular implementation for the containers in the [AEM core components](https://www.aemcomponents.dev/). 4 | This only works with the [AEM SPA editor](https://docs.adobe.com/content/help/en/experience-manager-64/developing/headless/spas/spa-overview.html). 5 | 6 | Current supported / exported components: 7 | 8 | ### Containers 9 | - Accordion (V1) 10 | - Carousel (V1) 11 | - Container (V1) 12 | - Tabs (V1) 13 | 14 | ### Abstraction 15 | - AbstractCoreContainerComponent 16 | 17 | ## Usage 18 | 19 | You can choose to import the entire library at once OR import components individually. 20 | The latter is useful if you want to only enable a few components and you want to save your javascript footprint. 21 | Also, if you want to load all core components, but you want to lazyload them with angular suspense, you will need to import them individually. 22 | 23 | ### Importing the whole library: 24 | 25 | ``` 26 | import * as SpaCoreComponents from "@adobe/aem-core-components-angular-spa"; 27 | const {CarouselV1, CarouselV1IsEmptyFn} = BaseCoreComponents; 28 | ``` 29 | 30 | ### Importing the CarouselV1 component individually (for code splitting): 31 | 32 | ``` 33 | import {CarouselV1, CarouselV1IsEmptyFn} from "@adobe/aem-core-components-angular-spa/containers/carousel/v1"; 34 | ``` 35 | 36 | ### Using the imported code 37 | 38 | Now that you have the CarouselV1 and CarouselV1IsEmptyFn imported, you can use them in your project. 39 | The properties of the Button 1 on 1 correspond to the Sling Model Exporter (.model.json) output. 40 | 41 | Note: There are some exceptions where some extra properties are added (mainly i18n labels) that are currently not present in the OOTB sling model exports. 42 | These can be added by the project itself with delegation. If they are not present, the default (English) values will be used. 43 | 44 | #### Carousel - Example with the spa editor: 45 | 46 | ``` 47 | MapTo('my-project/wcm/components/containers')(CarouselV1, {isEmpty: CarouselV1IsEmptyFn}); 48 | ``` 49 | 50 | For a complete project with examples, visit the [github page](https://github.com/adobe/aem-angular-core-wcm-components/tree/master/examples). -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/src/common.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {ComponentMapping,MappedComponentProperties} from "@adobe/aem-angular-editable-components"; 18 | 19 | export interface ContainerProperties extends MappedComponentProperties { 20 | componentMapping?: typeof ComponentMapping; 21 | cqItems: {[key: string]: Model}; 22 | cqItemsOrder: string[]; 23 | } 24 | 25 | export interface ContainerModel extends Model{ 26 | 27 | } 28 | 29 | 30 | export interface Model extends Object { 31 | ":hierarchyType"?: string; 32 | /** 33 | * Path of the item/page 34 | */ 35 | ":path"?: string; 36 | /** 37 | * Child pages (only present on page's itself, not on items) 38 | */ 39 | ":children"?: {[key: string]: Model}; 40 | 41 | /** 42 | * Items under the page / item 43 | */ 44 | ":items"?: {[key: string]: Model}; 45 | 46 | /** 47 | * Order of the items under the page / item 48 | * Can be used as keys for the :items property to iterate items in the proper order 49 | */ 50 | ":itemsOrder"?: string[]; 51 | 52 | /** 53 | * Resource type of the page / item 54 | */ 55 | ":type"?: string; 56 | } 57 | 58 | export interface LabelledModel extends Model{ 59 | "cq:panelTitle": string 60 | } 61 | 62 | /** 63 | * Indicated whether force reload is turned on, forcing the model to be refetched on every MapTo instantiation. 64 | */ 65 | export interface ReloadForceAble { 66 | cqForceReload?: boolean; 67 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/tabs.v1.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |
19 |
20 | 21 |
24 |
25 |
26 |
27 | 28 | 29 |
    32 |
  1. 33 |
34 | 35 | 36 |
42 |
43 |
46 |
47 | 48 |
-------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/src/aem-angular-core-spa-wcm-components.module.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {NgModule} from '@angular/core'; 18 | import {CommonModule} from "@angular/common"; 19 | 20 | 21 | import {SpaAngularEditableComponentsModule} from "@adobe/aem-angular-editable-components"; 22 | import {AemAngularCoreWcmComponentsAccordionV1} from "@adobe/aem-core-components-angular-spa/containers/accordion/v1"; 23 | import {AemAngularCoreWcmComponentsCarouselV1} from "@adobe/aem-core-components-angular-spa/containers/carousel/v1"; 24 | import {AemAngularCoreWcmComponentsTabsV1} from "@adobe/aem-core-components-angular-spa/containers/tabs/v1"; 25 | import {AemAngularCoreWcmComponentsContainerV1} from "@adobe/aem-core-components-angular-spa/containers/container/v1"; 26 | import {AemAngularCoreSpaWcmComponentsCore} from "@adobe/aem-core-components-angular-spa/core"; 27 | 28 | @NgModule({ 29 | imports: [ 30 | CommonModule, 31 | SpaAngularEditableComponentsModule, 32 | AemAngularCoreWcmComponentsAccordionV1, 33 | AemAngularCoreWcmComponentsCarouselV1, 34 | AemAngularCoreWcmComponentsContainerV1, 35 | AemAngularCoreWcmComponentsTabsV1, 36 | AemAngularCoreSpaWcmComponentsCore 37 | ], 38 | exports: [ 39 | SpaAngularEditableComponentsModule, 40 | AemAngularCoreWcmComponentsAccordionV1, 41 | AemAngularCoreWcmComponentsCarouselV1, 42 | AemAngularCoreWcmComponentsContainerV1, 43 | AemAngularCoreWcmComponentsTabsV1, 44 | AemAngularCoreSpaWcmComponentsCore 45 | ] 46 | }) 47 | export class AemAngularCoreSpaWcmComponentsModule { 48 | } 49 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/container.v1.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |
19 |
20 | 21 |
24 |
25 |
26 |
27 | 28 | 29 | 30 |
36 |
37 |
40 |
41 |
42 | 43 | 44 | 45 | 46 |
51 |
52 |
55 |
-------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/container.v1.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import {Component, HostBinding, Input} from "@angular/core"; 19 | import {AEMResponsiveGridComponent} from "@adobe/aem-angular-editable-components"; 20 | import {DomSanitizer, SafeStyle} from "@angular/platform-browser"; 21 | 22 | export enum ContainerLayout { 23 | SIMPLE = "simple", 24 | RESPONSIVEGRID = "responsiveGrid" 25 | } 26 | 27 | export interface ContainerV1Properties{ 28 | layout: ContainerLayout; 29 | id: string; 30 | backgroundStyle: string; 31 | } 32 | @Component({ 33 | selector: 'core-container-v1', 34 | host: { 35 | '[class]': 'hostClasses', 36 | '[attr.data-cq-data-path]':'cqPath' 37 | }, 38 | templateUrl: './container.v1.component.html' 39 | }) 40 | export class ContainerV1Component extends AEMResponsiveGridComponent implements ContainerV1Properties{ 41 | 42 | @Input() layout: ContainerLayout; 43 | @Input() id: string; 44 | @Input() backgroundStyle: string; 45 | 46 | @Input() baseCssClass = 'cmp-container'; 47 | 48 | constructor(private sanitizer: DomSanitizer) { 49 | super(); 50 | } 51 | 52 | 53 | showResponsiveGrid():boolean{ 54 | return this.layout !== ContainerLayout.SIMPLE; 55 | } 56 | 57 | @HostBinding('style') 58 | get cssStyles(): SafeStyle{ 59 | 60 | if(!!this.backgroundStyle && this.backgroundStyle.length > 0){ 61 | return this.sanitizer.bypassSecurityTrustStyle('background: ' + this.backgroundStyle); 62 | } 63 | return null; 64 | } 65 | 66 | 67 | /** 68 | * Returns the class names of the responsive grid based on the data from the cqModel 69 | */ 70 | getHostClassNames() { 71 | let classNames = super.getHostClassNames() + ' ' + this.baseCssClass; 72 | 73 | if(this.showResponsiveGrid()){ 74 | return classNames; 75 | } 76 | 77 | //if we are in simple layout, we need to remove the gridClassNames computed in the parent 78 | return classNames.replace(this.gridClassNames, ''); 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/accordion.v1.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |
19 |
20 | 21 |
24 |
25 |
26 |
27 | 28 | 29 | 30 |
33 |

34 | 40 |

41 |
46 |
52 |
53 |
54 | 55 |
58 |
59 | 60 |
-------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/accordion.v1.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {Component, HostBinding, Input} from "@angular/core"; 18 | import {ContainerProperties,AbstractContainerComponent} from "@adobe/aem-core-components-angular-spa/core"; 19 | 20 | export interface AccordionV1Properties extends ContainerProperties{ 21 | expandedItems: string[] 22 | singleExpansion: boolean 23 | } 24 | 25 | @Component({ 26 | selector: 'core-accordion-v1', 27 | host: { 28 | '[class]': 'hostClasses', 29 | '[attr.data-cq-data-path]':'cqPath', 30 | '[attr.data-cmp-data-layer]': 'dataLayerString', 31 | '[attr.data-panelcontainer]': '"accordion"' 32 | }, 33 | templateUrl: './accordion.v1.component.html' 34 | }) 35 | export class AccordionV1Component extends AbstractContainerComponent implements AccordionV1Properties { 36 | @Input() singleExpansion: boolean; 37 | @Input() expandedItems: string[] = []; 38 | 39 | @Input() baseCssClass = 'cmp-accordion'; 40 | 41 | onClick(itemKey){ 42 | 43 | const isActive = this.expandedItems.indexOf(itemKey) > -1; 44 | const isSingleExpansion = this.singleExpansion; 45 | 46 | if(isSingleExpansion){ 47 | this.expandedItems = (isActive) ? [] : [itemKey]; 48 | }else{ 49 | if(isActive){ 50 | const index = this.expandedItems.indexOf(itemKey); 51 | this.expandedItems.splice( index ); 52 | }else{ 53 | this.expandedItems.push(itemKey); 54 | } 55 | } 56 | } 57 | 58 | onAuthorIndexChange(index:number){ 59 | this.expandedItems = [ 60 | this.cqItemsOrder[index] 61 | ]; 62 | } 63 | 64 | isItemExpanded(itemKey){ 65 | return this.expandedItems.indexOf(itemKey) > -1; 66 | } 67 | 68 | getButtonClass(itemKey){ 69 | return this.isItemExpanded(itemKey) ? `${this.baseCssClass}__button ${this.baseCssClass}__button--expanded` : `${this.baseCssClass}__button`; 70 | } 71 | 72 | getItemStyle(itemKey:string){ 73 | const display = this.isItemExpanded(itemKey) ? 'block': 'none'; 74 | return { 'display' : display}; 75 | } 76 | 77 | getItemClass(itemKey){ 78 | return this.isItemExpanded(itemKey) ? `${this.baseCssClass}__panel ${this.baseCssClass}__panel--expanded`: `${this.baseCssClass}__panel ${this.baseCssClass}__panel--hidden`; 79 | } 80 | 81 | getButtonTitle(itemKey:string){ 82 | return this.cqItems[itemKey]["cq:panelTitle"]; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rulesDirectory": [ 4 | "codelyzer" 5 | ], 6 | "rules": { 7 | "align": { 8 | "options": [ 9 | "parameters", 10 | "statements" 11 | ] 12 | }, 13 | "array-type": false, 14 | "arrow-return-shorthand": true, 15 | "curly": true, 16 | "deprecation": { 17 | "severity": "warning" 18 | }, 19 | "eofline": true, 20 | "import-blacklist": [ 21 | true, 22 | "rxjs/Rx" 23 | ], 24 | "import-spacing": true, 25 | "indent": { 26 | "options": [ 27 | "spaces" 28 | ] 29 | }, 30 | "max-classes-per-file": false, 31 | "max-line-length": [ 32 | true, 33 | 140 34 | ], 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-console": [ 47 | true, 48 | "debug", 49 | "info", 50 | "time", 51 | "timeEnd", 52 | "trace" 53 | ], 54 | "no-empty": false, 55 | "no-inferrable-types": [ 56 | true, 57 | "ignore-params" 58 | ], 59 | "no-non-null-assertion": true, 60 | "no-redundant-jsdoc": true, 61 | "no-switch-case-fall-through": true, 62 | "no-var-requires": false, 63 | "object-literal-key-quotes": [ 64 | true, 65 | "as-needed" 66 | ], 67 | "quotemark": [ 68 | true, 69 | "single" 70 | ], 71 | "semicolon": { 72 | "options": [ 73 | "always" 74 | ] 75 | }, 76 | "space-before-function-paren": { 77 | "options": { 78 | "anonymous": "never", 79 | "asyncArrow": "always", 80 | "constructor": "never", 81 | "method": "never", 82 | "named": "never" 83 | } 84 | }, 85 | "typedef-whitespace": { 86 | "options": [ 87 | { 88 | "call-signature": "nospace", 89 | "index-signature": "nospace", 90 | "parameter": "nospace", 91 | "property-declaration": "nospace", 92 | "variable-declaration": "nospace" 93 | }, 94 | { 95 | "call-signature": "onespace", 96 | "index-signature": "onespace", 97 | "parameter": "onespace", 98 | "property-declaration": "onespace", 99 | "variable-declaration": "onespace" 100 | } 101 | ] 102 | }, 103 | "variable-name": { 104 | "options": [ 105 | "ban-keywords", 106 | "check-format", 107 | "allow-pascal-case" 108 | ] 109 | }, 110 | "whitespace": { 111 | "options": [ 112 | "check-branch", 113 | "check-decl", 114 | "check-operator", 115 | "check-separator", 116 | "check-type", 117 | "check-typecast" 118 | ] 119 | }, 120 | "component-class-suffix": true, 121 | "contextual-lifecycle": true, 122 | "directive-class-suffix": true, 123 | "no-conflicting-lifecycle": true, 124 | "no-host-metadata-property": true, 125 | "no-input-rename": true, 126 | "no-inputs-metadata-property": true, 127 | "no-output-native": true, 128 | "no-output-on-prefix": true, 129 | "no-output-rename": true, 130 | "no-outputs-metadata-property": true, 131 | "template-banana-in-box": true, 132 | "template-no-negated-async": true, 133 | "use-lifecycle-interface": true, 134 | "use-pipe-transform-interface": true 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/src/AbstractContainerComponent.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | 19 | import {ComponentMapping, AEMAllowedComponentsContainerComponent, MappedComponentProperties, Utils} from "@adobe/aem-angular-editable-components"; 20 | import {Component, HostBinding, Injectable, Input, OnDestroy, AfterViewInit, PLATFORM_ID, Inject} from "@angular/core"; 21 | import {ContainerModel, ContainerProperties, Model} from "./common"; 22 | import {isPlatformBrowser} from "@angular/common"; 23 | 24 | export function ContainerIsEmptyFn(props:ContainerModel){ 25 | return props[":itemsOrder"] == null || props[":itemsOrder"].length === 0; 26 | } 27 | 28 | @Component({ 29 | selector: 'aem-core-abstract-container', 30 | template: '' 31 | }) 32 | export class AbstractContainerComponent extends AEMAllowedComponentsContainerComponent implements ContainerProperties, AfterViewInit, OnDestroy, MappedComponentProperties{ 33 | @Input() componentMapping: typeof ComponentMapping = ComponentMapping; 34 | @Input() cqForceReload: boolean = false; 35 | @Input() cqItems: {[key: string]: Model} = {}; 36 | @Input() cqItemsOrder: string[] = []; 37 | @Input() id: string; 38 | 39 | @Input() baseCssClass; 40 | @Input() dataLayer: {[key: string]: {[key: string]: string}} = {}; 41 | 42 | //@ts-ignore 43 | messageChannel; 44 | 45 | constructor(@Inject(PLATFORM_ID) protected _platformId: Object) { 46 | super(); 47 | 48 | //@ts-ignore 49 | if (isPlatformBrowser(_platformId) && window.Granite && window.Granite.author && window.Granite.author.MessageChannel) { 50 | //@ts-ignore 51 | this.messageChannel = new window.Granite.author.MessageChannel("cqauthor", window); 52 | this.callback = this.callback.bind(this); 53 | this.onAuthorIndexChange = this.onAuthorIndexChange.bind(this); 54 | } 55 | } 56 | 57 | callback(message:any){ 58 | if (message.data && message.data.id === this.cqPath) { 59 | if (message.data.operation === "navigate") { 60 | const index = message.data.index as number; 61 | this.onAuthorIndexChange(index); 62 | } 63 | } 64 | } 65 | 66 | /** 67 | * Returns the class names of the container based on the data from the cqModel 68 | */ 69 | getHostClassNames() { 70 | return super.getHostClassNames() +' ' + this.baseCssClass; 71 | } 72 | 73 | onAuthorIndexChange(index:number){ 74 | //implement me 75 | } 76 | 77 | 78 | ngAfterViewInit(): void { 79 | if(this.messageChannel){ 80 | this.messageChannel.subscribeRequestMessage("cmp.panelcontainer", this.callback); 81 | } 82 | } 83 | 84 | ngOnDestroy(): void { 85 | if(this.messageChannel){ 86 | this.messageChannel.unsubscribeRequestMessage("cmp.panelcontainer", this.callback); 87 | } 88 | } 89 | 90 | public get dataLayerString(){ 91 | return this.dataLayer ? JSON.stringify(this.dataLayer) : ""; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/tabs.v1.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | 19 | import {AfterViewInit, ChangeDetectorRef, Component, HostBinding, Inject, Input, OnInit, PLATFORM_ID} from '@angular/core'; 20 | import {AEMAllowedComponentsContainerComponent} from "@adobe/aem-angular-editable-components"; 21 | import {AbstractContainerComponent} from "@adobe/aem-core-components-angular-spa/core"; 22 | 23 | const CONTAINER_CLASS_NAMES = 'aem-container'; 24 | 25 | @Component({ 26 | selector: 'core-tabs-v1', 27 | host: { 28 | '[id]': 'containerId', 29 | '[class]': 'hostClasses', 30 | '[attr.data-cq-data-path]':'cqPath', 31 | '[attr.data-panelcontainer]': '"tabs"' 32 | }, 33 | templateUrl: './tabs.v1.component.html' 34 | }) 35 | /** 36 | * The current component provides the base presentational logic common to containers such as a grid or a page. 37 | * Container have in common the notion of item holders. Items are represented in the model by the fields _:items_ and _:itemsOrder_ 38 | */ 39 | export class TabsV1Component extends AbstractContainerComponent implements OnInit{ 40 | 41 | @Input() baseCssClass = 'cmp-tabs'; 42 | 43 | activeItemName?:string; 44 | @Input() activeItem?: string; 45 | @Input() accessibilityLabel?: string; 46 | 47 | 48 | constructor(private changeDetectorRef:ChangeDetectorRef,@Inject(PLATFORM_ID) protected _platformId: Object) { 49 | super(_platformId); 50 | } 51 | 52 | onAuthorIndexChange(index:number){ 53 | this.activeItemName = this.cqItemsOrder[index]; 54 | } 55 | 56 | isActive(itemKey:string){ 57 | return (this.activeItemName === itemKey); 58 | } 59 | 60 | getTabClass(itemKey:string){ 61 | return `${this.baseCssClass}__tab` + ((this.isActive(itemKey) ? ` ${this.baseCssClass}__tab--active` : '')); 62 | } 63 | 64 | getTabTitle(itemKey:string){ 65 | return this.getItem(itemKey)['cq:panelTitle']; 66 | } 67 | getItemStyle(itemKey:string){ 68 | const display = this.isActive(itemKey) ? 'block': 'none'; 69 | return { 'display' : display}; 70 | } 71 | 72 | onClick(itemKey:string){ 73 | this.activeItemName = itemKey; 74 | this.changeDetectorRef.detectChanges(); 75 | } 76 | 77 | ngOnInit(): void { 78 | 79 | if(this.activeItem && this.activeItem.trim().length > 0 ){ 80 | this.activeItemName = this.activeItem; 81 | }else{ 82 | this.activeItemName = this.cqItemsOrder && this.cqItemsOrder.length > 0 ? this.cqItemsOrder[0] : ''; 83 | } 84 | this.changeDetectorRef.detectChanges(); 85 | 86 | } 87 | 88 | get containerId(){ 89 | return 'tabs-' + this.id; 90 | } 91 | 92 | get activeTabItem(){ 93 | return this.getItem(this.activeItemName); 94 | } 95 | 96 | get activeTabItemDataPath(){ 97 | return this.getDataPath(this.activeItemName); 98 | } 99 | 100 | get activeTabItemName(){ 101 | return this.activeItemName; 102 | } 103 | 104 | get hostClasses () { 105 | return this.getHostClassNames(); 106 | } 107 | 108 | get isActiveItemNameSet(){ 109 | return !!this.activeItemName && this.activeItemName.length > 0; 110 | } 111 | 112 | } 113 | 114 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-core", 3 | "version": "1.0.1", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build aem-angular-core-spa-wcm-components", 8 | "build-internal": "ng build aem-angular-core-spa-wcm-components && ngcc -s ./dist", 9 | "build-prod": "ng build aem-angular-core-spa-wcm-components --prod", 10 | "build-prod-internal": "ng build aem-angular-core-spa-wcm-components --prod && ngcc -s ./dist", 11 | "test": "ng test aem-angular-core-spa-wcm-components", 12 | "test-cover-libs": "npm-run-all test-container-core test-accordion-v1 test-carousel-v1 test-container-v1 test-tabs-v1 build-spa", 13 | "lint": "ng lint", 14 | "e2e": "ng e2e", 15 | "cover:library:spa:container:core": "ng test aem-angular-core-spa-wcm-components-core --code-coverage=true", 16 | "cover:library:spa:accordion:v1": "ng test aem-angular-core-spa-wcm-components-accordion-v1 --code-coverage=true", 17 | "cover:library:spa:carousel:v1": "ng test aem-angular-core-spa-wcm-components-carousel-v1 --code-coverage=true", 18 | "cover:library:spa:container:v1": "ng test aem-angular-core-spa-wcm-components-container-v1 --code-coverage=true", 19 | "cover:library:spa:tabs:v1": "ng test aem-angular-core-spa-wcm-components-tabs-v1 --code-coverage=true", 20 | "cover": "run-p cover:** --max-parallel 4", 21 | "postcover": "istanbul report json && node combine-coverage.js", 22 | "ngcc": "ngcc", 23 | "semantic-release": "semantic-release", 24 | "update-version": "node update-version.js" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "https://github.com/adobe/aem-angular-core-wcm-components-spa" 29 | }, 30 | "private": true, 31 | "dependencies": { 32 | "@angular/animations": "~9.1.12", 33 | "@angular/common": "~9.1.12", 34 | "@angular/compiler": "~9.1.12", 35 | "@angular/core": "~9.1.12", 36 | "@angular/forms": "~9.1.12", 37 | "@angular/platform-browser": "~9.1.12", 38 | "@angular/platform-browser-dynamic": "~9.1.12", 39 | "@angular/router": "~9.1.12", 40 | "rxjs": "~6.5.4", 41 | "tslib": "^1.10.0", 42 | "zone.js": "~0.10.2" 43 | }, 44 | "devDependencies": { 45 | "@adobe/aem-angular-editable-components": "^1.2.0", 46 | "@adobe/aem-spa-component-mapping": "^1.1.0", 47 | "@adobe/aem-spa-page-model-manager": "^1.3.3", 48 | "@angular-devkit/build-angular": "~0.901.11", 49 | "@angular-devkit/build-ng-packagr": "~0.901.11", 50 | "@angular/cli": "~9.1.8", 51 | "@angular/compiler-cli": "~9.1.12", 52 | "@types/node": "^12.11.1", 53 | "@types/jasmine": "~3.5.0", 54 | "@types/jasminewd2": "~2.0.3", 55 | "codelyzer": "^5.1.2", 56 | "jasmine-core": "~3.5.0", 57 | "jasmine-spec-reporter": "~4.2.1", 58 | "istanbul": "^0.4.5", 59 | "istanbul-api": "^3.0.0", 60 | "istanbul-lib-coverage": "^3.0.0", 61 | "karma": "~5.0.0", 62 | "karma-chrome-launcher": "~3.1.0", 63 | "karma-coverage-istanbul-reporter": "~2.1.0", 64 | "karma-jasmine": "~3.0.1", 65 | "karma-jasmine-html-reporter": "^1.4.2", 66 | "puppeteer": "^9.1.1", 67 | "ng-packagr": "^9.0.0", 68 | "protractor": "~7.0.0", 69 | "ts-node": "~8.3.0", 70 | "tslint": "~6.1.0", 71 | "typescript": "~3.8.3", 72 | "npm-run-all": "^4.1.5", 73 | "istanbul-combine": "^0.3.0", 74 | "commitizen": "^4.2.3", 75 | "cz-conventional-changelog": "^3.3.0", 76 | "@semantic-release/changelog": "^5.0.1", 77 | "@semantic-release/git": "^9.0.0", 78 | "@semantic-release/github": "^7.2.0", 79 | "@semantic-release/exec": "^5.0.0", 80 | "semantic-release": "^17.4.1" 81 | }, 82 | "release": { 83 | "plugins": [ 84 | "@semantic-release/commit-analyzer", 85 | "@semantic-release/release-notes-generator", 86 | [ 87 | "@semantic-release/npm", 88 | { 89 | "pkgRoot": "./dist/aem-angular-core-spa-wcm-components" 90 | } 91 | ], 92 | [ 93 | "@semantic-release/exec", 94 | { 95 | "prepareCmd": "npm run update-version" 96 | } 97 | ], 98 | [ 99 | "@semantic-release/git", 100 | { 101 | "assets": [ 102 | "package.json", 103 | "projects/aem-angular-core-spa-wcm-components/package.json" 104 | ] 105 | } 106 | ] 107 | ] 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 4.0.0 19 | 20 | 21 | 22 | 23 | 24 | com.adobe.cq 25 | core.wcm.components.angular.core 26 | pom 27 | Angular Core Components 28 | UI Angular core code 29 | 1.0.0-SNAPSHOT 30 | 31 | 32 | 1.6 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | maven-clean-plugin 42 | 3.1.0 43 | 44 | 45 | 46 | dist 47 | 48 | **/*.* 49 | 50 | false 51 | 52 | 53 | 54 | 55 | 56 | com.github.eirslett 57 | frontend-maven-plugin 58 | ${frontend-maven-plugin.version} 59 | 60 | 61 | 62 | 63 | npm install 64 | 65 | npm 66 | 67 | 68 | 69 | install 70 | 71 | 72 | 73 | npm ngcc 74 | 75 | npm 76 | 77 | 78 | 79 | run ngcc 80 | 81 | 82 | 83 | npm run build 84 | 85 | npm 86 | 87 | 88 | run build-prod-internal 89 | 90 | 91 | 92 | test 93 | test 94 | 95 | npm 96 | 97 | 98 | run test 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/core/src/AbstractContainerComponent.spec.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {ComponentFixture, TestBed} from '@angular/core/testing'; 18 | 19 | import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; 20 | 21 | 22 | import {AbstractContainerComponent} from './AbstractContainerComponent'; 23 | import {Utils} from "@adobe/aem-angular-editable-components"; 24 | 25 | import {ModelManager} from '@adobe/aem-spa-page-model-manager'; 26 | 27 | let callbacks: { (message: any): void; } [] = []; 28 | 29 | //@ts-ignore 30 | window.Granite = { 31 | author: { 32 | trigger: (path:string, index:number) => { 33 | callbacks.forEach((callback) => { 34 | callback({ 35 | data: { 36 | id: path, 37 | operation: 'navigate', 38 | index: index 39 | } 40 | }) 41 | }) 42 | }, 43 | 44 | MessageChannel : function() { 45 | 46 | return { 47 | subscribeRequestMessage: (topic:string, callback:(message:any)=>void) => { 48 | callbacks.push(callback) 49 | }, 50 | unsubscribeRequestMessage: (topic:string, callback:(message:any)=>void) => { 51 | const index:number = callbacks.indexOf(callback); 52 | callbacks.splice(index, 1); 53 | } 54 | } 55 | 56 | } 57 | 58 | } 59 | }; 60 | 61 | let onAuthorIndexChangeCalls; 62 | 63 | describe('AbstractContainerComponent', () => { 64 | 65 | 66 | let component: AbstractContainerComponent; 67 | let fixture: ComponentFixture; 68 | 69 | let isInEditorSpy; 70 | let onAuthorChangeIndexSpy; 71 | 72 | beforeEach(() => { 73 | 74 | callbacks = []; 75 | onAuthorIndexChangeCalls = []; 76 | spyOn(ModelManager, 'addListener').and.returnValue(undefined); 77 | isInEditorSpy = spyOn(Utils, 'isInEditor').and.returnValue(false); 78 | 79 | TestBed.configureTestingModule({ 80 | declarations: [AbstractContainerComponent] 81 | }).overrideModule(BrowserDynamicTestingModule, { 82 | set: { 83 | entryComponents: [AbstractContainerComponent] 84 | } 85 | }).compileComponents(); 86 | 87 | fixture = TestBed.createComponent(AbstractContainerComponent); 88 | component = fixture.componentInstance; 89 | component.cqPath = '/content/some/component'; 90 | fixture.detectChanges(); 91 | 92 | onAuthorChangeIndexSpy = spyOn(component, 'onAuthorIndexChange').and.callFake((index:number) => { 93 | onAuthorIndexChangeCalls.push(index); 94 | }); 95 | }); 96 | 97 | 98 | it('should trigger the onAuthorIndex if granite calls it with the same path', () => { 99 | 100 | component = fixture.componentInstance; 101 | component.cqPath = '/content/some/component'; 102 | fixture.detectChanges(); 103 | //@ts-ignore 104 | window.Granite.author.trigger('/content/some/component', 2); 105 | 106 | expect(onAuthorIndexChangeCalls.length).toEqual(1); 107 | 108 | expect(onAuthorIndexChangeCalls[0]).toEqual(2); 109 | 110 | expect(component.isInEditor).toEqual(false); 111 | fixture.destroy(); 112 | 113 | expect(callbacks.length).toEqual(0); 114 | 115 | }); 116 | 117 | it('should NOT trigger the onAuthorIndex if granite calls it with a different path', () => { 118 | 119 | component = fixture.componentInstance; 120 | component.cqPath = '/content/some/other'; 121 | fixture.detectChanges(); 122 | //@ts-ignore 123 | window.Granite.author.trigger('/content/some/component', 2); 124 | 125 | expect(onAuthorIndexChangeCalls.length).toEqual(0); 126 | 127 | }); 128 | 129 | it('should NOT trigger the onAuthorIndex if granite does not call it', () => { 130 | 131 | //@ts-ignore 132 | expect(onAuthorIndexChangeCalls.length).toEqual(0); 133 | 134 | }); 135 | 136 | }); 137 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/carousel.v1.component.html: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |
19 |
20 | 21 |
24 |
25 |
26 |
27 | 28 | 29 | 95 | 96 |
99 |
100 | 101 |
102 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/carousel.v1.component.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | 18 | import {ChangeDetectorRef, Component, HostBinding, Inject, Input, OnInit, PLATFORM_ID} from "@angular/core"; 19 | import {ContainerProperties,AbstractContainerComponent} from "@adobe/aem-core-components-angular-spa/core"; 20 | import {isPlatformBrowser} from "@angular/common"; 21 | 22 | export interface CarouselV1PropertiesAccessibility { 23 | play: string; 24 | pause: string; 25 | next: string; 26 | previous: string; 27 | slide: string; 28 | indicator: string; 29 | indicators:string; 30 | } 31 | 32 | const formatFn = (value:string, args:any[]) => { 33 | var content = value; 34 | for (var i = 0; i < args.length; i++) { 35 | var replacement = '{' + i + '}'; 36 | content = content.replace(replacement, args[i]); 37 | } 38 | return content; 39 | }; 40 | 41 | export interface CarouselV1Properties extends ContainerProperties{ 42 | id:string; 43 | autopauseDisabled:boolean 44 | accessibility:CarouselV1PropertiesAccessibility 45 | } 46 | 47 | @Component({ 48 | selector: 'core-carousel-v1', 49 | host: { 50 | '[class]': 'hostClasses', 51 | '[attr.data-cq-data-path]':'cqPath', 52 | '[attr.data-cmp-data-layer]': 'dataLayerString', 53 | '[attr.data-panelcontainer]': '"carousel"' 54 | }, 55 | templateUrl: './carousel.v1.component.html' 56 | }) 57 | export class CarouselV1Component extends AbstractContainerComponent implements CarouselV1Properties{ 58 | 59 | @Input() autoplay:boolean = false; 60 | @Input() accessibilityLabel = 'Carousel'; 61 | @Input() autopauseDisabled: false; 62 | @Input() activeIndex: number = 0; 63 | @Input() delay: number = 0; 64 | @HostBinding('class') baseCssClass = 'cmp-carousel'; 65 | 66 | @Input() accessibility = { 67 | play: 'Play', 68 | pause: 'Pause', 69 | next: 'Next', 70 | previous: 'Previous', 71 | slide: 'Slide {0} of {1}', 72 | indicator: 'Slide {0}', 73 | indicators: 'Choose a slide to display' 74 | }; 75 | 76 | interval = 0; 77 | 78 | autoPlayIntervalOn = false; 79 | autoPlayHalted = false; 80 | 81 | constructor(private changeDetectorRef:ChangeDetectorRef,@Inject(PLATFORM_ID) protected _platformId: Object) { 82 | super(_platformId); 83 | } 84 | 85 | 86 | ngAfterViewInit(): void { 87 | super.ngAfterViewInit(); 88 | if (isPlatformBrowser(this._platformId) &&this.autoplay) { 89 | this.__autoPlay(); 90 | } 91 | } 92 | 93 | ngOnDestroy(): void { 94 | super.ngOnDestroy(); 95 | if (isPlatformBrowser(this._platformId) && this.autoplay && !this.isInEditor) { 96 | this.clearAutoPlay(); 97 | } 98 | } 99 | 100 | onAuthorIndexChange(index:number){ 101 | this.activeIndex = index; 102 | this.clearAutoPlay(); 103 | } 104 | 105 | handleOnMouseEnter(){ 106 | if(!this.autopauseDisabled && this.autoplay){ 107 | this.autoPlayHalted = true; 108 | } 109 | } 110 | 111 | handleOnMouseLeave(){ 112 | if(!this.autopauseDisabled && this.autoplay){ 113 | this.autoPlayHalted = false; 114 | } 115 | } 116 | 117 | getAriaControlsId(index:number){ 118 | return `${this.id}-item-${index}`; 119 | } 120 | 121 | getIndicatorAriaLabel(index:number){ 122 | return formatFn(this.accessibility.indicator, [index + 1]); 123 | } 124 | 125 | getSlideAriaLabel(index:number){ 126 | return formatFn(this.accessibility.slide, [index + 1, this.cqItemsOrder.length]); 127 | } 128 | 129 | getSlideCssClass(index:number){ 130 | return (this.activeIndex === index) ? `${this.baseCssClass}__item ${this.baseCssClass}__item--active` : `${this.baseCssClass}__item`; 131 | } 132 | 133 | getIndicatorCssClass(index:number){ 134 | return (this.activeIndex === index) ? `${this.baseCssClass}__indicator ${this.baseCssClass}__indicator--active` : `${this.baseCssClass}__indicator`; 135 | } 136 | 137 | handleOnButtonPrev(){ 138 | this.prevSlide(); 139 | } 140 | 141 | handleOnButtonNext(){ 142 | this.nextSlide(); 143 | } 144 | 145 | handleIndicatorClick(index){ 146 | this.activeIndex = index; 147 | } 148 | 149 | __autoPlay(){ 150 | this.autoPlayIntervalOn = true; 151 | this.interval = window.setInterval(() => { 152 | this.autoPlayTick(); 153 | }, this.delay); 154 | this.changeDetectorRef.detectChanges(); 155 | } 156 | 157 | autoPlayTick() { 158 | 159 | if (!this.autoplay || this.autoPlayHalted || this.cqItemsOrder.length <= 1) { 160 | return; 161 | } 162 | 163 | this.nextSlide(); 164 | }; 165 | 166 | clearAutoPlay = () => { 167 | this.autoPlayIntervalOn = false; 168 | this.changeDetectorRef.detectChanges(); 169 | window.clearInterval(this.interval); 170 | }; 171 | 172 | toggleAutoPlay(toggle:boolean){ 173 | if(toggle){ 174 | this.__autoPlay(); 175 | }else{ 176 | this.clearAutoPlay(); 177 | } 178 | } 179 | 180 | nextSlide(){ 181 | 182 | const activeIndex = this.__getActiveIndex(); 183 | 184 | if(activeIndex=== (this.cqItemsOrder.length-1)){ 185 | 186 | this.__setSlide(0); 187 | }else{ 188 | this.__setSlide(activeIndex + 1); 189 | } 190 | } 191 | 192 | prevSlide(){ 193 | const activeIndex = this.__getActiveIndex(); 194 | if(activeIndex === 0){ 195 | 196 | this.__setSlide(this.cqItemsOrder.length - 1); 197 | }else{ 198 | this.__setSlide(activeIndex - 1); 199 | } 200 | } 201 | 202 | __getActiveIndex(){ 203 | return this.activeIndex; 204 | } 205 | 206 | __setSlide(index){ 207 | this.activeIndex = index; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/container.v1.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ADOBE CONFIDENTIAL 3 | * 4 | * Copyright 2020 Adobe Systems Incorporated 5 | * All Rights Reserved. 6 | * 7 | * NOTICE: All information contained herein is, and remains 8 | * the property of Adobe Systems Incorporated and its suppliers, 9 | * if any. The intellectual and technical concepts contained 10 | * herein are proprietary to Adobe Systems Incorporated and its 11 | * suppliers and may be covered by U.S. and Foreign Patents, 12 | * patents in process, and are protected by trade secret or copyright law. 13 | * Dissemination of this information or reproduction of this material 14 | * is strictly forbidden unless prior written permission is obtained 15 | * from Adobe Systems Incorporated. 16 | */ 17 | 18 | import {ComponentFixture, TestBed} from '@angular/core/testing'; 19 | 20 | import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; 21 | 22 | 23 | import {ContainerLayout, ContainerV1Component} from './container.v1.component'; 24 | import { 25 | AEMAllowedComponentsContainerComponent, 26 | AEMComponentDirective, AEMContainerComponent, 27 | AEMModelProviderComponent, AEMResponsiveGridComponent, 28 | Constants, MapTo, 29 | Utils 30 | } from "@adobe/aem-angular-editable-components"; 31 | 32 | import {Component1} from "../../../../test/test-comp1.component"; 33 | import {Component2} from "../../../../test/test-comp2.component"; 34 | import {Component3} from "../../../../test/test-comp3.component"; 35 | 36 | import {ModelManager} from '@adobe/aem-spa-page-model-manager'; 37 | 38 | describe('ContainerV1', () => { 39 | 40 | const TEST_COMPONENT_TITLE = 'test container title'; 41 | const LAYOUT = require('../../../../test/data/container.json'); 42 | 43 | let component: ContainerV1Component; 44 | let fixture: ComponentFixture; 45 | 46 | let isInEditorSpy; 47 | 48 | 49 | beforeEach(() => { 50 | 51 | spyOn(ModelManager, 'addListener').and.returnValue(undefined); 52 | isInEditorSpy = spyOn(Utils, 'isInEditor').and.returnValue(false); 53 | 54 | TestBed.configureTestingModule({ 55 | declarations: [ 56 | ContainerV1Component, 57 | AEMResponsiveGridComponent, 58 | AEMContainerComponent, 59 | AEMComponentDirective, 60 | AEMAllowedComponentsContainerComponent, 61 | AEMModelProviderComponent, 62 | Component1, 63 | Component2, 64 | Component3,] 65 | }).overrideModule(BrowserDynamicTestingModule, { 66 | set: { 67 | entryComponents: [ContainerV1Component, AEMContainerComponent,AEMAllowedComponentsContainerComponent, AEMResponsiveGridComponent,Component1, Component2, Component3] 68 | } 69 | }).compileComponents(); 70 | 71 | MapTo("app/components/comp1")(Component1); 72 | MapTo("app/components/comp2")(Component2); 73 | MapTo("app/components/comp3")(Component3); 74 | MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent); 75 | 76 | fixture = TestBed.createComponent(ContainerV1Component); 77 | component = fixture.componentInstance; 78 | }); 79 | 80 | it('should create placeholder', () => { 81 | isInEditorSpy.and.returnValue(true); 82 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 83 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 84 | component.classNames = LAYOUT.classNames; 85 | 86 | fixture.detectChanges(); 87 | let element = fixture.debugElement.nativeElement; 88 | expect(element.querySelector('.new.section')).toBeDefined(); 89 | 90 | }); 91 | 92 | it('should create the allowed components with the default title and no allowed component', () => { 93 | isInEditorSpy.and.returnValue(true); 94 | component.title = TEST_COMPONENT_TITLE; 95 | component.allowedComponents = { 96 | applicable: true, 97 | components: [] 98 | }; 99 | 100 | fixture.detectChanges(); 101 | 102 | const element = fixture.nativeElement.firstElementChild; 103 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 104 | .toEqual(0); 105 | }); 106 | 107 | 108 | it('should create the allowed components with a custom title and allowed components', () => { 109 | isInEditorSpy.and.returnValue(true); 110 | component.title = TEST_COMPONENT_TITLE; 111 | component.allowedComponents = { 112 | applicable: true, 113 | components: [{ 114 | path: 'test/components/component1', 115 | title: 'Test component title 1' 116 | }, 117 | { 118 | path: 'test/components/component2', 119 | title: 'Test component title 2' 120 | }] 121 | }; 122 | 123 | fixture.detectChanges(); 124 | 125 | const element = fixture.nativeElement.firstElementChild; 126 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 127 | .toEqual(2); 128 | }); 129 | 130 | it('should render the cssClass specified in the properties along with items, with a red background color', () => { 131 | component.title = TEST_COMPONENT_TITLE; 132 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 133 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 134 | component.backgroundStyle = 'red'; 135 | component.baseCssClass = "cmp-custom-container"; 136 | 137 | fixture.detectChanges(); 138 | 139 | const element = fixture.nativeElement; 140 | 141 | expect(element.getAttributeNode("class").value).toContain("cmp-custom-container"); 142 | }); 143 | 144 | 145 | it('should render the grid if the layout is responsivegrid', () => { 146 | component.title = TEST_COMPONENT_TITLE; 147 | component.gridClassNames = LAYOUT['gridClassNames']; 148 | component.columnClassNames = LAYOUT['columnClassNames']; 149 | component.columnCount = LAYOUT['columnCount']; 150 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 151 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 152 | component.layout = ContainerLayout.RESPONSIVEGRID; 153 | component.baseCssClass = "cmp-custom-container"; 154 | 155 | fixture.detectChanges(); 156 | 157 | const element = fixture.nativeElement; 158 | 159 | expect(element.getAttributeNode("class").value).toContain("aem-Grid-root-responsivegrid"); 160 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component1 test-comp1')).toBeDefined(); 161 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component2 test-comp2')).toBeDefined(); 162 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component3 test-comp3')).toBeDefined(); 163 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component4 test-comp4')).toBeDefined(); 164 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component5 test-comp5')).toBeDefined(); 165 | }); 166 | 167 | it('should NOT render the grid if the layout is simple', () => { 168 | component.title = TEST_COMPONENT_TITLE; 169 | component.gridClassNames = LAYOUT['gridClassNames']; 170 | component.columnClassNames = LAYOUT['columnClassNames']; 171 | component.columnCount = LAYOUT['columnCount']; 172 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 173 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 174 | component.layout = ContainerLayout.SIMPLE; 175 | component.baseCssClass = "cmp-custom-container"; 176 | 177 | fixture.detectChanges(); 178 | 179 | const element = fixture.nativeElement; 180 | 181 | expect(element.getAttributeNode("class").value.indexOf(LAYOUT['gridClassNames'])).toBe(-1); 182 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component1')).toBeNull(); 183 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component2')).toBeNull(); 184 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component3')).toBeNull(); 185 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component4')).toBeNull(); 186 | expect(element.querySelector('.aem-GridColumn-root-responsivegrid-component5')).toBeNull(); 187 | }); 188 | 189 | }); 190 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/carousel.v1.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ADOBE CONFIDENTIAL 3 | * 4 | * Copyright 2020 Adobe Systems Incorporated 5 | * All Rights Reserved. 6 | * 7 | * NOTICE: All information contained herein is, and remains 8 | * the property of Adobe Systems Incorporated and its suppliers, 9 | * if any. The intellectual and technical concepts contained 10 | * herein are proprietary to Adobe Systems Incorporated and its 11 | * suppliers and may be covered by U.S. and Foreign Patents, 12 | * patents in process, and are protected by trade secret or copyright law. 13 | * Dissemination of this information or reproduction of this material 14 | * is strictly forbidden unless prior written permission is obtained 15 | * from Adobe Systems Incorporated. 16 | */ 17 | 18 | import {ComponentFixture, discardPeriodicTasks, fakeAsync, TestBed, tick} from '@angular/core/testing'; 19 | 20 | import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; 21 | 22 | 23 | import {CarouselV1Component} from './carousel.v1.component'; 24 | import {Utils,AEMComponentDirective, Constants,AEMAllowedComponentsContainerComponent,AEMModelProviderComponent} from "@adobe/aem-angular-editable-components"; 25 | 26 | import {Component1} from "../../../../test/test-comp1.component"; 27 | import {Component2} from "../../../../test/test-comp2.component"; 28 | import {Component3} from "../../../../test/test-comp3.component"; 29 | 30 | import {ModelManager} from '@adobe/aem-spa-page-model-manager'; 31 | 32 | describe('CarouselV1', () => { 33 | 34 | const TEST_COMPONENT_TITLE = 'test container title'; 35 | const LAYOUT = require('../../../../test/data/carousel.json'); 36 | 37 | let component: CarouselV1Component; 38 | let fixture: ComponentFixture; 39 | 40 | let isInEditorSpy; 41 | 42 | beforeEach(() => { 43 | 44 | spyOn(ModelManager, 'addListener').and.returnValue(undefined); 45 | isInEditorSpy = spyOn(Utils, 'isInEditor').and.returnValue(false); 46 | 47 | TestBed.configureTestingModule({ 48 | declarations: [ 49 | CarouselV1Component, 50 | AEMComponentDirective, 51 | AEMAllowedComponentsContainerComponent, 52 | AEMModelProviderComponent, 53 | Component1, 54 | Component2, 55 | Component3,] 56 | }).overrideModule(BrowserDynamicTestingModule, { 57 | set: { 58 | entryComponents: [CarouselV1Component, Component1, Component2, Component3] 59 | } 60 | }).compileComponents(); 61 | 62 | fixture = TestBed.createComponent(CarouselV1Component); 63 | component = fixture.componentInstance; 64 | }); 65 | 66 | it('should create placeholder', () => { 67 | isInEditorSpy.and.returnValue(true); 68 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 69 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 70 | component.classNames = LAYOUT.classNames; 71 | 72 | fixture.detectChanges(); 73 | let element = fixture.debugElement.nativeElement; 74 | expect(element.querySelector('.new.section')).toBeDefined(); 75 | 76 | }); 77 | 78 | it('should create the allowed components with the default title and no allowed component', () => { 79 | isInEditorSpy.and.returnValue(true); 80 | component.title = TEST_COMPONENT_TITLE; 81 | component.allowedComponents = { 82 | applicable: true, 83 | components: [] 84 | }; 85 | 86 | fixture.detectChanges(); 87 | 88 | const element = fixture.nativeElement.firstElementChild; 89 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 90 | .toEqual(0); 91 | }); 92 | 93 | it('should create the allowed components with a custom title and allowed components', () => { 94 | isInEditorSpy.and.returnValue(true); 95 | component.title = TEST_COMPONENT_TITLE; 96 | component.allowedComponents = { 97 | applicable: true, 98 | components: [{ 99 | path: 'test/components/component1', 100 | title: 'Test component title 1' 101 | }, 102 | { 103 | path: 'test/components/component2', 104 | title: 'Test component title 2' 105 | }] 106 | }; 107 | 108 | fixture.detectChanges(); 109 | 110 | const element = fixture.nativeElement.firstElementChild; 111 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 112 | .toEqual(2); 113 | }); 114 | 115 | it('should render the cssClass specified in the properties', () => { 116 | component.title = TEST_COMPONENT_TITLE; 117 | component.allowedComponents = { 118 | applicable: true, 119 | components: [{ 120 | path: 'test/components/component1', 121 | title: 'Test component title 1' 122 | }, 123 | { 124 | path: 'test/components/component2', 125 | title: 'Test component title 2' 126 | }] 127 | }; 128 | component.baseCssClass = "cmp-custom-accordion"; 129 | 130 | fixture.detectChanges(); 131 | 132 | const element = fixture.nativeElement; 133 | 134 | expect(element.getAttributeNode("class").value).toContain("cmp-custom-accordion"); 135 | }); 136 | 137 | const clickNextOrPev = (direction:string) => { 138 | const element = fixture.nativeElement; 139 | element.querySelector('.cmp-carousel__action--' + direction).click(); 140 | fixture.detectChanges(); 141 | }; 142 | 143 | it('should only render the first entry on load - handle on navigations clicks', () => { 144 | component.title = TEST_COMPONENT_TITLE; 145 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 146 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 147 | component.classNames = LAYOUT.classNames; 148 | component.id = "myID"; 149 | fixture.detectChanges(); 150 | 151 | const element = fixture.nativeElement; 152 | 153 | expect(element.querySelectorAll('.cmp-carousel__item--active').length) 154 | .toEqual(1); 155 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-0"); 156 | 157 | clickNextOrPev('next'); 158 | 159 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-1"); 160 | 161 | clickNextOrPev('next'); 162 | 163 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-2"); 164 | 165 | clickNextOrPev('next'); 166 | 167 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-3"); 168 | 169 | clickNextOrPev('previous'); 170 | 171 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-2"); 172 | 173 | clickNextOrPev('next'); 174 | 175 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-3"); 176 | 177 | clickNextOrPev('next'); 178 | 179 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-4"); 180 | 181 | clickNextOrPev('next'); 182 | 183 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-0"); 184 | 185 | clickNextOrPev('previous'); 186 | 187 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-4"); 188 | 189 | }); 190 | 191 | it('should autoplay - also when hovering over', fakeAsync(() => { 192 | component.title = TEST_COMPONENT_TITLE; 193 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 194 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 195 | component.classNames = LAYOUT.classNames; 196 | component.id = "myID"; 197 | component.autoplay = true; 198 | component.delay = 1000; 199 | 200 | fixture.detectChanges(); 201 | 202 | const element = fixture.nativeElement; 203 | 204 | expect(element.querySelectorAll('.cmp-carousel__item--active').length) 205 | .toEqual(1); 206 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-0"); 207 | 208 | tick(1500); 209 | 210 | fixture.detectChanges(); 211 | 212 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-1"); 213 | 214 | element.querySelector('.cmp-carousel__content').dispatchEvent(new MouseEvent('mouseover', { 215 | view: window, 216 | bubbles: true, 217 | cancelable: true 218 | })); 219 | 220 | tick(500); 221 | 222 | fixture.detectChanges(); 223 | 224 | expect(element.querySelector('.cmp-carousel__item--active').getAttribute("id")).toEqual("myID-item-2"); 225 | 226 | discardPeriodicTasks(); 227 | })); 228 | 229 | it('render proper DOM',() => { 230 | 231 | const baseCssClass = 'myCustomCssClass'; 232 | 233 | component.title = TEST_COMPONENT_TITLE; 234 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 235 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 236 | component.classNames = LAYOUT.classNames; 237 | component.id = "myID"; 238 | component.autoplay = true; 239 | component.delay = 1000; 240 | component.baseCssClass = baseCssClass; 241 | 242 | fixture.detectChanges(); 243 | 244 | const element = fixture.nativeElement; 245 | 246 | expect(element).toBeDefined(); 247 | 248 | expect(element.querySelector(`.${baseCssClass}[role="group"][aria-roledescription="Carousel"]`)).toBeDefined(); 249 | 250 | const contentElement = element.querySelector(`.${baseCssClass}[role="group"][aria-roledescription="Carousel"] .${baseCssClass}__content`); 251 | 252 | expect(contentElement).toBeDefined(); 253 | 254 | const totalElements = LAYOUT[Constants.ITEMS_ORDER_PROP].length; 255 | 256 | const validateTabPanel = (index:number) => { 257 | expect(contentElement.querySelector(`div#${component.id}-item-${index}.${baseCssClass}__item[aria-label="Slide ${index + 1} of ${totalElements}"]`)).toBeDefined(); 258 | }; 259 | 260 | validateTabPanel(0); 261 | validateTabPanel(1); 262 | validateTabPanel(2); 263 | validateTabPanel(3); 264 | validateTabPanel(4); 265 | 266 | 267 | }); 268 | 269 | }); 270 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/tabs.v1.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ADOBE CONFIDENTIAL 3 | * 4 | * Copyright 2020 Adobe Systems Incorporated 5 | * All Rights Reserved. 6 | * 7 | * NOTICE: All information contained herein is, and remains 8 | * the property of Adobe Systems Incorporated and its suppliers, 9 | * if any. The intellectual and technical concepts contained 10 | * herein are proprietary to Adobe Systems Incorporated and its 11 | * suppliers and may be covered by U.S. and Foreign Patents, 12 | * patents in process, and are protected by trade secret or copyright law. 13 | * Dissemination of this information or reproduction of this material 14 | * is strictly forbidden unless prior written permission is obtained 15 | * from Adobe Systems Incorporated. 16 | */ 17 | 18 | import {ComponentFixture, TestBed} from '@angular/core/testing'; 19 | 20 | import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; 21 | 22 | 23 | import {TabsV1Component} from './tabs.v1.component'; 24 | import { 25 | Utils, 26 | AEMComponentDirective, 27 | Constants, 28 | AEMAllowedComponentsContainerComponent, 29 | AEMModelProviderComponent, 30 | MapTo, AEMResponsiveGridComponent 31 | } from "@adobe/aem-angular-editable-components"; 32 | 33 | import {Component1} from "../../../../test/test-comp1.component"; 34 | import {Component2} from "../../../../test/test-comp2.component"; 35 | import {Component3} from "../../../../test/test-comp3.component"; 36 | 37 | import {ModelManager} from '@adobe/aem-spa-page-model-manager'; 38 | 39 | describe('TabsV1', () => { 40 | 41 | const TEST_COMPONENT_TITLE = 'test container title'; 42 | const LAYOUT = require('../../../../test/data/tabs.json'); 43 | 44 | let component: TabsV1Component; 45 | let fixture: ComponentFixture; 46 | 47 | let isInEditorSpy; 48 | 49 | beforeEach(() => { 50 | 51 | spyOn(ModelManager, 'addListener').and.returnValue(undefined); 52 | isInEditorSpy = spyOn(Utils, 'isInEditor').and.returnValue(false); 53 | 54 | TestBed.configureTestingModule({ 55 | declarations: [ 56 | TabsV1Component, 57 | AEMComponentDirective, 58 | AEMAllowedComponentsContainerComponent, 59 | AEMModelProviderComponent, 60 | Component1, 61 | Component2, 62 | Component3 63 | ] 64 | }).overrideModule(BrowserDynamicTestingModule, { 65 | set: { 66 | entryComponents: [TabsV1Component, Component1, Component2, Component3] 67 | } 68 | }).compileComponents(); 69 | 70 | fixture = TestBed.createComponent(TabsV1Component); 71 | component = fixture.componentInstance; 72 | 73 | MapTo("app/components/comp1")(Component1); 74 | MapTo("app/components/comp2")(Component2); 75 | MapTo("app/components/comp3")(Component3); 76 | MapTo('wcm/foundation/components/responsivegrid')(AEMResponsiveGridComponent); 77 | 78 | fixture.detectChanges(); 79 | }); 80 | 81 | it('should create placeholder', () => { 82 | isInEditorSpy.and.returnValue(true); 83 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 84 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 85 | component.classNames = LAYOUT.classNames; 86 | 87 | fixture.detectChanges(); 88 | let element = fixture.debugElement.nativeElement; 89 | expect(element.querySelector('.new.section')).toBeDefined(); 90 | 91 | }); 92 | 93 | it('should create the allowed components with the default title and no allowed component', () => { 94 | isInEditorSpy.and.returnValue(true); 95 | component.title = TEST_COMPONENT_TITLE; 96 | component.allowedComponents = { 97 | applicable: true, 98 | components: [] 99 | }; 100 | 101 | fixture.detectChanges(); 102 | 103 | const element = fixture.nativeElement.firstElementChild; 104 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 105 | .toEqual(0); 106 | }); 107 | 108 | it('should create the allowed components with a custom title and allowed components', () => { 109 | isInEditorSpy.and.returnValue(true); 110 | component.title = TEST_COMPONENT_TITLE; 111 | component.allowedComponents = { 112 | applicable: true, 113 | components: [{ 114 | path: 'test/components/component1', 115 | title: 'Test component title 1' 116 | }, 117 | { 118 | path: 'test/components/component2', 119 | title: 'Test component title 2' 120 | }] 121 | }; 122 | 123 | fixture.detectChanges(); 124 | 125 | const element = fixture.nativeElement.firstElementChild; 126 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 127 | .toEqual(2); 128 | }); 129 | 130 | it('should render the cssClass specified in the properties', () => { 131 | component.title = TEST_COMPONENT_TITLE; 132 | component.allowedComponents = { 133 | applicable: true, 134 | components: [{ 135 | path: 'test/components/component1', 136 | title: 'Test component title 1' 137 | }, 138 | { 139 | path: 'test/components/component2', 140 | title: 'Test component title 2' 141 | }] 142 | }; 143 | component.baseCssClass = "cmp-custom-tabs"; 144 | 145 | fixture.detectChanges(); 146 | 147 | const element = fixture.nativeElement; 148 | expect(element.getAttributeNode("class").value).toContain("cmp-custom-tabs"); 149 | }); 150 | 151 | it('should NOT create the allowed components if not in the editor', () => { 152 | component.title = TEST_COMPONENT_TITLE; 153 | component.allowedComponents = { 154 | applicable: true, 155 | components: [{ 156 | path: 'test/components/component1', 157 | title: 'Test component title 1' 158 | }, 159 | { 160 | path: 'test/components/component2', 161 | title: 'Test component title 2' 162 | }] 163 | }; 164 | 165 | fixture.detectChanges(); 166 | 167 | const element = fixture.nativeElement; 168 | 169 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 170 | .toEqual(0); 171 | expect(element.querySelector('div[data-cq-data-path="root/*"][class="new section aem-Parsys-newComponent"]')) 172 | .toBeDefined(); 173 | expect(element.querySelector('div[data-cq-data-path="root/parsys/*"][class="new section aem-Parsys-newComponent"]')) 174 | .toBeDefined(); 175 | }); 176 | 177 | const getTabDisplay = (dataPath:string) => { 178 | return fixture.debugElement.nativeElement.querySelector("div[data-cq-data-path='" + dataPath + "']").attributeStyleMap.get("display").value; 179 | }; 180 | 181 | const clickTab = (index:number) => { 182 | fixture.debugElement.nativeElement.querySelector('.cmp-tabs__tablist li:nth-child(' + index + ')').click(); 183 | fixture.detectChanges(); 184 | }; 185 | 186 | it('should navigate tabs if we click', async() => { 187 | component.title = TEST_COMPONENT_TITLE; 188 | 189 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 190 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 191 | component.classNames = LAYOUT.classNames; 192 | 193 | component.ngOnInit(); 194 | 195 | fixture.detectChanges(); 196 | 197 | const element = fixture.debugElement.nativeElement; 198 | 199 | 200 | const tabList = element.querySelector('.cmp-tabs__tablist'); 201 | expect(tabList) 202 | .toBeDefined(); 203 | 204 | const tabElements = tabList.querySelectorAll("li"); 205 | expect(tabElements.length).toBe(LAYOUT[Constants.ITEMS_ORDER_PROP].length); 206 | 207 | expect(getTabDisplay('component1')).toEqual('block'); 208 | 209 | clickTab(4); 210 | 211 | expect(getTabDisplay('component1')).toEqual('none'); 212 | 213 | clickTab(2); 214 | 215 | expect(getTabDisplay('component3')).toEqual('block'); 216 | 217 | expect(component.activeTabItemDataPath).toEqual('component3'); 218 | expect(component.activeTabItemName).toEqual('component3'); 219 | expect(component.isActiveItemNameSet).toBeTrue(); 220 | }); 221 | 222 | 223 | it('should initiate with the tab from the properties', async() => { 224 | component.title = TEST_COMPONENT_TITLE; 225 | 226 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 227 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 228 | component.classNames = LAYOUT.classNames; 229 | component.activeItem = 'component3'; 230 | 231 | component.ngOnInit(); 232 | 233 | fixture.detectChanges(); 234 | 235 | expect(getTabDisplay('component3')).toEqual('block'); 236 | 237 | expect(component.activeTabItemDataPath).toEqual('component3'); 238 | expect(component.activeTabItemName).toEqual('component3'); 239 | expect(component.isActiveItemNameSet).toBeTrue(); 240 | }); 241 | 242 | it('should render the expected DOM', async() => { 243 | component.title = TEST_COMPONENT_TITLE; 244 | 245 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 246 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 247 | component.classNames = LAYOUT.classNames; 248 | component.activeItem = 'component3'; 249 | 250 | component.ngOnInit(); 251 | 252 | fixture.detectChanges(); 253 | 254 | const element = fixture.nativeElement; 255 | 256 | const tabList = element.querySelector(`ol.cmp-tabs__tablist[aria-multiselectable="false"][role="tablist"]`); 257 | expect(tabList).toBeDefined(); 258 | 259 | expect(tabList.querySelectorAll(`li.cmp-tabs__tab`).length).toEqual(5); 260 | 261 | expect(tabList.querySelector("li.cmp-tabs__tab.cmp-tabs__tab--active:nth-child(2)")).toBeDefined(); 262 | 263 | expect(tabList.querySelectorAll(`li.cmp-tabs__tab.cmp-tabs__tab--active`).length).toEqual(1); 264 | 265 | const components = element.querySelectorAll(`[data-cq-data-path]`); 266 | 267 | expect(components.length).toEqual(5); 268 | 269 | const getDisplay = (index:number) => components[index].attributeStyleMap.get("display").value; 270 | 271 | expect(getDisplay(0)).toEqual('none'); 272 | expect(getDisplay(1)).toEqual('block'); 273 | expect(getDisplay(2)).toEqual('none'); 274 | expect(getDisplay(3)).toEqual('none'); 275 | expect(getDisplay(4)).toEqual('none'); 276 | 277 | }); 278 | 279 | 280 | 281 | }); 282 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "aem-angular-core-spa-wcm-components": { 7 | "projectType": "library", 8 | "root": "projects/aem-angular-core-spa-wcm-components", 9 | "sourceRoot": "projects/aem-angular-core-spa-wcm-components/src", 10 | "prefix": "lib", 11 | "architect": { 12 | "build": { 13 | "builder": "@angular-devkit/build-ng-packagr:build", 14 | "options": { 15 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/tsconfig.lib.json", 16 | "project": "projects/aem-angular-core-spa-wcm-components/ng-package.json" 17 | }, 18 | "configurations": { 19 | "production": { 20 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/tsconfig.lib.prod.json" 21 | } 22 | } 23 | }, 24 | "test": { 25 | "builder": "@angular-devkit/build-angular:karma", 26 | "options": { 27 | "main": "projects/aem-angular-core-spa-wcm-components/src/test.ts", 28 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/tsconfig.spec.json", 29 | "karmaConfig": "projects/aem-angular-core-spa-wcm-components/karma.conf.js" 30 | } 31 | }, 32 | "lint": { 33 | "builder": "@angular-devkit/build-angular:tslint", 34 | "options": { 35 | "tsConfig": [ 36 | "projects/aem-angular-core-spa-wcm-components/tsconfig.lib.json", 37 | "projects/aem-angular-core-spa-wcm-components/tsconfig.spec.json" 38 | ], 39 | "exclude": [ 40 | "**/node_modules/**" 41 | ] 42 | } 43 | } 44 | } 45 | }, 46 | "aem-angular-core-spa-wcm-components-core": { 47 | "projectType": "library", 48 | "root": "projects/aem-angular-core-spa-wcm-components/core", 49 | "sourceRoot": "projects/aem-angular-core-spa-wcm-components/core/src", 50 | "prefix": "lib", 51 | "architect": { 52 | "build": { 53 | "builder": "@angular-devkit/build-ng-packagr:build", 54 | "options": { 55 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/core/tsconfig.lib.json", 56 | "project": "projects/aem-angular-core-spa-wcm-components/core/ng-package.json" 57 | }, 58 | "configurations": { 59 | "production": { 60 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/core/tsconfig.lib.prod.json" 61 | } 62 | } 63 | }, 64 | "test": { 65 | "builder": "@angular-devkit/build-angular:karma", 66 | "options": { 67 | "main": "projects/aem-angular-core-spa-wcm-components/core/src/test.ts", 68 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/core/tsconfig.spec.json", 69 | "karmaConfig": "projects/aem-angular-core-spa-wcm-components/core/karma.conf.js" 70 | } 71 | }, 72 | "lint": { 73 | "builder": "@angular-devkit/build-angular:tslint", 74 | "options": { 75 | "tsConfig": [ 76 | "projects/aem-angular-core-spa-wcm-components/core/tsconfig.lib.json", 77 | "projects/aem-angular-core-spa-wcm-components/core/tsconfig.spec.json" 78 | ], 79 | "exclude": [ 80 | "**/node_modules/**" 81 | ] 82 | } 83 | } 84 | } 85 | }, 86 | "aem-angular-core-spa-wcm-components-accordion-v1": { 87 | "projectType": "library", 88 | "root": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1", 89 | "sourceRoot": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src", 90 | "prefix": "lib", 91 | "architect": { 92 | "build": { 93 | "builder": "@angular-devkit/build-ng-packagr:build", 94 | "options": { 95 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.lib.json", 96 | "project": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/ng-package.json" 97 | }, 98 | "configurations": { 99 | "production": { 100 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.lib.prod.json" 101 | } 102 | } 103 | }, 104 | "test": { 105 | "builder": "@angular-devkit/build-angular:karma", 106 | "options": { 107 | "main": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/test.ts", 108 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.spec.json", 109 | "karmaConfig": "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/karma.conf.js" 110 | } 111 | }, 112 | "lint": { 113 | "builder": "@angular-devkit/build-angular:tslint", 114 | "options": { 115 | "tsConfig": [ 116 | "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.lib.json", 117 | "projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/tsconfig.spec.json" 118 | ], 119 | "exclude": [ 120 | "**/node_modules/**" 121 | ] 122 | } 123 | } 124 | } 125 | }, 126 | "aem-angular-core-spa-wcm-components-carousel-v1": { 127 | "projectType": "library", 128 | "root": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1", 129 | "sourceRoot": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src", 130 | "prefix": "lib", 131 | "architect": { 132 | "build": { 133 | "builder": "@angular-devkit/build-ng-packagr:build", 134 | "options": { 135 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.lib.json", 136 | "project": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/ng-package.json" 137 | }, 138 | "configurations": { 139 | "production": { 140 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.lib.prod.json" 141 | } 142 | } 143 | }, 144 | "test": { 145 | "builder": "@angular-devkit/build-angular:karma", 146 | "options": { 147 | "main": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/src/test.ts", 148 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.spec.json", 149 | "karmaConfig": "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/karma.conf.js" 150 | } 151 | }, 152 | "lint": { 153 | "builder": "@angular-devkit/build-angular:tslint", 154 | "options": { 155 | "tsConfig": [ 156 | "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.lib.json", 157 | "projects/aem-angular-core-spa-wcm-components/containers/carousel/v1/tsconfig.spec.json" 158 | ], 159 | "exclude": [ 160 | "**/node_modules/**" 161 | ] 162 | } 163 | } 164 | } 165 | }, 166 | "aem-angular-core-spa-wcm-components-container-v1": { 167 | "projectType": "library", 168 | "root": "projects/aem-angular-core-spa-wcm-components/containers/container/v1", 169 | "sourceRoot": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/src", 170 | "prefix": "lib", 171 | "architect": { 172 | "build": { 173 | "builder": "@angular-devkit/build-ng-packagr:build", 174 | "options": { 175 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.lib.json", 176 | "project": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/ng-package.json" 177 | }, 178 | "configurations": { 179 | "production": { 180 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.lib.prod.json" 181 | } 182 | } 183 | }, 184 | "test": { 185 | "builder": "@angular-devkit/build-angular:karma", 186 | "options": { 187 | "main": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/src/test.ts", 188 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.spec.json", 189 | "karmaConfig": "projects/aem-angular-core-spa-wcm-components/containers/container/v1/karma.conf.js" 190 | } 191 | }, 192 | "lint": { 193 | "builder": "@angular-devkit/build-angular:tslint", 194 | "options": { 195 | "tsConfig": [ 196 | "projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.lib.json", 197 | "projects/aem-angular-core-spa-wcm-components/containers/container/v1/tsconfig.spec.json" 198 | ], 199 | "exclude": [ 200 | "**/node_modules/**" 201 | ] 202 | } 203 | } 204 | } 205 | }, 206 | "aem-angular-core-spa-wcm-components-tabs-v1": { 207 | "projectType": "library", 208 | "root": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1", 209 | "sourceRoot": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src", 210 | "prefix": "lib", 211 | "architect": { 212 | "build": { 213 | "builder": "@angular-devkit/build-ng-packagr:build", 214 | "options": { 215 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.lib.json", 216 | "project": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/ng-package.json" 217 | }, 218 | "configurations": { 219 | "production": { 220 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.lib.prod.json" 221 | } 222 | } 223 | }, 224 | "test": { 225 | "builder": "@angular-devkit/build-angular:karma", 226 | "options": { 227 | "main": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/src/test.ts", 228 | "tsConfig": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.spec.json", 229 | "karmaConfig": "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/karma.conf.js" 230 | } 231 | }, 232 | "lint": { 233 | "builder": "@angular-devkit/build-angular:tslint", 234 | "options": { 235 | "tsConfig": [ 236 | "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.lib.json", 237 | "projects/aem-angular-core-spa-wcm-components/containers/tabs/v1/tsconfig.spec.json" 238 | ], 239 | "exclude": [ 240 | "**/node_modules/**" 241 | ] 242 | } 243 | } 244 | } 245 | } 246 | }, 247 | "cli": { 248 | "analytics": false 249 | }, 250 | "defaultProject": "aem-angular-core-spa-wcm-components" 251 | } 252 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /projects/aem-angular-core-spa-wcm-components/containers/accordion/v1/src/accordion.v1.component.spec.ts: -------------------------------------------------------------------------------- 1 | /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 | ~ Copyright 2020 Adobe Systems Incorporated 3 | ~ 4 | ~ Licensed under the Apache License, Version 2.0 (the "License"); 5 | ~ you may not use this file except in compliance with the License. 6 | ~ You may obtain a copy of the License at 7 | ~ 8 | ~ http://www.apache.org/licenses/LICENSE-2.0 9 | ~ 10 | ~ Unless required by applicable law or agreed to in writing, software 11 | ~ distributed under the License is distributed on an "AS IS" BASIS, 12 | ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | ~ See the License for the specific language governing permissions and 14 | ~ limitations under the License. 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 16 | 17 | import {ComponentFixture, TestBed} from '@angular/core/testing'; 18 | 19 | import {BrowserDynamicTestingModule} from '@angular/platform-browser-dynamic/testing'; 20 | 21 | 22 | import {AccordionV1Component} from './accordion.v1.component'; 23 | import {Utils,AEMComponentDirective, Constants,AEMAllowedComponentsContainerComponent,AEMModelProviderComponent} from "@adobe/aem-angular-editable-components"; 24 | 25 | import {Component1} from "../../../../test/test-comp1.component"; 26 | import {Component2} from "../../../../test/test-comp2.component"; 27 | import {Component3} from "../../../../test/test-comp3.component"; 28 | 29 | import {ModelManager} from '@adobe/aem-spa-page-model-manager'; 30 | 31 | describe('AccordionV1', () => { 32 | 33 | const TEST_COMPONENT_TITLE = 'test container title'; 34 | const LAYOUT = require('../../../../test/data/accordion.json'); 35 | 36 | let component: AccordionV1Component; 37 | let fixture: ComponentFixture; 38 | 39 | let isInEditorSpy; 40 | 41 | beforeEach(() => { 42 | 43 | spyOn(ModelManager, 'addListener').and.returnValue(undefined); 44 | isInEditorSpy = spyOn(Utils, 'isInEditor').and.returnValue(false); 45 | 46 | TestBed.configureTestingModule({ 47 | declarations: [ 48 | AccordionV1Component, 49 | AEMComponentDirective, 50 | AEMAllowedComponentsContainerComponent, 51 | AEMModelProviderComponent, 52 | Component1, 53 | Component2, 54 | Component3,] 55 | }).overrideModule(BrowserDynamicTestingModule, { 56 | set: { 57 | entryComponents: [AccordionV1Component, Component1, Component2, Component3] 58 | } 59 | }).compileComponents(); 60 | 61 | fixture = TestBed.createComponent(AccordionV1Component); 62 | component = fixture.componentInstance; 63 | fixture.detectChanges(); 64 | }); 65 | 66 | it('should create placeholder', () => { 67 | isInEditorSpy.and.returnValue(true); 68 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 69 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 70 | component.classNames = LAYOUT.classNames; 71 | 72 | fixture.detectChanges(); 73 | let element = fixture.debugElement.nativeElement; 74 | expect(element.querySelector('.new.section')).toBeDefined(); 75 | 76 | }); 77 | 78 | it('should create the allowed components with the default title and no allowed component', () => { 79 | isInEditorSpy.and.returnValue(true); 80 | component.title = TEST_COMPONENT_TITLE; 81 | component.allowedComponents = { 82 | applicable: true, 83 | components: [] 84 | }; 85 | 86 | fixture.detectChanges(); 87 | 88 | const element = fixture.nativeElement.firstElementChild; 89 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 90 | .toEqual(0); 91 | }); 92 | 93 | it('should create the allowed components with a custom title and allowed components', () => { 94 | isInEditorSpy.and.returnValue(true); 95 | component.title = TEST_COMPONENT_TITLE; 96 | component.allowedComponents = { 97 | applicable: true, 98 | components: [{ 99 | path: 'test/components/component1', 100 | title: 'Test component title 1' 101 | }, 102 | { 103 | path: 'test/components/component2', 104 | title: 'Test component title 2' 105 | }] 106 | }; 107 | 108 | fixture.detectChanges(); 109 | 110 | const element = fixture.nativeElement.firstElementChild; 111 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 112 | .toEqual(2); 113 | }); 114 | 115 | it('should render the cssClass specified in the properties', () => { 116 | component.title = TEST_COMPONENT_TITLE; 117 | component.allowedComponents = { 118 | applicable: true, 119 | components: [{ 120 | path: 'test/components/component1', 121 | title: 'Test component title 1' 122 | }, 123 | { 124 | path: 'test/components/component2', 125 | title: 'Test component title 2' 126 | }] 127 | }; 128 | 129 | fixture.detectChanges(); 130 | 131 | const element = fixture.nativeElement; 132 | 133 | const cssClasses = component.getHostClassNames(); 134 | console.log(cssClasses); 135 | expect(element.getAttributeNode("class").value).toContain("cmp-accordion"); 136 | expect(cssClasses).toContain("cmp-accordion"); 137 | }); 138 | 139 | it('should NOT create the allowed components if not in the editor', () => { 140 | component.title = TEST_COMPONENT_TITLE; 141 | component.allowedComponents = { 142 | applicable: true, 143 | components: [{ 144 | path: 'test/components/component1', 145 | title: 'Test component title 1' 146 | }, 147 | { 148 | path: 'test/components/component2', 149 | title: 'Test component title 2' 150 | }] 151 | }; 152 | 153 | fixture.detectChanges(); 154 | 155 | const element = fixture.nativeElement; 156 | //expect(element.querySelector('.' + ALLOWED_COMPONENT_TITLE_CLASS_NAMES)).toBeNull(); 157 | 158 | //expect(element.classList.contains(ALLOWED_PLACEHOLDER_CLASS_NAMES)).toBeFalsy(); 159 | 160 | expect(element.querySelectorAll('.aem-AllowedComponent--component.cq-placeholder.placeholder').length) 161 | .toEqual(0); 162 | expect(element.querySelector('div[data-cq-data-path="root/*"][class="new section aem-Parsys-newComponent"]')) 163 | .toBeDefined(); 164 | expect(element.querySelector('div[data-cq-data-path="root/parsys/*"][class="new section aem-Parsys-newComponent"]')) 165 | .toBeDefined(); 166 | }); 167 | 168 | 169 | 170 | 171 | it('should open multiple when clicked upon', () => { 172 | component.title = TEST_COMPONENT_TITLE; 173 | component.allowedComponents = { 174 | applicable: true, 175 | components: [{ 176 | path: 'test/components/component1', 177 | title: 'Test component title 1' 178 | }, 179 | { 180 | path: 'test/components/component2', 181 | title: 'Test component title 2' 182 | }] 183 | }; 184 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 185 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 186 | component.classNames = LAYOUT.classNames; 187 | 188 | fixture.detectChanges(); 189 | 190 | const element = fixture.debugElement.nativeElement; 191 | 192 | const button = element.querySelector('.cmp-accordion__item:first-child .cmp-accordion__button'); 193 | const button2 = element.querySelector('.cmp-accordion__item:last-child .cmp-accordion__button'); 194 | 195 | expect(button).toBeDefined(); 196 | expect(button2).toBeDefined(); 197 | 198 | button.click(); 199 | button2.click(); 200 | fixture.detectChanges(); 201 | 202 | const tab1 = element.querySelector('.cmp-accordion__item:first-child'); 203 | const buttonClicked = tab1.querySelector('.cmp-accordion__button'); 204 | const tab1Content = tab1.querySelector('.cmp-accordion__panel'); 205 | expect(tab1Content).toBeDefined(); 206 | expect(buttonClicked.getAttributeNode("class").value).toBe("cmp-accordion__button cmp-accordion__button--expanded"); 207 | 208 | const tab2 = element.querySelector('.cmp-accordion__item:last-child'); 209 | const button2Clicked = tab2.querySelector('.cmp-accordion__button'); 210 | const tab2Content = tab2.querySelector('.cmp-accordion__panel'); 211 | expect(tab2Content).toBeDefined(); 212 | expect(button2Clicked.getAttributeNode("class").value).toBe("cmp-accordion__button cmp-accordion__button--expanded"); 213 | 214 | }); 215 | 216 | 217 | it('should open only 1 item at a time when clicked upon', () => { 218 | component.title = TEST_COMPONENT_TITLE; 219 | component.allowedComponents = { 220 | applicable: true, 221 | components: [{ 222 | path: 'test/components/component1', 223 | title: 'Test component title 1' 224 | }, 225 | { 226 | path: 'test/components/component2', 227 | title: 'Test component title 2' 228 | }] 229 | }; 230 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 231 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 232 | component.classNames = LAYOUT.classNames; 233 | component.singleExpansion = true; 234 | component.id = LAYOUT.id; 235 | 236 | fixture.detectChanges(); 237 | 238 | const element = fixture.debugElement.nativeElement; 239 | 240 | const button = element.querySelector('.cmp-accordion__item:first-child .cmp-accordion__button'); 241 | const button2 = element.querySelector('.cmp-accordion__item:last-child .cmp-accordion__button'); 242 | 243 | expect(button).toBeDefined(); 244 | expect(button2).toBeDefined(); 245 | 246 | button.click(); 247 | fixture.detectChanges(); 248 | button2.click(); 249 | fixture.detectChanges(); 250 | 251 | const tab1 = element.querySelector('.cmp-accordion__item:first-child'); 252 | const buttonClicked = tab1.querySelector('.cmp-accordion__button'); 253 | expect(buttonClicked.getAttributeNode("class").value).toBe("cmp-accordion__button"); 254 | 255 | const tab2 = element.querySelector('.cmp-accordion__item:last-child'); 256 | const button2Clicked = tab2.querySelector('.cmp-accordion__button'); 257 | expect(button2Clicked.getAttributeNode("class").value).toBe("cmp-accordion__button cmp-accordion__button--expanded"); 258 | 259 | }); 260 | 261 | 262 | it('generate the proper DOM structure', () => { 263 | component.title = TEST_COMPONENT_TITLE; 264 | component.allowedComponents = { 265 | applicable: true, 266 | components: [{ 267 | path: 'test/components/component1', 268 | title: 'Test component title 1' 269 | }, 270 | { 271 | path: 'test/components/component2', 272 | title: 'Test component title 2' 273 | }] 274 | }; 275 | 276 | const cssClass = 'myCustomBemClass'; 277 | component.baseCssClass = cssClass; 278 | component.cqItems = LAYOUT[Constants.ITEMS_PROP]; 279 | component.cqItemsOrder = LAYOUT[Constants.ITEMS_ORDER_PROP]; 280 | component.classNames = LAYOUT.classNames; 281 | component.singleExpansion = true; 282 | component.dataLayer = { 283 | "testaccordion": { 284 | "test1": "test", 285 | "test2": "test" 286 | } 287 | }; 288 | component.id = LAYOUT.id; 289 | 290 | fixture.detectChanges(); 291 | 292 | const element = fixture.nativeElement; 293 | expect(element.getAttribute("data-cmp-data-layer")).toEqual('{"testaccordion":{"test1":"test","test2":"test"}}'); 294 | 295 | const validateEntry = (index:number) => { 296 | const expectedElement = element.querySelector(`.${cssClass}__item:nth-child(${index})[data-cmp-hook-accordion="item"]`); 297 | expect(expectedElement).toBeDefined(); 298 | 299 | expect(expectedElement.querySelector(`h3.${cssClass}__header`)).toBeDefined(); 300 | expect(expectedElement.querySelector(`h3.${cssClass}__header`)).toBeDefined(); 301 | const indexAdjusted = index - 1; 302 | 303 | expect(expectedElement.querySelector(`h3.${cssClass}__header button#${LAYOUT.id}-button-${indexAdjusted}.${cssClass}__button[aria-controls="${LAYOUT.id}-panel-${indexAdjusted}"]`)).toBeDefined(); 304 | const titleSpan = expectedElement.querySelector(`h3.${cssClass}__header button span.${cssClass}__title`); 305 | expect(titleSpan).toBeDefined(); 306 | 307 | const expectedTitle = LAYOUT[":items"][LAYOUT[":itemsOrder"][indexAdjusted]]["cq:panelTitle"]; 308 | 309 | expect(titleSpan.innerHTML).toEqual(expectedTitle); 310 | expect(expectedElement.querySelector(`h3.${cssClass}__header button span.${cssClass}__icon`)).toBeDefined(); 311 | 312 | }; 313 | 314 | validateEntry(1); 315 | validateEntry(2); 316 | validateEntry(3); 317 | validateEntry(4); 318 | validateEntry(5); 319 | 320 | }); 321 | }); 322 | --------------------------------------------------------------------------------