├── .babelrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .jshintrc
├── .npmignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE-pt.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── bin
├── chromedriver
├── chromedriver-mac
├── chromedriver-win
├── phantomjs
└── selenium-server-standalone-3.0.1.jar
├── config
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js
├── dist
├── capivara.js
├── capivara.js.map
└── capivara.min.js
├── index.js
├── karma.conf.js
├── nightwatch.conf.js
├── nightwatch.json
├── package-lock.json
├── package.json
├── src
├── common.ts
├── constants.ts
├── core
│ ├── capivara.instance.ts
│ ├── component.config.ts
│ ├── component.instance.ts
│ ├── component.ts
│ ├── controller.ts
│ ├── element.ts
│ ├── eval.ts
│ ├── index.ts
│ ├── magic
│ │ ├── check.context.ts
│ │ ├── context.ts
│ │ ├── magic.ts
│ │ └── types
│ │ │ ├── angular.context.ts
│ │ │ ├── angularjs.context.ts
│ │ │ ├── capivara.context.ts
│ │ │ ├── react.context.ts
│ │ │ └── vuejs.context.ts
│ ├── observer
│ │ ├── index.ts
│ │ ├── polyfill.ts
│ │ └── util.ts
│ └── util
│ │ └── keycodes.enum.ts
├── decorators
│ ├── component-state.ts
│ ├── component.ts
│ ├── controller.ts
│ └── index.ts
├── index.ts
├── map
│ ├── directive
│ │ ├── cp-attr.ts
│ │ ├── cp-blur.ts
│ │ ├── cp-change.ts
│ │ ├── cp-class.ts
│ │ ├── cp-click.ts
│ │ ├── cp-disabled.ts
│ │ ├── cp-else-if.ts
│ │ ├── cp-else.ts
│ │ ├── cp-focus.ts
│ │ ├── cp-hide.ts
│ │ ├── cp-if.ts
│ │ ├── cp-init.ts
│ │ ├── cp-key.ts
│ │ ├── cp-model.ts
│ │ ├── cp-mouse.ts
│ │ ├── cp-repeat.ts
│ │ ├── cp-show.ts
│ │ ├── cp-style.ts
│ │ └── directive.interface.ts
│ └── map-dom.ts
└── scope
│ ├── scope.proxy.ts
│ └── scope.ts
├── test
├── e2e
│ ├── cpBlur
│ │ ├── template.html
│ │ └── test.js
│ ├── cpChange
│ │ ├── template.html
│ │ └── test.js
│ ├── cpClass
│ │ ├── template.html
│ │ └── test.js
│ ├── cpClick
│ │ ├── template.html
│ │ └── test.js
│ ├── cpDisabled
│ │ ├── template.html
│ │ └── test.js
│ ├── cpDoubleClick
│ │ ├── template.html
│ │ └── test.js
│ ├── cpElse
│ │ ├── template.html
│ │ └── test.js
│ ├── cpElseIf
│ │ ├── template.html
│ │ └── test.js
│ ├── cpFocus
│ │ ├── template.html
│ │ └── test.js
│ ├── cpHide
│ │ ├── template.html
│ │ └── test.js
│ ├── cpIf
│ │ ├── template.html
│ │ └── test.js
│ ├── cpInit
│ │ ├── template.html
│ │ └── test.js
│ ├── cpKey
│ │ ├── template.html
│ │ └── test.js
│ ├── cpMax
│ │ ├── template.html
│ │ └── test.js
│ ├── cpMaxLength
│ │ ├── template.html
│ │ └── test.js
│ ├── cpMin
│ │ ├── template.html
│ │ └── test.js
│ ├── cpModel
│ │ ├── template.html
│ │ └── test.js
│ ├── cpMouse
│ │ ├── template.html
│ │ └── test.js
│ ├── cpPlaceholder
│ │ ├── template.html
│ │ └── test.js
│ ├── cpRepeat
│ │ ├── template.html
│ │ └── test.js
│ ├── cpShow
│ │ ├── template.html
│ │ └── test.js
│ ├── cpSrc
│ │ ├── template.html
│ │ └── test.js
│ ├── cpStep
│ │ ├── template.html
│ │ └── test.js
│ ├── cpStyle
│ │ ├── template.html
│ │ └── test.js
│ ├── index.js
│ ├── interpolation
│ │ ├── template.html
│ │ └── test.js
│ └── noBind
│ │ ├── template.html
│ │ └── test.js
└── spec
│ ├── capivara-change.spec.ts
│ ├── capivara-class.spec.ts
│ ├── capivara-click.spec.ts
│ ├── capivara-common.spec.ts
│ ├── capivara-component-instance.spec.ts
│ ├── capivara-component.spec.ts
│ ├── capivara-disabled.spec.ts
│ ├── capivara-doubleclick.spec.ts
│ ├── capivara-else-if.spec.ts
│ ├── capivara-else.spec.ts
│ ├── capivara-eval.spec.ts
│ ├── capivara-focus.spec.ts
│ ├── capivara-hide.spec.ts
│ ├── capivara-if.spec.ts
│ ├── capivara-init.spec.ts
│ ├── capivara-interpolation.spec.ts
│ ├── capivara-key.spec.ts
│ ├── capivara-max.spec.ts
│ ├── capivara-maxlength.spec.ts
│ ├── capivara-methods.spec.ts
│ ├── capivara-min.spec.ts
│ ├── capivara-model.spec.ts
│ ├── capivara-mouse.spec.ts
│ ├── capivara-no-bind.spec.ts
│ ├── capivara-placeholder.spec.ts
│ ├── capivara-polyfill.spec.ts
│ ├── capivara-repeat.spec.ts
│ ├── capivara-show.spec.ts
│ ├── capivara-src.spec.ts
│ ├── capivara-step.spec.ts
│ ├── capivara-style.spec.ts
│ ├── capivara-title.spec.ts
│ └── capivara-util.spec.ts
├── tsconfig.json
├── tslint.json
└── webpack-nightwatch-plugin
├── .babelrc
├── .npmignore
├── LICENSE
├── README.md
├── index.js
├── lib
└── index.js
├── package.json
├── rollup.config.js
├── test
├── index.spec.js
├── nightwatch.conf.js
└── ui
│ └── ui.nightwatch.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | // "env"
4 | ]
5 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 |
2 | # http://editorconfig.org
3 |
4 | root = true
5 |
6 | [*]
7 | charset = utf-8
8 | indent_style = space
9 | indent_size = 2
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 |
14 | [*.md]
15 | insert_final_newline = false
16 | trim_trailing_whitespace = false
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "env": {
3 | "browser": true,
4 | "es6": true
5 | },
6 | "extends": "eslint:recommended",
7 | "rules": {
8 | 'no-console': 'off',
9 | 'no-undef': 'off',
10 | "indent": [
11 | "error",
12 | "tab"
13 | ],
14 | "linebreak-style": [
15 | "error",
16 | "unix"
17 | ],
18 | "quotes": [
19 | "error",
20 | "single"
21 | ],
22 | "semi": [
23 | "error",
24 | "always"
25 | ]
26 | }
27 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea/
3 | coverage/
4 | selenium-debug.log
5 | reports/
6 | .nyc_output
7 | coverage.lcov
8 | phantomjsdriver.log
9 | div/
10 | dev/
11 | examples/
12 | demo/
13 | dev.html
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "undef": true,
3 | "unused": true,
4 | "esversion": 6,
5 | "node": true,
6 | "globals": {
7 | "angular": true,
8 | "capivara": true,
9 | "window": true,
10 | "document": true,
11 | "require": true
12 | }
13 | }
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | bin
2 | example
3 | coverage
4 | test
5 | .idea
6 | config
7 | dev
8 | webpack-nightwatch-plugin
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - node
4 | before_script:
5 | - npm install
6 | script:
7 | - npm run coverage
8 | branches:
9 | only:
10 | - master
11 | - /^greenkeeper/.*$/
12 | notifications:
13 | email:
14 | on_failure: change
15 | on_success: change
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | education, socio-economic status, nationality, personal appearance, race,
10 | religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at [Gumgait@gmail.com](mailto:Gumgait@gmail.com). All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribuindo com CapivaraJS
2 |
3 | Nós gostamos muito de contribuições em nosso projeto, isso faz com que o CapivaraJS fique melhor a cada dia, para isso criamos esse documento que gostaríamos que você seguisse:
4 |
5 | * [Questões e Problemas](#question)
6 | * [Issues e Bugs](#issue)
7 | * [Requisição de novas funcionalidades](#feature)
8 | * [Melhorias de documentação](#docs)
9 | * [Orientação para a Submissão de Issue](#submit)
10 | * [Orientação para a Submissão de Pull Request](#submit-pr)
11 |
12 | ## Questões e Problemas?
13 |
14 | Abrir uma issue não é a melhor maneira de resolver problemas e questões sobre a utilização do CapivaraJS, explicaremos melhor no próximo tópico quando se deve abrir issues, pois isso evita misturar problemas e questões com Bugs dificultando o trabalho de determinar qual a velocidade em que as requisições devem ser atendidas. A maneira mais rápida e eficiente de resolver isso é utilizando nossos grupos, devido a velocidade em que a equipe ou a comunidade pode resolver. Esses são os links para acessar os grupos:
15 |
16 | Nossos links para contato:
17 | - O [Google Group][groups] do CapivaraJS
18 |
19 | ## Issue ou Bug?
20 |
21 | Se você encontrou um bug no código fonte, você pode nos ajudar submetendo uma issue em nosso [Repositório do GitHub][github]. Melhor ainda se essa issue vier com um Pull Request para fixar o problema.
22 | A equipe empenha-se muito na resolução e fechamento de todas as issues que são abertas, infelizmente algumas podem demorar mais tempo que outras para serem fechadas, mas estaremos investindo muito esforço para que o CapivaraJS alcance sempre as expectatívas dos usuários.
23 | **Veja o tópico sobre [Orientações de Submissão](#submit).**
24 |
25 | ## Requisição de novas funcionalidades?
26 |
27 | Você pode requerir uma nova funcionalidade para o CapivaraJS submetendo uma isssue ao nosso [Repositório do GitHub][github]
28 |
29 | Se você quiser pode também não apenas abrir a issue, mas também ajudar na criação da funcionalidade, fazendo descrições bem detalhadas da sua issue, para que o time não tenha dúvidas durante o desenvolvimento.
30 | Caso você consiga criar a issue e já resolver, visite a sessão de [Orientações sobre Pull Request](#submit-pr).
31 |
32 | ## Melhorias de documentação?
33 |
34 | Se você tiver uma sugestão para a documentação, você pode abrir uma issue e descrever o problema ou melhorias que você tenha.
35 | Caso você esteja disposto a resolver o problema de documentação, seja ele pequeno como alguns erros ortográficos ou grandes inserções de texto. É muito importante criar [issues][github-new-issue] comentando qual é seu objetivo e a sua melhoria de documentação, evitando assim trabalho duplicado para outras pessoas que também possam ter encontrado o mesmo problema.
36 |
37 | ## Orientação para a Submissão de Issue
38 | Antes de qualquer submissão de issue, não custa nada passar lá na sessão de [issues][github-issues] e ver se já não foi aberta ou solucionada.
39 | Se a sua issue for um bug que ainda não tenha sido reportado a nós, abra a issue imediatamente. Isso ajuda a concentrar o foco do time de desenvolvimento, pois não será necessário procurar problemas e sim apenas concerta-los, fazendo com que bugs sejam resolvidos com mais eficiência.
40 |
41 | A [nova issue][github-new-issue] contem vários campos que gostaríamos que fossem preenchidos para entendermos melhor o problema e categorizar por nível de urgência.
42 |
43 | Mesmo que já falamos anteriormente reforçar nunca é demais, então aqui vão algumas dicas de como melhorar a documentação da issue, para que ela vá direto ao ponto.
44 |
45 | * **Explicações** - Explique qual o motivo disso ser um problema para você
46 | * **A versão do CapivaraJS** - Não se esqueça de dizer qual é a sua versão utilizada, pois muitas vezes uma migração para uma nova versão do sistema já pode resolver.
47 | * **Reprodução do erro** - Nos mostre um exemplo do problema, pode ser utilizando [JSFiddle][jsfiddle] ou [Plunker][plunker] (ou qualquer outro editor online) para entendermos com mais facilidade
48 | * **Issues Parecidas** - Alguma issue reportada anteriormente é relacionada com a sua? Nos avise.
49 | * **Sugestão para Solução** - Se você conseguiu resolver o problema você mesmo, avise também para ajudar outras pessoas.
50 |
51 | ## Orientação para a Submissão de Pull Request
52 |
53 | Esse é um pequeno tutorial de como enviar pull requests para o [CapivaraJS][CapivaraDoc]
54 |
55 | * Primeiro acesse o github do [CapivaraJS][github] e faça um fork do projeto
56 | * Dentro do seu fork você pode fazer as suas modificações, logo em seguida você pode enviar as suas alterações para o seu fork no github utilizando os seguintes comandos, dentro da pasta do seu projeto
57 |
58 | git add .
59 |
60 | git commit -m "Adicione aqui a mensagem que você quer que apareça"
61 |
62 | git push origin (master ou outraBranch)
63 |
64 | * Agora entre novamente em nosso [github][github] e abra o pull request
65 |
66 | * Escolha a opção de comparação entre o nosso repositório e o seu fork clicando em **compare across forks**
67 | * Não se esqueça de nos dar permissão para editarmos qualquer código que você nos envie marcando a opção **Allow edits from maintainers**
68 | * Agora é so enviar o seu **Pull Request** e esperar nossa resposta
69 |
70 |
71 |
72 | [github-issues]: https://github.com/CapivaraJS/capivarajs/issues
73 | [github-new-issue]: https://github.com/CapivaraJS/capivarajs/issues/new
74 | [github]: https://github.com/CapivaraJS/capivarajs
75 | [groups]: https://groups.google.com/d/forum/capivarajs
76 | [individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
77 | [jsfiddle]: http://jsfiddle.net/
78 | [plunker]: https://plnkr.co/
79 | [CapivaraDoc]: https://capivarajs.github.io/
80 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE-pt.md:
--------------------------------------------------------------------------------
1 | ### Passo 1: Você está no local correto?
2 |
3 | * Para submter isssues ou features relacionadas com o código, adicione uma [issue](github) em nosso Github.
4 | * Para dúvidas ou questões sobre utilização, utilize o [Google Groups](https://groups.google.com/forum/#!forum/capivarajs) que nós responderemos.
5 |
6 | ### Passo 2: Descreva seu ambiente
7 |
8 | * Versão do SO: _____
9 | * Versão do CapivaraJS: _____
10 | * Versão do Npm: _____
11 |
12 | ### Passo 3: Descreva o problema:
13 |
14 | #### Passos para reprodução do erro:
15 |
16 | 1. _____
17 | 2. _____
18 | 3. _____
19 |
20 | #### Resultados da execução:
21 |
22 | * O que aconteceu? Você pode nos dar uma descrição, um print de saída ou até um documento de texto.
23 |
24 | #### Resultado Esperado:
25 |
26 | * Nos diga qual era a saída esperada do seu programa.
27 | #### Seu código:
28 |
29 | ```
30 | // TODO(você): Coloque seu código para mostrar o problema
31 | ```
32 | * Se você preferir, pode colocar o código no [JSFiddle][jsfiddle] ou [Plunker][plunker] e nos enviar o link.
33 |
34 | ### Conseguiu desenvolver uma solução?
35 |
36 | Abra um [pull request] e faça a submissão do seu código.
37 |
38 | #### Esse template de issue foi baseado no template desse [Github](https://github.com/googlesamples/google-services).
39 |
40 | [jsfiddle]: http://jsfiddle.net/
41 | [plunker]: https://plnkr.co/
42 | [github]: https://github.com/CapivaraJS/capivarajs
43 | [google-github]: https://github.com/googlesamples/google-services
44 | [pull request]: https://github.com/CapivaraJS/capivarajs/compare
45 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Step 1: Are you in the right place?
2 |
3 | * For issues or feature requests related to the code in [this repository](github) file a Github issue.
4 | * For general technical questions, post a question on [Google Groups](https://groups.google.com/forum/#!forum/capivarajs) tagged appropriately.
5 |
6 | ### Step 2: Describe your environment
7 |
8 | * OS version: _____
9 | * CapivaraJS version: _____
10 | * Npm Version: _____
11 |
12 | ### Step 3: Describe the problem:
13 |
14 | #### Steps to reproduce:
15 |
16 | 1. _____
17 | 2. _____
18 | 3. _____
19 |
20 | #### Observed Results:
21 |
22 | * What happened? This could be a description, log output, etc.
23 |
24 | #### Expected Results:
25 |
26 | * What did you expect to happen?
27 |
28 | #### Relevant Code:
29 |
30 | ```
31 | // TODO(you): code here to reproduce the problem
32 | ```
33 | * If you prefer, you can put the code on [JSFiddle][jsfiddle] or [Plunker][plunker].
34 |
35 | ### Did you develop a solution?
36 | Open a [pull request] and submit your code.
37 |
38 |
39 | #### The issue template are based on this [GitHub](https://github.com/googlesamples/google-services).
40 |
41 | [jsfiddle]: http://jsfiddle.net/
42 | [plunker]: https://plnkr.co/
43 | [github]: https://github.com/CapivaraJS/capivarajs
44 | [google]: https://github.com/googlesamples/google-services
45 | [pull request]: https://github.com/CapivaraJS/capivarajs/compare
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | The MIT License
3 |
4 | Copyright (c) 2010-2018 Gumga, S/A. https://capivarajs.github.io/
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Atualmente existem vários frameworks que possibilitam a criação de componentes, entretanto tais componentes acabam ficando isolados em determinada tecnologia, fazendo com que uma possível migração seja mais complexa.
20 |
21 | Criamos um **framework híbrido** e suas diretivas são totalmente personalizáveis, tornando assim os componentes independentes da tecnologia utilizada.
22 |
23 | Componentes CapivaraJS são compatíveis com todos frameworks. Experimente!
24 |
25 | _____________________________________________________________________
26 |
27 | [Ir para documentação / Go to documentation](https://capivarajs.github.io/)
28 |
29 | [Seja um contribuidor / Be a contributor][contributing]
30 |
31 | [contributing]: https://github.com/CapivaraJS/capivarajs/blob/master/CONTRIBUTING.md
32 |
33 | _____________________________________________________________________
34 |
35 | Nowadays there are a lot of frameworks to component creation, but these components become isolated in the technology. and this increase the complexity to migrate them.
36 |
37 | We create a **hibrid framework** and yours directives are totaly customizable, making your components independent of the used technology
38 |
39 | CapivaraJS components are compatible with all frameworks. Try it!
40 |
--------------------------------------------------------------------------------
/bin/chromedriver:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CapivaraJS/capivarajs/4e4f735a092b70634d32ebd6d821dae9439a0569/bin/chromedriver
--------------------------------------------------------------------------------
/bin/chromedriver-mac:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CapivaraJS/capivarajs/4e4f735a092b70634d32ebd6d821dae9439a0569/bin/chromedriver-mac
--------------------------------------------------------------------------------
/bin/chromedriver-win:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CapivaraJS/capivarajs/4e4f735a092b70634d32ebd6d821dae9439a0569/bin/chromedriver-win
--------------------------------------------------------------------------------
/bin/phantomjs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CapivaraJS/capivarajs/4e4f735a092b70634d32ebd6d821dae9439a0569/bin/phantomjs
--------------------------------------------------------------------------------
/bin/selenium-server-standalone-3.0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CapivaraJS/capivarajs/4e4f735a092b70634d32ebd6d821dae9439a0569/bin/selenium-server-standalone-3.0.1.jar
--------------------------------------------------------------------------------
/config/webpack.common.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const isTest = process.argv.indexOf('--t') !== -1;
3 | const WebpackNightWatchPlugin = require('../webpack-nightwatch-plugin');
4 |
5 | const plugins = [];
6 |
7 | if(isTest){
8 | plugins.push(
9 | new WebpackNightWatchPlugin({
10 | url: 'nightwatch.conf.js'
11 | })
12 | );
13 | }
14 |
15 | module.exports = {
16 | context: __dirname,
17 | entry: {
18 | bundle: path.join(__dirname, '../src', 'index')
19 | },
20 | plugins: plugins,
21 | resolve: {
22 | extensions: ['.ts', '.tsx', '.js']
23 | },
24 | module: {
25 | rules: [
26 | {
27 | test: /\.(html)$/,
28 | use: 'html-loader'
29 | },
30 | {
31 | test: /\.tsx?$/,
32 | use: 'ts-loader',
33 | exclude: /node_modules/
34 | },
35 | {
36 | test: /\.js$/,
37 | exclude: /node_modules/,
38 | use: 'babel-loader'
39 | },
40 | {
41 | test: /\.(jpe?g|png|gif|svg|eot|woff2|woff|ttf)$/i,
42 | use: 'file-loader?name=assets/[name].[ext]'
43 | }
44 | ]
45 | }
46 | };
--------------------------------------------------------------------------------
/config/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const merge = require('webpack-merge');
3 | const webpackCommon = require('./webpack.common');
4 |
5 | module.exports = merge(webpackCommon, {
6 | mode: 'development',
7 | devtool: 'source-map',
8 | output: {
9 | path: path.join(__dirname, '../dist/'),
10 | filename: 'capivara.js',
11 | publicPath: '/dist/'
12 | },
13 | devServer: {
14 | inline: true,
15 | host: '0.0.0.0',
16 | port: 1111
17 | },
18 | plugins: [],
19 | module: {
20 | rules: []
21 | }
22 | });
--------------------------------------------------------------------------------
/config/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const merge = require('webpack-merge');
3 | const webpackCommon = require('./webpack.common');
4 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
5 |
6 | module.exports = merge(webpackCommon, {
7 | mode: 'production',
8 | output: {
9 | path: path.join(__dirname, '../dist/'),
10 | filename: 'capivara.min.js',
11 | publicPath: '/dist/'
12 | },
13 | plugins: [
14 | new UglifyJSPlugin()
15 | ],
16 | module: {
17 | rules: []
18 | }
19 | });
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require('./dist/capivara.js');
2 | module.exports = window.capivara;
3 |
4 |
5 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | config.set({
3 |
4 | // base path that will be used to resolve all patterns (eg. files, exclude)
5 | basePath: '',
6 |
7 |
8 | // frameworks to use
9 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
10 | frameworks: ['jasmine', 'karma-typescript', 'es6-shim'],
11 |
12 | // list of files / patterns to load in the browser
13 | files: [
14 | './node_modules/babel-polyfill/dist/polyfill.js',
15 | 'src/*.ts',
16 | 'src/**/*.ts',
17 | 'test/spec/*spec.ts',
18 | ],
19 |
20 | // Configure code coverage reporter
21 | coverageReporter: {
22 | reporters: [
23 | // generates ./coverage/lcov.info
24 | {type:'lcovonly', subdir: '.'},
25 | // generates ./coverage/coverage-final.json
26 | {type:'json', subdir: '.'},
27 | ]
28 | },
29 |
30 | // list of files to exclude
31 | exclude: [],
32 |
33 |
34 | // preprocess matching files before serving them to the browser
35 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
36 | preprocessors: {
37 | '**/*.ts': ['karma-typescript']
38 | },
39 |
40 | karmaTypescriptConfig: {
41 | compilerOptions: {
42 | target: 'ES5',
43 | lib: ['ES2015', 'DOM']
44 | }
45 | },
46 | // test results reporter to use
47 | // possible values: 'dots', 'progress'
48 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
49 | reporters: ['progress', 'karma-typescript', 'coverage'],
50 |
51 |
52 | // web server port
53 | port: 9876,
54 |
55 |
56 | // enable / disable colors in the output (reporters and logs)
57 | colors: true,
58 |
59 |
60 | // level of logging
61 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
62 | logLevel: config.LOG_INFO,
63 |
64 |
65 | // enable / disable watching file and executing tests whenever any file changes
66 | autoWatch: true,
67 |
68 |
69 | // start these browsers
70 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
71 | browsers: ['PhantomJS'],
72 |
73 |
74 | // Continuous Integration mode
75 | // if true, Karma captures browsers, runs the tests and exits
76 | singleRun: true,
77 |
78 | // Concurrency level
79 | // how many browser should be started simultaneous
80 | concurrency: Infinity
81 | });
82 | };
83 |
--------------------------------------------------------------------------------
/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = (function(settings) {
2 | settings.test_workers = false;
3 | return settings;
4 | })(require('./nightwatch.json'));
--------------------------------------------------------------------------------
/nightwatch.json:
--------------------------------------------------------------------------------
1 | {
2 | "src_folders": [
3 | "test/e2e/index.js"
4 | ],
5 | "output_folder": "reports",
6 | "custom_commands_path": "",
7 | "custom_assertions_path": "",
8 | "page_objects_path": "",
9 | "globals_path": "",
10 | "selenium": {
11 | "start_process": true,
12 | "server_path": "./bin/selenium-server-standalone-3.0.1.jar",
13 | "log_path": "",
14 | "port": 5555,
15 | "cli_args": {
16 | "webdriver.chrome.driver": "./bin/chromedriver"
17 | }
18 | },
19 | "test_settings": {
20 | "default": {
21 | "launch_url": "http://localhost",
22 | "selenium_port": 5555,
23 | "selenium_host": "localhost",
24 | "silent": true,
25 | "screenshots": {
26 | "enabled": false,
27 | "path": "./screenshots"
28 | },
29 | "desiredCapabilities": {
30 | "browserName" : "chrome"
31 | },
32 | "phantom": {
33 | "browserName" : "phantomjs",
34 | "javascriptEnabled" : true,
35 | "acceptSslCerts" : true,
36 | "phantomjs.binary.path" : "./bin/phantomjs",
37 | "phantomjs.cli.args" : ["--ignore-ssl-errors=true"]
38 | },
39 | "chrome": {
40 | "browserName": "chrome",
41 | "javascriptEnabled": true,
42 | "acceptSslCerts": true,
43 | "chromeOptions": {
44 | "args": [
45 | "start-fullscreen"
46 | ]
47 | }
48 | }
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "capivarajs",
3 | "version": "3.10.2",
4 | "description": "Um framework para criação de componentes.",
5 | "main": "./src/index.ts",
6 | "repository": {
7 | "url": "https://github.com/CapivaraJS/capivarajs",
8 | "type": "git"
9 | },
10 | "scripts": {
11 | "dev": "webpack-dev-server --config ./config/webpack.dev.js",
12 | "prod": "npm run test-single && webpack --config ./config/webpack.dev.js && webpack --config ./config/webpack.prod.js",
13 | "test": "karma start",
14 | "test-single": "karma start --single-run",
15 | "e2e": "webpack-dev-server --config ./config/webpack.dev.js --t true",
16 | "generate-report": "nyc --report-dir coverage npm run test && nyc report --reporter=text",
17 | "coverage": "npm run generate-report && nyc report --reporter=text-lcov > coverage.lcov && codecov"
18 | },
19 | "author": "Capivara Team.",
20 | "license": "MIT",
21 | "dependencies": {
22 | "lodash.get": "^4.4.2",
23 | "lodash.isequal": "^4.5.0",
24 | "lodash.set": "^4.3.2",
25 | "melanke-watchjs": "^1.4.3"
26 | },
27 | "keywords": [
28 | "frameworkjs",
29 | "web components",
30 | "front end",
31 | "documentation",
32 | "components",
33 | "gumga",
34 | "capivara",
35 | "capivarajs",
36 | "js",
37 | "javascript",
38 | "framework"
39 | ],
40 | "nyc": {
41 | "include": [
42 | "src/*.ts",
43 | "src/**/*.ts"
44 | ],
45 | "exclude": [
46 | "typings"
47 | ],
48 | "extension": [
49 | ".ts",
50 | ".js"
51 | ],
52 | "reporter": [
53 | "json",
54 | "html"
55 | ],
56 | "all": true
57 | },
58 | "devDependencies": {
59 | "@babel/core": "^7.0.0-beta.42",
60 | "@babel/preset-env": "^7.0.0-beta.42",
61 | "@types/jasmine": "^2.6.3",
62 | "@types/node": "^10.0.3",
63 | "babel-loader": "^7.1.4",
64 | "babel-polyfill": "^6.26.0",
65 | "babel-preset-stage-0": "^6.24.1",
66 | "codecov": "^3.0.0",
67 | "css-loader": "^1.0.0",
68 | "eslint": "^4.19.1",
69 | "extract-text-webpack-plugin": "^4.0.0-beta.0",
70 | "file-loader": "^1.1.5",
71 | "html-loader": "^0.5.1",
72 | "jasmine": "^3.1.0",
73 | "jasmine-core": "^3.1.0",
74 | "karma": "^3.0.0",
75 | "karma-cli": "^1.0.1",
76 | "karma-es6-shim": "^1.0.0",
77 | "karma-jasmine": "^1.1.1",
78 | "karma-phantomjs-launcher": "^1.0.4",
79 | "karma-typescript": "^3.0.12",
80 | "nightwatch": "^0.9.20",
81 | "node-sass": "^4.7.2",
82 | "nyc": "^12.0.1",
83 | "style-loader": "^0.22.0",
84 | "ts-loader": "^4.1.0",
85 | "typescript": "^2.7.2",
86 | "tslint": "^5.9.1",
87 | "uglifyjs-webpack-plugin": "^1.1.2",
88 | "weakset": "^1.0.0",
89 | "webpack": "^4.8.1",
90 | "webpack-cli": "^2.1.3",
91 | "webpack-dev-server": "^3.1.1",
92 | "webpack-merge": "^4.1.2"
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 | export const Constants = {
2 | SCOPE_ATTRIBUTE_NAME : '$scope',
3 | EVENT_ATTRIBUTE_NAME : '$event',
4 | REPEAT_ATTRIBUTE_NAME : 'cp-repeat',
5 | REPEAT_INDEX_NAME : '$index',
6 | REPEAT_ATTRIBUTE_OPERATOR : 'in',
7 | MODEL_ATTRIBUTE_NAME : 'cp-model',
8 | CLICK_ATTRIBUTE_NAME : 'cp-click',
9 | DBLCLICK_ATTRIBUTE_NAME : 'cp-dblclick',
10 | SHOW_ATTRIBUTE_NAME : 'cp-show',
11 | IF_ATTRIBUTE_NAME : 'cp-if',
12 | STEP_ATTRIBUTE_NAME : 'cp-step',
13 | MAX_ATTRIBUTE_NAME : 'cp-max',
14 | MAX_LENGTH_ATTRIBUTE_NAME : 'cp-maxlength',
15 | MIN_ATTRIBUTE_NAME : 'cp-min',
16 | ELSE_ATTRIBUTE_NAME : 'cp-else',
17 | ELSE_IF_ATTRIBUTE_NAME : 'cp-else-if',
18 | INIT_ATTRIBUTE_NAME : 'cp-init',
19 | STYLE_ATTRIBUTE_NAME : 'cp-style',
20 | CLASS_ATTRIBUTE_NAME : 'cp-class',
21 | SRC_ATTRIBUTE_NAME : 'cp-src',
22 | KEY_ATTRIBUTE_NAME : 'cp-key',
23 | ATTR_ATTRIBUTE_NAME : 'cp-attr',
24 | DISABLE_ATTRIBUTE_NAME : 'cp-disabled',
25 | START_INTERPOLATION : '[[',
26 | END_INTERPOLATION : ']]',
27 | IGNORE_BINDINGS : 'cp-non-bindable',
28 | FOCUS_ATTRIBUTE_NAME : 'cp-focus',
29 | HIDE_ATTRIBUTE_NAME : 'cp-hide',
30 | BLUR_ATTRIBUTE_NAME : 'cp-blur',
31 | TITLE_ATTRIBUTE_NAME : 'cp-title',
32 | PLACEHOLDER_ATTRIBUTE_NAME: 'cp-placeholder',
33 | MOUSE_ATTRIBUTE_NAME : 'cp-mouse',
34 | CHANGE_ATTRIBUTE_NAME : 'cp-change',
35 | };
36 |
--------------------------------------------------------------------------------
/src/core/component.config.ts:
--------------------------------------------------------------------------------
1 | export interface ComponentConfig {
2 | template?: string;
3 | controller: any;
4 | controllerAs?: string;
5 | bindings?: string[];
6 | functions?: any[];
7 | constants?: string[];
8 | }
9 |
--------------------------------------------------------------------------------
/src/core/component.ts:
--------------------------------------------------------------------------------
1 | import { ComponentInstance } from './component.instance';
2 |
3 | export class Component {
4 |
5 | public componentName: string;
6 | public config: any;
7 |
8 | constructor(_componentName, config) {
9 | this.componentName = _componentName;
10 | this.config = config;
11 | this.customElementsVue();
12 | }
13 |
14 | private customElementsVue() {
15 | if (window['Vue']) {
16 | window['Vue'].config.ignoredElements = window['Vue'].config.ignoredElements || [];
17 | if (window['Vue'].config.ignoredElements.filter((value) => value === this.componentName).length === 0) {
18 | window['Vue'].config.ignoredElements.push(this.componentName);
19 | }
20 | }
21 | }
22 |
23 | public createNewInstance(elm) {
24 | return new ComponentInstance(elm, this.config);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/core/controller.ts:
--------------------------------------------------------------------------------
1 | import { Constants } from '../constants';
2 | import { Scope } from '../scope/scope';
3 |
4 | export class Controller {
5 |
6 | constructor(element?: HTMLElement, callback?) {
7 | const scope = new Scope(element);
8 | callback(scope.getScopeProxy());
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/core/element.ts:
--------------------------------------------------------------------------------
1 | export class CapivaraElement {
2 |
3 | private events = {};
4 | private onEvent;
5 |
6 | constructor(private element) {
7 | if (typeof element === 'string') {
8 | element = document.querySelector(element);
9 | }
10 | }
11 |
12 | public on(eventName, callback) {
13 | if (this.events[eventName]) {
14 | this.events[eventName].push(callback);
15 | } else {
16 | this.events[eventName] = [callback];
17 | if (!this.onEvent) {
18 | this.onEvent = (evt) => {
19 | (this.events[evt.type] || []).forEach((cb) => cb(evt));
20 | };
21 | }
22 | this.element.addEventListener(eventName, this.onEvent);
23 | }
24 | }
25 |
26 | public destroy() {
27 | Object.keys(this.events).forEach((eventName) => {
28 | this.element.removeEventListener(eventName, this.onEvent);
29 | });
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/core/eval.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../common';
2 |
3 | export namespace Eval {
4 |
5 | export function replaceAt(input, search, replace, start, end) {
6 | return input.slice(0, start)
7 | + input.slice(start, end).replace(search, replace)
8 | + input.slice(end);
9 | }
10 |
11 | export function getIndexStart(arr, currentIndex) {
12 | if (currentIndex === 0) { return 0; }
13 | const getPreviousSize = (i, size) => {
14 | const index = i - 1;
15 | if (index === -1) { return size; }
16 | size += arr[index].length;
17 | return getPreviousSize(index, size);
18 | };
19 | return getPreviousSize(currentIndex, 0);
20 | }
21 |
22 | export function isVariable(str = '') {
23 | const firstChar = str.charAt(0);
24 | return /[a-zA-Z]/g.test(firstChar)
25 | || firstChar === '$'
26 | || firstChar === '_';
27 | }
28 |
29 | export function evaluation(source, context, prefix = '') {
30 | const contexts = Array.isArray(context) ? context : [context];
31 | const referenceSelf = `this.${prefix ? prefix += '.' : ''}`, regex = /\$*[a-z0-9.$]+\s*/gi, keys = source.match(regex);
32 | if (keys && Array.isArray(keys)) {
33 | keys.forEach((str, i) => {
34 | const key = str.replace(/\s/g, ''),
35 | indexStart = getIndexStart(keys, i);
36 | const indexEnd = indexStart + source.substring(indexStart, source.length).indexOf(key) + key.length;
37 | if (!key.includes(referenceSelf)) {
38 | const isVar = !prefix.trim() ? contexts.filter((c) => c.hasOwnProperty(Common.getFirstKey(key))).length > 0 : isVariable(key);
39 | if (isVar) {
40 | source = replaceAt(source, key, `${referenceSelf}${key}`, indexStart, indexEnd);
41 | }
42 | }
43 | });
44 | }
45 | try {
46 | return function executeCode(str) {
47 | (contexts || []).forEach((c) => Object.keys(c).forEach((key) => {
48 | if (!this[key]) {
49 | this[key] = c[key];
50 | }
51 | }));
52 | return eval(str);
53 | }.call({}, source);
54 | } catch (e) { throw e; }
55 | }
56 |
57 | export function exec(source, context) {
58 | try {
59 | const contexts = (Array.isArray(context) ? context : [context]);
60 | const contextMerged = Object.assign({}, ...contexts);
61 | const params = Object.keys(contextMerged), paramsValues = params.map((param) => contextMerged[param]);
62 | const toReturn = new Function(...params, `
63 | const value = ${ source};
64 | return value == undefined ? '' : Number.isNaN(value) ? 0 : value;
65 | `)(...paramsValues);
66 | if (toReturn === undefined) { return evaluation(source, context); }
67 | return toReturn;
68 | } catch (e) { return evaluation(source, context); }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/core/index.ts:
--------------------------------------------------------------------------------
1 | export { CapivaraInstance } from './capivara.instance';
2 | export { Controller } from './controller';
3 | export { ComponentConfig } from './component.config';
4 | export { ComponentInstance } from './component.instance';
5 | export { Component } from './component';
6 | export { Eval } from './eval';
7 | export * from './observer';
8 |
--------------------------------------------------------------------------------
/src/core/magic/check.context.ts:
--------------------------------------------------------------------------------
1 | import { Common } from "../../common";
2 | import { AngularContext } from "./types/angular.context";
3 | import { AngularJSContext } from "./types/angularjs.context";
4 | import { CapivaraJSContext} from './types/capivara.context';
5 | import { ReactContext } from "./types/react.context";
6 | import { VueJSContext } from "./types/vuejs.context";
7 |
8 | export namespace CheckContext {
9 |
10 | /**
11 | * @pattern https://pt.wikipedia.org/wiki/Chain_of_Responsibility
12 | * @param element
13 | */
14 | export function getContext(element) {
15 | if (Common.insideComponent(element)) {
16 | return new CapivaraJSContext().getContext(element);
17 | }
18 | const context = new AngularJSContext(new AngularContext(new VueJSContext(new ReactContext(new CapivaraJSContext()))));
19 | return context.getContext(element);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/core/magic/context.ts:
--------------------------------------------------------------------------------
1 | export abstract class Context {
2 | public successor: Context;
3 | protected name: string;
4 |
5 | constructor(context?: Context) {
6 | if (context) {
7 | this.successor = context;
8 | }
9 | }
10 |
11 | public getContext(element) {
12 | if (window[this.name]) {
13 | return this.process(element);
14 | } else if (this.successor) {
15 | return this.successor.getContext(element);
16 | }
17 | }
18 |
19 | public abstract process(element);
20 | }
21 |
--------------------------------------------------------------------------------
/src/core/magic/magic.ts:
--------------------------------------------------------------------------------
1 | import { CheckContext } from './check.context';
2 |
3 | export namespace Magic {
4 | export function getContext(element) {
5 | return CheckContext.getContext(element);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/core/magic/types/angular.context.ts:
--------------------------------------------------------------------------------
1 | import { Context } from "../context";
2 |
3 | export class AngularContext extends Context {
4 |
5 | constructor(context?: Context) {
6 | super(context);
7 | this.name = 'ng';
8 | }
9 |
10 | public process(element) {
11 | const probe = window[this.name].probe(element);
12 | if (probe && probe._debugContext && probe._debugContext.context) {
13 | return probe._debugContext.context;
14 | }
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/core/magic/types/angularjs.context.ts:
--------------------------------------------------------------------------------
1 | import { Context } from "../context";
2 |
3 | export class AngularJSContext extends Context {
4 |
5 | constructor(context?: Context) {
6 | super(context);
7 | this.name = 'angular';
8 | }
9 |
10 | public process(element) {
11 | return window[this.name].element(element).scope();
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/core/magic/types/capivara.context.ts:
--------------------------------------------------------------------------------
1 | import { Common } from "../../../common";
2 | import { Constants } from "../../../constants";
3 | import { Context } from "../context";
4 |
5 | export class CapivaraJSContext extends Context {
6 |
7 | constructor(context?: Context) {
8 | super(context);
9 | this.name = 'capivara';
10 | }
11 |
12 | public process(element) {
13 | if (Common.isComponent(element) && element.parentNode && element.parentNode[Constants.SCOPE_ATTRIBUTE_NAME]) {
14 | return element.parentNode[Constants.SCOPE_ATTRIBUTE_NAME].scope;
15 | }
16 | if (element && element[Constants.SCOPE_ATTRIBUTE_NAME]) {
17 | return element[Constants.SCOPE_ATTRIBUTE_NAME].scope;
18 | }
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/core/magic/types/react.context.ts:
--------------------------------------------------------------------------------
1 | import { Context } from "../context";
2 |
3 | export class ReactContext extends Context {
4 |
5 | constructor(context?: Context) {
6 | super(context);
7 | this.name = 'React';
8 | }
9 |
10 | private constainsAttr(attr, element) {
11 | let keyValue;
12 | for (const key in element) {
13 | if (key.startsWith('__reactInternalInstance$')) {
14 | keyValue = key;
15 | break;
16 | }
17 | }
18 | return keyValue;
19 | }
20 |
21 | public process(element) {
22 | const key = this.constainsAttr('__reactInternalInstance$', element);
23 | if (key) {
24 | const fiberNode = element[key];
25 | if (fiberNode && fiberNode._debugOwner) {
26 | return fiberNode._debugOwner.stateNode;
27 | }
28 | } else if (element.parentElement) {
29 | return this.process(element.parentElement);
30 | }
31 | }
32 |
33 | public teste(element) {
34 | if (element.parentElement && element.parentElement.startsWith('__reactInternalInstance$')) {
35 | return element.parentElement.startsWith('__reactInternalInstance$');
36 | } else if (element.parentElement) {
37 | return this.teste(element.parentElement);
38 | } else {
39 | return;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/core/magic/types/vuejs.context.ts:
--------------------------------------------------------------------------------
1 | import { Context } from "../context";
2 |
3 | export class VueJSContext extends Context {
4 |
5 | constructor(context?: Context) {
6 | super(context);
7 | this.name = 'Vue';
8 | }
9 |
10 | public process(element) {
11 | if (element.parentElement && element.parentElement.__vue__) {
12 | return element.parentElement.__vue__;
13 | } else if (element.parentElement) {
14 | return this.process(element.parentElement);
15 | } else {
16 | return;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/core/observer/index.ts:
--------------------------------------------------------------------------------
1 | import { Polyfill } from './polyfill';
2 | import { Util } from './util';
3 |
4 | export namespace Observe {
5 |
6 | const watchers = new WeakMap();
7 |
8 | export function observe(obj, handler) {
9 | if (!obj) {
10 | return;
11 | }
12 | if (!watchers.has(obj)) {
13 | watchers.set(obj, [handler]);
14 | this.create(obj, (changes) => {
15 | (watchers.get(obj) || []).forEach((watcher) => {
16 | watcher(changes);
17 | });
18 | });
19 | } else {
20 | const handlers = watchers.get(obj);
21 | handlers.push(handler);
22 | watchers.set(obj, handlers);
23 | }
24 | }
25 |
26 | export function unobserve(obj) {
27 | this.destroy(obj);
28 | watchers.delete(obj);
29 | }
30 |
31 | export function create(obj, handler, objCreated = []) {
32 | if (obj && obj.__observer__) {
33 | return false;
34 | }
35 | objCreated.push(obj);
36 | let props = Util.keys(obj);
37 | const propsL = props.length;
38 | Polyfill.setDirtyCheck(obj, 50, updateProperties);
39 | for (let i = 0; i < propsL; i++) {
40 | if (Object.prototype.toString.call(obj[props[i]]) === '[object Object]' || Array.isArray(obj[props[i]])) {
41 | if (objCreated.indexOf(obj[props[i]]) === -1 && !obj[props[i]].__observer__) {
42 | this.create(obj[props[i]], handler, objCreated);
43 | }
44 | } else {
45 | Polyfill.watchProperty(obj, props[i], handler);
46 | }
47 | }
48 | function updateProperties() {
49 | if (!Util.compare(props, Util.keys(obj))) {
50 | Polyfill.updateProperties(Util.diff(props, Util.keys(obj)), obj, handler);
51 | props = Util.keys(obj);
52 | }
53 | }
54 | }
55 |
56 | export function destroy(obj, objDestroyed = []) {
57 | if (!obj || !obj.__observer__) {
58 | return false;
59 | }
60 |
61 | objDestroyed.push(obj);
62 | const props = Object.keys(obj),
63 | propsL = props.length;
64 |
65 | Polyfill.clearDirtyCheck(obj);
66 |
67 | for (let i = 0; i < propsL; i++) {
68 | if (Object.prototype.toString.call(obj[props[i]]) === '[object Object]' || Array.isArray(obj[props[i]])) {
69 | if (objDestroyed.indexOf(obj[props[i]]) === -1 && obj[props[i]].__observer__) {
70 | this.destroy(obj[props[i]], objDestroyed);
71 | }
72 | } else {
73 | Polyfill.unWatchProperty(obj, props[i]);
74 | }
75 | }
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/core/observer/polyfill.ts:
--------------------------------------------------------------------------------
1 | import { Observe } from './index';
2 |
3 | export namespace Polyfill {
4 | const keyObserver = '__observer__';
5 |
6 | export function watchProperty(obj, prop, handler) {
7 | let oldVal = obj[prop];
8 | let newVal = oldVal;
9 |
10 | const getter = () => {
11 | return newVal;
12 | };
13 |
14 | const setter = (val) => {
15 | oldVal = newVal;
16 | const value = (newVal = val);
17 | if (oldVal !== val) {
18 | handler([{
19 | type: 'update',
20 | object: obj,
21 | name: prop,
22 | oldValue: oldVal,
23 | }]);
24 | }
25 | return value;
26 | };
27 |
28 | if (delete obj[prop]) {
29 | Object.defineProperty(obj, prop, {
30 | get: getter,
31 | set: setter,
32 | enumerable: true,
33 | configurable: true,
34 | });
35 | }
36 | }
37 |
38 | export function updateProperties(delta, obj, handler) {
39 | const added = delta.added,
40 | deleted = delta.deleted,
41 | hasAdded = !!added.length,
42 | hasDeleted = !!deleted.length,
43 | all = delta.all,
44 | allL = all.length,
45 | response = [];
46 |
47 | for (let i = 0; i < allL; i++) {
48 | watchProperty(obj, all[i], handler);
49 | if (hasAdded && i <= added.length) {
50 | response.push({
51 | type: 'add',
52 | object: obj,
53 | name: added[i],
54 | });
55 | }
56 | if (hasDeleted && i <= deleted.length) {
57 | response.push({
58 | type: 'deleted',
59 | object: obj,
60 | name: deleted[i],
61 | });
62 | }
63 | }
64 | Observe.destroy(obj);
65 | Observe.create(obj, handler);
66 | handler(response);
67 | }
68 |
69 | export function unWatchProperty(obj, prop) {
70 | const val = obj[prop];
71 | delete obj[prop];
72 | obj[prop] = val;
73 | }
74 |
75 | export function setDirtyCheck(obj, time, fn) {
76 | Object.defineProperty(obj, keyObserver, {
77 | enumerable: false,
78 | configurable: true,
79 | writable: false,
80 | value: setInterval(fn, time),
81 | });
82 | }
83 |
84 | export function clearDirtyCheck(obj) {
85 | clearInterval(obj[keyObserver]);
86 | delete obj[keyObserver];
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/src/core/observer/util.ts:
--------------------------------------------------------------------------------
1 | export namespace Util {
2 | export function compare(arr1, arr2) {
3 | if (!(arr1 instanceof Array) || !(arr2 instanceof Array)) {
4 | throw new TypeError('#compare accepts two parameters, both being Arrays.');
5 | }
6 | if (arr1.length !== arr2.length) {
7 | return false;
8 | }
9 | for (let i = 0, l = arr1.length; i < l; i++) {
10 | if (arr1[i] instanceof Array && arr2[i] instanceof Array) {
11 | if (!this.compare(arr1[i], arr2[i])) {
12 | return false;
13 | }
14 | } else if (arr1[i] !== arr2[i]) {
15 | return false;
16 | }
17 | }
18 | return true;
19 | }
20 | export function diff(arr1, arr2) {
21 | if (!arr1 || !arr2 || !(arr1 instanceof Array) || !(arr2 instanceof Array)) {
22 | throw new TypeError('#diff accepts two parameters, both being Arrays.');
23 | }
24 | const a = [],
25 | diffValue: any = {},
26 | a1L = arr1.length,
27 | a2L = arr2.length;
28 |
29 | diffValue.added = [];
30 | diffValue.deleted = [];
31 | diffValue.all = [];
32 | for (let i = 0; i < a1L; i++) {
33 | a[arr1[i]] = 1;
34 | }
35 | for (let j = 0; j < a2L; j++) {
36 | if (a[arr2[j]]) {
37 | try {
38 | delete a[arr2[j]];
39 | } catch (e) {}
40 | } else {
41 | a[arr2[j]] = 2;
42 | }
43 | }
44 | for (const k in a) {
45 | if (k) {
46 | diffValue.all.push(k);
47 | if (a[k] === 1) {
48 | diffValue.deleted.push(k);
49 | } else {
50 | diffValue.added.push(k);
51 | }
52 | }
53 | }
54 | return diffValue;
55 | }
56 |
57 | export function keys(obj) {
58 | if (Object.prototype.toString.call(obj) !== '[object Object]' && !Array.isArray(obj)) {
59 | return [];
60 | }
61 | const props = [];
62 | for (const prop in obj) {
63 | if (prop) {
64 | props.push(prop);
65 | }
66 | }
67 | return props;
68 | }
69 |
70 | export function clone(obj) {
71 | const a = [];
72 | for (const prop in obj) {
73 | if (prop) {
74 | a[prop] = obj[prop];
75 | }
76 | }
77 | return a;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/core/util/keycodes.enum.ts:
--------------------------------------------------------------------------------
1 | export enum KeyCode {
2 | BACKSPACE = 8,
3 | TAB = 9,
4 | ENTER = 13,
5 | SHIFT = 16,
6 | CTRL = 17,
7 | ALT = 18,
8 | PAUSEBREAK = 19,
9 | CAPSLOCK = 20,
10 | ESCAPE = 27,
11 | SPACE = 32,
12 | PAGEUP = 33,
13 | PAGEDOWN = 34,
14 | END = 35,
15 | HOME = 36,
16 | LEFTARROW = 37,
17 | UPARROW = 38,
18 | RIGHTARROW = 39,
19 | DOWNARROW = 40,
20 | INSERT = 45,
21 | DELETE = 46,
22 | ZERO = 48,
23 | CLOSEDPAREN = ZERO,
24 | ONE = 49,
25 | EXCLAMATIONMARK = ONE,
26 | TWO = 50,
27 | ATSIGN = TWO,
28 | THREE = 51,
29 | POUNDSIGN = THREE,
30 | HASH = POUNDSIGN,
31 | FOUR = 52,
32 | DOLLARSIGN = FOUR,
33 | FIVE = 53,
34 | PERCENTSIGN = FIVE,
35 | SIX = 54,
36 | CARET = SIX,
37 | HAT = CARET,
38 | SEVEN = 55,
39 | AMPERSAND = SEVEN,
40 | EIGHT = 56,
41 | STAR = EIGHT,
42 | ASTERIK = STAR,
43 | NINE = 57,
44 | OPENPAREN = NINE,
45 | A = 65,
46 | B = 66,
47 | C = 67,
48 | D = 68,
49 | E = 69,
50 | F = 70,
51 | G = 71,
52 | H = 72,
53 | I = 73,
54 | J = 74,
55 | K = 75,
56 | L = 76,
57 | M = 77,
58 | N = 78,
59 | O = 79,
60 | P = 80,
61 | Q = 81,
62 | R = 82,
63 | S = 83,
64 | T = 84,
65 | U = 85,
66 | V = 86,
67 | W = 87,
68 | X = 88,
69 | Y = 89,
70 | Z = 90,
71 | LEFTWINDOWKEY = 91,
72 | RIGHTWINDOWKEY = 92,
73 | SELECTKEY = 93,
74 | NUMPAD0 = 96,
75 | NUMPAD1 = 97,
76 | NUMPAD2 = 98,
77 | NUMPAD3 = 99,
78 | NUMPAD4 = 100,
79 | NUMPAD5 = 101,
80 | NUMPAD6 = 102,
81 | NUMPAD7 = 103,
82 | NUMPAD8 = 104,
83 | NUMPAD9 = 105,
84 | MULTIPLY = 106,
85 | ADD = 107,
86 | SUBTRACT = 109,
87 | DECIMALPOINT = 110,
88 | DIVIDE = 111,
89 | F1 = 112,
90 | F2 = 113,
91 | F3 = 114,
92 | F4 = 115,
93 | F5 = 116,
94 | F6 = 117,
95 | F7 = 118,
96 | F8 = 119,
97 | F9 = 120,
98 | F10 = 121,
99 | F11 = 122,
100 | F12 = 123,
101 | NUMLOCK = 144,
102 | SCROLLLOCK = 145,
103 | SEMICOLON = 186,
104 | EQUALS = 187,
105 | COMMA = 188,
106 | DASH = 189,
107 | PERIOD = 190,
108 | UNDERSCORE = DASH,
109 | PLUSSIGN = EQUALS,
110 | FORWARDSLASH = 191,
111 | TILDE = 192,
112 | GRAVEACCENT = TILDE,
113 | OPENBRACKET = 219,
114 | CLOSEDBRACKET = 221,
115 | QUOTE = 222,
116 | }
117 |
--------------------------------------------------------------------------------
/src/decorators/component-state.ts:
--------------------------------------------------------------------------------
1 | export interface OnInit {
2 | $onInit(): void;
3 | }
4 |
5 | export interface OnViewInit {
6 | $onViewInit(): void;
7 | }
8 |
9 | export interface OnChanges {
10 | $onChanges(): void;
11 | }
12 |
13 | export interface OnDestroy {
14 | $onDestroy(): void;
15 | }
16 |
17 | export interface Bindings {
18 | $bindings: any;
19 | }
20 |
21 | export interface Functions {
22 | $functions: any;
23 | }
24 |
25 | export interface Constants {
26 | $constants: any;
27 | }
28 |
--------------------------------------------------------------------------------
/src/decorators/component.ts:
--------------------------------------------------------------------------------
1 | import { Capivara } from '../';
2 |
3 | export interface ComponentInterface {
4 | /**
5 | * @description Name that will be used to invoke the component in html.
6 | */
7 | tag?: string;
8 | /**
9 | * @description Component HTML template.
10 | */
11 | template: string;
12 | /**
13 | * @description Update controller name. default: $ctrl
14 | */
15 | controllerAs?: string;
16 | /**
17 | * @description Css path you want to import.
18 | */
19 | style?: string;
20 | /**
21 | * @description Declares the constants that will be accepted by component. See https://capivarajs.github.io/#/GettingStarted/Components?id=constants
22 | */
23 | constants?: string[];
24 | /**
25 | * @description Declares the functions that will be accepted by component. See https://capivarajs.github.io/#/GettingStarted/Components?id=fun%C3%A7%C3%B5es
26 | */
27 | functions?: string[];
28 | /**
29 | * @description Declares the variables that will be accepted by component. See https://capivarajs.github.io/#/GettingStarted/Components?id=bindings
30 | */
31 | bindings?: string[];
32 | }
33 |
34 | export const Component = (componentConfig: ComponentInterface) => {
35 | return (target: any) => {
36 | const config = {
37 | template: componentConfig.template,
38 | style: componentConfig.style,
39 | constants: componentConfig.constants,
40 | functions: componentConfig.functions,
41 | bindings: componentConfig.bindings,
42 | controllerAs: componentConfig.controllerAs,
43 | controller: target,
44 | };
45 | Capivara.component(componentConfig.tag, config);
46 | };
47 | };
48 |
--------------------------------------------------------------------------------
/src/decorators/controller.ts:
--------------------------------------------------------------------------------
1 | import { Bindings, Constants, Functions } from './component-state';
2 |
3 | export class Controller implements Bindings, Constants, Functions {
4 | public $bindings;
5 | public $constants;
6 | public $functions;
7 | constructor(public $scope?, public $element?) { }
8 | }
9 |
--------------------------------------------------------------------------------
/src/decorators/index.ts:
--------------------------------------------------------------------------------
1 | export { Component } from './component';
2 | export { Controller } from './controller';
3 | export * from './component-state';
4 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Eval } from './core';
2 | import { CapivaraInstance } from './core/capivara.instance';
3 | import { Component, Controller } from './decorators';
4 |
5 | const Capivara: CapivaraInstance = (function initCapivara(ctx, aliasName) {
6 | if (!ctx[aliasName]) {
7 | ctx[aliasName] = new CapivaraInstance();
8 | ctx[aliasName].core = {
9 | Eval,
10 | Component,
11 | Controller,
12 | Capivara,
13 | };
14 | } else {
15 | console.warn("Gee! CapivaraJS tried to load more than once.");
16 | }
17 | return ctx[aliasName];
18 | })(window, 'capivara');
19 |
20 | export { Capivara };
21 | export * from './decorators';
22 | export default Capivara;
23 |
--------------------------------------------------------------------------------
/src/map/directive/cp-attr.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPAttr implements Directive {
7 | private readonly element: any;
8 | private map: MapDom;
9 | private attributes = [];
10 |
11 | constructor(_element: HTMLElement, _map: MapDom) {
12 | this.element = _element;
13 | this.map = _map;
14 | Array.from(this.element.attributes).forEach((attribute: any) => {
15 | if (attribute.nodeName && attribute.nodeName.startsWith(Constants.ATTR_ATTRIBUTE_NAME)) {
16 | if (!attribute.value) {
17 | throw new Error(`syntax error ${Constants.ATTR_ATTRIBUTE_NAME} expected arguments`);
18 | }
19 | this.attributes.push(attribute.name);
20 | }
21 | });
22 | }
23 |
24 | public create() {
25 | this.init();
26 | }
27 |
28 | public init() {
29 | this.attributes.forEach((attribute) => {
30 | const attributeValue = this.element.getAttribute(attribute);
31 | const attr = attribute.replace(Constants.ATTR_ATTRIBUTE_NAME + '.', '');
32 | const value = Common.evalInMultiContext(this.element, attributeValue);
33 | if (value === undefined || value === null) {
34 | this.element.setAttribute(attr, '');
35 | } else {
36 | this.element.setAttribute(attr, value);
37 | }
38 | });
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/map/directive/cp-blur.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPBlur implements Directive {
7 | private attribute;
8 | private element: any;
9 | private map: MapDom;
10 |
11 | constructor(_element: HTMLElement, _map: MapDom) {
12 | this.element = _element;
13 | this.map = _map;
14 | this.element['cpBlur'] = this;
15 | this.attribute = Common.getAttributeCpBlur(this.element);
16 | if (this.attribute === undefined) {
17 | throw new Error(`syntax error ${Constants.BLUR_ATTRIBUTE_NAME} expected arguments`);
18 | }
19 | }
20 |
21 | public create() {
22 | this.init();
23 | }
24 |
25 | public onBlur(evt) {
26 | Common.executeFunctionCallback(evt.target['cpBlur'].element, evt.target['cpBlur'].attribute, { [Constants.EVENT_ATTRIBUTE_NAME] : evt });
27 | }
28 |
29 | public init() {
30 | // Remove old event
31 | this.element.removeEventListener('blur', this.onBlur);
32 | // Add new event
33 | this.element.addEventListener('blur', this.onBlur);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/map/directive/cp-change.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPChange implements Directive {
7 |
8 | private attribute;
9 | private element: any;
10 | private map: MapDom;
11 |
12 | constructor(_element: HTMLElement, _map: MapDom) {
13 | this.element = _element;
14 | this.map = _map;
15 | this.attribute = this.element.getAttribute(Constants.CHANGE_ATTRIBUTE_NAME);
16 | if (!this.attribute) {
17 | throw new Error(`syntax error ${Constants.CHANGE_ATTRIBUTE_NAME} expected arguments`);
18 | }
19 | if (!this.element.hasAttribute(Constants.MODEL_ATTRIBUTE_NAME)) {
20 | throw new Error(`syntax error ${Constants.MODEL_ATTRIBUTE_NAME} expected arguments`);
21 | }
22 | }
23 |
24 | public create() {
25 | this.init();
26 | }
27 |
28 | public onModelChange(newValue, oldValue) {
29 | Common.executeFunctionCallback(this.element, this.attribute, { $newValue: newValue, $oldValue: oldValue });
30 | }
31 |
32 | public init() {
33 | const modelAttribute = this.element.getAttribute(Constants.MODEL_ATTRIBUTE_NAME).replace(Common.getScope(this.element).scope['__$controllerAs__'] + '.', '');
34 | Common.getScope(this.element).$unwatch(modelAttribute, this.onModelChange);
35 | Common.getScope(this.element).$watch(modelAttribute, this.onModelChange, this);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/map/directive/cp-class.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { MapDom } from '../map-dom';
3 | import { Directive } from './directive.interface';
4 |
5 | export class CPClass implements Directive {
6 |
7 | private readonly element: any;
8 | private readonly attribute;
9 | private map: MapDom;
10 | private elementComment;
11 | private elmScope;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.element['cpClass'] = this;
16 | this.map = _map;
17 | this.attribute = Common.getAttributeCpClass(this.element);
18 | this.elementComment = document.createComment('cpClass ' + this.attribute);
19 | this.elmScope = Common.getScope(_element);
20 | }
21 |
22 | public create() {
23 | this.init();
24 | }
25 |
26 | public setClassByObject(classObj) {
27 | if (classObj && window['capivara'].isObject(classObj)) {
28 | Object.keys(classObj).forEach((key) => {
29 | if (classObj[key]) {
30 | this.addClass(key.replace(/ /g, ''));
31 | } else {
32 | this.removeClass(key.replace(/ /g, ''));
33 | }
34 | });
35 | }
36 | }
37 |
38 | public init() {
39 | try {
40 | this.attribute.split(',')
41 | .map((attr) => {
42 | return {
43 | key: attr.substring(0, attr.indexOf(':')).replace(/'/g, "").replace(/"/, '').replace(/{/g, '').replace(/}/, ''),
44 | value: Common.evalInMultiContext(this.element, attr.substring(attr.indexOf(':') + 1, attr.length).replace(/{/g, '').replace(/}/, '')),
45 | };
46 | })
47 | .forEach((cpClass) => {
48 | if (window['capivara'].isObject(cpClass.value)) {
49 | this.setClassByObject(cpClass.value);
50 | } else {
51 | if (cpClass.value) {
52 | this.addClass(cpClass.key.replace(/ /g, ''));
53 | } else {
54 | this.removeClass(cpClass.key.replace(/ /g, ''));
55 | }
56 | }
57 | });
58 | } catch (e) {
59 | }
60 | }
61 |
62 | public removeClass(className) {
63 | if (this.element.classList && this.element.classList.contains(className)) {
64 | this.element.classList.remove(className);
65 | } else if (!this.element.classList && this.element.className.indexOf(className) !== -1) {
66 | this.element.className = this.element.className.replace(className, '');
67 | }
68 | }
69 |
70 | public addClass(className) {
71 | if (this.element.classList && !this.element.classList.contains(className)) {
72 | this.element.classList.add(className);
73 | } else if (!this.element.classList && this.element.className.indexOf(className) === -1) {
74 | this.element.className += " " + className;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/map/directive/cp-click.ts:
--------------------------------------------------------------------------------
1 | import {Common} from '../../common';
2 | import {Constants} from '../../constants';
3 | import {MapDom} from '../map-dom';
4 | import {Directive} from './directive.interface';
5 |
6 | export class CPClick implements Directive {
7 |
8 | private readonly element: any;
9 | private readonly eventName;
10 | private map: MapDom;
11 | private attribute;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.map = _map;
16 | this.attribute = this.element.getAttribute(Constants.CLICK_ATTRIBUTE_NAME);
17 | this.eventName = 'click';
18 | if (!this.attribute) {
19 | this.attribute = this.element.getAttribute(Constants.DBLCLICK_ATTRIBUTE_NAME);
20 | this.eventName = 'dblclick';
21 | }
22 | if (!this.attribute) {
23 | throw new Error(`syntax error cp-${this.eventName} expected arguments`);
24 | }
25 | }
26 |
27 | public create() {
28 | this.init();
29 | }
30 |
31 | public getIndexRow(element) {
32 | const index = Common.get(Common.getScope(element).scope, Constants.REPEAT_INDEX_NAME);
33 | if (index === undefined && element.parentNode) {
34 | return this.getIndexRow(element.parentNode);
35 | }
36 | return index;
37 | }
38 |
39 | public init() {
40 | const onClick = (evt) => {
41 | this.attribute = this.attribute.trim();
42 | Common.executeFunctionCallback(this.element, this.attribute, { [Constants.EVENT_ATTRIBUTE_NAME] : evt });
43 | };
44 | // Remove old event
45 | this.element.removeEventListener(this.eventName, onClick);
46 | // Add new event
47 | this.element.addEventListener(this.eventName, onClick);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/map/directive/cp-disabled.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPDisabled implements Directive {
7 |
8 | private readonly element: any;
9 | private readonly attribute;
10 |
11 | constructor(_element: HTMLElement, _map: MapDom) {
12 | this.element = _element;
13 | this.attribute = Common.getAttributeCpDisable(this.element);
14 | if (!this.attribute) {
15 | throw new Error(`syntax error ${Constants.DISABLE_ATTRIBUTE_NAME} expected arguments`);
16 | }
17 | }
18 |
19 | public create() {
20 | this.init();
21 | }
22 |
23 | public init() {
24 | try {
25 | JSON.parse(Common.isValidCondition(this.element, Common.getAttributeCpDisable(this.element))) ? this.elementDisabled() : this.elementEnabled();
26 | } catch (ex) {
27 | this.elementEnabled();
28 | }
29 | }
30 |
31 | public elementDisabled() {
32 | this.element.setAttribute('disabled', true);
33 | }
34 |
35 | public elementEnabled() {
36 | this.element.removeAttribute('disabled');
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/map/directive/cp-else-if.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPElseIf implements Directive {
7 |
8 | private readonly element: any;
9 | private readonly attribute;
10 | private readonly elementComment;
11 | private map: MapDom;
12 | private prevElement;
13 | private parentCondition;
14 | private cpElseIf;
15 |
16 | constructor(_element: HTMLElement, _map: MapDom) {
17 | this.element = _element;
18 | this.element['cpElseIf'] = this;
19 | this.attribute = Common.getAttributeCpElseIf(this.element);
20 | if (!this.attribute) {
21 | throw new Error(`syntax error ${Constants.ELSE_IF_ATTRIBUTE_NAME} expected arguments`);
22 | }
23 | this.prevElement = _element.previousSibling;
24 | this.map = _map;
25 | this.elementComment = document.createComment('CPElseIf ' + this.attribute);
26 | }
27 |
28 | public create() {
29 | if (this.element.hasAttribute(Constants.REPEAT_ATTRIBUTE_NAME)) {
30 | return;
31 | }
32 | this.integrationCpElse();
33 | this.parentCondition = Common.getScope(this.element).parentCondition;
34 | if (!this.parentCondition) {
35 | throw new Error(`syntax error ${Constants.ELSE_IF_ATTRIBUTE_NAME} used on element ` +
36 | `<${this.element.nodeName.toLowerCase()}> without corresponding ${Constants.IF_ATTRIBUTE_NAME}.`);
37 | }
38 | this.init();
39 | }
40 |
41 | public integrationCpElse() {
42 | const nextElement = this.element.nextElementSibling;
43 | if (nextElement && (nextElement.hasAttribute(Constants.ELSE_ATTRIBUTE_NAME) || nextElement.hasAttribute(Constants.ELSE_IF_ATTRIBUTE_NAME))) {
44 | Common.getScope(nextElement).parentCondition = this;
45 | }
46 | }
47 |
48 | public init() {
49 | if (!this.element || this.element.hasAttribute(Constants.REPEAT_ATTRIBUTE_NAME)) {
50 | return;
51 | }
52 | try {
53 | if (!Common.isValidCondition(this.parentCondition.element, Common.getAttributeCpIf(this.parentCondition.element))) {
54 | Common.createElement(this.element, this.elementComment);
55 | if (!Common.isValidCondition(this.element, this.attribute)) {
56 | Common.destroyElement(this.element, this.elementComment);
57 | }
58 | } else {
59 | Common.destroyElement(this.element, this.elementComment);
60 | }
61 | } catch (ex) {
62 | Common.destroyElement(this.element, this.elementComment);
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/map/directive/cp-else.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPElse implements Directive {
7 |
8 | private readonly element: any;
9 | private readonly elementComment;
10 | private map: MapDom;
11 | private prevElement;
12 | private parentCondition;
13 |
14 | constructor(_element: HTMLElement, _map: MapDom) {
15 | this.element = _element;
16 | if (Common.getAttributeCpElse(this.element)) {
17 | throw new Error(`${Constants.ELSE_ATTRIBUTE_NAME} don't expect arguments`);
18 | }
19 | this.prevElement = _element.previousSibling;
20 | this.map = _map;
21 | this.elementComment = document.createComment('cpElse');
22 | }
23 |
24 | public create() {
25 | if (this.element.hasAttribute(Constants.REPEAT_ATTRIBUTE_NAME)) {
26 | return;
27 | }
28 | this.parentCondition = Common.getScope(this.element).parentCondition;
29 | if (!this.parentCondition) {
30 | throw new Error(`syntax error ${Constants.ELSE_ATTRIBUTE_NAME} used on element ` +
31 | `<${this.element.nodeName.toLowerCase()}> without corresponding ${Constants.IF_ATTRIBUTE_NAME}.`);
32 |
33 | }
34 | this.init();
35 | }
36 |
37 | public hasValidCondition(_element, conditions) {
38 | if (_element && ((_element.hasAttribute && _element.hasAttribute(Constants.IF_ATTRIBUTE_NAME)) || (_element.nodeType === 8 && _element.data.indexOf('cpIf') !== -1))) {
39 | if (_element['$$cpDestroyed']) { return false; }
40 | return !((_element.nodeType === 8 && _element.data.indexOf('cpIf') !== -1) && conditions.length === 0);
41 | }
42 | if (_element && _element.previousSibling) {
43 | if (_element.hasAttribute && _element.hasAttribute(Constants.ELSE_IF_ATTRIBUTE_NAME)) {
44 | conditions.push(_element);
45 | }
46 | return this.hasValidCondition(_element.previousSibling, conditions);
47 | }
48 | }
49 |
50 | public init() {
51 | if (!this.element || this.element.hasAttribute(Constants.REPEAT_ATTRIBUTE_NAME)) {
52 | return;
53 | }
54 | try {
55 | Common.createElement(this.element, this.elementComment);
56 | if (this.hasValidCondition(this.element, [])) {
57 | Common.destroyElement(this.element, this.elementComment);
58 | }
59 | } catch (ex) {
60 | Common.destroyElement(this.element, this.elementComment);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/map/directive/cp-focus.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPFocus implements Directive {
7 | private attribute;
8 | private element: any;
9 | private map: MapDom;
10 |
11 | constructor(_element: HTMLElement, _map: MapDom) {
12 | this.element = _element;
13 | this.map = _map;
14 | this.element['cpFocus'] = this;
15 | this.attribute = Common.getAttributeCpFocus(this.element);
16 | if (this.attribute === undefined) {
17 | throw new Error(`syntax error ${Constants.FOCUS_ATTRIBUTE_NAME} expected arguments`);
18 | }
19 | }
20 |
21 | public create() {
22 | this.init();
23 | }
24 |
25 | public onFocus(evt) {
26 | Common.executeFunctionCallback(evt.target['cpFocus'].element, evt.target['cpFocus'].attribute, { [Constants.EVENT_ATTRIBUTE_NAME] : evt });
27 | }
28 |
29 | public init() {
30 | // Remove old event
31 | this.element.removeEventListener('focus', this.onFocus);
32 | // Add new event
33 | this.element.addEventListener('focus', this.onFocus);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/map/directive/cp-hide.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPHide implements Directive {
7 |
8 | private element: any;
9 | private map: MapDom;
10 | private attribute;
11 | private initialDisplay;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.initialDisplay = this.element.style.display || '';
16 | this.map = _map;
17 | this.attribute = Common.getAttributeCpHide(this.element);
18 | if (!this.attribute) {
19 | throw new Error(`syntax error ${Constants.HIDE_ATTRIBUTE_NAME} expected arguments`);
20 | }
21 | }
22 |
23 | public create() {
24 | this.init();
25 | }
26 |
27 | public init() {
28 | try {
29 | Common.isValidCondition(this.element, Common.getAttributeCpHide(this.element)) ? this.hide() : this.show();
30 | } catch (ex) {
31 | this.hide();
32 | }
33 | }
34 |
35 | public hide() {
36 | this.element.style.display = 'none';
37 | }
38 |
39 | public show() {
40 | this.element.style.display = this.initialDisplay;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/map/directive/cp-if.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPIf implements Directive {
7 |
8 | private readonly element: any;
9 | private readonly attribute;
10 | private readonly elementComment;
11 | private map: MapDom;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.element['cpIf'] = this;
16 | this.map = _map;
17 | this.attribute = Common.getAttributeCpIf(this.element);
18 | if (!this.attribute) {
19 | throw new Error(`syntax error ${Constants.IF_ATTRIBUTE_NAME} expected arguments`);
20 | }
21 | this.elementComment = document.createComment('cpIf ' + this.attribute);
22 | }
23 |
24 | public create() {
25 | if (this.element.hasAttribute(Constants.REPEAT_ATTRIBUTE_NAME)) {
26 | return;
27 | }
28 | this.integrationCpElse();
29 | this.init();
30 | }
31 |
32 | public integrationCpElse() {
33 | const nextElement = this.element.nextElementSibling;
34 | if (nextElement && (nextElement.hasAttribute(Constants.ELSE_ATTRIBUTE_NAME) || nextElement.hasAttribute(Constants.ELSE_IF_ATTRIBUTE_NAME))) {
35 | Common.getScope(nextElement).parentCondition = this;
36 | }
37 | }
38 |
39 | public init() {
40 | if (!this.element || this.element.hasAttribute(Constants.REPEAT_ATTRIBUTE_NAME)) {
41 | return;
42 | }
43 | try {
44 | if (!Common.isValidCondition(this.element, Common.getAttributeCpIf(this.element))) {
45 | Common.destroyElement(this.element, this.elementComment);
46 | } else {
47 | Common.createElement(this.element, this.elementComment);
48 | }
49 | } catch (ex) {
50 | Common.destroyElement(this.element, this.elementComment);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/map/directive/cp-init.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPInit implements Directive {
7 |
8 | private readonly element: any;
9 | private attribute;
10 | private map: MapDom;
11 |
12 | constructor(_element: HTMLElement, _map: MapDom) {
13 | this.element = _element;
14 | this.map = _map;
15 | this.attribute = Common.getAttributeCpInit(this.element);
16 | if (!this.attribute) {
17 | throw new Error(`syntax error ${Constants.INIT_ATTRIBUTE_NAME} expected arguments`);
18 | }
19 | }
20 |
21 | public create() {
22 | this.init();
23 | }
24 |
25 | public init() {
26 | this.attribute = this.attribute.trim();
27 | Common.evalInMultiContext(this.element, this.attribute);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/map/directive/cp-key.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { KeyCode } from '../../core/util/keycodes.enum';
4 | import { MapDom } from '../map-dom';
5 | import { Directive } from './directive.interface';
6 |
7 | export class CPKey implements Directive {
8 |
9 | private readonly element: any;
10 | private map: MapDom;
11 | private attributes;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.attributes = [];
16 | this.map = _map;
17 | Array.from(this.element.attributes).forEach((attribute: any) => {
18 | if (attribute.nodeName && attribute.nodeName.startsWith(Constants.KEY_ATTRIBUTE_NAME)) {
19 | if (!attribute.value) {
20 | throw new Error(`syntax error ${Constants.KEY_ATTRIBUTE_NAME} expected arguments`);
21 | }
22 | this.element[attribute.name] = this;
23 | this.attributes.push(attribute.name);
24 | }
25 | });
26 | }
27 |
28 | public create() {
29 | this.init();
30 | }
31 |
32 | public onKeyPress(evt) {
33 | const directiveName: any = 'cp-' + evt.type;
34 | if (evt.target && evt.target.hasAttributeStartingWith(directiveName)) {
35 | const attribute = evt.target.getAttributeStartingWith(directiveName)[0].name;
36 | const indexSeparator = attribute.lastIndexOf('.');
37 | if (indexSeparator === -1) {
38 | Common.executeFunctionCallback(evt.target[attribute].element, evt.target[attribute].element.getAttribute(attribute), { [Constants.EVENT_ATTRIBUTE_NAME] : evt });
39 | } else {
40 | const watchKeyName = attribute.substring(attribute.lastIndexOf('.') + 1);
41 | const watchKey = !isNaN(watchKeyName) ? Number(watchKeyName) : KeyCode[(watchKeyName || '').toUpperCase()];
42 | if (watchKey !== undefined && evt.keyCode === watchKey) {
43 | Common.executeFunctionCallback(evt.target[attribute].element, evt.target[attribute].element.getAttribute(attribute), { [Constants.EVENT_ATTRIBUTE_NAME] : evt });
44 | }
45 | }
46 | }
47 | }
48 |
49 | public init() {
50 | this.attributes.forEach((attribute) => {
51 | const indexSeparator = attribute.lastIndexOf('.');
52 | const keyType = attribute.substring(0, (indexSeparator === -1 ? attribute.length : indexSeparator)).replace(Constants.KEY_ATTRIBUTE_NAME, '');
53 | // Remove old event
54 | this.element.removeEventListener(`key${keyType}`, this.onKeyPress);
55 | // Add new event
56 | this.element.addEventListener(`key${keyType}`, this.onKeyPress);
57 | });
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/map/directive/cp-model.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPModel implements Directive {
7 |
8 | private readonly attribute;
9 | private element: any;
10 | private map: MapDom;
11 |
12 | constructor(_element: HTMLElement, _map: MapDom) {
13 | this.element = _element;
14 | this.element['cpModel'] = this;
15 | this.map = _map;
16 | this.attribute = this.element.getAttribute(Constants.MODEL_ATTRIBUTE_NAME);
17 | if (!this.attribute) {
18 | throw new Error(`syntax error ${Constants.MODEL_ATTRIBUTE_NAME} expected arguments`);
19 | }
20 | }
21 |
22 | public create(_element?) {
23 | this.init();
24 | this.applyModelInValue();
25 | }
26 |
27 | public init() {
28 | this.map.addCpModels(this);
29 | if (!Common.isComponent(this.element)) {
30 | this.element.removeEventListener('input', this.applyValueInModel);
31 | this.element.addEventListener('input', this.applyValueInModel);
32 | }
33 | }
34 |
35 | public applyModelInValue() {
36 | const value = Common.get(Common.getScope(this.element).scope, this.attribute);
37 | switch (this.element.type) {
38 | case 'date':
39 | if (this.element.valueAsDate && this.element.valueAsDate.getTime() !== value.getTime()) {
40 | this.element.valueAsDate = value || null;
41 | }
42 | break;
43 | case 'number':
44 | if (value !== this.element.valueAsNumber && value !== undefined) {
45 | this.element.valueAsNumber = value || null;
46 | }
47 | break;
48 | default:
49 | if (this.element.value !== value) {
50 | this.element.value = value || null;
51 | }
52 | }
53 | }
54 |
55 | public applyValueInModel(evt) {
56 | const self = (evt ? (evt.target || evt.srcElement) : this.element)['cpModel'];
57 | switch (self.element.type) {
58 | case 'date':
59 | Common.set(Common.getScope(self.element).scope, self.attribute, self.element.valueAsDate);
60 | break;
61 | case 'number':
62 | Common.set(Common.getScope(self.element).scope, self.attribute, isNaN(self.element.valueAsNumber) ? undefined : self.element.valueAsNumber);
63 | break;
64 | default:
65 | Common.set(Common.getScope(self.element).scope, self.attribute, self.element.value);
66 | }
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/map/directive/cp-mouse.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPMouse implements Directive {
7 |
8 | private readonly element: any;
9 | private map: MapDom;
10 | private attributes;
11 |
12 | constructor(_element: HTMLElement, _map: MapDom) {
13 | this.element = _element;
14 | this.attributes = [];
15 | this.map = _map;
16 | Array.from(this.element.attributes).forEach((attribute: any) => {
17 | if (attribute.nodeName && attribute.nodeName.startsWith(Constants.MOUSE_ATTRIBUTE_NAME)) {
18 | if (!attribute.value) {
19 | throw new Error(`syntax error ${Constants.MOUSE_ATTRIBUTE_NAME} expected arguments`);
20 | }
21 | this.element[attribute.name] = this;
22 | this.attributes.push(attribute.name);
23 | }
24 | });
25 | }
26 |
27 | public create() {
28 | this.init();
29 | }
30 |
31 | public onMouse(evt) {
32 | const directiveName = 'cp-' + evt.type;
33 | if (evt.target && evt.target[directiveName]) {
34 | Common.executeFunctionCallback(evt.target[directiveName].element, evt.target[directiveName].element.getAttribute(directiveName), { [Constants.EVENT_ATTRIBUTE_NAME] : evt });
35 | }
36 | }
37 |
38 | public init() {
39 | this.attributes.forEach((attribute) => {
40 | const indexSeparator = attribute.lastIndexOf('.');
41 | const eventType = attribute.substring(0, (indexSeparator === -1 ? attribute.length : indexSeparator)).replace(Constants.MOUSE_ATTRIBUTE_NAME, '');
42 | // Remove old event
43 | this.element.removeEventListener(`mouse${eventType}`, (evt) => this.onMouse(evt));
44 | // Add new event
45 | this.element.addEventListener(`mouse${eventType}`, this.onMouse);
46 | });
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/map/directive/cp-repeat.ts:
--------------------------------------------------------------------------------
1 | import isEqual from 'lodash.isequal';
2 | import { Common } from '../../common';
3 | import { Constants } from '../../constants';
4 | import { Controller } from '../../core/controller';
5 | import capivara from '../../index';
6 | import { MapDom } from '../map-dom';
7 | import { Directive } from './directive.interface';
8 |
9 | export class CPRepeat implements Directive {
10 |
11 | private readonly attribute;
12 | private readonly originalElement;
13 | private readonly referenceNode;
14 | private readonly regex;
15 | private map: MapDom;
16 | private element;
17 | private lastArray = [];
18 | private elms = [];
19 | private attributeAlias;
20 | private attributeScope;
21 |
22 | constructor(_element: HTMLElement, _map: MapDom) {
23 | this.element = _element.cloneNode(true);
24 | this.element.removeAttribute(Constants.REPEAT_ATTRIBUTE_NAME);
25 | this.element.classList.add('binding-repeat');
26 | this.originalElement = _element;
27 | this.map = _map;
28 | this.attribute = _element.getAttribute(Constants.REPEAT_ATTRIBUTE_NAME).replace(/\s+/g, ' ');
29 | this.regex = new RegExp('^[\\s*|\\S]+\\s+' + Constants.REPEAT_ATTRIBUTE_OPERATOR.replace(/ /g, '') + '\\s+\\S+\\s*', 'g');
30 | const matches = this.attribute.match(this.regex);
31 | if (!this.attribute || (!matches || matches.length === 0)) {
32 | throw new Error(`syntax error invalid ${Constants.REPEAT_ATTRIBUTE_NAME} expresion: ${this.attribute}`);
33 | }
34 | this.referenceNode = document.createComment('start repeat ' + this.attribute);
35 | if (this.originalElement.parentNode.replaceChild) {
36 | this.originalElement.parentNode.replaceChild(this.referenceNode, this.originalElement);
37 | }
38 | }
39 |
40 | public create() {
41 | const operator = ` ${Constants.REPEAT_ATTRIBUTE_OPERATOR} `;
42 | this.attributeAlias = this.attribute.substring(0, this.attribute.indexOf(operator)).replace(/ /g, '');
43 | this.attributeScope = this.attribute.substring(this.attribute.indexOf(operator) + operator.length, this.attribute.length).replace(/ /g, '');
44 | this.applyLoop();
45 | }
46 |
47 | public applyLoop() {
48 | const array = Common.evalInMultiContext(this.originalElement, this.attributeScope);
49 | if (array && !isEqual(array, this.lastArray)) {
50 | this.lastArray = array.slice();
51 | this.removeChildes();
52 | this.loop(array, this.attributeAlias);
53 | }
54 | }
55 |
56 | public removeChildes() {
57 | this.elms.forEach((elm) => this.referenceNode.parentNode.removeChild(elm));
58 | }
59 |
60 | public loop(array, attributeAlias) {
61 | this.elms = []; // reset elements render
62 | let lastAdded = this.referenceNode;
63 |
64 | array.forEach((row, index) => {
65 | const elm = this.element.cloneNode(true);
66 | new Controller(elm, () => { });
67 | Common.appendAfter(lastAdded, elm);
68 | const elementContext = Common.getScope(elm);
69 | elementContext.scope[attributeAlias] = row;
70 | elementContext.scope[Constants.REPEAT_INDEX_NAME] = index;
71 | elementContext.$parent = Common.getScope(this.referenceNode.parentNode);
72 | this.createChildrenComponents(elm);
73 | lastAdded = elm;
74 | this.elms.push(elm); // add element reference.
75 | });
76 |
77 | if (lastAdded) {
78 | Common.appendAfter(lastAdded, this.referenceNode.parentNode.appendChild(document.createComment('end repeat ' + this.attribute)));
79 | }
80 | }
81 |
82 | private createChildrenComponents(elm) {
83 | (Array.from(elm.children) || []).forEach((child) => {
84 | capivara.constroyIfComponent(child);
85 | });
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/map/directive/cp-show.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { Constants } from '../../constants';
3 | import { MapDom } from '../map-dom';
4 | import { Directive } from './directive.interface';
5 |
6 | export class CPShow implements Directive {
7 |
8 | private readonly element: any;
9 | private readonly attribute;
10 | private readonly initialDisplay;
11 | private map: MapDom;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.initialDisplay = this.element.style.display || '';
16 | this.map = _map;
17 | this.attribute = Common.getAttributeCpShow(this.element);
18 | if (!this.attribute) {
19 | throw new Error(`syntax error ${Constants.SHOW_ATTRIBUTE_NAME} expected arguments`);
20 | }
21 | }
22 |
23 | public create() {
24 | this.init();
25 | }
26 |
27 | public init() {
28 | try {
29 | Common.isValidCondition(this.element, Common.getAttributeCpShow(this.element)) ? this.show() : this.hide();
30 | } catch (ex) {
31 | this.hide();
32 | }
33 | }
34 |
35 | public hide() {
36 | this.element.style.display = 'none';
37 | }
38 |
39 | public show() {
40 | this.element.style.display = this.initialDisplay;
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/map/directive/cp-style.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../../common';
2 | import { MapDom } from '../map-dom';
3 | import { Directive } from './directive.interface';
4 |
5 | export class CPStyle implements Directive {
6 |
7 | private readonly element: any;
8 | private readonly attribute;
9 | private map: MapDom;
10 | private elementComment;
11 | private elmScope;
12 |
13 | constructor(_element: HTMLElement, _map: MapDom) {
14 | this.element = _element;
15 | this.element['cpStyle'] = this;
16 | this.map = _map;
17 | this.attribute = Common.getAttributeCpStyle(this.element);
18 | this.elementComment = document.createComment('cpStyle ' + this.attribute);
19 | this.elmScope = Common.getScope(_element);
20 | }
21 |
22 | public create() {
23 | this.init();
24 | }
25 |
26 | public setStyleByObject(style) {
27 | if (style && window['capivara'].isObject(style)) {
28 | Object.keys(style).forEach((key) => {
29 | this.element.style.setProperty(key.replace(/ /g, ''), style[key]);
30 | });
31 | }
32 | }
33 |
34 | public init() {
35 | try {
36 | this.attribute.split(',')
37 | .map((attr) => {
38 | return {
39 | key: attr.substring(0, attr.indexOf(':')).replace(/'/g, "").replace(/"/, '').replace(/{/g, '').replace(/}/, ''),
40 | value: Common.evalInMultiContext(this.element, attr.substring(attr.indexOf(':') + 1, attr.length).replace(/{/g, '').replace(/}/, '')),
41 | };
42 | })
43 | .forEach((style) => {
44 | if (window['capivara'].isString(style.value)) {
45 | this.element.style.setProperty(style.key.replace(/ /g, ''), style.value);
46 | } else {
47 | this.setStyleByObject(style.value);
48 | }
49 | });
50 | } catch (e) {
51 | this.setStyleByObject(Common.executeFunctionCallback(this.element, this.attribute));
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/map/directive/directive.interface.ts:
--------------------------------------------------------------------------------
1 | export interface Directive {
2 | create(_element?);
3 | }
4 |
--------------------------------------------------------------------------------
/src/scope/scope.proxy.ts:
--------------------------------------------------------------------------------
1 | import { Constants } from '../constants';
2 | import { Observe } from '../core/observer';
3 | import { MapDom } from '../map/map-dom';
4 | import { Scope } from './scope';
5 |
6 | export class ScopeProxy {
7 |
8 | public mapDom: MapDom;
9 | public element: HTMLElement;
10 |
11 | constructor(_scope: Scope, _mapDom: MapDom, _element: HTMLElement) {
12 | this.mapDom = _mapDom;
13 | this.element = _element;
14 | this.createWatcherScope(_scope, this);
15 | }
16 |
17 | public createWatcherScope(scope, objectObserve) {
18 | if (this.element['$instance']) {
19 | scope.$on('$onInit', () => {
20 | Observe.observe(objectObserve[this.element['$instance'].config.controllerAs], (changes) => {
21 | if (changes.length > 0) {
22 | this.updateScopes(objectObserve.element[Constants.SCOPE_ATTRIBUTE_NAME]);
23 | }
24 | scope.$emit('$onChanges', changes);
25 | this.executeObservers(objectObserve, '$onChanges', changes);
26 | this.executeObservers(objectObserve, '_$$checkBindings', changes);
27 | });
28 | });
29 | }
30 | }
31 |
32 | private updateScopes(scope: Scope) {
33 | if (!scope.$parent) {
34 | scope.mapDom.reload();
35 | } else {
36 | this.updateScopes(scope.$parent);
37 | }
38 | }
39 |
40 | private executeObservers(objectObserve, observeName, changes) {
41 | if (objectObserve[this.element['$instance'].config.controllerAs][observeName]) {
42 | objectObserve[this.element['$instance'].config.controllerAs][observeName](changes);
43 | }
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/scope/scope.ts:
--------------------------------------------------------------------------------
1 | import { Common } from '../common';
2 | import { Constants } from '../constants';
3 | import { CapivaraElement } from '../core/element';
4 | import { Eval } from '../core/eval';
5 | import { MapDom } from '../map/map-dom';
6 | import { ScopeProxy } from './scope.proxy';
7 |
8 | export class Scope {
9 |
10 | // Dados disponíveis nesse escopo
11 | public scope: ScopeProxy;
12 |
13 | public $parent: Scope;
14 |
15 | public mapDom: MapDom;
16 |
17 | public watchers;
18 |
19 | public observers;
20 |
21 | public id;
22 |
23 | private cpElements = {};
24 |
25 | constructor(_element: HTMLElement) {
26 | if (!_element || !_element.nodeName) {
27 | console.warn('Unable to create a scope, it is necessary to report an html element.');
28 | }
29 | Common.setScopeId(this);
30 | this.watchers = [];
31 | Scope.addScope(_element, this);
32 | this.mapDom = new MapDom(_element);
33 | this.scope = new ScopeProxy(this, this.mapDom, _element);
34 | if (!_element['$instance']) {
35 | this.$emit('$onInit');
36 | }
37 | this.observers = [];
38 | this.$on('$onChanges', this.onChanges);
39 | if (_element && _element.parentNode && _element.parentNode[Constants.SCOPE_ATTRIBUTE_NAME]) {
40 | this.$parent = _element.parentNode[Constants.SCOPE_ATTRIBUTE_NAME];
41 | }
42 | }
43 |
44 | public getScopeProxy() {
45 | return this.scope;
46 | }
47 |
48 | /** #Mudar não poderia ser adicionar a referencia do scope do componente no elemento do componente
49 | * @method void Aplicado um escopo em um elemento HTML.
50 | * @param element Elemento que será aplicado o escopo
51 | * @param scope Escopo que será aplicado no elemento
52 | */
53 | public static addScope(element: any, scope: Scope) {
54 | if (element && element.nodeName) { element[Constants.SCOPE_ATTRIBUTE_NAME] = scope; }
55 | }
56 |
57 | public $on = (evtName, callback) => {
58 | this.watchers.push({ evtName, callback });
59 | }
60 |
61 | public $emit = (evtName, ...args) => {
62 | this.watchers
63 | .filter((watcher) => watcher.evtName === evtName)
64 | .forEach((watcher) => {
65 | watcher.callback.call(this, ...args);
66 | });
67 | }
68 |
69 | public $eval = (source) => {
70 | return Eval.exec(this.scope, source);
71 | }
72 |
73 | public onChanges(changes) {
74 | this.observers.forEach((observer) => {
75 | changes.filter((change) => change.type === 'update' && change.name === observer.key).forEach((change) => {
76 | observer.callback.call(observer.ctx, change.object[change.name], change.oldValue);
77 | });
78 | });
79 | }
80 |
81 | public $watch(key: string, callback?, ctx?) {
82 | this.observers.push({
83 | key,
84 | callback,
85 | ctx,
86 | });
87 | }
88 |
89 | public $unwatch(key: string, callback) {
90 | this.observers = this.observers.filter((observer) => observer.key !== key);
91 | }
92 |
93 | public element(element) {
94 | if (this.cpElements[element] && this.cpElements[element].element === element) {
95 | return this.cpElements[element];
96 | }
97 | const capivaraElement = new CapivaraElement(element);
98 | this.cpElements[element] = capivaraElement;
99 | return capivaraElement;
100 | }
101 |
102 | public destroy() {
103 | Object.keys(this.cpElements).forEach((key) => {
104 | this.cpElements[key].destroy();
105 | });
106 | }
107 |
108 | public refresh() {
109 | this.mapDom.reload();
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/test/e2e/cpBlur/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
34 |
35 |
--------------------------------------------------------------------------------
/test/e2e/cpBlur/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpBlur': function(browser){
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpBlur/template.html')
6 | .assert.containsText('h1', 'False')
7 | .pause(1000)
8 | .click('input')
9 | .click('h1')
10 | .pause(500)
11 | .assert.containsText('h1', 'True')
12 | .pause(500)
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpChange/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/test/e2e/cpChange/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpChange' : function(browser){
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpChange/template.html')
6 | .waitForElementVisible('input', 10000)
7 | .pause(1000)
8 | .setValue('input[cp-model="$ctrl.var"]', ' world')
9 | .pause(1000)
10 | .setValue('input[cp-model="$ctrl.var2"]', ' =)')
11 | .pause(1000)
12 | .assert.containsText('#first', '6')
13 | .assert.containsText('#second', '3')
14 | .pause(1000)
15 | .end();
16 | }
17 | };
--------------------------------------------------------------------------------
/test/e2e/cpClass/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
21 |
22 |
23 |
24 |
25 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/test/e2e/cpClass/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpClass': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpClass/template.html')
6 | .waitForElementVisible('body', 10000)
7 | .waitForElementVisible('p#p1', 10000)
8 | .pause(1000)
9 | .click('button#btn1')
10 | .pause(1500)
11 | .waitForElementVisible('p#p1.democlass', 2000)
12 | .waitForElementVisible('p#p2', 10000)
13 | .pause(1000)
14 | .click('button#btn2')
15 | .pause(1500)
16 | .waitForElementVisible('p#p2.democlass2', 2000)
17 | .pause(1000)
18 | .end();
19 | }
20 | };
--------------------------------------------------------------------------------
/test/e2e/cpClick/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
31 |
32 |
--------------------------------------------------------------------------------
/test/e2e/cpClick/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpClick': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpClick/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .assert.containsText('button', 'Click me')
9 | .click('button')
10 | .pause(1000)
11 | .assert.containsText('button', 'Clicked')
12 | .pause(1000)
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpDisabled/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
32 |
33 |
--------------------------------------------------------------------------------
/test/e2e/cpDisabled/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpDisable': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpDisabled/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .assert.containsText('button', 'Click me')
9 | .click('button')
10 | .pause(1000)
11 | .assert.containsText('button', 'Click me')
12 | .pause(1000)
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpDoubleClick/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
30 |
31 |
--------------------------------------------------------------------------------
/test/e2e/cpDoubleClick/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpDoubleClick': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpDoubleClick/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .moveToElement('button', 10, 10)
9 | .doubleClick()
10 | .pause(1000)
11 | .assert.containsText('button', 'Double Clicked')
12 | .pause(1000)
13 | .end();
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/test/e2e/cpElse/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/test/e2e/cpElse/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpElse': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpElse/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .assert.containsText('button', 'Click to show!')
9 | .click('button')
10 | .pause(1000)
11 | .assert.containsText('h1', 'This is an other text.')
12 | .pause(1000)
13 | .end();
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/test/e2e/cpElseIf/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
36 |
37 |
--------------------------------------------------------------------------------
/test/e2e/cpElseIf/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpElseIf': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpElseIf/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .assert.containsText('h1','H1 with ELSE has the sum equal to 1.')
9 | .click('button')
10 | .pause(1000)
11 | .assert.containsText('h1', 'H1 with IF has the sum equal to 2.')
12 | .click('button')
13 | .pause(1000)
14 | .assert.containsText('h1', 'H1 with ELSE IF has the sum equal to 3.')
15 | .pause(1000)
16 | .end();
17 | }
18 | };
--------------------------------------------------------------------------------
/test/e2e/cpFocus/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
34 |
35 |
--------------------------------------------------------------------------------
/test/e2e/cpFocus/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpFocus': function(browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpFocus/template.html')
6 | .assert.containsText('h1', 'Input not Focused')
7 | .pause(1000)
8 | .click('input')
9 | .assert.containsText('h1', 'Input focused')
10 | .pause(500)
11 | .end();
12 | }
13 | };
--------------------------------------------------------------------------------
/test/e2e/cpHide/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/e2e/cpHide/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpHide': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpHide/template.html')
6 | .waitForElementVisible('div', 10000)
7 | .pause(1000)
8 | .expect.element('div').to.have.css('display').which.contains('');
9 | browser
10 | .setValue('input', 'red')
11 | .pause(1000)
12 | .expect.element('div').to.have.css('display').which.contains('none');
13 | browser
14 | .pause(500)
15 | .end();
16 | }
17 | };
--------------------------------------------------------------------------------
/test/e2e/cpIf/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
33 |
34 |
--------------------------------------------------------------------------------
/test/e2e/cpIf/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpIf': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpIf/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .waitForElementNotPresent('h1', 1000)
8 | .pause(1000)
9 | .click('button')
10 | .pause(1000)
11 | .assert.containsText('h1', 'This is a simple text.')
12 | .pause(1000)
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpInit/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
35 |
36 |
--------------------------------------------------------------------------------
/test/e2e/cpInit/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpInit': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpInit/template.html')
6 | .waitForElementVisible('h1', 10000)
7 | .assert.containsText('h1', 'CpInit Test')
8 | .pause(5000)
9 | .assert.containsText('h1', 'CpInit complete')
10 | .end();
11 | }
12 | };
--------------------------------------------------------------------------------
/test/e2e/cpKey/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test/e2e/cpKey/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpKey': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpKey/template.html')
6 | .waitForElementVisible('input', 10000)
7 | .pause(1000)
8 | .setValue('input', ' Capivara')
9 | .pause(1000)
10 | .sendKeys('button', browser.Keys.ENTER)
11 | .assert.containsText('p', 'Mateus Capivara')
12 | .end();
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/test/e2e/cpMax/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/e2e/cpMax/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpMax': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpMax/template.html')
6 | .waitForElementVisible('input', 10000)
7 | .pause(1000)
8 | .click('input');
9 | for (let i = 0; i < 10; i++) {
10 | browser
11 | .sendKeys('input', browser.Keys.RIGHT_ARROW);
12 | }
13 | browser
14 | .pause(1000)
15 | .assert.containsText('h1', '5')
16 | .pause(1000)
17 | .end();
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/test/e2e/cpMaxLength/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/test/e2e/cpMaxLength/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpMaxLength': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpMaxLength/template.html')
6 | .waitForElementVisible('input', 10000)
7 | .pause(1000)
8 | .assert.containsText('p', 'Capivara')
9 | .setValue('input', ' JS')
10 | .pause(1500)
11 | .assert.containsText('p', 'Capivara J')
12 | .end();
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/test/e2e/cpMin/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/test/e2e/cpMin/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpMin': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpMin/template.html')
6 | .waitForElementVisible('input', 10000)
7 | .pause(1000)
8 | .click('input');
9 | for (let i = 0; i < 100; i++) {
10 | browser
11 | .sendKeys('input', browser.Keys.DOWN_ARROW);
12 | }
13 | browser
14 | .assert.containsText('h1', '0')
15 | .pause(1000)
16 | .end();
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/test/e2e/cpModel/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Test
8 |
9 |
10 |
11 |
12 |
13 |
14 |
35 |
36 |
--------------------------------------------------------------------------------
/test/e2e/cpModel/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpModel': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpModel/template.html')
6 | .waitForElementVisible('p', 10000)
7 | .pause(1000)
8 | .assert.containsText('p', 'Capivara')
9 | .setValue('input', ' JS')
10 | .pause(1500)
11 | .assert.containsText('p', 'Capivara JS')
12 | .end();
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/test/e2e/cpMouse/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/test/e2e/cpMouse/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpMouse': function(browser){
3 | browser
4 | .resizeWindow(1920, 1020)
5 | .url('http://localhost:1111/test/e2e/cpMouse/template.html')
6 | .waitForElementVisible('input', 5000)
7 | .pause(3000)
8 | .moveToElement('input', 10, 10)
9 | .pause(1000)
10 | .assert.containsText('h1', 'mousein')
11 | .pause(1000)
12 | .moveToElement('body', 100, 100)
13 | .pause(1000)
14 | .assert.containsText('h1', 'mouseout')
15 | .pause(1000)
16 | .end();
17 | }
18 | };
--------------------------------------------------------------------------------
/test/e2e/cpPlaceholder/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
12 |
13 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/test/e2e/cpPlaceholder/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpPlaceholder': function(browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpPlaceholder/template.html')
6 | .pause(1000)
7 | .expect.element('input').to.have.attribute('placeholder').which.contains('Capivara');
8 | browser
9 | .click('button')
10 | .pause(1000)
11 | .expect.element('input').to.have.attribute('placeholder').which.contains('CapivaraJS');
12 | browser.pause(2000);
13 | },
14 | };
--------------------------------------------------------------------------------
/test/e2e/cpRepeat/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/test/e2e/cpRepeat/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpRepeat': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpRepeat/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .assert.containsText('li:nth-child(1) p', 'John')
9 | .assert.containsText('li:nth-child(2) p', 'Bob')
10 | .click('button')
11 | .pause(1000)
12 | .assert.containsText('li:nth-child(3) p', 'Anna')
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpShow/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test/e2e/cpShow/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpShow': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpShow/template.html')
6 | .waitForElementVisible('button', 10000)
7 | .pause(1000)
8 | .expect.element('h1').to.have.css('display').which.contains('none');
9 | browser
10 | .click('button')
11 | .pause(1000)
12 | .expect.element('h1').to.have.css('display').which.contains('');
13 | browser.end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpSrc/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/test/e2e/cpSrc/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpSrc': function (browser) {
3 | browser.resizeWindow(1920, 1080);
4 | browser
5 | .url('http://localhost:1111/test/e2e/cpSrc/template.html')
6 | .pause(1500)
7 | .waitForElementVisible('img[src="https://avatars1.githubusercontent.com/u/33517395?s=200&v=4"]', 3000)
8 | .pause(1000)
9 | .click('button[cp-click="$ctrl.click()"]')
10 | .pause(5000)
11 | .waitForElementVisible('img[src="https://bit.ly/2pTjZnU"]', 20000)
12 | .pause(3000)
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/cpStep/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/test/e2e/cpStep/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpStep': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpStep/template.html')
6 | .waitForElementVisible('input', 10000)
7 | .pause(1000)
8 | .click('input');
9 | for (let i = 0; i < 10; i++) {
10 | browser
11 | .sendKeys('input', browser.Keys.UP_ARROW);
12 | }
13 | browser
14 | .assert.containsText('h1', '30')
15 | .pause(1000)
16 | .end();
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/test/e2e/cpStyle/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/test/e2e/cpStyle/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'cpStyle': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/cpStyle/template.html')
6 | .pause(1000)
7 | .waitForElementVisible('h1', 10000)
8 | .assert.cssProperty('h1', 'color', 'rgba(0, 128, 0, 1)')
9 | .pause(1000)
10 | .click('button[id="btn1"]')
11 | .pause(1000)
12 | .assert.cssProperty('h1', 'color', 'rgba(255, 0, 0, 1)')
13 | .pause(1000)
14 | .expect.element('p#p1').to.have.css('background').which.contains('rgb(0, 0, 255)');
15 | browser
16 | .pause(1000)
17 | .click('button[id="btn2"]')
18 | .pause(1000)
19 | .expect.element('p#p1').to.have.css('background').which.contains('rgb(128, 128, 128)');
20 | browser
21 | .pause(1000)
22 | .click('button[id="btn3"]')
23 | .pause(1000)
24 | .expect.element('p#p3').to.have.css('background').which.contains('rgb(0, 128, 0)');
25 | browser
26 | .pause(1000)
27 | .end();
28 | }
29 | };
--------------------------------------------------------------------------------
/test/e2e/index.js:
--------------------------------------------------------------------------------
1 | module.exports = Object.assign(
2 | require('./cpModel/test'),
3 | require('./cpClick/test'),
4 | require('./cpKey/test'),
5 | require('./cpChange/test'),
6 | require('./cpDoubleClick/test'),
7 | require('./cpMouse/test'),
8 | require('./cpPlaceholder/test'),
9 | require('./cpClass/test'),
10 | require('./cpElse/test'),
11 | require('./cpElseIf/test'),
12 | require('./cpIf/test'),
13 | require('./cpInit/test'),
14 | require('./cpRepeat/test'),
15 | require('./cpShow/test'),
16 | require('./cpSrc/test'),
17 | require('./cpStyle/test'),
18 | require('./interpolation/test'),
19 | require('./noBind/test'),
20 | require('./cpDisabled/test'),
21 | require('./cpMax/test'),
22 | require('./cpMin/test'),
23 | require('./cpStep/test'),
24 | require('./cpMaxLength/test'),
25 | require('./cpDisabled/test'),
26 | require('./cpFocus/test'),
27 | require('./cpHide/test'),
28 | require('./cpBlur/test')
29 | );
30 |
--------------------------------------------------------------------------------
/test/e2e/interpolation/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test/e2e/interpolation/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'interpolation': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/interpolation/template.html')
6 | .pause(1000)
7 | .waitForElementVisible('h1', 10000)
8 | .pause(1000)
9 | .click('button')
10 | .pause(1000)
11 | .assert.containsText('h1', 'felipe2')
12 | .assert.containsText('h2', 'felipe')
13 | .end();
14 | }
15 | };
--------------------------------------------------------------------------------
/test/e2e/noBind/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Test
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/test/e2e/noBind/test.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | 'noBind': function (browser) {
3 | browser
4 | .resizeWindow(1920, 1080)
5 | .url('http://localhost:1111/test/e2e/noBind/template.html')
6 | .pause(1000)
7 | .waitForElementVisible('div', 10000)
8 | .pause(1000)
9 | .assert.containsText('div h2', '[[2+2]]')
10 | .assert.containsText('h1', '4')
11 | .end();
12 | }
13 | };
--------------------------------------------------------------------------------
/test/spec/capivara-change.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of click without parameters', () => {
5 | const template = `
6 |
7 |
8 |
9 | `;
10 | const element = document.createElement('div');
11 | element.innerHTML = template;
12 | capivara.controller(element, function() {
13 | const $ctrl = this;
14 |
15 | this.$onInit = function() {
16 | this.var = 'hello';
17 | this.cont = 0;
18 | };
19 |
20 | this.clicked = function() {
21 | this.var = this.var + 'aaa';
22 | };
23 |
24 | this.change = function() {
25 | this.cont = this.cont + 1;
26 | };
27 |
28 | $ctrl.$onViewInit = () => {
29 | it('The value of the cont must be 3', (done) => {
30 | setTimeout(function() {
31 | element.querySelector('button').click();
32 | element.querySelector('button').click();
33 | element.querySelector('button').click();
34 | expect($ctrl.cont).toEqual(3);
35 | done();
36 | }, 1000);
37 | });
38 | };
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/test/spec/capivara-class.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 | import { CPClass } from '../../src/map/directive/cp-class';
4 |
5 | describe('test of class with fixed object', () => {
6 | const template = `
7 |
8 | `;
9 | const element = document.createElement('div');
10 | element.innerHTML = template;
11 | capivara.controller(element, function() {
12 | const $ctrl = this;
13 | $ctrl.activeClass = true;
14 |
15 | $ctrl.$onInit = () => {
16 | it('Expected to add the class', () => {
17 | expect(element.querySelector('h1').classList.contains('demo')).toEqual(true);
18 | });
19 | };
20 |
21 | });
22 | });
23 |
24 | describe('test of class with dynamic object', () => {
25 | const template = `
26 |
27 | `;
28 | const element = document.createElement('div');
29 | element.innerHTML = template;
30 | capivara.controller(element, function() {
31 | const $ctrl = this;
32 |
33 | $ctrl.getClass = () => {
34 | return {
35 | ['demo'] : true,
36 | };
37 | };
38 |
39 | $ctrl.$onInit = () => {
40 | it("Expected to add the class", function(done) {
41 | setTimeout(function() {
42 | expect(element.querySelector('h1').classList.contains('demo')).toEqual(true);
43 | done();
44 | });
45 | });
46 | };
47 | });
48 | });
49 |
50 | describe('test methods', () => {
51 | const template = `
52 |
53 | `;
54 | const element = document.createElement('div');
55 | element.innerHTML = template;
56 | capivara.controller(element, function() {});
57 | const cpClass = new CPClass(element.querySelector('h1'), null);
58 | cpClass.create();
59 | it("Expected to add the class", function() {
60 | cpClass.addClass('demo');
61 | expect(element.querySelector('h1').classList.contains('demo')).toEqual(true);
62 | });
63 | it("Expected to remove the class", function() {
64 | cpClass.removeClass('demo');
65 | expect(element.querySelector('h1').classList.contains('demo')).toEqual(false);
66 | });
67 | });
68 |
--------------------------------------------------------------------------------
/test/spec/capivara-click.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 | import { CPClick } from '../../src/map/directive/cp-click';
4 |
5 | describe('test of click without parameters', () => {
6 | const template = `
7 |
8 | `;
9 | const element = document.createElement('div');
10 | element.innerHTML = template;
11 | capivara.controller(element, function() {
12 | const $ctrl = this;
13 |
14 | $ctrl.$onInit = () => {
15 | $ctrl.clicked = false;
16 | };
17 |
18 | $ctrl.toggleClicked = () => {
19 | $ctrl.clicked = !$ctrl.clicked;
20 | };
21 |
22 | $ctrl.$onViewInit = () => {
23 | it('The value of the variable must be true', () => {
24 | element.querySelector('button').click();
25 | expect(element['$instance'].componentScope.$ctrl.clicked).toEqual(true);
26 | });
27 | };
28 | });
29 | });
30 |
31 | describe('test of click with parameters method sum', () => {
32 | const template = `
33 |
34 |
35 |
36 | `;
37 | const element = document.createElement('div');
38 | element.innerHTML = template;
39 |
40 | capivara.controller(element, function() {
41 | const $ctrl = this;
42 |
43 | $ctrl.$onInit = () => {
44 | $ctrl.numberOne = 90;
45 | $ctrl.numberTwo = 10;
46 | };
47 |
48 | $ctrl.sum = (value) => {
49 | $ctrl.result = value;
50 | };
51 |
52 | $ctrl.$onViewInit = () => {
53 | it('Must be the sum of the two numbers', () => {
54 | element.querySelector('button').click();
55 | expect(element['$instance'].componentScope.$ctrl.result).toEqual(100);
56 | });
57 | };
58 |
59 | });
60 |
61 | });
62 |
63 | describe('test of click with parameters method subtract', () => {
64 | const template = `
65 |
66 |
67 |
68 | `;
69 | const element = document.createElement('div');
70 | element.innerHTML = template;
71 |
72 | capivara.controller(element, function() {
73 | const $ctrl = this;
74 |
75 | $ctrl.$onInit = () => {
76 | $ctrl.numberOne = 90;
77 | $ctrl.numberTwo = 10;
78 | };
79 |
80 | $ctrl.subtract = (value) => {
81 | $ctrl.result = value;
82 | };
83 |
84 | $ctrl.$onViewInit = () => {
85 | it('Must be the subtraction of the two numbers', () => {
86 | element.querySelector('button').click();
87 | expect(element['$instance'].componentScope.$ctrl.result).toEqual(80);
88 | });
89 | };
90 | });
91 | });
92 |
93 | describe('test of click with parameters object', () => {
94 | const template = `
95 |
96 | `;
97 | const element = document.createElement('div');
98 | element.innerHTML = template;
99 |
100 | capivara.controller(element, function() {
101 | const $ctrl = this;
102 |
103 | $ctrl.$onInit = () => {
104 | $ctrl.person = {
105 | name: 'Mateus',
106 | };
107 | };
108 |
109 | $ctrl.save = (person) => {
110 | $ctrl.result = person;
111 | };
112 |
113 | $ctrl.$onViewInit = () => {
114 | it('Must be the same object', () => {
115 | element.querySelector('button').click();
116 | expect(element['$instance'].componentScope.$ctrl.result).toEqual(element['$instance'].componentScope.$ctrl.person);
117 | });
118 | };
119 |
120 | });
121 | });
122 |
123 | describe('test methods', () => {
124 | const template = `
125 |
126 | `;
127 | const element = document.createElement('div');
128 | element.innerHTML = template;
129 | capivara.controller(element, function() {
130 | const $ctrl = this;
131 |
132 | $ctrl.save = function() {
133 | $ctrl.clicked = true;
134 | };
135 |
136 | $ctrl.$onViewInit = () => {
137 | const cpClick = new CPClick(element.querySelector('button'), null);
138 | it('Should create the click event', (done) => {
139 | cpClick.create();
140 | element.querySelector('button').click();
141 | setTimeout(() => {
142 | expect(element.querySelector('button')['$scope'].scope.$ctrl.clicked).toEqual(true);
143 | done();
144 | }, 1000);
145 | });
146 | };
147 |
148 | });
149 | });
150 |
--------------------------------------------------------------------------------
/test/spec/capivara-component-instance.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | // describe('test create component', () => {
5 | // const template = `
6 | //
7 | // `;
8 | // const element = document.createElement('div');
9 | // element.innerHTML = template;
10 | // });
11 |
--------------------------------------------------------------------------------
/test/spec/capivara-component.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test create component', () => {
5 | const template = `
6 |
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | document.body.appendChild(element);
11 | const config = {
12 | template: 'Hello World ',
13 | };
14 | capivara.component('my-component', config);
15 | it("Expected config equal", function() {
16 | expect(capivara.components['MY-COMPONENT'].config.template).toEqual(config.template);
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/test/spec/capivara-disabled.spec.ts:
--------------------------------------------------------------------------------
1 | import {} from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('Directive cp-disabled', () => {
5 |
6 | it('Should check if disable is truth', () => {
7 | const template = ` `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 |
13 | $ctrl.$onInit = () => {
14 | $ctrl.clicked = 0;
15 | };
16 |
17 | $ctrl.addOne = () => {
18 | $ctrl.clicked += 1;
19 | };
20 |
21 | $ctrl.$onViewInit = () => {
22 | element.querySelector('button').click();
23 | expect(element['$instance'].componentScope.$ctrl.clicked).toEqual(0);
24 | };
25 | });
26 | });
27 |
28 | it('Should check if disable is false', () => {
29 | const template = ` `;
30 | const element = document.createElement('div');
31 | element.innerHTML = template;
32 | capivara.controller(element, function() {
33 | const $ctrl = this;
34 |
35 | $ctrl.$onInit = () => {
36 | $ctrl.clicked = 0;
37 | };
38 |
39 | $ctrl.addOne = () => {
40 | $ctrl.clicked += 1;
41 | };
42 |
43 | $ctrl.$onViewInit = () => {
44 | setTimeout(function() {
45 | element.querySelector('button').click();
46 | expect(element['$instance'].componentScope.$ctrl.clicked).toEqual(1);
47 | }, 0);
48 | };
49 |
50 | });
51 | });
52 |
53 | it('Should update disable value changed', () => {
54 | const template = ` `;
55 | const element = document.createElement('div');
56 | element.innerHTML = template;
57 | capivara.controller(element, function() {
58 | const $ctrl = this;
59 | $ctrl.$onInit = () => {
60 | $ctrl.clicked = false;
61 | };
62 | $ctrl.$onViewInit = () => {
63 | setTimeout(function() {
64 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
65 | element['$instance'].componentScope.$ctrl.clicked = true;
66 | }, 0);
67 | setTimeout(function() {
68 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(true);
69 | element['$instance'].componentScope.$ctrl.clicked = false;
70 | }, 0);
71 | setTimeout(function() {
72 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
73 | element['$instance'].componentScope.$ctrl.clicked = true;
74 | }, 0);
75 | setTimeout(function() {
76 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(true);
77 | element['$instance'].componentScope.$ctrl.clicked = null;
78 | }, 0);
79 | setTimeout(function() {
80 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
81 | element['$instance'].componentScope.$ctrl.clicked = undefined;
82 | }, 0);
83 | setTimeout(function() {
84 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
85 | element['$instance'].componentScope.$ctrl.clicked = {};
86 | }, 0);
87 | setTimeout(function() {
88 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
89 | element['$instance'].componentScope.$ctrl.clicked = [];
90 | }, 0);
91 | setTimeout(function() {
92 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
93 | element['$instance'].componentScope.$ctrl.clicked = 0;
94 | }, 0);
95 | setTimeout(function() {
96 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
97 | element['$instance'].componentScope.$ctrl.clicked = 1;
98 | }, 0);
99 | setTimeout(function() {
100 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(true);
101 | element['$instance'].componentScope.$ctrl.clicked = 0;
102 | }, 0);
103 | setTimeout(function() {
104 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(false);
105 | element['$instance'].componentScope.$ctrl.clicked = 1;
106 | }, 0);
107 | setTimeout(function() {
108 | expect(element.querySelector('button').hasAttribute('disabled')).toEqual(true);
109 | }, 0);
110 | };
111 | });
112 | });
113 | });
114 |
--------------------------------------------------------------------------------
/test/spec/capivara-doubleclick.spec.ts:
--------------------------------------------------------------------------------
1 | // import {} from 'jasmine';
2 | // import capivara from '../../src/index';
3 | // import {CPClick} from '../../src/map/directive/cp-click';
4 |
5 | // function triggerDoubeClick(element) {
6 | // const doubleClickEvent = document.createEvent('MouseEvents');
7 | // doubleClickEvent.initEvent('dblclick', true, true);
8 | // element.querySelector('button').dispatchEvent(doubleClickEvent);
9 | // }
10 |
11 | // describe('Directive cp-dblclick', () => {
12 |
13 | // it('The value of the variable must be true', () => {
14 | // const template = `
15 | //
16 | // `;
17 | // const element = document.createElement('div');
18 | // element.innerHTML = template;
19 | // capivara.controller(element, function() {
20 | // const $ctrl = this;
21 |
22 | // $ctrl.$onInit = () => {
23 | // $ctrl.clicked = false;
24 | // };
25 |
26 | // $ctrl.toggleClicked = () => {
27 | // $ctrl.clicked = !$ctrl.clicked;
28 | // };
29 | // });
30 | // triggerDoubeClick(element);
31 | // expect(element['$instance'].componentScope.$ctrl.clicked).toEqual(true);
32 | // });
33 |
34 | // it('Must be the sum of the two numbers', () => {
35 | // const template = `
36 | //
37 | //
38 | //
39 | // `;
40 | // const element = document.createElement('div');
41 | // element.innerHTML = template;
42 |
43 | // capivara.controller(element, function() {
44 | // const $ctrl = this;
45 |
46 | // $ctrl.$onInit = () => {
47 | // $ctrl.numberOne = 90;
48 | // $ctrl.numberTwo = 10;
49 | // };
50 |
51 | // $ctrl.sum = (value) => {
52 | // $ctrl.result = value;
53 | // };
54 | // });
55 | // triggerDoubeClick(element);
56 | // expect(element['$instance'].componentScope.$ctrl.result).toEqual(100);
57 | // });
58 | // it('Must be the subtraction of the two numbers', () => {
59 | // const template = `
60 | //
61 | //
62 | //
63 | // `;
64 | // const element = document.createElement('div');
65 | // element.innerHTML = template;
66 |
67 | // capivara.controller(element, function() {
68 | // const $ctrl = this;
69 |
70 | // $ctrl.$onInit = () => {
71 | // $ctrl.numberOne = 90;
72 | // $ctrl.numberTwo = 10;
73 | // };
74 |
75 | // $ctrl.subtract = (value) => {
76 | // $ctrl.result = value;
77 | // };
78 | // });
79 | // triggerDoubeClick(element);
80 | // expect(element['$instance'].componentScope.$ctrl.result).toEqual(80);
81 | // });
82 |
83 | // it('Must be the same object', () => {
84 | // const template = `
85 | //
86 | // `;
87 | // const element = document.createElement('div');
88 | // element.innerHTML = template;
89 |
90 | // capivara.controller(element, function() {
91 | // const $ctrl = this;
92 |
93 | // $ctrl.$onInit = () => {
94 | // $ctrl.person = {
95 | // name: 'Mateus',
96 | // };
97 | // };
98 |
99 | // $ctrl.save = (person) => {
100 | // $ctrl.result = person;
101 | // };
102 | // });
103 | // triggerDoubeClick(element);
104 | // expect(element['$instance'].componentScope.$ctrl.result).toEqual(element['$instance'].componentScope.$ctrl.person);
105 | // });
106 |
107 | // it('Should create the click event', (done) => {
108 | // const template = `
109 | //
110 | // `;
111 | // const element = document.createElement('div');
112 | // element.innerHTML = template;
113 | // capivara.controller(element, function() {
114 | // const $ctrl = this;
115 |
116 | // $ctrl.save = function() {
117 | // $ctrl.clicked = true;
118 | // };
119 | // });
120 | // const cpClick = new CPClick(element.querySelector('button'), null);
121 | // cpClick.create();
122 | // triggerDoubeClick(element);
123 | // setTimeout(() => {
124 | // expect(element.querySelector('button')['$scope'].scope.$ctrl.clicked).toEqual(true);
125 | // done();
126 | // }, 1000);
127 | // });
128 |
129 | // });
130 |
--------------------------------------------------------------------------------
/test/spec/capivara-else-if.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test cpElseIf hide element', () => {
5 | const template = `
6 | Show this
7 | Show this
8 | `;
9 | const element = document.createElement('div');
10 | element.innerHTML = template;
11 | capivara.controller(element, function() {
12 | const $ctrl = this;
13 | $ctrl.isActive = 1;
14 |
15 | $ctrl.$onInit = () => {
16 | it("Expected h2 not found", function(done) {
17 | setTimeout(function() {
18 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(true);
19 | done();
20 | });
21 | });
22 | };
23 | });
24 | });
25 |
26 | describe('test cpElseIf show element', () => {
27 | const template = `
28 | Show this
29 | Show this
30 | `;
31 | const element = document.createElement('div');
32 | element.innerHTML = template;
33 | capivara.controller(element, function() {
34 | const $ctrl = this;
35 | $ctrl.isActive = 2;
36 |
37 | $ctrl.$onInit = () => {
38 | it("Expected h2 not found", function(done) {
39 | setTimeout(function() {
40 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(false);
41 | done();
42 | });
43 | });
44 | };
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/test/spec/capivara-else.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test cpElse hide element', () => {
5 | const template = `
6 | Show this
7 | Not show this
8 | `;
9 | const element = document.createElement('div');
10 | element.innerHTML = template;
11 | capivara.controller(element, function() {
12 | const $ctrl = this;
13 | $ctrl.isActive = true;
14 |
15 | $ctrl.$onInit = () => {
16 | it("Expected h2 not found", function(done) {
17 | setTimeout(function() {
18 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(true);
19 | done();
20 | });
21 | });
22 | };
23 | });
24 | });
25 |
26 | describe('test cpElse show element', () => {
27 | const template = `
28 | Show this
29 | Not show this
30 | `;
31 | const element = document.createElement('div');
32 | element.innerHTML = template;
33 | document.body.appendChild(element);
34 | capivara.controller(element, function() {
35 | const $ctrl = this;
36 | $ctrl.isActive = false;
37 |
38 | $ctrl.$onViewInit = () => {
39 | it("Expected h2 found", function() {
40 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(false);
41 | });
42 | };
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/test/spec/capivara-eval.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import {Eval} from '../../src/core/eval';
3 |
4 | describe('This will be test the eval method', () => {
5 | const person = { firstName: 'Mateus', lastName: 'Miranda de Almeida', age: 22 };
6 | it('Should return object first name', () => {
7 | expect(Eval.exec('firstName', person)).toEqual(person.firstName);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/test/spec/capivara-focus.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of focus', () => {
5 | const template = `
6 |
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.focused = false;
13 |
14 | $ctrl.teste = () => {
15 | $ctrl.focused = true;
16 | };
17 |
18 | $ctrl.$onViewInit = () => {
19 | const event = new Event('focus');
20 | element.querySelector('input').dispatchEvent(event);
21 | it('Expected attribute focused is true', (done) => {
22 | setTimeout(() => {
23 | expect($ctrl.focused).toEqual(true);
24 | done();
25 | });
26 | });
27 |
28 | };
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/test/spec/capivara-hide.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of hide with fixed object', () => {
5 | const template = `
6 | hide this
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.isActive = false;
13 |
14 | $ctrl.$onInit = () => {
15 | it("Expected to find the element", function(done) {
16 | setTimeout(function() {
17 | expect(element.querySelector('h1').style.display).toEqual('');
18 | done();
19 | });
20 | });
21 | };
22 | });
23 | });
24 |
25 | describe('test of hide with dynamic object', () => {
26 | const template = `
27 | hide this
28 | Click me!
29 | `;
30 | const element = document.createElement('div');
31 | element.innerHTML = template;
32 | capivara.controller(element, function() {
33 | const $ctrl = this;
34 | $ctrl.isActive = false;
35 |
36 | $ctrl.click = () => {
37 | $ctrl.isActive = true;
38 | };
39 |
40 | $ctrl.$onViewInit = () => {
41 | element.querySelector('button').click();
42 | it("Expected to not find the element", function(done) {
43 | setTimeout(function() {
44 | expect(element.querySelector('h1').style.display).toEqual('none');
45 | done();
46 | });
47 | }, 5000);
48 | };
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/test/spec/capivara-if.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test cpIf with static elements', () => {
5 | const template = `
6 | Not Show this
7 | Show this
8 | `;
9 | const element = document.createElement('div');
10 | element.innerHTML = template;
11 | capivara.controller(element, function() {
12 | const $ctrl = this;
13 | $ctrl.isActive = false;
14 |
15 | $ctrl.$onInit = () => {
16 | it("Expected h1 not found and h2 was found", function(done) {
17 | setTimeout(function() {
18 | expect(element.querySelector('h1')['$$cpDestroyed']).toEqual(true);
19 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(false);
20 | done();
21 | });
22 | });
23 | };
24 | });
25 | });
26 |
27 | describe('test cpIf with static elements', () => {
28 | const template = `
29 | Not Show this
30 | Show this
31 | `;
32 | const element = document.createElement('div');
33 | element.innerHTML = template;
34 | capivara.controller(element, function() {
35 | const $ctrl = this;
36 | $ctrl.isActive = true;
37 |
38 | $ctrl.$onInit = () => {
39 | it("Expected h2 not found and h1 was found", function(done) {
40 | setTimeout(function() {
41 | expect(element.querySelector('h1')['$$cpDestroyed']).toEqual(false);
42 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(true);
43 | done();
44 | });
45 | });
46 | };
47 | });
48 | });
49 |
50 | describe('test cpIf with first dynamic elements', () => {
51 | const template = `
52 | Show this
53 | Not Show this
54 | Click me!
55 | `;
56 | const element = document.createElement('div');
57 | element.innerHTML = template;
58 | capivara.controller(element, function() {
59 | const $ctrl = this;
60 | $ctrl.isActive = true;
61 | $ctrl.clickMe = function() {
62 | $ctrl.isActive = !$ctrl.isActive;
63 | };
64 | $ctrl.$onInit = () => {
65 | it("Expected h2 found and h1 not found", function(done) {
66 | setTimeout(function() {
67 | element.querySelector('button').click();
68 | expect(element.querySelector('h1')['$$cpDestroyed']).toEqual(true);
69 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(false);
70 | done();
71 | setTimeout(function() {
72 | element.querySelector('button').click();
73 | expect(element.querySelector('h1')['$$cpDestroyed']).not.toEqual(true);
74 | expect(element.querySelector('h2')['$$cpDestroyed']).not.toEqual(false);
75 | });
76 | });
77 | });
78 | };
79 | });
80 | });
81 |
82 | describe('test cpIf with second dynamic elements', () => {
83 | const template = `
84 | Show this
85 | Not Show this
86 | Click me!
87 | `;
88 | const element = document.createElement('div');
89 | element.innerHTML = template;
90 | capivara.controller(element, function() {
91 | const $ctrl = this;
92 | $ctrl.isActive = false;
93 | $ctrl.clickMe = function() {
94 | $ctrl.isActive = !$ctrl.isActive;
95 | };
96 |
97 | $ctrl.$onInit = () => {
98 | it("Expected h1 found and h2 not found", function(done) {
99 | element.querySelector('button').click();
100 | expect(element.querySelector('h1')['$$cpDestroyed']).toEqual(false);
101 | expect(element.querySelector('h2')['$$cpDestroyed']).toEqual(true);
102 | done();
103 | setTimeout(function() {
104 | element.querySelector('button').click();
105 | expect(element.querySelector('h1')['$$cpDestroyed']).not.toEqual(false);
106 | expect(element.querySelector('h2')['$$cpDestroyed']).not.toEqual(true);
107 | });
108 | });
109 | };
110 | });
111 | });
112 |
--------------------------------------------------------------------------------
/test/spec/capivara-init.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of init with fixed object', () => {
5 | const template = `
6 | String test
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.value = '';
13 |
14 | $ctrl.initialize = (value) => {
15 | $ctrl.value = value;
16 | };
17 |
18 | $ctrl.$onInit = () => {
19 | it("Expected to not find the element", function(done) {
20 | setTimeout(function() {
21 | expect($ctrl.value).toEqual('This is the init function');
22 | done();
23 | });
24 | }, 5000);
25 | };
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/test/spec/capivara-interpolation.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test interpolation', () => {
5 | const template = `
6 | [[$ctrl.name]]
7 | [[:$ctrl.name]]
8 | `;
9 | const element = document.createElement('div');
10 | element.innerHTML = template;
11 |
12 | capivara.controller(element, function() {
13 | const $ctrl = this;
14 |
15 | $ctrl.$onInit = () => {
16 | $ctrl.name = 'Felipe';
17 | };
18 |
19 | $ctrl.$onViewInit = () => {
20 | setTimeout(() => {
21 | $ctrl.name = 'Felipe Sabadini';
22 | }, 1000);
23 | it("Expected field name is equal to scope", function(done) {
24 | setTimeout(function() {
25 | expect(element.querySelector('h1').innerHTML).toEqual($ctrl.name);
26 | done();
27 | }, 2000);
28 | }, 3000);
29 | it("Expected field name not equal to scope", function(done) {
30 | setTimeout(function() {
31 | expect(element.querySelector('h2').innerHTML).toEqual('Felipe');
32 | done();
33 | }, 2000);
34 | }, 3000);
35 | };
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/test/spec/capivara-key.spec.ts:
--------------------------------------------------------------------------------
1 | // import { } from 'jasmine';
2 | // import capivara from '../../src/index';
3 |
4 | // describe('test of key', () => {
5 | // const template = `
6 | //
7 | // `;
8 | // const element = document.createElement('div');
9 | // element.innerHTML = template;
10 | // capivara.controller(element, function() {
11 | // const $ctrl = this;
12 |
13 | // $ctrl.$onInit = () => {
14 | // $ctrl.clicked = false;
15 | // };
16 |
17 | // $ctrl.toggleClicked = () => {
18 | // $ctrl.clicked = !$ctrl.clicked;
19 | // };
20 |
21 | // });
22 | // it('The value of the variable must be true', () => {
23 | // expect(element['$instance'].componentScope.$ctrl.clicked).toEqual(true);
24 | // });
25 | // });
26 |
--------------------------------------------------------------------------------
/test/spec/capivara-max.spec.ts:
--------------------------------------------------------------------------------
1 | // import { } from 'jasmine';
2 | //
3 | // describe('test of max', () => {
4 | // const template = `
5 | //
6 | // `;
7 | // const element = document.createElement('div');
8 | // element.innerHTML = template;
9 | //
10 | // it("Expected to increase the value of the input to max", function(done) {
11 | // setTimeout(function() { element.querySelector('input').click(); }, 500);
12 | // setTimeout(function() {
13 | // expect(element.querySelector('input').value).toEqual('1');
14 | // done();
15 | // }, 1000);
16 | // setTimeout(function() { element.querySelector('input').click(); }, 1500);
17 | // setTimeout(function() {
18 | // expect(element.querySelector('input').value).toEqual('1');
19 | // done();
20 | // }, 2000);
21 | // });
22 | // });
23 |
--------------------------------------------------------------------------------
/test/spec/capivara-maxlength.spec.ts:
--------------------------------------------------------------------------------
1 | // import {} from 'jasmine';
2 | // import capivara from '../../src/index';
3 |
4 | // describe('Directive cp-maxlength', () => {
5 |
6 | // it("Expected field maxLength are equal to 10", function(done) {
7 | // const template = `
8 | //
9 | // `;
10 | // const element = document.createElement('div');
11 | // element.innerHTML = template;
12 | // capivara.controller(element, function() {
13 | // const $ctrl = this;
14 | // $ctrl.$onViewInit = () => {
15 | // setTimeout(function() {
16 | // expect(element.querySelector('input').maxLength).toEqual(10);
17 | // done();
18 | // }, 0);
19 | // };
20 | // });
21 | // });
22 |
23 | // it("Expected field maxLength are equal to the local variable", function(done) {
24 | // const template = `
25 | //
26 | // `;
27 | // const element = document.createElement('div');
28 | // element.innerHTML = template;
29 | // capivara.controller(element, function() {
30 | // const $ctrl = this;
31 | // $ctrl.max = 20;
32 | // $ctrl.$onViewInit = () => {
33 | // setTimeout(function() {
34 | // expect(element.querySelector('input').maxLength).toEqual($ctrl.max);
35 | // done();
36 | // }, 0);
37 | // };
38 | // });
39 | // });
40 | // });
41 |
--------------------------------------------------------------------------------
/test/spec/capivara-min.spec.ts:
--------------------------------------------------------------------------------
1 | // import { } from 'jasmine';
2 | //
3 | // describe('test of min', () => {
4 | // const template = `
5 | //
6 | // `;
7 | // const element = document.createElement('div');
8 | // element.innerHTML = template;
9 | //
10 | // it("Expected to decrease the input value to zero", function(done) {
11 | // setTimeout(function() { element.querySelector('input').click(); }, 500);
12 | // setTimeout(function() {
13 | // expect(element.querySelector('input').value).toEqual('0');
14 | // done();
15 | // }, 1000);
16 | // setTimeout(function() { element.querySelector('input').click(); }, 1500);
17 | // setTimeout(function() {
18 | // expect(element.querySelector('input').value).toEqual('0');
19 | // done();
20 | // }, 2000);
21 | // });
22 | // });
23 |
--------------------------------------------------------------------------------
/test/spec/capivara-model.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test model scope to field', () => {
5 | const template = `
6 |
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.$onInit = () => {
13 | $ctrl.name = 'Mateus Miranda';
14 |
15 | it("Expected field value is equal to scope", function(done) {
16 | setTimeout(function() {
17 | expect(element.querySelector('input').value).toEqual($ctrl.name);
18 | done();
19 | });
20 | });
21 |
22 | };
23 | });
24 | });
25 |
26 | describe('test model field to scope', () => {
27 | const template = `
28 |
29 | `;
30 | const element = document.createElement('div');
31 | element.innerHTML = template;
32 | capivara.controller(element, function() {
33 | const $ctrl = this;
34 | $ctrl.$onViewInit = () => {
35 | element.querySelector('input').setAttribute('value', 'Mateus Miranda');
36 | Object.keys(element['$scope'].mapDom.directives.cpModelsElements).forEach((key) => {
37 | element['$scope'].mapDom.directives.cpModelsElements[key].forEach((elm) => elm.applyValueInModel());
38 | });
39 | it("Expected field value is equal to scope", function(done) {
40 | setTimeout(function() {
41 | expect(element.querySelector('input').value).toEqual($ctrl.name);
42 | done();
43 | });
44 | });
45 | };
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/test/spec/capivara-mouse.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of mousein and out', () => {
5 | const template = `
6 |
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.mousein = function() {
13 | $ctrl.test = 'mousein';
14 | };
15 |
16 | $ctrl.mouseout = function() {
17 | $ctrl.test = 'mouseout';
18 | };
19 |
20 | $ctrl.$onViewInit = () => {
21 | const evtIn = new Event('mouseover');
22 | const evtOut = new Event('mouseout');
23 | element.querySelector('input').dispatchEvent(evtIn);
24 | element.querySelector('input').dispatchEvent(evtOut);
25 |
26 | it('expect the element test have value mouseout', (done) => {
27 | expect(element.querySelector('input').value).toEqual('mouseout');
28 | done();
29 | });
30 | };
31 |
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/test/spec/capivara-no-bind.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test no bind', () => {
5 | const template = `
6 |
7 |
8 |
[[4+4]]
9 |
10 | `;
11 | const element = document.createElement('div');
12 | element.innerHTML = template;
13 | capivara.controller(element, function() {
14 |
15 | it("Expected ignore interpolation", function(done) {
16 | setTimeout(function() {
17 | expect(element.querySelector('div h1').innerHTML).toEqual('[[4+4]]');
18 | done();
19 | });
20 | });
21 |
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/test/spec/capivara-placeholder.spec.ts:
--------------------------------------------------------------------------------
1 | import {} from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('Directive cp-attr.placeholder', () => {
5 | it("", () => {
6 | const template = `
7 |
8 | Testing
9 | `;
10 | const element = document.createElement('div');
11 | element.innerHTML = template;
12 | capivara.controller(element, function() {
13 | this.name = 'Test';
14 |
15 | this.test = () => {
16 | this.name = 'Testing';
17 | };
18 |
19 | this.$onViewInit = () => {
20 | const event = new Event('click');
21 | element.querySelector('button').dispatchEvent(event);
22 | setTimeout(() => {
23 | expect(element.querySelector('input').getAttribute('placeholder')).toEqual('Testing');
24 | });
25 | };
26 | });
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/test/spec/capivara-polyfill.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import { Polyfill } from '../../src/core/observer/polyfill';
3 |
4 | describe('test of polyfill methods', () => {
5 | const person = {
6 | name: 'John',
7 | lastName: 'Smith',
8 | };
9 | Polyfill.unWatchProperty(person, 'job');
10 | const keys = Object.keys(person);
11 | it('should unWatchProperty of a object ', function() {
12 | expect(keys.length).toEqual(3);
13 | });
14 | });
15 |
16 | // describe('test of polyfill methods', () => {
17 | // const person = {
18 | // name: 'John',
19 | // lastName: 'Smith',
20 | // };
21 | //
22 | // const someFunc = function() {
23 | // };
24 | //
25 | // Polyfill.setDirtyCheck(person, 1, '');
26 | // it('should setDirtyCheck of a object ', function() {
27 | // expect(person['__observer__']).toEqual(2);
28 | // });
29 | // });
30 |
31 | describe('test of polyfill methods', () => {
32 | const person = {
33 | name: 'John',
34 | lastName: 'Smith',
35 | };
36 |
37 | Polyfill.clearDirtyCheck(person);
38 | it('should setDirtyCheck of a object ', function() {
39 | expect(person['__observer__']).toEqual(undefined);
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/test/spec/capivara-repeat.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of repeat with fixed object', () => {
5 | const template = `
6 | [[person.name]]
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.persons = [
13 | { name: 'John' },
14 | { name: 'Bob' },
15 | { name: 'Anna' },
16 | { name: 'Kyle' },
17 | ];
18 |
19 | $ctrl.$onInit = () => {
20 | it("Expected find 4 children", function(done) {
21 | setTimeout(function() {
22 | expect(element.childElementCount).toEqual($ctrl.persons.length);
23 | done();
24 | });
25 | }, 5000);
26 | };
27 | });
28 | });
29 |
30 | describe('test of repeat with dynamic object', () => {
31 | const template = `
32 | [[person.name]]
33 | Add Carlos
34 | `;
35 | const element = document.createElement('div');
36 | element.innerHTML = template;
37 | capivara.controller(element, function() {
38 | const $ctrl = this;
39 |
40 | $ctrl.persons = [
41 | { name: 'John' },
42 | { name: 'Bob' },
43 | { name: 'Anna' },
44 | { name: 'Kyle' },
45 | ];
46 |
47 | $ctrl.add = function() {
48 | $ctrl.persons.push({ name: 'Carlos' });
49 | };
50 |
51 | $ctrl.$onViewInit = () => {
52 | element.querySelector('button').click();
53 | it("Expected find 5 children", function(done) {
54 | setTimeout(function() {
55 | expect(element.querySelectorAll('h1').length).toEqual($ctrl.persons.length);
56 | done();
57 | });
58 | }, 7000);
59 | };
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/test/spec/capivara-show.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of show with fixed object', () => {
5 | const template = `
6 | Show this
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.isActive = false;
13 |
14 | $ctrl.$onInit = () => {
15 | it("Expected to not find the element", function(done) {
16 | setTimeout(function() {
17 | expect(element.querySelector('h1').style.display).toEqual('none');
18 | done();
19 | });
20 | }, 10000);
21 | };
22 | });
23 | });
24 |
25 | describe('test of show with dynamic object', () => {
26 | const template = `
27 | Show this
28 | `;
29 | const element = document.createElement('div');
30 | element.innerHTML = template;
31 | capivara.controller(element, function() {
32 | const $ctrl = this;
33 | $ctrl.isActive = true;
34 |
35 | $ctrl.$onInit = () => {
36 | it("Expected to not find the element", function(done) {
37 | setTimeout(function() {
38 | expect(element.querySelector('h1').style.display).toEqual('');
39 | done();
40 | });
41 | }, 10000);
42 | };
43 |
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/test/spec/capivara-src.spec.ts:
--------------------------------------------------------------------------------
1 | // import {} from 'jasmine';
2 | // import capivara from '../../src/index';
3 |
4 | // describe('Directive cp-attr.src', () => {
5 |
6 | // it("Should set the src dynamically", function(done) {
7 |
8 | // const template = `
9 | //
10 | // `;
11 | // const element = document.createElement('div');
12 | // element.innerHTML = template;
13 | // capivara.controller(element, function() {
14 | // const $ctrl = this;
15 | // $ctrl.src = 'https://avatars1.githubusercontent.com/u/33517395?s=200&v=4';
16 |
17 | // $ctrl.$onInit = () => {
18 | // setTimeout(function() {
19 | // expect(element.querySelector('img').src).toEqual($ctrl.src);
20 | // done();
21 | // }, 2000);
22 | // };
23 | // });
24 | // });
25 |
26 | // it("Should set the src dynamically", function(done) {
27 |
28 | // const template = `
29 | //
30 | // Click me!
31 | // `;
32 | // const element = document.createElement('div');
33 | // element.innerHTML = template;
34 | // capivara.controller(element, function() {
35 | // const $ctrl = this;
36 | // $ctrl.src = 'https://avatars1.githubusercontent.com/u/33517395?s=200&v=4';
37 |
38 | // $ctrl.click = () => {
39 | // $ctrl.src = 'https://bit.ly/2pTjZnU';
40 | // };
41 |
42 | // $ctrl.$onInit = () => {
43 | // setTimeout(function() {
44 | // element.querySelector('button').click();
45 | // }, 1000);
46 | // setTimeout(function() {
47 | // expect(element.querySelector('img').src).toEqual('https://bit.ly/2pTjZnU');
48 | // done();
49 | // }, 2000);
50 | // };
51 | // });
52 | // });
53 | // });
54 |
--------------------------------------------------------------------------------
/test/spec/capivara-step.spec.ts:
--------------------------------------------------------------------------------
1 | // import { } from 'jasmine';
2 | //
3 | // describe('test of step', () => {
4 | // const template = `
5 | //
6 | // `;
7 | // const element = document.createElement('div');
8 | // element.innerHTML = template;
9 | //
10 | // it("Expected to add the step size on the input value", function(done) {
11 | // setTimeout(function() { element.querySelector('input').click(); }, 500);
12 | // setTimeout(function() {
13 | // expect(element.querySelector('input').value).toEqual('3');
14 | // done();
15 | // }, 1000);
16 | // setTimeout(function() { element.querySelector('input').click(); }, 1500);
17 | // setTimeout(function() {
18 | // expect(element.querySelector('input').value).toEqual('6');
19 | // done();
20 | // }, 2000);
21 | // });
22 | // });
23 |
--------------------------------------------------------------------------------
/test/spec/capivara-style.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('test of style with fixed object', () => {
5 | const template = `
6 | Sample HTML text
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | const $ctrl = this;
12 | $ctrl.activeStyle = 'red';
13 |
14 | $ctrl.$onInit = () => {
15 | it('Expected to add the style', () => {
16 | expect(element.querySelector('h1').style.background).toEqual('red');
17 | });
18 | };
19 | });
20 | });
21 |
22 | describe('test of style with dynamic object', () => {
23 | const template = `
24 | String of test
25 | `;
26 | const element = document.createElement('div');
27 | element.innerHTML = template;
28 | capivara.controller(element, function() {
29 | const $ctrl = this;
30 | $ctrl.backGround = 'red';
31 | $ctrl.fontColor = 'blue';
32 | $ctrl.sizeFont = '20px';
33 |
34 | $ctrl.getStyle = () => {
35 | return {
36 | ['background-color']: $ctrl.backGround,
37 | [' color: ']: $ctrl.fontColor,
38 | ['font-size']: $ctrl.sizeFont,
39 | };
40 | };
41 |
42 | $ctrl.$onInit = () => {
43 | it("Expected to add the style", function(done) {
44 | setTimeout(function() {
45 | expect(element.querySelector('h1').style.backgroundColor).toEqual('red');
46 | done();
47 | });
48 | });
49 | };
50 | });
51 | });
52 |
53 | describe('test of style with dynamic object', () => {
54 | const template = `
55 | Sample HTML text
56 | Click me!
57 | `;
58 | const element = document.createElement('div');
59 | element.innerHTML = template;
60 | capivara.controller(element, function() {
61 | const $ctrl = this;
62 | $ctrl.color = 'blue';
63 |
64 | $ctrl.click = () => {
65 | $ctrl.color = 'red';
66 | };
67 |
68 | $ctrl.$onInit = () => {
69 | it("Expected to add the style", function(done) {
70 | setTimeout(function() { element.querySelector('button').click(); }, 1000);
71 | setTimeout(function() {
72 | expect(element.querySelector('h1').style.background).toEqual('red');
73 | done();
74 | }, 2000);
75 | });
76 | };
77 | });
78 | });
79 |
--------------------------------------------------------------------------------
/test/spec/capivara-title.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import capivara from '../../src/index';
3 |
4 | describe('Directive cp-attr.tittle', () => {
5 | const template = `
6 | test
7 | `;
8 | const element = document.createElement('div');
9 | element.innerHTML = template;
10 | capivara.controller(element, function() {
11 | this.var = 'test1';
12 |
13 | this.$onViewInit = () => {
14 | it('expect the element title = test1 be found', (done) => {
15 | expect(element.querySelector('h1').getAttribute("title")).toEqual('test1');
16 | done();
17 | });
18 | };
19 |
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/test/spec/capivara-util.spec.ts:
--------------------------------------------------------------------------------
1 | import { } from 'jasmine';
2 | import { Util } from '../../src/core/observer/util';
3 |
4 | describe('Tests of the util methods', () => {
5 | const a = [1, 2, 3, 4, 5, 6, 7];
6 | const b = [1, 2, 3, 9];
7 |
8 | const result = Util.diff(a, b);
9 | it('should return added elements', function() {
10 | expect(result.added).toEqual(['9']);
11 | });
12 |
13 | it('should return deleted elements', function() {
14 | expect(result.deleted).toEqual(['4', '5', '6', '7']);
15 | });
16 |
17 | it('should return all the common elements on the array', function() {
18 | expect(result.all).toEqual(['4', '5', '6', '7', '9']);
19 | });
20 | });
21 |
22 | describe('Tests of the util methods', () => {
23 | const a = ['1', '2', '3', '4', '5', '6', '7'];
24 | const b = ['1', '2', '3', '9'];
25 |
26 | const firstResult = Util.compare(a, b);
27 | it('should return the comparison are false', function() {
28 | expect(firstResult).toEqual(false);
29 | });
30 |
31 | const c = ['1', '2', '3', '4', '5', '6', '7'];
32 | const d = ['1', '3', '2', '4', '5', '6', '7'];
33 |
34 | const secondResult = Util.compare(c, d);
35 | it('should return the comparison are false', function() {
36 | expect(secondResult).toEqual(false);
37 | });
38 |
39 | const thirdResult = Util.compare(c, a);
40 | it('should return the comparison are true', function() {
41 | expect(thirdResult).toEqual(true);
42 | });
43 |
44 | });
45 |
46 | describe('Tests of the util methods', () => {
47 | const person = {
48 | name: 'John',
49 | lastName: 'Smith',
50 | };
51 | const getKeys = Util.keys(person);
52 |
53 | it('should return the keys of the object', function() {
54 | expect(getKeys).toEqual(["name", "lastName"]);
55 | });
56 | });
57 |
58 | describe('Tests of the util methods', () => {
59 | const person = {
60 | name: 'John',
61 | lastName: 'Smith',
62 | };
63 | const otherPerson = Util.clone(person);
64 | it('should return true if the objects are equal', function() {
65 | expect(Util.keys(otherPerson)).toEqual(Util.keys(person));
66 | });
67 | });
68 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "allowSyntheticDefaultImports": true,
5 | "declaration": false,
6 | "types": ["node"],
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "lib": [
10 | "dom",
11 | "es2015"
12 | ],
13 | "module": "es2015",
14 | "moduleResolution": "node",
15 | "target": "es5"
16 | },
17 | "include": [
18 | "src/**/*.ts"
19 | ],
20 | "globals": {
21 | "require": true
22 | },
23 | "exclude": [
24 | "node_modules"
25 | ],
26 | "compileOnSave": false,
27 | "atom": {
28 | "rewriteTsconfig": false
29 | }
30 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "error",
3 | "extends": [
4 | "tslint:recommended"
5 | ],
6 | "jsRules": {},
7 | "rules": {
8 | "only-arrow-functions": false,
9 | "no-var-requires": false,
10 | "no-string-literal": false,
11 | "no-console": false,
12 | "object-literal-sort-keys": false,
13 | "max-line-length": [false],
14 | "quotemark": ["single"],
15 | "variable-name": ["allow-leading-underscore"],
16 | "no-empty": false,
17 | "jsdoc-format": false,
18 | "member-ordering": false,
19 | "interface-name": [true, "never-prefix"],
20 | "no-namespace": false,
21 | "no-eval": false,
22 | "one-variable-per-declaration": false,
23 | "no-conditional-assignment": false,
24 | "no-unused-expression": [false]
25 | },
26 | "rulesDirectory": []
27 | }
28 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015-rollup"]
3 | }
4 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .DS_Store
3 | yarn-error.log
4 | test/reports
5 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 wi2
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## webpack-nightwatch-plugin
3 |
4 |
5 | #### NightWatch config
6 | ```
7 | //test/nightwatch.conf.js
8 |
9 | var selenium = require('selenium-server-standalone-jar');
10 | var chromedriver = require('chromedriver');
11 |
12 | module.exports = {
13 | src_folders: ['./test/ui'],
14 | output_folder: './test/reports',
15 | selenium: {
16 | start_process: true,
17 | server_path: selenium.path,
18 | log_path: './test/reports',
19 | cli_args: {
20 | 'webdriver.chrome.driver': chromedriver.path,
21 | 'webdriver.ie.driver': ''
22 | }
23 | },
24 | test_settings: {
25 | default: {
26 | launch_url: 'http://localhost:8080/',
27 | selenium_port: 4444,
28 | selenium_host: 'localhost',
29 | desiredCapabilities: {
30 | browserName: 'chrome',
31 | javascriptEnabled: true,
32 | acceptSslCerts: true
33 | },
34 | }
35 | },
36 | "chrome" : {
37 | "desiredCapabilities" : {
38 | "browserName" : "chrome",
39 | "chromeOptions" : {
40 | "args" : [
41 | "use-fake-device-for-media-stream",
42 | "use-fake-ui-for-media-stream"
43 | ]
44 | }
45 | }
46 | }
47 | };
48 | ```
49 |
50 | #### Webpack config
51 | ```
52 | //webpack.config.js
53 |
54 | config.plugins.push(
55 | new WebpackNightWatchPlugin({
56 | url: './test/nightwatch.conf.js'
57 | })
58 | )
59 | ```
60 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/index.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import {spawn, spawnSync} from 'child_process'
3 |
4 | export default class WebpackNightWatchPlugin {
5 |
6 | constructor(options = {}) {
7 | const defaultOptions = {
8 | onEmit: false
9 | }
10 | this.options = Object.assign({}, defaultOptions, options)
11 | }
12 |
13 | apply(compiler) {
14 |
15 | compiler.plugin('compilation', (compilation) => {
16 | spawnSync('pkill', ['-f', 'selenium'])
17 | })
18 |
19 | compiler.plugin(this.options.onEmit ? 'emit' : 'done', (compilation, callback) => {
20 | const env = Object.assign({}, process.env, {LANG: 'en_US.UTF-8'});
21 | console.log(__dirname)
22 | const nightwatch = spawn(path.join(__dirname, '../node_modules/.bin/nightwatch'), [
23 | '-c',
24 | this.options.url
25 | ], {env})
26 |
27 | nightwatch.stdout.on('data', data => {
28 | process.stdout.write(data.toString())
29 | })
30 |
31 | nightwatch.stderr.on('data', data => {
32 | process.stdout.write(data.toString())
33 | })
34 |
35 | nightwatch.on('close', () => {
36 | if (this.options.onEmit) callback()
37 | spawnSync('pkill', ['-f', 'selenium'])
38 | })
39 | })
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "_from": "webpack-nightwatch-plugin",
3 | "_id": "webpack-nightwatch-plugin@1.0.0",
4 | "_inBundle": false,
5 | "_integrity": "sha1-xatQte+SyDHi406R1TZhf2tra40=",
6 | "_location": "/webpack-nightwatch-plugin",
7 | "_phantomChildren": {},
8 | "_requested": {
9 | "type": "tag",
10 | "registry": true,
11 | "raw": "webpack-nightwatch-plugin",
12 | "name": "webpack-nightwatch-plugin",
13 | "escapedName": "webpack-nightwatch-plugin",
14 | "rawSpec": "",
15 | "saveSpec": null,
16 | "fetchSpec": "latest"
17 | },
18 | "_requiredBy": [
19 | "#DEV:/",
20 | "#USER"
21 | ],
22 | "_resolved": "https://registry.npmjs.org/webpack-nightwatch-plugin/-/webpack-nightwatch-plugin-1.0.0.tgz",
23 | "_shasum": "c5ab50b5ef92c831e2e34e91d536617f6b6b6b8d",
24 | "_spec": "webpack-nightwatch-plugin",
25 | "_where": "/home/mateus/capivara/capivarajs",
26 | "author": {
27 | "name": "Mike wi2"
28 | },
29 | "bugs": {
30 | "url": "https://github.com/wi2/webpack-nightwatch-plugin/issues"
31 | },
32 | "bundleDependencies": false,
33 | "dependencies": {
34 | "child_process": "^1.0.2",
35 | "nightwatch": "^0.9.8"
36 | },
37 | "deprecated": false,
38 | "description": "Webpack plugin, Browser Automation with Nightwatch.js",
39 | "devDependencies": {
40 | "ava": "^0.16.0",
41 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
42 | "babel-plugin-transform-runtime": "^6.15.0",
43 | "babel-preset-es2015": "^6.18.0",
44 | "babel-preset-es2015-rollup": "^1.2.0",
45 | "chromedriver": "^2.24.1",
46 | "rollup-plugin-babel": "^2.6.1",
47 | "rollup-plugin-json": "^2.0.2",
48 | "selenium-server-standalone-jar": "^3.0.1",
49 | "webpack": "^1.13.3"
50 | },
51 | "homepage": "https://github.com/wi2/webpack-nightwatch-plugin#readme",
52 | "keywords": [
53 | "webpack",
54 | "plugin",
55 | "Nightwatch"
56 | ],
57 | "license": "MIT",
58 | "main": "lib/index.js",
59 | "name": "webpack-nightwatch-plugin",
60 | "repository": {
61 | "type": "git",
62 | "url": "git+ssh://git@github.com/wi2/webpack-nightwatch-plugin.git"
63 | },
64 | "scripts": {
65 | "build": "rollup -c",
66 | "test": "npm run build && ava -v test/*.spec.js"
67 | },
68 | "version": "1.0.0"
69 | }
70 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel';
2 |
3 | export default {
4 | entry: 'index.js',
5 | format: 'cjs',
6 | plugins: [
7 | babel()
8 | ],
9 | dest: 'lib/index.js'
10 | };
11 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/test/index.spec.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import webpack from 'webpack'
3 | import WebpackNightWatchPlugin from '../lib/index'
4 |
5 | const webpackConfig = {
6 | plugins: [
7 | new WebpackNightWatchPlugin({
8 | onEmit: true,
9 | url: './nightwatch.conf.js'
10 | })
11 | ]
12 | }
13 |
14 | test('webpack', async t => {
15 | const promise = new Promise((resolve, reject) => {
16 | webpack(webpackConfig, (err, stats) => {
17 | if (err || stats.hasErrors()) {
18 | reject(err)
19 | }
20 | resolve(typeof stats)
21 | })
22 | })
23 | t.is(await promise, 'object')
24 | })
25 |
26 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/test/nightwatch.conf.js:
--------------------------------------------------------------------------------
1 | var selenium = require('selenium-server-standalone-jar');
2 | var chromedriver = require('chromedriver');
3 |
4 | module.exports = {
5 | src_folders: ['ui'],
6 | output_folder: 'reports',
7 | selenium: {
8 | start_process: true,
9 | server_path: selenium.path,
10 | log_path: 'reports',
11 | cli_args: {
12 | 'webdriver.chrome.driver': chromedriver.path,
13 | 'webdriver.ie.driver': ''
14 | }
15 | },
16 | test_settings: {
17 | default: {
18 | launch_url: 'https://google.fr/',
19 | selenium_port: 4444,
20 | selenium_host: 'localhost',
21 | desiredCapabilities: {
22 | browserName: 'chrome',
23 | javascriptEnabled: true,
24 | acceptSslCerts: true
25 | },
26 | }
27 | },
28 | "chrome" : {
29 | "desiredCapabilities" : {
30 | "browserName" : "chrome",
31 | "chromeOptions" : {
32 | "args" : [
33 | "use-fake-device-for-media-stream",
34 | "use-fake-ui-for-media-stream"
35 | ]
36 | }
37 | }
38 | }
39 | };
40 |
--------------------------------------------------------------------------------
/webpack-nightwatch-plugin/test/ui/ui.nightwatch.js:
--------------------------------------------------------------------------------
1 | const timer = 2500
2 | const wait = 1000
3 |
4 | module.exports = {
5 | after: browser => {
6 | console.log('Closing down...')
7 | browser.end()
8 | },
9 |
10 | 'should be able to init a session': browser => {
11 | browser
12 | .url(browser.launch_url)
13 | .waitForElementVisible('body', timer);
14 | },
15 |
16 | 'should be able to see body': browser => {
17 | browser.assert.elementPresent('body');
18 | },
19 |
20 | 'should be equal to https://www.google.fr/': browser => {
21 | browser.assert.urlEquals('https://www.google.fr/');
22 | },
23 | }
24 |
--------------------------------------------------------------------------------