├── .editorconfig ├── .eslintrc ├── .gitattributes ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE.md ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gruntfile.js ├── LICENSE ├── README.md ├── dist ├── ui-bootstrap-csp.css ├── ui-bootstrap-tpls.js ├── ui-bootstrap.js └── versions-mapping.json ├── docs ├── assets │ ├── app.js │ ├── demo.css │ ├── favicon.ico │ ├── github-16px.png │ ├── header.png │ ├── img │ │ ├── glyphicons-halflings-white.png │ │ └── glyphicons-halflings.png │ ├── module-mapping.json │ ├── plunker.js │ ├── rainbow-generic.js │ ├── rainbow-html.js │ ├── rainbow-javascript.js │ ├── rainbow.css │ ├── rainbow.js │ ├── raw-files.json │ ├── smoothscroll-angular-custom.js │ └── uglifyjs.js ├── index.html ├── ui-bootstrap-2.5.0-csp.css ├── ui-bootstrap-2.5.0.js ├── ui-bootstrap-3.0.0-csp.css ├── ui-bootstrap-3.0.0.js ├── ui-bootstrap-3.0.0.min.js ├── ui-bootstrap-3.0.1-csp.css ├── ui-bootstrap-3.0.1.js ├── ui-bootstrap-3.0.1.min.js ├── ui-bootstrap-3.0.2-csp.css ├── ui-bootstrap-3.0.2.js ├── ui-bootstrap-3.0.2.min.js ├── ui-bootstrap-3.0.3-csp.css ├── ui-bootstrap-3.0.3.js ├── ui-bootstrap-3.0.3.min.js ├── ui-bootstrap-3.0.4-csp.css ├── ui-bootstrap-3.0.4.js ├── ui-bootstrap-3.0.4.min.js ├── ui-bootstrap-3.0.5-csp.css ├── ui-bootstrap-3.0.5.js ├── ui-bootstrap-3.0.5.min.js ├── ui-bootstrap-3.0.6-csp.css ├── ui-bootstrap-3.0.6.js ├── ui-bootstrap-3.0.6.min.js ├── ui-bootstrap-csp.css ├── ui-bootstrap-tpls-2.5.0.js ├── ui-bootstrap-tpls-3.0.0.js ├── ui-bootstrap-tpls-3.0.0.min.js ├── ui-bootstrap-tpls-3.0.1.js ├── ui-bootstrap-tpls-3.0.1.min.js ├── ui-bootstrap-tpls-3.0.2.js ├── ui-bootstrap-tpls-3.0.2.min.js ├── ui-bootstrap-tpls-3.0.3.js ├── ui-bootstrap-tpls-3.0.3.min.js ├── ui-bootstrap-tpls-3.0.4.js ├── ui-bootstrap-tpls-3.0.4.min.js ├── ui-bootstrap-tpls-3.0.5.js ├── ui-bootstrap-tpls-3.0.5.min.js ├── ui-bootstrap-tpls-3.0.6.js ├── ui-bootstrap-tpls-3.0.6.min.js ├── ui-bootstrap-tpls.js ├── ui-bootstrap.js ├── versioned-docs │ ├── 2.5.0 │ │ ├── assets │ │ │ ├── app.js │ │ │ ├── demo.css │ │ │ ├── favicon.ico │ │ │ ├── github-16px.png │ │ │ ├── header.png │ │ │ ├── img │ │ │ │ ├── glyphicons-halflings-white.png │ │ │ │ └── glyphicons-halflings.png │ │ │ ├── module-mapping.json │ │ │ ├── plunker.js │ │ │ ├── rainbow-generic.js │ │ │ ├── rainbow-html.js │ │ │ ├── rainbow-javascript.js │ │ │ ├── rainbow.css │ │ │ ├── rainbow.js │ │ │ ├── raw-files.json │ │ │ ├── smoothscroll-angular-custom.js │ │ │ └── uglifyjs.js │ │ ├── index.html │ │ ├── ui-bootstrap-2.5.0-csp.css │ │ ├── ui-bootstrap-2.5.0.js │ │ ├── ui-bootstrap-2.5.0.min.js │ │ ├── ui-bootstrap-tpls-2.5.0.js │ │ └── ui-bootstrap-tpls-2.5.0.min.js │ └── 3.0.5 │ │ ├── assets │ │ ├── app.js │ │ ├── demo.css │ │ ├── favicon.ico │ │ ├── github-16px.png │ │ ├── header.png │ │ ├── img │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ ├── module-mapping.json │ │ ├── plunker.js │ │ ├── rainbow-generic.js │ │ ├── rainbow-html.js │ │ ├── rainbow-javascript.js │ │ ├── rainbow.css │ │ ├── rainbow.js │ │ ├── raw-files.json │ │ ├── smoothscroll-angular-custom.js │ │ └── uglifyjs.js │ │ ├── index.html │ │ ├── ui-bootstrap-3.0.5-csp.css │ │ ├── ui-bootstrap-3.0.5.js │ │ ├── ui-bootstrap-3.0.5.min.js │ │ ├── ui-bootstrap-tpls-3.0.5.js │ │ └── ui-bootstrap-tpls-3.0.5.min.js └── versions-mapping.json ├── index.js ├── karma.conf.js ├── misc ├── changelog.tpl.md ├── demo │ ├── assets │ │ ├── app.js │ │ ├── demo.css │ │ ├── favicon.ico │ │ ├── github-16px.png │ │ ├── header.png │ │ ├── img │ │ │ ├── glyphicons-halflings-white.png │ │ │ └── glyphicons-halflings.png │ │ ├── plunker.js │ │ ├── rainbow-generic.js │ │ ├── rainbow-html.js │ │ ├── rainbow-javascript.js │ │ ├── rainbow.css │ │ ├── rainbow.js │ │ ├── smoothscroll-angular-custom.js │ │ └── uglifyjs.js │ └── index.html ├── raw-files-generator.js ├── test-lib │ ├── helpers.js │ └── jquery-1.8.2.min.js └── validate-commit-msg.js ├── package-lock.json ├── package.json ├── src ├── accordion │ ├── accordion.js │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ └── test │ │ └── accordion.spec.js ├── alert │ ├── alert.js │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ └── test │ │ └── alert.spec.js ├── buttons │ ├── buttons.js │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ └── test │ │ └── buttons.spec.js ├── carousel │ ├── carousel.css │ ├── carousel.js │ ├── docs │ │ ├── README.md │ │ ├── demo.html │ │ └── demo.js │ ├── index-nocss.js │ ├── index.js │ └── test │ │ └── carousel.spec.js ├── collapse │ ├── collapse.js │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ └── test │ │ ├── collapse.spec.js │ │ └── collapseHorizontally.spec.js ├── common │ ├── common.js │ ├── index-nocss.js │ ├── index.js │ └── svg-icon.css ├── dateparser │ ├── dateparser.js │ ├── docs │ │ ├── README.md │ │ ├── demo.html │ │ └── demo.js │ ├── index.js │ └── test │ │ └── dateparser.spec.js ├── datepicker │ ├── datepicker.css │ ├── datepicker.js │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ └── test │ │ └── datepicker.spec.js ├── datepickerPopup │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── popup.css │ ├── popup.js │ └── test │ │ └── popup.spec.js ├── debounce │ ├── debounce.js │ ├── index.js │ └── test │ │ └── debounce.spec.js ├── dropdown │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── dropdown.js │ ├── index-nocss.js │ ├── index.js │ └── test │ │ └── dropdown.spec.js ├── isClass │ ├── index.js │ ├── isClass.js │ └── test │ │ └── isClass.spec.js ├── modal │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── modal.js │ └── test │ │ └── modal.spec.js ├── multiMap │ ├── index.js │ ├── multiMap.js │ └── test │ │ └── multiMap.spec.js ├── pager │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ ├── pager.js │ └── test │ │ └── pager.spec.js ├── pagination │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ ├── pagination.js │ └── test │ │ └── pagination.spec.js ├── paging │ ├── index.js │ ├── paging.js │ └── test │ │ └── paging.spec.js ├── popover │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── popover.js │ └── test │ │ ├── popover-html.spec.js │ │ ├── popover-template.spec.js │ │ └── popover.spec.js ├── position │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── position.css │ ├── position.js │ └── test │ │ ├── position.spec.js │ │ └── test.html ├── progressbar │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ ├── progressbar.js │ └── test │ │ └── progressbar.spec.js ├── rating │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── rating.js │ └── test │ │ └── rating.spec.js ├── stackedMap │ ├── index.js │ ├── stackedMap.js │ └── test │ │ └── stackedMap.spec.js ├── tabindex │ ├── index.js │ ├── tabindex.js │ └── test │ │ └── tabindex.spec.js ├── tabs │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index.js │ ├── tabs.js │ └── test │ │ └── tabs.spec.js ├── timepicker │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── test │ │ └── timepicker.spec.js │ ├── timepicker.css │ └── timepicker.js ├── tooltip │ ├── docs │ │ ├── demo.html │ │ ├── demo.js │ │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── test │ │ ├── tooltip-template.spec.js │ │ ├── tooltip.spec.js │ │ └── tooltip2.spec.js │ ├── tooltip.css │ └── tooltip.js └── typeahead │ ├── docs │ ├── demo.html │ ├── demo.js │ └── readme.md │ ├── index-nocss.js │ ├── index.js │ ├── test │ ├── typeahead-highlight-ngsanitize.spec.js │ ├── typeahead-highlight.spec.js │ ├── typeahead-parser.spec.js │ ├── typeahead-popup.spec.js │ └── typeahead.spec.js │ ├── typeahead.css │ └── typeahead.js ├── template ├── accordion │ ├── accordion-group.html │ └── accordion.html ├── alert │ └── alert.html ├── carousel │ ├── carousel.html │ └── slide.html ├── datepicker │ ├── datepicker.html │ ├── day.html │ ├── month.html │ └── year.html ├── datepickerPopup │ └── popup.html ├── modal │ └── window.html ├── pager │ └── pager.html ├── pagination │ └── pagination.html ├── popover │ ├── popover-html.html │ ├── popover-template.html │ └── popover.html ├── progressbar │ ├── bar.html │ ├── progress.html │ └── progressbar.html ├── rating │ └── rating.html ├── tabs │ ├── tab.html │ └── tabset.html ├── timepicker │ └── timepicker.html ├── tooltip │ ├── tooltip-html-popup.html │ ├── tooltip-popup.html │ └── tooltip-template-popup.html └── typeahead │ ├── typeahead-match.html │ └── typeahead-popup.html └── ui-bootstrap4 /.editorconfig: -------------------------------------------------------------------------------- 1 | # This project uses EditorConfig for setting code formatting options: http://EditorConfig.org 2 | 3 | root = true 4 | 5 | # Default settings for all files 6 | [*] 7 | charset = utf-8 8 | end_of_line = lf 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = tab 12 | indent_size = tab 13 | tab_width = 4 14 | max_line_length = 120 15 | 16 | spaces_around_operators = true 17 | spaces_around_brackets = none 18 | curly_bracket_next_line = true 19 | indent_brace_style = Allman 20 | continuation_indent_size = 4 21 | 22 | [*.{css,less}] 23 | curly_bracket_next_line = false 24 | continuation_indent_size = 0 25 | 26 | # Formats likely to be pasted into an REPL on a terminal should not use tabs to avoid triggering tab-completion. 27 | [*.{sh,bash,sql,psql,pgsql}] 28 | indent_style = space 29 | indent_size = 4 30 | 31 | [*.yml] 32 | indent_style = space 33 | indent_size = 2 34 | 35 | [*.{js,json}] 36 | indent_style = space 37 | indent_size = 4 38 | 39 | # Special overrides for automatically-generated files 40 | [package.json] 41 | indent_size = 2 42 | 43 | # For some formats, trailing whitespace is significant; don't strip it. 44 | [*.{md,diff,patch}] 45 | trim_trailing_whitespace = false 46 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true 5 | }, 6 | "rules": { 7 | "comma-dangle": 2, 8 | "no-cond-assign": 2, 9 | "no-control-regex": 2, 10 | "no-debugger": 2, 11 | "no-dupe-args": 2, 12 | "no-dupe-keys": 2, 13 | "no-duplicate-case": 2, 14 | "no-empty-character-class": 2, 15 | "no-empty": 2, 16 | "no-ex-assign": 2, 17 | "no-extra-boolean-cast": 2, 18 | "no-extra-parens": 2, 19 | "no-extra-semi": 2, 20 | "no-func-assign": 2, 21 | "no-inner-declarations": 2, 22 | "no-invalid-regexp": 2, 23 | "no-negated-in-lhs": 2, 24 | "no-regex-spaces": 2, 25 | "no-sparse-arrays": 2, 26 | "no-unexpected-multiline": 2, 27 | "no-unreachable": 2, 28 | "valid-typeof": 2, 29 | "accessor-pairs": 2, 30 | "block-scoped-var": 2, 31 | "complexity": 2, 32 | "curly": 2, 33 | "dot-notation": [2, {"allowKeywords": false}], 34 | "eqeqeq": 2, 35 | "guard-for-in": 2, 36 | "semi": 2, 37 | "no-alert": 2, 38 | "no-caller": 2, 39 | "no-case-declarations": 2, 40 | "no-div-regex": 2, 41 | "no-else-return": 2, 42 | "no-empty-label": 2, 43 | "no-empty-pattern": 2, 44 | "no-eq-null": 2, 45 | "no-eval": 2, 46 | "no-extend-native": 2, 47 | "no-extra-bind": 2, 48 | "no-floating-decimal": 2, 49 | "no-implied-eval": 2, 50 | "no-invalid-this": 2, 51 | "no-iterator": 2, 52 | "no-lone-blocks": 2, 53 | "no-loop-func": 2, 54 | "no-multi-spaces": 2, 55 | "no-native-reassign": 2, 56 | "no-new-func": 2, 57 | "no-new-wrappers": 2, 58 | "no-new": 2, 59 | "no-octal-escape": 2, 60 | "no-octal": 2, 61 | "no-proto": 2, 62 | "no-redeclare": 2, 63 | "no-script-url": 2, 64 | "no-self-compare": 2, 65 | "no-sequences": 2, 66 | "no-throw-literal": 2, 67 | "no-unused-expressions": 2, 68 | "no-useless-call": 2, 69 | "no-useless-concat": 2, 70 | "no-void": 2, 71 | "no-with": 2, 72 | "radix": 2, 73 | "wrap-iife": 2, 74 | "yoda": 2 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html eol=lf 2 | *.css eol=lf 3 | *.js eol=lf 4 | *.md eol=lf 5 | *.json eol=lf 6 | *.yml eol=lf 7 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | open_collective: morgul 4 | issuehunt: morgul 5 | custom: https://www.paypal.me/morgul 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | The issues forum is __NOT__ for support requests. It is for bugs and feature requests only. 2 | Please read https://github.com/angular-ui/bootstrap/blob/master/CONTRIBUTING.md and search 3 | existing issues (both open and closed) prior to opening any new issue and ensure you follow the instructions therein. 4 | 5 | ### Bug description: 6 | 7 | ### Link to minimally-working plunker that reproduces the issue: 8 | 9 | ### Steps to reproduce the issue: 10 | 11 | ### Version of Angular, UIBS, and Bootstrap 12 | 13 | Angular: 14 | 15 | UIBS: 16 | 17 | Bootstrap: 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | *.swp 10 | *.swo 11 | .DS_Store 12 | .idea 13 | 14 | pids 15 | logs 16 | results 17 | # dist 18 | # test coverage files 19 | .coverage/ 20 | 21 | node_modules 22 | npm-debug.log 23 | 24 | template/**/*.js 25 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "immed": true, 4 | "newcap": true, 5 | "noarg": true, 6 | "sub": true, 7 | "boss": true, 8 | "eqnull": true, 9 | "quotmark": "single", 10 | "trailing": true, 11 | "undef": true, 12 | "browser": true, 13 | "jquery": true, 14 | "globals": { 15 | "angular": false, 16 | 17 | // For Jasmine 18 | "after" : false, 19 | "afterEach" : false, 20 | "before" : false, 21 | "beforeEach" : false, 22 | "describe" : false, 23 | "expect" : false, 24 | "jasmine" : false, 25 | "module" : false, 26 | "spyOn" : false, 27 | "inject" : false, 28 | "it" : false 29 | } 30 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | *.swp 10 | *.swo 11 | .DS_Store 12 | 13 | pids 14 | logs 15 | results 16 | # test coverage files 17 | .coverage/ 18 | 19 | node_modules 20 | npm-debug.log 21 | 22 | .git 23 | docs 24 | misc 25 | .editorconfig 26 | .gitattributes 27 | .gitignore 28 | .jshintrc 29 | .travis.yml 30 | CONTRIBUTING.md 31 | Gruntfile.js 32 | karma.conf.js 33 | ROADMAP.md 34 | 35 | dist/assets 36 | dist/index.html 37 | dist/versions-mapping.json 38 | dist/*-SNAPSHOT* 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | dist: xenial 3 | node_js: 4 | - 10 5 | env: 6 | - CXX=g++-4.8 7 | addons: 8 | apt: 9 | sources: 10 | - ubuntu-toolchain-r-test 11 | packages: 12 | - g++-4.8 13 | 14 | before_install: 15 | - npm install --quiet -g karma 16 | 17 | script: xvfb-run grunt 18 | sudo: false 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. 6 | 7 | Examples of unacceptable behavior by participants include: 8 | 9 | * The use of sexualized language or imagery 10 | * Personal attacks 11 | * Trolling or insulting/derogatory comments 12 | * Public or private harassment 13 | * Publishing other's private information, such as physical or electronic addresses, without explicit permission 14 | * Other unethical or unprofessional conduct. 15 | 16 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. 17 | 18 | This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 21 | 22 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012-2017 the AngularUI Team, https://github.com/organizations/angular-ui/teams/291112 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 13 | all 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 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /dist/versions-mapping.json: -------------------------------------------------------------------------------- 1 | [{"version":"3.0.x (Current)","url":"/ui-bootstrap4/"}, {"version":"3.0.5","url":"/ui-bootstrap4/versioned-docs/3.0.5/index.html"}, {"version":"2.5.0","url":"/ui-bootstrap4/versioned-docs/2.5.0/index.html"}] 2 | -------------------------------------------------------------------------------- /docs/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/assets/favicon.ico -------------------------------------------------------------------------------- /docs/assets/github-16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/assets/github-16px.png -------------------------------------------------------------------------------- /docs/assets/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/assets/header.png -------------------------------------------------------------------------------- /docs/assets/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/assets/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/assets/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/assets/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/assets/plunker.js: -------------------------------------------------------------------------------- 1 | angular.module('plunker', []) 2 | 3 | .factory('plunkGenerator', function ($document) { 4 | 5 | return function (ngVersion, bsVersion, version, module, content) { 6 | 7 | var form = angular.element('
'); 8 | var addField = function (name, value) { 9 | var input = angular.element(''); 10 | input.attr('value', value); 11 | form.append(input); 12 | }; 13 | 14 | var indexContent = function (content, version) { 15 | return '\n' + 16 | '\n' + 17 | ' \n' + 18 | ' \n' + 19 | ' \n' + 20 | ' \n' + 21 | ' \n' + 22 | ' \n' + 23 | ' \n' + 24 | ' \n' + 25 | ' \n\n' + 26 | content + '\n' + 27 | ' \n' + 28 | '\n'; 29 | }; 30 | 31 | var scriptContent = function(content) { 32 | return "angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);" + "\n" + content; 33 | }; 34 | 35 | addField('description', 'http://angular-ui.github.io/bootstrap/'); 36 | addField('files[index.html]', indexContent(content.markup, version)); 37 | addField('files[example.js]', scriptContent(content.javascript)); 38 | 39 | $document.find('body').append(form); 40 | form[0].submit(); 41 | form.remove(); 42 | }; 43 | }) 44 | 45 | .controller('PlunkerCtrl', function ($scope, plunkGenerator) { 46 | 47 | $scope.content = {}; 48 | 49 | $scope.edit = function (ngVersion, bsVersion, version, module) { 50 | plunkGenerator(ngVersion, bsVersion, version, module, $scope.content); 51 | }; 52 | }) 53 | 54 | .directive('plunkerContent', function () { 55 | return { 56 | link:function (scope, element, attrs) { 57 | scope.content[attrs.plunkerContent] = element.text().trim(); 58 | } 59 | } 60 | }); 61 | -------------------------------------------------------------------------------- /docs/assets/rainbow-generic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic language patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.9 6 | */ 7 | Rainbow.extend([ 8 | { 9 | 'matches': { 10 | 1: { 11 | 'name': 'keyword.operator', 12 | 'pattern': /\=/g 13 | }, 14 | 2: { 15 | 'name': 'string', 16 | 'matches': { 17 | 'name': 'constant.character.escape', 18 | 'pattern': /\\('|"){1}/g 19 | } 20 | } 21 | }, 22 | 'pattern': /(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm 23 | }, 24 | { 25 | 'name': 'comment', 26 | 'pattern': /\/\*[\s\S]*?\*\/|(\/\/|\#)[\s\S]*?$/gm 27 | }, 28 | { 29 | 'name': 'constant.numeric', 30 | 'pattern': /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi 31 | }, 32 | { 33 | 'matches': { 34 | 1: 'keyword' 35 | }, 36 | 'pattern': /\b(and|array|as|bool(ean)?|c(atch|har|lass|onst)|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\(|\b)/gi 37 | }, 38 | { 39 | 'name': 'constant.language', 40 | 'pattern': /true|false|null/g 41 | }, 42 | { 43 | 'name': 'keyword.operator', 44 | 'pattern': /\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g 45 | }, 46 | { 47 | 'matches': { 48 | 1: 'function.call' 49 | }, 50 | 'pattern': /(\w+?)(?=\()/g 51 | }, 52 | { 53 | 'matches': { 54 | 1: 'storage.function', 55 | 2: 'entity.name.function' 56 | }, 57 | 'pattern': /(function)\s(.*?)(?=\()/g 58 | } 59 | ]); 60 | -------------------------------------------------------------------------------- /docs/assets/rainbow-html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * HTML patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('html', [ 8 | { 9 | 'name': 'source.php.embedded', 10 | 'matches': { 11 | 2: { 12 | 'language': 'php' 13 | } 14 | }, 15 | 'pattern': /<\?=?(?!xml)(php)?([\s\S]*?)(\?>)/gm 16 | }, 17 | { 18 | 'name': 'source.css.embedded', 19 | 'matches': { 20 | 0: { 21 | 'language': 'css' 22 | } 23 | }, 24 | 'pattern': /<style(.*?)>([\s\S]*?)<\/style>/gm 25 | }, 26 | { 27 | 'name': 'source.js.embedded', 28 | 'matches': { 29 | 0: { 30 | 'language': 'javascript' 31 | } 32 | }, 33 | 'pattern': /<script(?! src)(.*?)>([\s\S]*?)<\/script>/gm 34 | }, 35 | { 36 | 'name': 'comment.html', 37 | 'pattern': /<\!--[\S\s]*?-->/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.open', 42 | 2: 'support.tag.cclose' 43 | }, 44 | 'pattern': /(<)|(\/?\??>)/g 45 | }, 46 | { 47 | 'name': 'support.tag', 48 | 'matches': { 49 | 1: 'support.tag', 50 | 2: 'support.tag.special', 51 | 3: 'support.tag-name' 52 | }, 53 | 'pattern': /(<\??)(\/|\!?)(\w+)/g 54 | }, 55 | { 56 | 'matches': { 57 | 1: 'support.attribute' 58 | }, 59 | 'pattern': /([a-z-]+)(?=\=)/gi 60 | }, 61 | { 62 | 'matches': { 63 | 1: 'support.operator', 64 | 2: 'string.quote', 65 | 3: 'string.value', 66 | 4: 'string.quote' 67 | }, 68 | 'pattern': /(=)('|")(.*?)(\2)/g 69 | }, 70 | { 71 | 'matches': { 72 | 1: 'support.operator', 73 | 2: 'support.value' 74 | }, 75 | 'pattern': /(=)([a-zA-Z\-0-9]*)\b/g 76 | }, 77 | { 78 | 'matches': { 79 | 1: 'support.attribute' 80 | }, 81 | 'pattern': /\s(\w+)(?=\s|>)(?![\s\S]*<)/g 82 | } 83 | ], true); 84 | -------------------------------------------------------------------------------- /docs/assets/rainbow-javascript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('javascript', [ 8 | 9 | /** 10 | * matches $. or $( 11 | */ 12 | { 13 | 'name': 'selector', 14 | 'pattern': /(\s|^)\$(?=\.|\()/g 15 | }, 16 | { 17 | 'name': 'support', 18 | 'pattern': /\b(window|document)\b/g 19 | }, 20 | { 21 | 'matches': { 22 | 1: 'support.property' 23 | }, 24 | 'pattern': /\.(length|node(Name|Value))\b/g 25 | }, 26 | { 27 | 'matches': { 28 | 1: 'support.function' 29 | }, 30 | 'pattern': /(setTimeout|setInterval)(?=\()/g 31 | 32 | }, 33 | { 34 | 'matches': { 35 | 1: 'support.method' 36 | }, 37 | 'pattern': /\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.script', 42 | 2: [ 43 | { 44 | 'name': 'string', 45 | 'pattern': /('|")(.*?)(\1)/g 46 | }, 47 | { 48 | 'name': 'entity.tag.script', 49 | 'pattern': /(\w+)/g 50 | } 51 | ], 52 | 3: 'support.tag.script' 53 | }, 54 | 'pattern': /(<\/?)(script.*?)(>)/g 55 | }, 56 | 57 | /** 58 | * matches any escaped characters inside of a js regex pattern 59 | * 60 | * @see https://github.com/ccampbell/rainbow/issues/22 61 | * 62 | * this was causing single line comments to fail so it now makes sure 63 | * the opening / is not directly followed by a * 64 | * 65 | * @todo check that there is valid regex in match group 1 66 | */ 67 | { 68 | 'name': 'string.regexp', 69 | 'matches': { 70 | 1: 'string.regexp.open', 71 | 2: { 72 | 'name': 'constant.regexp.escape', 73 | 'pattern': /\\(.){1}/g 74 | }, 75 | 3: 'string.regexp.cclose', 76 | 4: 'string.regexp.modifier' 77 | }, 78 | 'pattern': /(\/)(?!\*)(.+)(\/)([igm]{0,3})/g 79 | }, 80 | 81 | /** 82 | * matches runtime function declarations 83 | */ 84 | { 85 | 'matches': { 86 | 1: 'storage', 87 | 3: 'entity.function' 88 | }, 89 | 'pattern': /(var)?(\s|^)(.*)(?=\s?=\s?function\()/g 90 | }, 91 | 92 | /** 93 | * matches constructor call 94 | */ 95 | { 96 | 'matches': { 97 | 1: 'keyword', 98 | 2: 'entity.function' 99 | }, 100 | 'pattern': /(new)\s+(.*)(?=\()/g 101 | }, 102 | 103 | /** 104 | * matches any function call in the style functionName: function() 105 | */ 106 | { 107 | 'name': 'entity.function', 108 | 'pattern': /(\w+)(?=:\s{0,}function)/g 109 | } 110 | ]); 111 | -------------------------------------------------------------------------------- /docs/assets/rainbow.css: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub theme 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.4 6 | */ 7 | pre { 8 | border: 1px solid #ccc; 9 | word-wrap: break-word; 10 | padding: 6px 10px; 11 | line-height: 19px; 12 | margin-bottom: 20px; 13 | } 14 | 15 | code { 16 | border: 1px solid #eaeaea; 17 | margin: 0 2px; 18 | padding: 0 5px; 19 | font-size: 12px; 20 | } 21 | 22 | pre code { 23 | border: 0; 24 | padding: 0; 25 | margin: 0; 26 | -moz-border-radius: 0; 27 | -webkit-border-radius: 0; 28 | border-radius: 0; 29 | } 30 | 31 | pre, code { 32 | font-family: Consolas, 'Liberation Mono', Courier, monospace; 33 | color: #333; 34 | background: #f8f8f8; 35 | -moz-border-radius: 3px; 36 | -webkit-border-radius: 3px; 37 | border-radius: 3px; 38 | } 39 | 40 | pre, pre code { 41 | font-size: 13px; 42 | } 43 | 44 | pre .comment { 45 | color: #998; 46 | } 47 | 48 | pre .support { 49 | color: #0086B3; 50 | } 51 | 52 | pre .tag, pre .tag-name { 53 | color: navy; 54 | } 55 | 56 | pre .keyword, pre .css-property, pre .vendor-prefix, pre .sass, pre .class, pre .id, pre .css-value, pre .entity.function, pre .storage.function { 57 | font-weight: bold; 58 | } 59 | 60 | pre .css-property, pre .css-value, pre .vendor-prefix, pre .support.namespace { 61 | color: #333; 62 | } 63 | 64 | pre .constant.numeric, pre .keyword.unit, pre .hex-color { 65 | font-weight: normal; 66 | color: #099; 67 | } 68 | 69 | pre .entity.class { 70 | color: #458; 71 | } 72 | 73 | pre .entity.id, pre .entity.function { 74 | color: #900; 75 | } 76 | 77 | pre .attribute, pre .variable { 78 | color: teal; 79 | } 80 | 81 | pre .string, pre .support.value { 82 | font-weight: normal; 83 | color: #d14; 84 | } 85 | 86 | pre .regexp { 87 | color: #009926; 88 | } 89 | -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/2.5.0/assets/favicon.ico -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/github-16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/2.5.0/assets/github-16px.png -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/2.5.0/assets/header.png -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/2.5.0/assets/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/2.5.0/assets/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/plunker.js: -------------------------------------------------------------------------------- 1 | angular.module('plunker', []) 2 | 3 | .factory('plunkGenerator', function ($document) { 4 | 5 | return function (ngVersion, bsVersion, version, module, content) { 6 | 7 | var form = angular.element('
'); 8 | var addField = function (name, value) { 9 | var input = angular.element(''); 10 | input.attr('value', value); 11 | form.append(input); 12 | }; 13 | 14 | var indexContent = function (content, version) { 15 | return '\n' + 16 | '\n' + 17 | ' \n' + 18 | ' \n' + 19 | ' \n' + 20 | ' \n' + 21 | ' \n' + 22 | ' \n' + 23 | ' \n' + 24 | ' \n' + 25 | ' \n\n' + 26 | content + '\n' + 27 | ' \n' + 28 | '\n'; 29 | }; 30 | 31 | var scriptContent = function(content) { 32 | return "angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);" + "\n" + content; 33 | }; 34 | 35 | addField('description', 'http://angular-ui.github.io/bootstrap/'); 36 | addField('files[index.html]', indexContent(content.markup, version)); 37 | addField('files[example.js]', scriptContent(content.javascript)); 38 | 39 | $document.find('body').append(form); 40 | form[0].submit(); 41 | form.remove(); 42 | }; 43 | }) 44 | 45 | .controller('PlunkerCtrl', function ($scope, plunkGenerator) { 46 | 47 | $scope.content = {}; 48 | 49 | $scope.edit = function (ngVersion, bsVersion, version, module) { 50 | plunkGenerator(ngVersion, bsVersion, version, module, $scope.content); 51 | }; 52 | }) 53 | 54 | .directive('plunkerContent', function () { 55 | return { 56 | link:function (scope, element, attrs) { 57 | scope.content[attrs.plunkerContent] = element.text().trim(); 58 | } 59 | } 60 | }); 61 | -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/rainbow-generic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic language patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.9 6 | */ 7 | Rainbow.extend([ 8 | { 9 | 'matches': { 10 | 1: { 11 | 'name': 'keyword.operator', 12 | 'pattern': /\=/g 13 | }, 14 | 2: { 15 | 'name': 'string', 16 | 'matches': { 17 | 'name': 'constant.character.escape', 18 | 'pattern': /\\('|"){1}/g 19 | } 20 | } 21 | }, 22 | 'pattern': /(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm 23 | }, 24 | { 25 | 'name': 'comment', 26 | 'pattern': /\/\*[\s\S]*?\*\/|(\/\/|\#)[\s\S]*?$/gm 27 | }, 28 | { 29 | 'name': 'constant.numeric', 30 | 'pattern': /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi 31 | }, 32 | { 33 | 'matches': { 34 | 1: 'keyword' 35 | }, 36 | 'pattern': /\b(and|array|as|bool(ean)?|c(atch|har|lass|onst)|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\(|\b)/gi 37 | }, 38 | { 39 | 'name': 'constant.language', 40 | 'pattern': /true|false|null/g 41 | }, 42 | { 43 | 'name': 'keyword.operator', 44 | 'pattern': /\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g 45 | }, 46 | { 47 | 'matches': { 48 | 1: 'function.call' 49 | }, 50 | 'pattern': /(\w+?)(?=\()/g 51 | }, 52 | { 53 | 'matches': { 54 | 1: 'storage.function', 55 | 2: 'entity.name.function' 56 | }, 57 | 'pattern': /(function)\s(.*?)(?=\()/g 58 | } 59 | ]); 60 | -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/rainbow-html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * HTML patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('html', [ 8 | { 9 | 'name': 'source.php.embedded', 10 | 'matches': { 11 | 2: { 12 | 'language': 'php' 13 | } 14 | }, 15 | 'pattern': /<\?=?(?!xml)(php)?([\s\S]*?)(\?>)/gm 16 | }, 17 | { 18 | 'name': 'source.css.embedded', 19 | 'matches': { 20 | 0: { 21 | 'language': 'css' 22 | } 23 | }, 24 | 'pattern': /<style(.*?)>([\s\S]*?)<\/style>/gm 25 | }, 26 | { 27 | 'name': 'source.js.embedded', 28 | 'matches': { 29 | 0: { 30 | 'language': 'javascript' 31 | } 32 | }, 33 | 'pattern': /<script(?! src)(.*?)>([\s\S]*?)<\/script>/gm 34 | }, 35 | { 36 | 'name': 'comment.html', 37 | 'pattern': /<\!--[\S\s]*?-->/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.open', 42 | 2: 'support.tag.cclose' 43 | }, 44 | 'pattern': /(<)|(\/?\??>)/g 45 | }, 46 | { 47 | 'name': 'support.tag', 48 | 'matches': { 49 | 1: 'support.tag', 50 | 2: 'support.tag.special', 51 | 3: 'support.tag-name' 52 | }, 53 | 'pattern': /(<\??)(\/|\!?)(\w+)/g 54 | }, 55 | { 56 | 'matches': { 57 | 1: 'support.attribute' 58 | }, 59 | 'pattern': /([a-z-]+)(?=\=)/gi 60 | }, 61 | { 62 | 'matches': { 63 | 1: 'support.operator', 64 | 2: 'string.quote', 65 | 3: 'string.value', 66 | 4: 'string.quote' 67 | }, 68 | 'pattern': /(=)('|")(.*?)(\2)/g 69 | }, 70 | { 71 | 'matches': { 72 | 1: 'support.operator', 73 | 2: 'support.value' 74 | }, 75 | 'pattern': /(=)([a-zA-Z\-0-9]*)\b/g 76 | }, 77 | { 78 | 'matches': { 79 | 1: 'support.attribute' 80 | }, 81 | 'pattern': /\s(\w+)(?=\s|>)(?![\s\S]*<)/g 82 | } 83 | ], true); 84 | -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/rainbow-javascript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('javascript', [ 8 | 9 | /** 10 | * matches $. or $( 11 | */ 12 | { 13 | 'name': 'selector', 14 | 'pattern': /(\s|^)\$(?=\.|\()/g 15 | }, 16 | { 17 | 'name': 'support', 18 | 'pattern': /\b(window|document)\b/g 19 | }, 20 | { 21 | 'matches': { 22 | 1: 'support.property' 23 | }, 24 | 'pattern': /\.(length|node(Name|Value))\b/g 25 | }, 26 | { 27 | 'matches': { 28 | 1: 'support.function' 29 | }, 30 | 'pattern': /(setTimeout|setInterval)(?=\()/g 31 | 32 | }, 33 | { 34 | 'matches': { 35 | 1: 'support.method' 36 | }, 37 | 'pattern': /\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.script', 42 | 2: [ 43 | { 44 | 'name': 'string', 45 | 'pattern': /('|")(.*?)(\1)/g 46 | }, 47 | { 48 | 'name': 'entity.tag.script', 49 | 'pattern': /(\w+)/g 50 | } 51 | ], 52 | 3: 'support.tag.script' 53 | }, 54 | 'pattern': /(<\/?)(script.*?)(>)/g 55 | }, 56 | 57 | /** 58 | * matches any escaped characters inside of a js regex pattern 59 | * 60 | * @see https://github.com/ccampbell/rainbow/issues/22 61 | * 62 | * this was causing single line comments to fail so it now makes sure 63 | * the opening / is not directly followed by a * 64 | * 65 | * @todo check that there is valid regex in match group 1 66 | */ 67 | { 68 | 'name': 'string.regexp', 69 | 'matches': { 70 | 1: 'string.regexp.open', 71 | 2: { 72 | 'name': 'constant.regexp.escape', 73 | 'pattern': /\\(.){1}/g 74 | }, 75 | 3: 'string.regexp.cclose', 76 | 4: 'string.regexp.modifier' 77 | }, 78 | 'pattern': /(\/)(?!\*)(.+)(\/)([igm]{0,3})/g 79 | }, 80 | 81 | /** 82 | * matches runtime function declarations 83 | */ 84 | { 85 | 'matches': { 86 | 1: 'storage', 87 | 3: 'entity.function' 88 | }, 89 | 'pattern': /(var)?(\s|^)(.*)(?=\s?=\s?function\()/g 90 | }, 91 | 92 | /** 93 | * matches constructor call 94 | */ 95 | { 96 | 'matches': { 97 | 1: 'keyword', 98 | 2: 'entity.function' 99 | }, 100 | 'pattern': /(new)\s+(.*)(?=\()/g 101 | }, 102 | 103 | /** 104 | * matches any function call in the style functionName: function() 105 | */ 106 | { 107 | 'name': 'entity.function', 108 | 'pattern': /(\w+)(?=:\s{0,}function)/g 109 | } 110 | ]); 111 | -------------------------------------------------------------------------------- /docs/versioned-docs/2.5.0/assets/rainbow.css: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub theme 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.4 6 | */ 7 | pre { 8 | border: 1px solid #ccc; 9 | word-wrap: break-word; 10 | padding: 6px 10px; 11 | line-height: 19px; 12 | margin-bottom: 20px; 13 | } 14 | 15 | code { 16 | border: 1px solid #eaeaea; 17 | margin: 0 2px; 18 | padding: 0 5px; 19 | font-size: 12px; 20 | } 21 | 22 | pre code { 23 | border: 0; 24 | padding: 0; 25 | margin: 0; 26 | -moz-border-radius: 0; 27 | -webkit-border-radius: 0; 28 | border-radius: 0; 29 | } 30 | 31 | pre, code { 32 | font-family: Consolas, 'Liberation Mono', Courier, monospace; 33 | color: #333; 34 | background: #f8f8f8; 35 | -moz-border-radius: 3px; 36 | -webkit-border-radius: 3px; 37 | border-radius: 3px; 38 | } 39 | 40 | pre, pre code { 41 | font-size: 13px; 42 | } 43 | 44 | pre .comment { 45 | color: #998; 46 | } 47 | 48 | pre .support { 49 | color: #0086B3; 50 | } 51 | 52 | pre .tag, pre .tag-name { 53 | color: navy; 54 | } 55 | 56 | pre .keyword, pre .css-property, pre .vendor-prefix, pre .sass, pre .class, pre .id, pre .css-value, pre .entity.function, pre .storage.function { 57 | font-weight: bold; 58 | } 59 | 60 | pre .css-property, pre .css-value, pre .vendor-prefix, pre .support.namespace { 61 | color: #333; 62 | } 63 | 64 | pre .constant.numeric, pre .keyword.unit, pre .hex-color { 65 | font-weight: normal; 66 | color: #099; 67 | } 68 | 69 | pre .entity.class { 70 | color: #458; 71 | } 72 | 73 | pre .entity.id, pre .entity.function { 74 | color: #900; 75 | } 76 | 77 | pre .attribute, pre .variable { 78 | color: teal; 79 | } 80 | 81 | pre .string, pre .support.value { 82 | font-weight: normal; 83 | color: #d14; 84 | } 85 | 86 | pre .regexp { 87 | color: #009926; 88 | } 89 | -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/3.0.5/assets/favicon.ico -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/github-16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/3.0.5/assets/github-16px.png -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/3.0.5/assets/header.png -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/3.0.5/assets/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/docs/versioned-docs/3.0.5/assets/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/plunker.js: -------------------------------------------------------------------------------- 1 | angular.module('plunker', []) 2 | 3 | .factory('plunkGenerator', function ($document) { 4 | 5 | return function (ngVersion, bsVersion, version, module, content) { 6 | 7 | var form = angular.element('
'); 8 | var addField = function (name, value) { 9 | var input = angular.element(''); 10 | input.attr('value', value); 11 | form.append(input); 12 | }; 13 | 14 | var indexContent = function (content, version) { 15 | return '\n' + 16 | '\n' + 17 | ' \n' + 18 | ' \n' + 19 | ' \n' + 20 | ' \n' + 21 | ' \n' + 22 | ' \n' + 23 | ' \n' + 24 | ' \n' + 25 | ' \n\n' + 26 | content + '\n' + 27 | ' \n' + 28 | '\n'; 29 | }; 30 | 31 | var scriptContent = function(content) { 32 | return "angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);" + "\n" + content; 33 | }; 34 | 35 | addField('description', 'http://angular-ui.github.io/bootstrap/'); 36 | addField('files[index.html]', indexContent(content.markup, version)); 37 | addField('files[example.js]', scriptContent(content.javascript)); 38 | 39 | $document.find('body').append(form); 40 | form[0].submit(); 41 | form.remove(); 42 | }; 43 | }) 44 | 45 | .controller('PlunkerCtrl', function ($scope, plunkGenerator) { 46 | 47 | $scope.content = {}; 48 | 49 | $scope.edit = function (ngVersion, bsVersion, version, module) { 50 | plunkGenerator(ngVersion, bsVersion, version, module, $scope.content); 51 | }; 52 | }) 53 | 54 | .directive('plunkerContent', function () { 55 | return { 56 | link:function (scope, element, attrs) { 57 | scope.content[attrs.plunkerContent] = element.text().trim(); 58 | } 59 | } 60 | }); 61 | -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/rainbow-generic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic language patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.9 6 | */ 7 | Rainbow.extend([ 8 | { 9 | 'matches': { 10 | 1: { 11 | 'name': 'keyword.operator', 12 | 'pattern': /\=/g 13 | }, 14 | 2: { 15 | 'name': 'string', 16 | 'matches': { 17 | 'name': 'constant.character.escape', 18 | 'pattern': /\\('|"){1}/g 19 | } 20 | } 21 | }, 22 | 'pattern': /(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm 23 | }, 24 | { 25 | 'name': 'comment', 26 | 'pattern': /\/\*[\s\S]*?\*\/|(\/\/|\#)[\s\S]*?$/gm 27 | }, 28 | { 29 | 'name': 'constant.numeric', 30 | 'pattern': /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi 31 | }, 32 | { 33 | 'matches': { 34 | 1: 'keyword' 35 | }, 36 | 'pattern': /\b(and|array|as|bool(ean)?|c(atch|har|lass|onst)|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\(|\b)/gi 37 | }, 38 | { 39 | 'name': 'constant.language', 40 | 'pattern': /true|false|null/g 41 | }, 42 | { 43 | 'name': 'keyword.operator', 44 | 'pattern': /\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g 45 | }, 46 | { 47 | 'matches': { 48 | 1: 'function.call' 49 | }, 50 | 'pattern': /(\w+?)(?=\()/g 51 | }, 52 | { 53 | 'matches': { 54 | 1: 'storage.function', 55 | 2: 'entity.name.function' 56 | }, 57 | 'pattern': /(function)\s(.*?)(?=\()/g 58 | } 59 | ]); 60 | -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/rainbow-html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * HTML patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('html', [ 8 | { 9 | 'name': 'source.php.embedded', 10 | 'matches': { 11 | 2: { 12 | 'language': 'php' 13 | } 14 | }, 15 | 'pattern': /<\?=?(?!xml)(php)?([\s\S]*?)(\?>)/gm 16 | }, 17 | { 18 | 'name': 'source.css.embedded', 19 | 'matches': { 20 | 0: { 21 | 'language': 'css' 22 | } 23 | }, 24 | 'pattern': /<style(.*?)>([\s\S]*?)<\/style>/gm 25 | }, 26 | { 27 | 'name': 'source.js.embedded', 28 | 'matches': { 29 | 0: { 30 | 'language': 'javascript' 31 | } 32 | }, 33 | 'pattern': /<script(?! src)(.*?)>([\s\S]*?)<\/script>/gm 34 | }, 35 | { 36 | 'name': 'comment.html', 37 | 'pattern': /<\!--[\S\s]*?-->/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.open', 42 | 2: 'support.tag.cclose' 43 | }, 44 | 'pattern': /(<)|(\/?\??>)/g 45 | }, 46 | { 47 | 'name': 'support.tag', 48 | 'matches': { 49 | 1: 'support.tag', 50 | 2: 'support.tag.special', 51 | 3: 'support.tag-name' 52 | }, 53 | 'pattern': /(<\??)(\/|\!?)(\w+)/g 54 | }, 55 | { 56 | 'matches': { 57 | 1: 'support.attribute' 58 | }, 59 | 'pattern': /([a-z-]+)(?=\=)/gi 60 | }, 61 | { 62 | 'matches': { 63 | 1: 'support.operator', 64 | 2: 'string.quote', 65 | 3: 'string.value', 66 | 4: 'string.quote' 67 | }, 68 | 'pattern': /(=)('|")(.*?)(\2)/g 69 | }, 70 | { 71 | 'matches': { 72 | 1: 'support.operator', 73 | 2: 'support.value' 74 | }, 75 | 'pattern': /(=)([a-zA-Z\-0-9]*)\b/g 76 | }, 77 | { 78 | 'matches': { 79 | 1: 'support.attribute' 80 | }, 81 | 'pattern': /\s(\w+)(?=\s|>)(?![\s\S]*<)/g 82 | } 83 | ], true); 84 | -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/rainbow-javascript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('javascript', [ 8 | 9 | /** 10 | * matches $. or $( 11 | */ 12 | { 13 | 'name': 'selector', 14 | 'pattern': /(\s|^)\$(?=\.|\()/g 15 | }, 16 | { 17 | 'name': 'support', 18 | 'pattern': /\b(window|document)\b/g 19 | }, 20 | { 21 | 'matches': { 22 | 1: 'support.property' 23 | }, 24 | 'pattern': /\.(length|node(Name|Value))\b/g 25 | }, 26 | { 27 | 'matches': { 28 | 1: 'support.function' 29 | }, 30 | 'pattern': /(setTimeout|setInterval)(?=\()/g 31 | 32 | }, 33 | { 34 | 'matches': { 35 | 1: 'support.method' 36 | }, 37 | 'pattern': /\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.script', 42 | 2: [ 43 | { 44 | 'name': 'string', 45 | 'pattern': /('|")(.*?)(\1)/g 46 | }, 47 | { 48 | 'name': 'entity.tag.script', 49 | 'pattern': /(\w+)/g 50 | } 51 | ], 52 | 3: 'support.tag.script' 53 | }, 54 | 'pattern': /(<\/?)(script.*?)(>)/g 55 | }, 56 | 57 | /** 58 | * matches any escaped characters inside of a js regex pattern 59 | * 60 | * @see https://github.com/ccampbell/rainbow/issues/22 61 | * 62 | * this was causing single line comments to fail so it now makes sure 63 | * the opening / is not directly followed by a * 64 | * 65 | * @todo check that there is valid regex in match group 1 66 | */ 67 | { 68 | 'name': 'string.regexp', 69 | 'matches': { 70 | 1: 'string.regexp.open', 71 | 2: { 72 | 'name': 'constant.regexp.escape', 73 | 'pattern': /\\(.){1}/g 74 | }, 75 | 3: 'string.regexp.cclose', 76 | 4: 'string.regexp.modifier' 77 | }, 78 | 'pattern': /(\/)(?!\*)(.+)(\/)([igm]{0,3})/g 79 | }, 80 | 81 | /** 82 | * matches runtime function declarations 83 | */ 84 | { 85 | 'matches': { 86 | 1: 'storage', 87 | 3: 'entity.function' 88 | }, 89 | 'pattern': /(var)?(\s|^)(.*)(?=\s?=\s?function\()/g 90 | }, 91 | 92 | /** 93 | * matches constructor call 94 | */ 95 | { 96 | 'matches': { 97 | 1: 'keyword', 98 | 2: 'entity.function' 99 | }, 100 | 'pattern': /(new)\s+(.*)(?=\()/g 101 | }, 102 | 103 | /** 104 | * matches any function call in the style functionName: function() 105 | */ 106 | { 107 | 'name': 'entity.function', 108 | 'pattern': /(\w+)(?=:\s{0,}function)/g 109 | } 110 | ]); 111 | -------------------------------------------------------------------------------- /docs/versioned-docs/3.0.5/assets/rainbow.css: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub theme 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.4 6 | */ 7 | pre { 8 | border: 1px solid #ccc; 9 | word-wrap: break-word; 10 | padding: 6px 10px; 11 | line-height: 19px; 12 | margin-bottom: 20px; 13 | } 14 | 15 | code { 16 | border: 1px solid #eaeaea; 17 | margin: 0 2px; 18 | padding: 0 5px; 19 | font-size: 12px; 20 | } 21 | 22 | pre code { 23 | border: 0; 24 | padding: 0; 25 | margin: 0; 26 | -moz-border-radius: 0; 27 | -webkit-border-radius: 0; 28 | border-radius: 0; 29 | } 30 | 31 | pre, code { 32 | font-family: Consolas, 'Liberation Mono', Courier, monospace; 33 | color: #333; 34 | background: #f8f8f8; 35 | -moz-border-radius: 3px; 36 | -webkit-border-radius: 3px; 37 | border-radius: 3px; 38 | } 39 | 40 | pre, pre code { 41 | font-size: 13px; 42 | } 43 | 44 | pre .comment { 45 | color: #998; 46 | } 47 | 48 | pre .support { 49 | color: #0086B3; 50 | } 51 | 52 | pre .tag, pre .tag-name { 53 | color: navy; 54 | } 55 | 56 | pre .keyword, pre .css-property, pre .vendor-prefix, pre .sass, pre .class, pre .id, pre .css-value, pre .entity.function, pre .storage.function { 57 | font-weight: bold; 58 | } 59 | 60 | pre .css-property, pre .css-value, pre .vendor-prefix, pre .support.namespace { 61 | color: #333; 62 | } 63 | 64 | pre .constant.numeric, pre .keyword.unit, pre .hex-color { 65 | font-weight: normal; 66 | color: #099; 67 | } 68 | 69 | pre .entity.class { 70 | color: #458; 71 | } 72 | 73 | pre .entity.id, pre .entity.function { 74 | color: #900; 75 | } 76 | 77 | pre .attribute, pre .variable { 78 | color: teal; 79 | } 80 | 81 | pre .string, pre .support.value { 82 | font-weight: normal; 83 | color: #d14; 84 | } 85 | 86 | pre .regexp { 87 | color: #009926; 88 | } 89 | -------------------------------------------------------------------------------- /docs/versions-mapping.json: -------------------------------------------------------------------------------- 1 | [{"version":"3.0.x (Current)","url":"/ui-bootstrap4/"}, {"version":"3.0.5","url":"/ui-bootstrap4/versioned-docs/3.0.5/index.html"}, {"version":"2.5.0","url":"/ui-bootstrap4/versioned-docs/2.5.0/index.html"}] 2 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('./dist/ui-bootstrap-tpls'); 2 | 3 | module.exports = 'ui.bootstrap'; 4 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Sat Mar 28 2015 11:17:34 GMT-0700 (PDT) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | files: [ 18 | 'misc/test-lib/jquery-1.8.2.min.js', 19 | 'node_modules/angular/angular.js', 20 | 'node_modules/angular-mocks/angular-mocks.js', 21 | 'node_modules/angular-sanitize/angular-sanitize.js', 22 | 'misc/test-lib/helpers.js', 23 | 'src/**/*.js', 24 | 'template/**/*.js' 25 | ], 26 | 27 | 28 | // list of files to exclude 29 | exclude: [ 30 | 'src/**/index.js', 31 | 'src/**/index-nocss.js', 32 | 'src/**/docs/*' 33 | ], 34 | 35 | 36 | // preprocess matching files before serving them to the browser 37 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 38 | preprocessors: { 39 | 'src/*/{*.js,!(test)/**/*.js}': ['coverage'] 40 | }, 41 | 42 | 43 | // test results reporter to use 44 | // possible values: 'dots', 'progress' 45 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 46 | reporters: ['progress', 'coverage'], 47 | 48 | coverageReporter: { 49 | dir: '.coverage/', 50 | type: 'html' 51 | }, 52 | 53 | reportSlowerThan: 100, 54 | 55 | // web server port 56 | port: 9876, 57 | 58 | 59 | // enable / disable colors in the output (reporters and logs) 60 | colors: true, 61 | 62 | 63 | // level of logging 64 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 65 | logLevel: config.LOG_INFO, 66 | 67 | 68 | // enable / disable watching file and executing tests whenever any file changes 69 | autoWatch: true, 70 | 71 | 72 | // start these browsers 73 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 74 | browsers: ['Chrome'], 75 | 76 | 77 | // Continuous Integration mode 78 | // if true, Karma captures browsers, runs the tests and exits 79 | singleRun: false 80 | }); 81 | }; 82 | -------------------------------------------------------------------------------- /misc/changelog.tpl.md: -------------------------------------------------------------------------------- 1 | # <%= version%> (<%= today%>) 2 | <% if (_(changelog.feat).size() > 0) { %> 3 | ## Features 4 | <% _(changelog.feat).keys().sort().forEach(function(scope) { %> 5 | - **<%= scope%>:** <% changelog.feat[scope].forEach(function(change) { %> 6 | - <%= change.msg%> (<%= helpers.commitLink(change.sha1) %>)<% }); %><% }); %> <% } %> 7 | <% if (_(changelog.fix).size() > 0) { %> 8 | ## Bug Fixes 9 | <% _(changelog.fix).keys().sort().forEach(function(scope) { %> 10 | - **<%= scope%>:** <% changelog.fix[scope].forEach(function(change) { %> 11 | - <%= change.msg%> (<%= helpers.commitLink(change.sha1) %>)<% }); %><% }); %> <% } %> 12 | <% if (_(changelog.breaking).size() > 0) { %> 13 | ## Breaking Changes 14 | <% _(changelog.breaking).keys().sort().forEach(function(scope) { %> 15 | - **<%= scope%>:** <% changelog.breaking[scope].forEach(function(change) { %> 16 | <%= change.msg%><% }); %><% }); %> <% } %> 17 | -------------------------------------------------------------------------------- /misc/demo/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/misc/demo/assets/favicon.ico -------------------------------------------------------------------------------- /misc/demo/assets/github-16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/misc/demo/assets/github-16px.png -------------------------------------------------------------------------------- /misc/demo/assets/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/misc/demo/assets/header.png -------------------------------------------------------------------------------- /misc/demo/assets/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/misc/demo/assets/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /misc/demo/assets/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Morgul/ui-bootstrap4/2cfc3130c3d95a958ab60c9e86af8a3a96bfeb5d/misc/demo/assets/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /misc/demo/assets/plunker.js: -------------------------------------------------------------------------------- 1 | angular.module('plunker', []) 2 | 3 | .factory('plunkGenerator', function ($document) { 4 | 5 | return function (ngVersion, bsVersion, version, module, content) { 6 | 7 | var form = angular.element('
'); 8 | var addField = function (name, value) { 9 | var input = angular.element(''); 10 | input.attr('value', value); 11 | form.append(input); 12 | }; 13 | 14 | var indexContent = function (content, version) { 15 | return '\n' + 16 | '\n' + 17 | ' \n' + 18 | ' \n' + 19 | ' \n' + 20 | ' \n' + 21 | ' \n' + 22 | ' \n' + 23 | ' \n' + 24 | ' \n' + 25 | ' \n\n' + 26 | content + '\n' + 27 | ' \n' + 28 | '\n'; 29 | }; 30 | 31 | var scriptContent = function(content) { 32 | return "angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);" + "\n" + content; 33 | }; 34 | 35 | addField('description', 'http://angular-ui.github.io/bootstrap/'); 36 | addField('files[index.html]', indexContent(content.markup, version)); 37 | addField('files[example.js]', scriptContent(content.javascript)); 38 | 39 | $document.find('body').append(form); 40 | form[0].submit(); 41 | form.remove(); 42 | }; 43 | }) 44 | 45 | .controller('PlunkerCtrl', function ($scope, plunkGenerator) { 46 | 47 | $scope.content = {}; 48 | 49 | $scope.edit = function (ngVersion, bsVersion, version, module) { 50 | plunkGenerator(ngVersion, bsVersion, version, module, $scope.content); 51 | }; 52 | }) 53 | 54 | .directive('plunkerContent', function () { 55 | return { 56 | link:function (scope, element, attrs) { 57 | scope.content[attrs.plunkerContent] = element.text().trim(); 58 | } 59 | } 60 | }); 61 | -------------------------------------------------------------------------------- /misc/demo/assets/rainbow-generic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Generic language patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.9 6 | */ 7 | Rainbow.extend([ 8 | { 9 | 'matches': { 10 | 1: { 11 | 'name': 'keyword.operator', 12 | 'pattern': /\=/g 13 | }, 14 | 2: { 15 | 'name': 'string', 16 | 'matches': { 17 | 'name': 'constant.character.escape', 18 | 'pattern': /\\('|"){1}/g 19 | } 20 | } 21 | }, 22 | 'pattern': /(\(|\s|\[|\=|:)(('|")([^\\\1]|\\.)*?(\3))/gm 23 | }, 24 | { 25 | 'name': 'comment', 26 | 'pattern': /\/\*[\s\S]*?\*\/|(\/\/|\#)[\s\S]*?$/gm 27 | }, 28 | { 29 | 'name': 'constant.numeric', 30 | 'pattern': /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi 31 | }, 32 | { 33 | 'matches': { 34 | 1: 'keyword' 35 | }, 36 | 'pattern': /\b(and|array|as|bool(ean)?|c(atch|har|lass|onst)|d(ef|elete|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\(|\b)/gi 37 | }, 38 | { 39 | 'name': 'constant.language', 40 | 'pattern': /true|false|null/g 41 | }, 42 | { 43 | 'name': 'keyword.operator', 44 | 'pattern': /\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g 45 | }, 46 | { 47 | 'matches': { 48 | 1: 'function.call' 49 | }, 50 | 'pattern': /(\w+?)(?=\()/g 51 | }, 52 | { 53 | 'matches': { 54 | 1: 'storage.function', 55 | 2: 'entity.name.function' 56 | }, 57 | 'pattern': /(function)\s(.*?)(?=\()/g 58 | } 59 | ]); 60 | -------------------------------------------------------------------------------- /misc/demo/assets/rainbow-html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * HTML patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('html', [ 8 | { 9 | 'name': 'source.php.embedded', 10 | 'matches': { 11 | 2: { 12 | 'language': 'php' 13 | } 14 | }, 15 | 'pattern': /<\?=?(?!xml)(php)?([\s\S]*?)(\?>)/gm 16 | }, 17 | { 18 | 'name': 'source.css.embedded', 19 | 'matches': { 20 | 0: { 21 | 'language': 'css' 22 | } 23 | }, 24 | 'pattern': /<style(.*?)>([\s\S]*?)<\/style>/gm 25 | }, 26 | { 27 | 'name': 'source.js.embedded', 28 | 'matches': { 29 | 0: { 30 | 'language': 'javascript' 31 | } 32 | }, 33 | 'pattern': /<script(?! src)(.*?)>([\s\S]*?)<\/script>/gm 34 | }, 35 | { 36 | 'name': 'comment.html', 37 | 'pattern': /<\!--[\S\s]*?-->/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.open', 42 | 2: 'support.tag.cclose' 43 | }, 44 | 'pattern': /(<)|(\/?\??>)/g 45 | }, 46 | { 47 | 'name': 'support.tag', 48 | 'matches': { 49 | 1: 'support.tag', 50 | 2: 'support.tag.special', 51 | 3: 'support.tag-name' 52 | }, 53 | 'pattern': /(<\??)(\/|\!?)(\w+)/g 54 | }, 55 | { 56 | 'matches': { 57 | 1: 'support.attribute' 58 | }, 59 | 'pattern': /([a-z-]+)(?=\=)/gi 60 | }, 61 | { 62 | 'matches': { 63 | 1: 'support.operator', 64 | 2: 'string.quote', 65 | 3: 'string.value', 66 | 4: 'string.quote' 67 | }, 68 | 'pattern': /(=)('|")(.*?)(\2)/g 69 | }, 70 | { 71 | 'matches': { 72 | 1: 'support.operator', 73 | 2: 'support.value' 74 | }, 75 | 'pattern': /(=)([a-zA-Z\-0-9]*)\b/g 76 | }, 77 | { 78 | 'matches': { 79 | 1: 'support.attribute' 80 | }, 81 | 'pattern': /\s(\w+)(?=\s|>)(?![\s\S]*<)/g 82 | } 83 | ], true); 84 | -------------------------------------------------------------------------------- /misc/demo/assets/rainbow-javascript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Javascript patterns 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.7 6 | */ 7 | Rainbow.extend('javascript', [ 8 | 9 | /** 10 | * matches $. or $( 11 | */ 12 | { 13 | 'name': 'selector', 14 | 'pattern': /(\s|^)\$(?=\.|\()/g 15 | }, 16 | { 17 | 'name': 'support', 18 | 'pattern': /\b(window|document)\b/g 19 | }, 20 | { 21 | 'matches': { 22 | 1: 'support.property' 23 | }, 24 | 'pattern': /\.(length|node(Name|Value))\b/g 25 | }, 26 | { 27 | 'matches': { 28 | 1: 'support.function' 29 | }, 30 | 'pattern': /(setTimeout|setInterval)(?=\()/g 31 | 32 | }, 33 | { 34 | 'matches': { 35 | 1: 'support.method' 36 | }, 37 | 'pattern': /\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g 38 | }, 39 | { 40 | 'matches': { 41 | 1: 'support.tag.script', 42 | 2: [ 43 | { 44 | 'name': 'string', 45 | 'pattern': /('|")(.*?)(\1)/g 46 | }, 47 | { 48 | 'name': 'entity.tag.script', 49 | 'pattern': /(\w+)/g 50 | } 51 | ], 52 | 3: 'support.tag.script' 53 | }, 54 | 'pattern': /(<\/?)(script.*?)(>)/g 55 | }, 56 | 57 | /** 58 | * matches any escaped characters inside of a js regex pattern 59 | * 60 | * @see https://github.com/ccampbell/rainbow/issues/22 61 | * 62 | * this was causing single line comments to fail so it now makes sure 63 | * the opening / is not directly followed by a * 64 | * 65 | * @todo check that there is valid regex in match group 1 66 | */ 67 | { 68 | 'name': 'string.regexp', 69 | 'matches': { 70 | 1: 'string.regexp.open', 71 | 2: { 72 | 'name': 'constant.regexp.escape', 73 | 'pattern': /\\(.){1}/g 74 | }, 75 | 3: 'string.regexp.cclose', 76 | 4: 'string.regexp.modifier' 77 | }, 78 | 'pattern': /(\/)(?!\*)(.+)(\/)([igm]{0,3})/g 79 | }, 80 | 81 | /** 82 | * matches runtime function declarations 83 | */ 84 | { 85 | 'matches': { 86 | 1: 'storage', 87 | 3: 'entity.function' 88 | }, 89 | 'pattern': /(var)?(\s|^)(.*)(?=\s?=\s?function\()/g 90 | }, 91 | 92 | /** 93 | * matches constructor call 94 | */ 95 | { 96 | 'matches': { 97 | 1: 'keyword', 98 | 2: 'entity.function' 99 | }, 100 | 'pattern': /(new)\s+(.*)(?=\()/g 101 | }, 102 | 103 | /** 104 | * matches any function call in the style functionName: function() 105 | */ 106 | { 107 | 'name': 'entity.function', 108 | 'pattern': /(\w+)(?=:\s{0,}function)/g 109 | } 110 | ]); 111 | -------------------------------------------------------------------------------- /misc/demo/assets/rainbow.css: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub theme 3 | * 4 | * @author Craig Campbell 5 | * @version 1.0.4 6 | */ 7 | pre { 8 | border: 1px solid #ccc; 9 | word-wrap: break-word; 10 | padding: 6px 10px; 11 | line-height: 19px; 12 | margin-bottom: 20px; 13 | } 14 | 15 | code { 16 | border: 1px solid #eaeaea; 17 | margin: 0 2px; 18 | padding: 0 5px; 19 | font-size: 12px; 20 | } 21 | 22 | pre code { 23 | border: 0; 24 | padding: 0; 25 | margin: 0; 26 | -moz-border-radius: 0; 27 | -webkit-border-radius: 0; 28 | border-radius: 0; 29 | } 30 | 31 | pre, code { 32 | font-family: Consolas, 'Liberation Mono', Courier, monospace; 33 | color: #333; 34 | background: #f8f8f8; 35 | -moz-border-radius: 3px; 36 | -webkit-border-radius: 3px; 37 | border-radius: 3px; 38 | } 39 | 40 | pre, pre code { 41 | font-size: 13px; 42 | } 43 | 44 | pre .comment { 45 | color: #998; 46 | } 47 | 48 | pre .support { 49 | color: #0086B3; 50 | } 51 | 52 | pre .tag, pre .tag-name { 53 | color: navy; 54 | } 55 | 56 | pre .keyword, pre .css-property, pre .vendor-prefix, pre .sass, pre .class, pre .id, pre .css-value, pre .entity.function, pre .storage.function { 57 | font-weight: bold; 58 | } 59 | 60 | pre .css-property, pre .css-value, pre .vendor-prefix, pre .support.namespace { 61 | color: #333; 62 | } 63 | 64 | pre .constant.numeric, pre .keyword.unit, pre .hex-color { 65 | font-weight: normal; 66 | color: #099; 67 | } 68 | 69 | pre .entity.class { 70 | color: #458; 71 | } 72 | 73 | pre .entity.id, pre .entity.function { 74 | color: #900; 75 | } 76 | 77 | pre .attribute, pre .variable { 78 | color: teal; 79 | } 80 | 81 | pre .string, pre .support.value { 82 | font-weight: normal; 83 | color: #d14; 84 | } 85 | 86 | pre .regexp { 87 | color: #009926; 88 | } 89 | -------------------------------------------------------------------------------- /misc/raw-files-generator.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Forked from: 3 | * Bootstrap Grunt task for generating raw-files.min.js for the Customizer 4 | * http://getbootstrap.com 5 | * Copyright 2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | */ 8 | 9 | /* jshint node: true */ 10 | 11 | 'use strict'; 12 | var fs = require('fs'); 13 | 14 | function getFiles(filePaths) { 15 | var files = {}; 16 | filePaths 17 | .forEach(function (path) { 18 | files[path] = fs.readFileSync(path, 'utf8'); 19 | }); 20 | return files; 21 | } 22 | 23 | module.exports = function generateRawFilesJs(grunt, jsFilename, files, banner, cssBanner) { 24 | if (!banner) { 25 | banner = ''; 26 | } 27 | 28 | if (!cssBanner) { 29 | cssBanner = ''; 30 | } 31 | 32 | var filesJsObject = { 33 | banner: banner, 34 | cssBanner: cssBanner, 35 | files: getFiles(files), 36 | }; 37 | 38 | var filesJsContent = JSON.stringify(filesJsObject); 39 | try { 40 | fs.writeFileSync(jsFilename, filesJsContent); 41 | } 42 | catch (err) { 43 | grunt.fail.warn(err); 44 | } 45 | grunt.log.writeln('File ' + jsFilename.cyan + ' created.'); 46 | }; 47 | -------------------------------------------------------------------------------- /misc/test-lib/helpers.js: -------------------------------------------------------------------------------- 1 | // jasmine matcher for expecting an element to have a css class 2 | // https://github.com/angular/angular.js/blob/master/test/matchers.js 3 | beforeEach(function() { 4 | jasmine.addMatchers({ 5 | toHaveClass: function(util, customEqualityTesters) { 6 | return { 7 | compare: function(actual, expected) { 8 | var result = { 9 | pass: actual.hasClass(expected) 10 | }; 11 | 12 | if (result.pass) { 13 | result.message = 'Expected "' + actual + '" not to have the "' + expected + '" class.'; 14 | } else { 15 | result.message = 'Expected "' + actual + '" to have the "' + expected + '" class.'; 16 | } 17 | 18 | return result; 19 | } 20 | } 21 | }, 22 | toBeHidden: function(util, customEqualityTesters) { 23 | return { 24 | compare: function(actual) { 25 | var result = { 26 | pass: actual.hasClass('ng-hide') || actual.css('display') === 'none' 27 | }; 28 | 29 | if (result.pass) { 30 | result.message = 'Expected "' + actual + '" not to be hidden'; 31 | } else { 32 | result.message = 'Expected "' + actual + '" to be hidden'; 33 | } 34 | 35 | return result; 36 | } 37 | } 38 | }, 39 | toHaveFocus: function(util, customEqualityTesters) { 40 | return { 41 | compare: function(actual) { 42 | var result = { 43 | pass: document.activeElement === actual[0] 44 | }; 45 | 46 | if (result.pass) { 47 | result.message = 'Expected "' + actual + '" not to have focus'; 48 | } else { 49 | result.message = 'Expected "' + actual + '" to have focus'; 50 | } 51 | 52 | return result; 53 | } 54 | } 55 | } 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /misc/validate-commit-msg.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Git COMMIT-MSG hook for validating commit message 5 | * See https://docs.google.com/document/d/1rk04jEuGfk9kYzfqCuOlPTSJw3hEDZJTBN5E5f1SALo/edit 6 | * 7 | * Installation: 8 | * >> cd 9 | * >> ln -s validate-commit-msg.js .git/hooks/commit-msg 10 | */ 11 | var fs = require('fs'); 12 | var util = require('util'); 13 | 14 | 15 | var MAX_LENGTH = 70; 16 | var PATTERN = /^(?:fixup!\s*)?(\w*)(\((\w+)\))?\: (.*)$/; 17 | var IGNORED = /^WIP\:/; 18 | var TYPES = { 19 | chore: true, 20 | demo: true, 21 | docs: true, 22 | feat: true, 23 | fix: true, 24 | refactor: true, 25 | revert: true, 26 | style: true, 27 | test: true 28 | }; 29 | 30 | 31 | var error = function() { 32 | // gitx does not display it 33 | // http://gitx.lighthouseapp.com/projects/17830/tickets/294-feature-display-hook-error-message-when-hook-fails 34 | // https://groups.google.com/group/gitx/browse_thread/thread/a03bcab60844b812 35 | console.error('INVALID COMMIT MSG: ' + util.format.apply(null, arguments)); 36 | }; 37 | 38 | 39 | var validateMessage = function(message) { 40 | var isValid = true; 41 | 42 | if (IGNORED.test(message)) { 43 | console.log('Commit message validation ignored.'); 44 | return true; 45 | } 46 | 47 | if (message.length > MAX_LENGTH) { 48 | error('is longer than %d characters !', MAX_LENGTH); 49 | isValid = false; 50 | } 51 | 52 | var match = PATTERN.exec(message); 53 | 54 | if (!match) { 55 | error('does not match "(): " ! was: "' + message + '"\nNote: must be only letters.'); 56 | return false; 57 | } 58 | 59 | var type = match[1]; 60 | var scope = match[3]; 61 | var subject = match[4]; 62 | 63 | if (!TYPES.hasOwnProperty(type)) { 64 | error('"%s" is not allowed type !', type); 65 | return false; 66 | } 67 | 68 | // Some more ideas, do want anything like this ? 69 | // - allow only specific scopes (eg. fix(docs) should not be allowed ? 70 | // - auto correct the type to lower case ? 71 | // - auto correct first letter of the subject to lower case ? 72 | // - auto add empty line after subject ? 73 | // - auto remove empty () ? 74 | // - auto correct typos in type ? 75 | // - store incorrect messages, so that we can learn 76 | 77 | return isValid; 78 | }; 79 | 80 | 81 | var firstLineFromBuffer = function(buffer) { 82 | return buffer.toString().split('\n').shift(); 83 | }; 84 | 85 | 86 | 87 | // publish for testing 88 | exports.validateMessage = validateMessage; 89 | 90 | // hacky start if not run by jasmine :-D 91 | if (process.argv.join('').indexOf('jasmine-node') === -1) { 92 | var commitMsgFile = process.argv[2]; 93 | var incorrectLogFile = commitMsgFile.replace('COMMIT_EDITMSG', 'logs/incorrect-commit-msgs'); 94 | 95 | fs.readFile(commitMsgFile, function(err, buffer) { 96 | var msg = firstLineFromBuffer(buffer); 97 | 98 | if (!validateMessage(msg)) { 99 | fs.appendFile(incorrectLogFile, msg + '\n', function() { 100 | process.exit(1); 101 | }); 102 | } else { 103 | process.exit(0); 104 | } 105 | }); 106 | } 107 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "https://github.com/morgul/ui-bootstrap4/graphs/contributors", 3 | "name": "ui-bootstrap4", 4 | "version": "3.0.7", 5 | "description": "Native AngularJS (Angular) directives for Bootstrap", 6 | "homepage": "http://morgul.github.io/ui-bootstrap4/", 7 | "keywords": [ 8 | "angularjs", 9 | "angular", 10 | "bootstrap", 11 | "ui" 12 | ], 13 | "dependencies": {}, 14 | "directories": { 15 | "lib": "src/" 16 | }, 17 | "files": [ 18 | "index.js", 19 | "dist/", 20 | "src/", 21 | "template/" 22 | ], 23 | "main": "index.js", 24 | "scripts": { 25 | "serve": "static dist -p 3857 -a 0.0.0.0 -H '{\"Cache-Control\": \"no-cache, must-revalidate\"}'", 26 | "demo": "grunt html2js after-test && static dist -p 3857 -a 0.0.0.0 -H '{\"Cache-Control\": \"no-cache, must-revalidate\"}'", 27 | "test": "grunt", 28 | "grunt": "grunt --" 29 | }, 30 | "repository": { 31 | "type": "git", 32 | "url": "https://github.com/morgul/ui-bootstrap4.git" 33 | }, 34 | "devDependencies": { 35 | "angular": "1.6.1", 36 | "angular-mocks": "1.6.1", 37 | "angular-sanitize": "1.6.1", 38 | "grunt": "^0.4.5", 39 | "grunt-cli": "^1.2.0", 40 | "grunt-contrib-concat": "^1.0.0", 41 | "grunt-contrib-copy": "^1.0.0", 42 | "grunt-contrib-uglify": "^1.0.1", 43 | "grunt-contrib-watch": "^1.0.0", 44 | "grunt-conventional-changelog": "^6.1.0", 45 | "grunt-ddescribe-iit": "0.0.6", 46 | "grunt-eslint": "^17.3.1", 47 | "grunt-html2js": "^0.3.0", 48 | "grunt-karma": "^0.12.0", 49 | "jasmine-core": "^2.2.0", 50 | "karma": "0.13.22", 51 | "karma-chrome-launcher": "^0.2.0", 52 | "karma-coverage": "^0.5.0", 53 | "karma-firefox-launcher": "^0.1.4", 54 | "karma-jasmine": "^0.3.5", 55 | "load-grunt-tasks": "^3.3.0", 56 | "lodash": "^4.1.0", 57 | "marked": "^0.3.5", 58 | "node-static": "^0.7.8", 59 | "semver": "^5.0.1", 60 | "shelljs": "^0.6.0" 61 | }, 62 | "license": "MIT" 63 | } 64 | -------------------------------------------------------------------------------- /src/accordion/docs/demo.html: -------------------------------------------------------------------------------- 1 |
2 | 16 | 17 |

18 | 19 | 20 |

21 | 22 |
23 | 27 |
28 | 29 |
30 | This content is straight in the template. 31 |
32 |
33 | {{group.content}} 34 |
35 |
36 |

The body of the uib-accordion group grows to fit the contents

37 | 38 |
{{item}}
39 |
40 |
41 | Hello 42 |
43 |
44 | 45 | Custom template with custom header template 46 | 47 | World 48 |
49 |
50 |

Please, to delete your account, click the button below

51 | 52 |
53 |
54 | 55 | I can have markup, too! 56 | 57 | This is just some content to illustrate fancy headings. 58 |
59 |
60 |
61 | -------------------------------------------------------------------------------- /src/accordion/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function ($scope) { 2 | $scope.oneAtATime = true; 3 | 4 | $scope.groups = [ 5 | { 6 | title: 'Dynamic Group Header - 1', 7 | content: 'Dynamic Group Body - 1' 8 | }, 9 | { 10 | title: 'Dynamic Group Header - 2', 11 | content: 'Dynamic Group Body - 2' 12 | } 13 | ]; 14 | 15 | $scope.items = ['Item 1', 'Item 2', 'Item 3']; 16 | 17 | $scope.addItem = function() { 18 | var newItemNo = $scope.items.length + 1; 19 | $scope.items.push('Item ' + newItemNo); 20 | }; 21 | 22 | $scope.status = { 23 | isCustomHeaderOpen: false, 24 | isFirstOpen: true, 25 | isFirstDisabled: false 26 | }; 27 | }); -------------------------------------------------------------------------------- /src/accordion/docs/readme.md: -------------------------------------------------------------------------------- 1 | The **accordion directive** builds on top of the collapse directive to provide a list of items, with collapsible bodies that are collapsed or expanded by clicking on the item's header. 2 | 3 | The body of each accordion group is transcluded into the body of the collapsible element. 4 | 5 | ### uib-accordion settings 6 | 7 | * `close-others` 8 | $ 9 | C 10 | _(Default: `true`)_ - 11 | Control whether expanding an item will cause the other items to close. 12 | 13 | * `template-url` 14 | _(Default: `template/accordion/accordion.html`)_ - 15 | Add the ability to override the template used on the component. 16 | 17 | ### uib-accordion-group settings 18 | 19 | * `heading` 20 | _(Default: `none`)_ - 21 | The clickable text on the group's header. You need one to be able to click on the header for toggling. 22 | 23 | * `is-disabled` 24 | $ 25 | 26 | _(Default: `false`)_ - 27 | Whether the accordion group is disabled or not. 28 | 29 | * `is-open` 30 | $ 31 | 32 | _(Default: `false`)_ - 33 | Whether accordion group is open or closed. 34 | 35 | * `template-url` 36 | _(Default: `uib/template/accordion/accordion-group.html`)_ - 37 | Add the ability to override the template used on the component. 38 | 39 | ### Accordion heading 40 | 41 | Instead of the `heading` attribute on the `uib-accordion-group`, you can use an `uib-accordion-heading` element inside a group that will be used as the group's header. 42 | 43 | If you're using a custom template for the `uib-accordion-group`, you'll need to have an element for the heading to be transcluded into using `uib-accordion-header` (e.g. `
`). 44 | 45 | ### Known issues 46 | 47 | To use clickable elements within the accordion, you have to override the accordion-group template to use div elements instead of anchor elements, and add `cursor: pointer` in your CSS. This is due to browsers interpreting anchor elements as the target of any click event, which triggers routing when certain elements such as buttons are nested inside the anchor element. 48 | 49 | If custom classes on the accordion-group element are desired, one needs to either modify the template to remove the `ng-class` usage in the accordion-group template and use ng-class on the accordion-group element (not recommended), or use an interpolated expression in the class attribute, i.e. ``. 50 | -------------------------------------------------------------------------------- /src/accordion/index.js: -------------------------------------------------------------------------------- 1 | require('../collapse'); 2 | require('../tabindex'); 3 | require('../../template/accordion/accordion-group.html.js'); 4 | require('../../template/accordion/accordion.html.js'); 5 | require('./accordion'); 6 | 7 | var MODULE_NAME = 'ui.bootstrap.module.accordion'; 8 | 9 | angular.module(MODULE_NAME, ['ui.bootstrap.accordion', 'uib/template/accordion/accordion.html', 'uib/template/accordion/accordion-group.html']); 10 | 11 | module.exports = MODULE_NAME; 12 | -------------------------------------------------------------------------------- /src/alert/alert.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.alert', []) 2 | 3 | .controller('UibAlertController', ['$scope', '$element', '$attrs', '$interpolate', '$timeout', function($scope, $element, $attrs, $interpolate, $timeout) { 4 | $scope.closeable = !!$attrs.close; 5 | $element.addClass('alert'); 6 | $attrs.$set('role', 'alert'); 7 | if ($scope.closeable) { 8 | $element.addClass('alert-dismissible'); 9 | } 10 | 11 | var dismissOnTimeout = angular.isDefined($attrs.dismissOnTimeout) ? 12 | $interpolate($attrs.dismissOnTimeout)($scope.$parent) : null; 13 | 14 | if (dismissOnTimeout) { 15 | $timeout(function() { 16 | $scope.close(); 17 | }, parseInt(dismissOnTimeout, 10)); 18 | } 19 | }]) 20 | 21 | .directive('uibAlert', function() { 22 | return { 23 | controller: 'UibAlertController', 24 | controllerAs: 'alert', 25 | restrict: 'A', 26 | templateUrl: function(element, attrs) { 27 | return attrs.templateUrl || 'uib/template/alert/alert.html'; 28 | }, 29 | transclude: true, 30 | scope: { 31 | close: '&' 32 | } 33 | }; 34 | }); 35 | -------------------------------------------------------------------------------- /src/alert/docs/demo.html: -------------------------------------------------------------------------------- 1 |
2 | 5 | 6 |
{{alert.msg}}
7 |
A happy alert!
8 | 9 |
10 | -------------------------------------------------------------------------------- /src/alert/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('AlertDemoCtrl', function ($scope) { 2 | $scope.alerts = [ 3 | { type: 'danger', msg: 'Oh snap! Change a few things up and try submitting again.' }, 4 | { type: 'success', msg: 'Well done! You successfully read this important alert message.' } 5 | ]; 6 | 7 | $scope.addAlert = function() { 8 | $scope.alerts.push({msg: 'Another alert!'}); 9 | }; 10 | 11 | $scope.closeAlert = function(index) { 12 | $scope.alerts.splice(index, 1); 13 | }; 14 | }); -------------------------------------------------------------------------------- /src/alert/docs/readme.md: -------------------------------------------------------------------------------- 1 | This directive can be used both to generate alerts from static and dynamic model data (using the `ng-repeat` directive). 2 | 3 | ### uib-alert settings 4 | 5 | * `close()` 6 | $ - 7 | A callback function that gets fired when an `alert` is closed. If the attribute exists, a close button is displayed as well. 8 | 9 | * `dismiss-on-timeout` 10 | _(Default: `none`)_ - 11 | Takes the number of milliseconds that specify the timeout duration, after which the alert will be closed. This attribute requires the presence of the `close` attribute. 12 | 13 | * `template-url` 14 | _(Default: `uib/template/alert/alert.html`)_ - 15 | Add the ability to override the template used in the component. 16 | -------------------------------------------------------------------------------- /src/alert/index.js: -------------------------------------------------------------------------------- 1 | require('../../template/alert/alert.html.js'); 2 | require('./alert'); 3 | 4 | var MODULE_NAME = 'ui.bootstrap.module.alert'; 5 | 6 | angular.module(MODULE_NAME, ['ui.bootstrap.alert', 'uib/template/alert/alert.html']); 7 | 8 | module.exports = MODULE_NAME; 9 | -------------------------------------------------------------------------------- /src/buttons/buttons.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.buttons', []) 2 | 3 | .constant('uibButtonConfig', { 4 | activeClass: 'active', 5 | toggleEvent: 'click' 6 | }) 7 | 8 | .controller('UibButtonsController', ['uibButtonConfig', function(buttonConfig) { 9 | this.activeClass = buttonConfig.activeClass || 'active'; 10 | this.toggleEvent = buttonConfig.toggleEvent || 'click'; 11 | }]) 12 | 13 | .directive('uibBtnRadio', ['$parse', function($parse) { 14 | return { 15 | require: ['uibBtnRadio', 'ngModel'], 16 | controller: 'UibButtonsController', 17 | controllerAs: 'buttons', 18 | link: function(scope, element, attrs, ctrls) { 19 | var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1]; 20 | var uncheckableExpr = $parse(attrs.uibUncheckable); 21 | 22 | element.find('input').css({display: 'none'}); 23 | 24 | //model -> UI 25 | ngModelCtrl.$render = function() { 26 | element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, scope.$eval(attrs.uibBtnRadio))); 27 | }; 28 | 29 | //ui->model 30 | element.on(buttonsCtrl.toggleEvent, function() { 31 | if (attrs.disabled) { 32 | return; 33 | } 34 | 35 | var isActive = element.hasClass(buttonsCtrl.activeClass); 36 | 37 | if (!isActive || angular.isDefined(attrs.uncheckable)) { 38 | scope.$apply(function() { 39 | ngModelCtrl.$setViewValue(isActive ? null : scope.$eval(attrs.uibBtnRadio)); 40 | ngModelCtrl.$render(); 41 | }); 42 | } 43 | }); 44 | 45 | if (attrs.uibUncheckable) { 46 | scope.$watch(uncheckableExpr, function(uncheckable) { 47 | attrs.$set('uncheckable', uncheckable ? '' : undefined); 48 | }); 49 | } 50 | } 51 | }; 52 | }]) 53 | 54 | .directive('uibBtnCheckbox', function() { 55 | return { 56 | require: ['uibBtnCheckbox', 'ngModel'], 57 | controller: 'UibButtonsController', 58 | controllerAs: 'button', 59 | link: function(scope, element, attrs, ctrls) { 60 | var buttonsCtrl = ctrls[0], ngModelCtrl = ctrls[1]; 61 | 62 | element.find('input').css({display: 'none'}); 63 | 64 | function getTrueValue() { 65 | return getCheckboxValue(attrs.btnCheckboxTrue, true); 66 | } 67 | 68 | function getFalseValue() { 69 | return getCheckboxValue(attrs.btnCheckboxFalse, false); 70 | } 71 | 72 | function getCheckboxValue(attribute, defaultValue) { 73 | return angular.isDefined(attribute) ? scope.$eval(attribute) : defaultValue; 74 | } 75 | 76 | //model -> UI 77 | ngModelCtrl.$render = function() { 78 | element.toggleClass(buttonsCtrl.activeClass, angular.equals(ngModelCtrl.$modelValue, getTrueValue())); 79 | }; 80 | 81 | //ui->model 82 | element.on(buttonsCtrl.toggleEvent, function() { 83 | if (attrs.disabled) { 84 | return; 85 | } 86 | 87 | scope.$apply(function() { 88 | ngModelCtrl.$setViewValue(element.hasClass(buttonsCtrl.activeClass) ? getFalseValue() : getTrueValue()); 89 | ngModelCtrl.$render(); 90 | }); 91 | }); 92 | } 93 | }; 94 | }); 95 | -------------------------------------------------------------------------------- /src/buttons/docs/demo.html: -------------------------------------------------------------------------------- 1 |
2 |

Single toggle

3 |
{{singleModel}}
4 | 7 |

Checkbox

8 |
Model: {{checkModel}}
9 |
Results: {{checkResults}}
10 |
11 | 12 | 13 | 14 |
15 |

Radio & Uncheckable Radio

16 |
{{radioModel || 'null'}}
17 |
18 | 19 | 20 | 21 |
22 |
23 | 24 | 25 | 26 |
27 |
28 | 31 |
32 |
33 | -------------------------------------------------------------------------------- /src/buttons/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('ButtonsCtrl', function ($scope) { 2 | $scope.singleModel = 1; 3 | 4 | $scope.radioModel = 'Middle'; 5 | 6 | $scope.checkModel = { 7 | left: false, 8 | middle: true, 9 | right: false 10 | }; 11 | 12 | $scope.checkResults = []; 13 | 14 | $scope.$watchCollection('checkModel', function () { 15 | $scope.checkResults = []; 16 | angular.forEach($scope.checkModel, function (value, key) { 17 | if (value) { 18 | $scope.checkResults.push(key); 19 | } 20 | }); 21 | }); 22 | }); -------------------------------------------------------------------------------- /src/buttons/docs/readme.md: -------------------------------------------------------------------------------- 1 | With the buttons directive, we can make a group of buttons behave like a set of checkboxes (`uib-btn-checkbox`) or behave like a set of radio buttons (`uib-btn-radio`). 2 | 3 | ### uib-btn-checkbox settings 4 | 5 | * `btn-checkbox-false` 6 | _(Default: `false`)_ - 7 | Sets the value for the unchecked status. 8 | 9 | * `btn-checkbox-true` 10 | _(Default: `true`)_ - 11 | Sets the value for the checked status. 12 | 13 | * `ng-model` 14 | $ 15 | - 16 | Model where we set the checkbox status. By default `true` or `false`. 17 | 18 | ### uib-btn-radio settings 19 | 20 | * `ng-model` 21 | $ 22 | - 23 | Model where we set the radio status. All radio buttons in a group should use the same `ng-model`. 24 | 25 | * `uib-btn-radio` - 26 | $ 27 | Value to assign to the `ng-model` if we check this radio button. 28 | 29 | * `uib-uncheckable` 30 | $ 31 | _(Default: `null`)_ - 32 | An expression that evaluates to a truthy or falsy value that determines whether the `uncheckable` attribute is present. 33 | 34 | * `uncheckable` 35 | B - 36 | Whether a radio button can be unchecked or not. 37 | 38 | ### Additional settings `uibButtonConfig` 39 | 40 | * `activeClass` 41 | _(Default: `active`)_ - 42 | Class to apply to the checked buttons. 43 | 44 | * `toggleEvent` 45 | _(Default: `click`)_ - 46 | Event used to toggle the buttons. 47 | 48 | ### Known issues 49 | 50 | To use tooltips or popovers on elements within a `btn-group`, set the tooltip/popover `appendToBody` option to `true`. This is due to Bootstrap CSS styling. See [here](http://getbootstrap.com/components/#btn-groups) for more information. 51 | -------------------------------------------------------------------------------- /src/buttons/index.js: -------------------------------------------------------------------------------- 1 | require('./buttons'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.buttons'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.buttons']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/carousel/carousel.css: -------------------------------------------------------------------------------- 1 | .ng-animate.item:not(.left):not(.right) { 2 | -webkit-transition: 0s ease-in-out left; 3 | transition: 0s ease-in-out left 4 | } 5 | -------------------------------------------------------------------------------- /src/carousel/docs/README.md: -------------------------------------------------------------------------------- 1 | Carousel creates a carousel similar to bootstrap's image carousel. 2 | 3 | The carousel also offers support for touchscreen devices in the form of swiping. To enable swiping, load the `ngTouch` module as a dependency. 4 | 5 | Use a `` element with `` elements inside it. 6 | 7 | ### uib-carousel settings 8 | 9 | * `active` 10 | 11 | _(Default: `Index of first slide`)_ - 12 | Index of current active slide. 13 | 14 | * `interval` 15 | $ 16 | 17 | _(Default: `none`)_ - 18 | Sets an interval to cycle through the slides. You need a number bigger than 0 to make the interval work. 19 | 20 | * `no-pause` 21 | $ 22 | 23 | _(Default: `false`)_ - 24 | The interval pauses on mouseover. Setting this to truthy, disables this pause. 25 | 26 | * `no-transition` 27 | $ 28 | 29 | _(Default: `false`)_ - 30 | Whether to disable the transition animation between slides. Setting this to truthy, disables this transition. 31 | 32 | * `no-wrap` 33 | $ 34 | _(Default: `false`)_ - 35 | Disables the looping of slides. Setting `no-wrap` to an expression which evaluates to a truthy value will prevent looping. 36 | 37 | * `template-url` 38 | _(Default: `uib/template/carousel/carousel.html`)_ - 39 | Add the ability to override the template used on the component. 40 | 41 | ### uib-slide settings 42 | 43 | * `actual` 44 | $ 45 | 46 | _(Default: `none`)_ - 47 | Use this attribute to bind the slide model (or any object of interest) onto the slide scope, which makes it available for customization in the carousel template. 48 | 49 | * `index` 50 | $ 51 | 52 | _(Default: `none`)_ - 53 | The index of the slide. Must be unique. 54 | 55 | * `template-url` 56 | _(Default: `uib/template/carousel/slide.html`)_ - 57 | Add the ability to override the template used on the component. 58 | -------------------------------------------------------------------------------- /src/carousel/docs/demo.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 10 |
11 |
12 |
13 |
14 |
15 | 16 | 17 |
18 | 22 |
23 |
24 |
25 | Interval, in milliseconds: 26 |
Enter a negative number or 0 to stop the interval. 27 |
28 |
29 |
30 | -------------------------------------------------------------------------------- /src/carousel/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('CarouselDemoCtrl', function ($scope) { 2 | $scope.myInterval = 5000; 3 | $scope.noWrapSlides = false; 4 | $scope.active = 0; 5 | var slides = $scope.slides = []; 6 | var currIndex = 0; 7 | 8 | $scope.addSlide = function() { 9 | var newWidth = 600 + slides.length + 1; 10 | slides.push({ 11 | image: '//unsplash.it/' + newWidth + '/300', 12 | text: ['Nice image','Awesome photograph','That is so cool','I love that'][slides.length % 4], 13 | id: currIndex++ 14 | }); 15 | }; 16 | 17 | $scope.randomize = function() { 18 | var indexes = generateIndexesArray(); 19 | assignNewIndexesToSlides(indexes); 20 | }; 21 | 22 | for (var i = 0; i < 4; i++) { 23 | $scope.addSlide(); 24 | } 25 | 26 | // Randomize logic below 27 | 28 | function assignNewIndexesToSlides(indexes) { 29 | for (var i = 0, l = slides.length; i < l; i++) { 30 | slides[i].id = indexes.pop(); 31 | } 32 | } 33 | 34 | function generateIndexesArray() { 35 | var indexes = []; 36 | for (var i = 0; i < currIndex; ++i) { 37 | indexes[i] = i; 38 | } 39 | return shuffle(indexes); 40 | } 41 | 42 | // http://stackoverflow.com/questions/962802#962890 43 | function shuffle(array) { 44 | var tmp, current, top = array.length; 45 | 46 | if (top) { 47 | while (--top) { 48 | current = Math.floor(Math.random() * (top + 1)); 49 | tmp = array[current]; 50 | array[current] = array[top]; 51 | array[top] = tmp; 52 | } 53 | } 54 | 55 | return array; 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /src/carousel/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../../template/carousel/carousel.html.js'); 2 | require('../../template/carousel/slide.html.js'); 3 | require('./carousel'); 4 | 5 | var MODULE_NAME = 'ui.bootstrap.module.carousel'; 6 | 7 | angular.module(MODULE_NAME, ['ui.bootstrap.carousel', 'uib/template/carousel/carousel.html', 'uib/template/carousel/slide.html']); 8 | 9 | module.exports = MODULE_NAME; 10 | -------------------------------------------------------------------------------- /src/carousel/index.js: -------------------------------------------------------------------------------- 1 | require('../common/svg-icon.css'); 2 | require('./carousel.css'); 3 | module.exports = require('./index-nocss.js'); 4 | -------------------------------------------------------------------------------- /src/collapse/docs/demo.html: -------------------------------------------------------------------------------- 1 | 9 |
10 |

Resize window to less than 768 pixels to display mobile menu toggle button.

11 | 28 |
29 | 30 |
31 |
32 |
33 |
34 | Some content 35 |
36 |
37 |
38 | 39 | 40 |
41 |
42 |
43 |
44 | Some content 45 |
46 |
47 |
48 |
49 | -------------------------------------------------------------------------------- /src/collapse/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('CollapseDemoCtrl', function ($scope) { 2 | $scope.isNavCollapsed = true; 3 | $scope.isCollapsed = false; 4 | $scope.isCollapsedHorizontal = false; 5 | }); 6 | -------------------------------------------------------------------------------- /src/collapse/docs/readme.md: -------------------------------------------------------------------------------- 1 | **uib-collapse** provides a simple way to hide and show an element with a css transition 2 | 3 | ### uib-collapse settings 4 | 5 | * `collapsed()` 6 | $ - 7 | An optional expression called after the element finished collapsing. 8 | 9 | * `collapsing()` 10 | $ - 11 | An optional expression called before the element begins collapsing. 12 | If the expression returns a promise, animation won't start until the promise resolves. 13 | If the returned promise is rejected, collapsing will be cancelled. 14 | 15 | * `expanded()` 16 | $ - 17 | An optional expression called after the element finished expanding. 18 | 19 | * `expanding()` 20 | $ - 21 | An optional expression called before the element begins expanding. 22 | If the expression returns a promise, animation won't start until the promise resolves. 23 | If the returned promise is rejected, expanding will be cancelled. 24 | 25 | * `uib-collapse` 26 | $ 27 | 28 | _(Default: `false`)_ - 29 | Whether the element should be collapsed or not. 30 | 31 | * `horizontal` 32 | $ - 33 | An optional attribute that permit to collapse horizontally. 34 | 35 | ### Known Issues 36 | 37 | When using the `horizontal` attribute with this directive, CSS can reflow as the collapse element goes from `0px` to its desired end width, which can result in height changes. This can cause animations to not appear to run. The best way around this is to set a fixed height via CSS on the horizontal collapse element so that this situation does not occur, and so the animation can run as expected. 38 | -------------------------------------------------------------------------------- /src/collapse/index.js: -------------------------------------------------------------------------------- 1 | require('./collapse'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.collapse'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.collapse']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/common/common.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.common', []); 2 | -------------------------------------------------------------------------------- /src/common/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('./common.js'); 2 | var MODULE_NAME = 'ui.bootstrap.module.common'; 3 | 4 | angular.module(MODULE_NAME, ['ui.bootstrap.common']); 5 | 6 | module.exports = MODULE_NAME; 7 | -------------------------------------------------------------------------------- /src/common/index.js: -------------------------------------------------------------------------------- 1 | require('./svg-icon.css'); 2 | module.exports = require('./index-nocss.js'); 3 | -------------------------------------------------------------------------------- /src/common/svg-icon.css: -------------------------------------------------------------------------------- 1 | .fa-svg-icon { 2 | display: inline-block; 3 | vertical-align: middle; 4 | min-width: 1em; 5 | min-height: 1em; 6 | height: 100%; 7 | position: relative; 8 | top: -1px; 9 | } 10 | 11 | .fa-svg-icon svg { 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100%; 17 | } 18 | 19 | .fa-svg-icon svg g, 20 | .fa-svg-icon svg path { 21 | fill: currentColor; 22 | } 23 | -------------------------------------------------------------------------------- /src/dateparser/docs/demo.html: -------------------------------------------------------------------------------- 1 |
2 |

Formatting codes playground

3 |

4 | 5 | 6 |

7 |

8 | 9 | 10 |

11 |
12 | -------------------------------------------------------------------------------- /src/dateparser/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('DateParserDemoCtrl', function ($scope, uibDateParser) { 2 | $scope.format = 'yyyy/MM/dd'; 3 | $scope.date = new Date(); 4 | }); 5 | -------------------------------------------------------------------------------- /src/dateparser/index.js: -------------------------------------------------------------------------------- 1 | require('./dateparser'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.dateparser'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.dateparser']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/datepicker/datepicker.css: -------------------------------------------------------------------------------- 1 | .uib-datepicker .uib-title { 2 | width: 100%; 3 | } 4 | 5 | .uib-day button, .uib-month button, .uib-year button { 6 | min-width: 100%; 7 | } 8 | 9 | .uib-left, .uib-right { 10 | width: 100% 11 | } 12 | -------------------------------------------------------------------------------- /src/datepicker/docs/demo.html: -------------------------------------------------------------------------------- 1 | 13 |
14 |
Selected date is: {{dt | date:'fullDate' }}
15 | 16 |

Inline

17 |
18 |
19 |
20 | 21 |
22 | 23 | 24 | 25 | 26 |
27 | -------------------------------------------------------------------------------- /src/datepicker/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('DatepickerDemoCtrl', function ($scope) { 2 | $scope.today = function() { 3 | $scope.dt = new Date(); 4 | }; 5 | $scope.today(); 6 | 7 | $scope.clear = function() { 8 | $scope.dt = null; 9 | }; 10 | 11 | $scope.options = { 12 | customClass: getDayClass, 13 | minDate: new Date(), 14 | showWeeks: true 15 | }; 16 | 17 | // Disable weekend selection 18 | function disabled(data) { 19 | var date = data.date, 20 | mode = data.mode; 21 | return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6); 22 | } 23 | 24 | $scope.toggleMin = function() { 25 | $scope.options.minDate = $scope.options.minDate ? null : new Date(); 26 | }; 27 | 28 | $scope.toggleMin(); 29 | 30 | $scope.setDate = function(year, month, day) { 31 | $scope.dt = new Date(year, month, day); 32 | }; 33 | 34 | var tomorrow = new Date(); 35 | tomorrow.setDate(tomorrow.getDate() + 1); 36 | var afterTomorrow = new Date(tomorrow); 37 | afterTomorrow.setDate(tomorrow.getDate() + 1); 38 | $scope.events = [ 39 | { 40 | date: tomorrow, 41 | status: 'full' 42 | }, 43 | { 44 | date: afterTomorrow, 45 | status: 'partially' 46 | } 47 | ]; 48 | 49 | function getDayClass(data) { 50 | var date = data.date, 51 | mode = data.mode; 52 | if (mode === 'day') { 53 | var dayToCheck = new Date(date).setHours(0,0,0,0); 54 | 55 | for (var i = 0; i < $scope.events.length; i++) { 56 | var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0); 57 | 58 | if (dayToCheck === currentDay) { 59 | return $scope.events[i].status; 60 | } 61 | } 62 | } 63 | 64 | return ''; 65 | } 66 | }); 67 | -------------------------------------------------------------------------------- /src/datepicker/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../dateparser'); 2 | require('../isClass'); 3 | require('../../template/datepicker/datepicker.html.js'); 4 | require('../../template/datepicker/day.html.js'); 5 | require('../../template/datepicker/month.html.js'); 6 | require('../../template/datepicker/year.html.js'); 7 | require('./datepicker'); 8 | 9 | var MODULE_NAME = 'ui.bootstrap.module.datepicker'; 10 | 11 | angular.module(MODULE_NAME, ['ui.bootstrap.datepicker', 'uib/template/datepicker/datepicker.html', 'uib/template/datepicker/day.html', 'uib/template/datepicker/month.html', 'uib/template/datepicker/year.html']); 12 | 13 | module.exports = MODULE_NAME; 14 | -------------------------------------------------------------------------------- /src/datepicker/index.js: -------------------------------------------------------------------------------- 1 | require('../common/svg-icon.css'); 2 | require('./datepicker.css'); 3 | module.exports = require('./index-nocss.js'); 4 | -------------------------------------------------------------------------------- /src/datepickerPopup/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('DatepickerPopupDemoCtrl', function ($scope) { 2 | $scope.today = function() { 3 | $scope.dt = new Date(); 4 | }; 5 | $scope.today(); 6 | 7 | $scope.clear = function() { 8 | $scope.dt = null; 9 | }; 10 | 11 | $scope.inlineOptions = { 12 | customClass: getDayClass, 13 | minDate: new Date(), 14 | showWeeks: true 15 | }; 16 | 17 | $scope.dateOptions = { 18 | dateDisabled: disabled, 19 | formatYear: 'yy', 20 | maxDate: new Date(2020, 5, 22), 21 | minDate: new Date(), 22 | startingDay: 1 23 | }; 24 | 25 | // Disable weekend selection 26 | function disabled(data) { 27 | var date = data.date, 28 | mode = data.mode; 29 | return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6); 30 | } 31 | 32 | $scope.toggleMin = function() { 33 | $scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date(); 34 | $scope.dateOptions.minDate = $scope.inlineOptions.minDate; 35 | }; 36 | 37 | $scope.toggleMin(); 38 | 39 | $scope.open1 = function() { 40 | $scope.popup1.opened = true; 41 | }; 42 | 43 | $scope.open2 = function() { 44 | $scope.popup2.opened = true; 45 | }; 46 | 47 | $scope.setDate = function(year, month, day) { 48 | $scope.dt = new Date(year, month, day); 49 | }; 50 | 51 | $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate']; 52 | $scope.format = $scope.formats[0]; 53 | $scope.altInputFormats = ['M!/d!/yyyy']; 54 | 55 | $scope.popup1 = { 56 | opened: false 57 | }; 58 | 59 | $scope.popup2 = { 60 | opened: false 61 | }; 62 | 63 | var tomorrow = new Date(); 64 | tomorrow.setDate(tomorrow.getDate() + 1); 65 | var afterTomorrow = new Date(); 66 | afterTomorrow.setDate(tomorrow.getDate() + 1); 67 | $scope.events = [ 68 | { 69 | date: tomorrow, 70 | status: 'full' 71 | }, 72 | { 73 | date: afterTomorrow, 74 | status: 'partially' 75 | } 76 | ]; 77 | 78 | function getDayClass(data) { 79 | var date = data.date, 80 | mode = data.mode; 81 | if (mode === 'day') { 82 | var dayToCheck = new Date(date).setHours(0,0,0,0); 83 | 84 | for (var i = 0; i < $scope.events.length; i++) { 85 | var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0); 86 | 87 | if (dayToCheck === currentDay) { 88 | return $scope.events[i].status; 89 | } 90 | } 91 | } 92 | 93 | return ''; 94 | } 95 | }); 96 | -------------------------------------------------------------------------------- /src/datepickerPopup/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../datepicker/index-nocss.js'); 2 | require('../position/index-nocss.js'); 3 | require('../../template/datepickerPopup/popup.html.js'); 4 | require('./popup.js'); 5 | 6 | var MODULE_NAME = 'ui.bootstrap.module.datepickerPopup'; 7 | 8 | angular.module(MODULE_NAME, ['ui.bootstrap.datepickerPopup', 'uib/template/datepickerPopup/popup.html', 'ui.bootstrap.module.datepicker']); 9 | 10 | module.exports = MODULE_NAME; 11 | -------------------------------------------------------------------------------- /src/datepickerPopup/index.js: -------------------------------------------------------------------------------- 1 | require('../common/svg-icon.css'); 2 | require('../datepicker/datepicker.css'); 3 | require('../position/position.css'); 4 | require('./popup.css'); 5 | module.exports = require('./index-nocss.js'); 6 | -------------------------------------------------------------------------------- /src/datepickerPopup/popup.css: -------------------------------------------------------------------------------- 1 | .uib-datepicker-popup.dropdown-menu { 2 | display: block; 3 | float: none; 4 | margin: 0; 5 | } 6 | 7 | .uib-button-bar { 8 | padding: 10px; 9 | } 10 | -------------------------------------------------------------------------------- /src/debounce/debounce.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.debounce', []) 2 | /** 3 | * A helper, internal service that debounces a function 4 | */ 5 | .factory('$$debounce', ['$timeout', function($timeout) { 6 | return function(callback, debounceTime) { 7 | var timeoutPromise; 8 | 9 | return function() { 10 | var self = this; 11 | var args = Array.prototype.slice.call(arguments); 12 | if (timeoutPromise) { 13 | $timeout.cancel(timeoutPromise); 14 | } 15 | 16 | timeoutPromise = $timeout(function() { 17 | callback.apply(self, args); 18 | }, debounceTime); 19 | }; 20 | }; 21 | }]); 22 | -------------------------------------------------------------------------------- /src/debounce/index.js: -------------------------------------------------------------------------------- 1 | require('./debounce'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.debounce'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.debounce']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/debounce/test/debounce.spec.js: -------------------------------------------------------------------------------- 1 | describe('$$debounce', function() { 2 | var $$debounce, $timeout, debouncedFunction, i, args; 3 | 4 | beforeEach(module('ui.bootstrap.debounce')); 5 | beforeEach(inject(function(_$$debounce_, _$timeout_) { 6 | $$debounce = _$$debounce_; 7 | $timeout = _$timeout_; 8 | i = 0; 9 | debouncedFunction = $$debounce(function() { 10 | args = Array.prototype.slice.call(arguments); 11 | i++; 12 | }, 100); 13 | })); 14 | 15 | it('should function like a $timeout when called once during timeout', function() { 16 | debouncedFunction(); 17 | $timeout.flush(50); 18 | 19 | expect(i).toBe(0); 20 | 21 | $timeout.flush(50); 22 | 23 | expect(i).toBe(1); 24 | }); 25 | 26 | it('should only execute 100ms after last call when called twice', function() { 27 | debouncedFunction(); 28 | $timeout.flush(50); 29 | 30 | expect(i).toBe(0); 31 | 32 | debouncedFunction(); 33 | $timeout.flush(50); 34 | 35 | expect(i).toBe(0); 36 | 37 | $timeout.flush(50); 38 | 39 | expect(i).toBe(1); 40 | }); 41 | 42 | it('should properly pass arguments to debounced function', function() { 43 | debouncedFunction(1, 2, 3); 44 | $timeout.flush(100); 45 | 46 | expect(args).toEqual([1, 2, 3]); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /src/dropdown/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('DropdownCtrl', function ($scope, $log) { 2 | $scope.items = [ 3 | 'The first choice!', 4 | 'And another choice for you.', 5 | 'but wait! A third!' 6 | ]; 7 | 8 | $scope.status = { 9 | isopen: false 10 | }; 11 | 12 | $scope.toggled = function(open) { 13 | $log.log('Dropdown is now: ', open); 14 | }; 15 | 16 | $scope.toggleDropdown = function($event) { 17 | $event.preventDefault(); 18 | $event.stopPropagation(); 19 | $scope.status.isopen = !$scope.status.isopen; 20 | }; 21 | 22 | $scope.appendToEl = angular.element(document.querySelector('#dropdown-long-content')); 23 | }); 24 | -------------------------------------------------------------------------------- /src/dropdown/docs/readme.md: -------------------------------------------------------------------------------- 1 | Dropdown is a simple directive which will toggle a dropdown menu on click or programmatically. 2 | 3 | This directive is composed by three parts: 4 | 5 | * `uib-dropdown` which transforms a node into a dropdown. 6 | * `uib-dropdown-toggle` which allows the dropdown to be toggled via click. This directive is optional. 7 | * `uib-dropdown-menu` which transforms a node into the popup menu. 8 | 9 | Each of these parts need to be used as attribute directives. 10 | 11 | ### uib-dropdown settings 12 | 13 | * `auto-close` 14 | _(Default: `always`)_ - 15 | Controls the behavior of the menu when clicked. 16 | * `always` - Automatically closes the dropdown when any of its elements is clicked. 17 | * `disabled` - Disables the auto close. You can control it manually with `is-open`. It still gets closed if the toggle is clicked, `esc` is pressed or another dropdown is open. 18 | * `outsideClick` - Closes the dropdown automatically only when the user clicks any element outside the dropdown. 19 | 20 | * `dropdown-append-to` 21 | $ 22 | _(Default: `null`)_ - 23 | Appends the inner dropdown-menu to an arbitrary DOM element. 24 | 25 | * `dropdown-append-to-body` 26 | B 27 | _(Default: `false`)_ - 28 | Appends the inner dropdown-menu to the body element if the attribute is present without a value, or with a non `false` value. 29 | 30 | * `is-open` 31 | $ 32 | 33 | _(Default: `false`)_ - 34 | Defines whether or not the dropdown-menu is open. The `uib-dropdown-toggle` will toggle this attribute on click. 35 | 36 | * `keyboard-nav`: 37 | B 38 | _(Default: `false`)_ - 39 | Enables navigation of dropdown list elements with the arrow keys. 40 | 41 | * `on-toggle(open)` 42 | $ - 43 | An optional expression called when the dropdown menu is opened or closed. 44 | 45 | ### uib-dropdown-menu settings 46 | 47 | * `template-url` 48 | _(Default: `none`)_ - 49 | You may specify a template for the dropdown menu. Check the demos for an example. 50 | 51 | ### Additional settings `uibDropdownConfig` 52 | 53 | * `appendToOpenClass` 54 | _(Default: `uib-dropdown-open`)_ - 55 | Class to apply when the dropdown is open and appended to a different DOM element. 56 | 57 | * `openClass` 58 | _(Default: `open`)_ - 59 | Class to apply when the dropdown is open. 60 | 61 | ### Known issues 62 | 63 | For usage with ngTouch, it is recommended to use the programmatic `is-open` trigger with ng-click - this is due to ngTouch decorating ng-click to prevent propagation of the event. 64 | -------------------------------------------------------------------------------- /src/dropdown/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../multiMap'); 2 | require('../position/index-nocss.js'); 3 | require('./dropdown'); 4 | 5 | var MODULE_NAME = 'ui.bootstrap.module.dropdown'; 6 | 7 | angular.module(MODULE_NAME, ['ui.bootstrap.dropdown']); 8 | 9 | module.exports = MODULE_NAME; 10 | -------------------------------------------------------------------------------- /src/dropdown/index.js: -------------------------------------------------------------------------------- 1 | require('../position/position.css'); 2 | module.exports = require('./index-nocss.js'); 3 | -------------------------------------------------------------------------------- /src/isClass/index.js: -------------------------------------------------------------------------------- 1 | require('./isClass'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.isClass'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.isClass']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/isClass/test/isClass.spec.js: -------------------------------------------------------------------------------- 1 | describe('uibIsClass', function() { 2 | var $rootScope; 3 | 4 | beforeEach(module('ui.bootstrap.isClass')); 5 | beforeEach(inject(function($compile, _$rootScope_) { 6 | $rootScope = _$rootScope_; 7 | $rootScope.activeClass = 'active'; 8 | $rootScope.items = [1, 2, 3]; 9 | element = $compile('
{{ item }}
')($rootScope); 11 | $rootScope.$digest(); 12 | })); 13 | 14 | it('initializes classes correctly', function() { 15 | expect(element.find('.active').length).toEqual(0); 16 | }); 17 | 18 | it('sets classes correctly', function() { 19 | $rootScope.activeItem = 2; 20 | $rootScope.$digest(); 21 | expect(element.find('.active').text()).toEqual('2'); 22 | 23 | $rootScope.items.splice(1, 1); 24 | $rootScope.$digest(); 25 | expect(element.find('.active').length).toEqual(0); 26 | }); 27 | 28 | it('handles removal of items correctly', function() { 29 | $rootScope.activeItem = 2; 30 | $rootScope.$digest(); 31 | expect(element.find('.active').text()).toEqual('2'); 32 | 33 | $rootScope.items.splice(1, 1); 34 | $rootScope.$digest(); 35 | expect(element.find('.active').length).toEqual(0); 36 | 37 | $rootScope.activeItem = 1; 38 | $rootScope.$digest(); 39 | expect(element.find('.active').text()).toEqual('1'); 40 | }); 41 | 42 | it('handles moving of items', function() { 43 | $rootScope.activeItem = 2; 44 | $rootScope.items = [2, 1, 3]; 45 | $rootScope.$digest(); 46 | expect(element.find('.active').text()).toEqual('2'); 47 | expect(element.find('.active').length).toEqual(1); 48 | expect(element.find('.active').index()).toEqual(0); 49 | 50 | $rootScope.items = [4, 3, 2]; 51 | $rootScope.$digest(); 52 | expect(element.find('.active').text()).toEqual('2'); 53 | expect(element.find('.active').length).toEqual(1); 54 | expect(element.find('.active').index()).toEqual(2); 55 | }); 56 | 57 | it('handles emptying and re-adding the items', function() { 58 | $rootScope.activeItem = 2; 59 | $rootScope.items = []; 60 | $rootScope.$digest(); 61 | expect(element.find('.active').length).toEqual(0); 62 | 63 | $rootScope.items = [4, 3, 2]; 64 | $rootScope.$digest(); 65 | expect(element.find('.active').text()).toEqual('2'); 66 | expect(element.find('.active').index()).toEqual(2); 67 | }); 68 | 69 | it('handles undefined items', function() { 70 | $rootScope.activeItem = undefined; 71 | $rootScope.items = []; 72 | $rootScope.$digest(); 73 | expect(element.find('.active').length).toEqual(0); 74 | 75 | $rootScope.items = [4, 3, undefined]; 76 | $rootScope.$digest(); 77 | expect(element.find('.active').length).toEqual(1); 78 | expect(element.find('.active').text()).toEqual(''); 79 | }); 80 | }); -------------------------------------------------------------------------------- /src/modal/docs/demo.html: -------------------------------------------------------------------------------- 1 | 45 | -------------------------------------------------------------------------------- /src/modal/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../multiMap'); 2 | require('../position/index-nocss.js'); 3 | require('../stackedMap'); 4 | require('../../template/modal/window.html.js'); 5 | require('./modal'); 6 | 7 | var MODULE_NAME = 'ui.bootstrap.module.modal'; 8 | 9 | angular.module(MODULE_NAME, ['ui.bootstrap.modal', 'uib/template/modal/window.html']); 10 | 11 | module.exports = MODULE_NAME; 12 | -------------------------------------------------------------------------------- /src/modal/index.js: -------------------------------------------------------------------------------- 1 | require('../position/position.css'); 2 | module.exports = require('./index-nocss.js'); 3 | -------------------------------------------------------------------------------- /src/multiMap/index.js: -------------------------------------------------------------------------------- 1 | require('./multiMap.js'); 2 | -------------------------------------------------------------------------------- /src/multiMap/multiMap.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.multiMap', []) 2 | /** 3 | * A helper, internal data structure that stores all references attached to key 4 | */ 5 | .factory('$$multiMap', function() { 6 | return { 7 | createNew: function() { 8 | var map = {}; 9 | 10 | return { 11 | entries: function() { 12 | return Object.keys(map).map(function(key) { 13 | return { 14 | key: key, 15 | value: map[key] 16 | }; 17 | }); 18 | }, 19 | get: function(key) { 20 | return map[key]; 21 | }, 22 | hasKey: function(key) { 23 | return !!map[key]; 24 | }, 25 | keys: function() { 26 | return Object.keys(map); 27 | }, 28 | put: function(key, value) { 29 | if (!map[key]) { 30 | map[key] = []; 31 | } 32 | 33 | map[key].push(value); 34 | }, 35 | remove: function(key, value) { 36 | var values = map[key]; 37 | 38 | if (!values) { 39 | return; 40 | } 41 | 42 | var idx = values.indexOf(value); 43 | 44 | if (idx !== -1) { 45 | values.splice(idx, 1); 46 | } 47 | 48 | if (!values.length) { 49 | delete map[key]; 50 | } 51 | } 52 | }; 53 | } 54 | }; 55 | }); 56 | -------------------------------------------------------------------------------- /src/multiMap/test/multiMap.spec.js: -------------------------------------------------------------------------------- 1 | describe('multi map', function() { 2 | var multiMap; 3 | 4 | beforeEach(module('ui.bootstrap.multiMap')); 5 | beforeEach(inject(function($$multiMap) { 6 | multiMap = $$multiMap.createNew(); 7 | })); 8 | 9 | it('should add and remove objects by key', function() { 10 | multiMap.put('foo', 'bar'); 11 | 12 | expect(multiMap.get('foo')).toEqual(['bar']); 13 | 14 | multiMap.put('foo', 'baz'); 15 | 16 | expect(multiMap.get('foo')).toEqual(['bar', 'baz']); 17 | 18 | multiMap.remove('foo', 'bar'); 19 | 20 | expect(multiMap.get('foo')).toEqual(['baz']); 21 | 22 | multiMap.remove('foo', 'baz'); 23 | 24 | expect(multiMap.hasKey('foo')).toBe(false); 25 | }); 26 | 27 | it('should support getting the keys', function() { 28 | multiMap.put('foo', 'bar'); 29 | multiMap.put('baz', 'boo'); 30 | 31 | expect(multiMap.keys()).toEqual(['foo', 'baz']); 32 | }); 33 | 34 | it('should return all entries', function() { 35 | multiMap.put('foo', 'bar'); 36 | multiMap.put('foo', 'bar2'); 37 | multiMap.put('baz', 'boo'); 38 | 39 | expect(multiMap.entries()).toEqual([ 40 | { 41 | key: 'foo', 42 | value: ['bar', 'bar2'] 43 | }, 44 | { 45 | key: 'baz', 46 | value: ['boo'] 47 | } 48 | ]); 49 | }); 50 | 51 | it('should preserve semantic of an empty key', function() { 52 | expect(multiMap.get('key')).toBeUndefined(); 53 | }); 54 | 55 | it('should respect removal of non-existing elements', function() { 56 | expect(multiMap.remove('foo', 'bar')).toBeUndefined(); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /src/pager/docs/demo.html: -------------------------------------------------------------------------------- 1 |
2 |

Pager

3 |
You are currently on page {{currentPage}}
4 |
    5 |
    6 | -------------------------------------------------------------------------------- /src/pager/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('PagerDemoCtrl', function($scope) { 2 | $scope.totalItems = 64; 3 | $scope.currentPage = 4; 4 | }); 5 | -------------------------------------------------------------------------------- /src/pager/docs/readme.md: -------------------------------------------------------------------------------- 1 | A lightweight pager directive that is focused on providing previous/next paging functionality 2 | 3 | ### uib-pager settings 4 | 5 | * `align` 6 | C 7 | _(Default: `true`)_ - 8 | Whether to align each link to the sides. 9 | 10 | * `items-per-page` 11 | $ 12 | C 13 | 14 | _(Default: `10`)_ - 15 | Maximum number of items per page. A value less than one indicates all items on one page. 16 | 17 | * `next-text` 18 | C 19 | _(Default: `Next »`)_ - 20 | Text for Next button. 21 | 22 | * `ng-disabled` 23 | $ 24 | 25 | _(Default: `false`)_ - 26 | Used to disable the pager component. 27 | 28 | * `ng-model` 29 | $ 30 | - 31 | Current page number. First page is 1. 32 | 33 | * `num-pages` 34 | $ 35 | readonly 36 | _(Default: `angular.noop`)_ - 37 | An optional expression assigned the total number of pages to display. 38 | 39 | * `previous-text` 40 | C 41 | _(Default: `« Previous`)_ - 42 | Text for Previous button. 43 | 44 | * `template-url` 45 | _(Default: `uib/template/pager/pager.html`)_ - 46 | Override the template for the component with a custom provided template. 47 | 48 | * `total-items` 49 | $ 50 | - 51 | Total number of items in all pages. 52 | -------------------------------------------------------------------------------- /src/pager/index.js: -------------------------------------------------------------------------------- 1 | require('../paging'); 2 | require('../tabindex'); 3 | require('../../template/pager/pager.html.js'); 4 | require('./pager'); 5 | 6 | var MODULE_NAME = 'ui.bootstrap.module.pager'; 7 | 8 | angular.module(MODULE_NAME, ['ui.bootstrap.pager', 'uib/template/pager/pager.html']); 9 | 10 | module.exports = MODULE_NAME; 11 | -------------------------------------------------------------------------------- /src/pager/pager.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.pager', ['ui.bootstrap.paging', 'ui.bootstrap.tabindex']) 2 | 3 | .controller('UibPagerController', ['$scope', '$attrs', 'uibPaging', 'uibPagerConfig', function($scope, $attrs, uibPaging, uibPagerConfig) { 4 | $scope.align = angular.isDefined($attrs.align) ? $scope.$parent.$eval($attrs.align) : uibPagerConfig.align; 5 | 6 | uibPaging.create(this, $scope, $attrs); 7 | }]) 8 | 9 | .constant('uibPagerConfig', { 10 | itemsPerPage: 10, 11 | previousText: '« Previous', 12 | nextText: 'Next »', 13 | align: true 14 | }) 15 | 16 | .directive('uibPager', ['uibPagerConfig', function(uibPagerConfig) { 17 | return { 18 | scope: { 19 | totalItems: '=', 20 | previousText: '@', 21 | nextText: '@', 22 | ngDisabled: '=' 23 | }, 24 | require: ['uibPager', '?ngModel'], 25 | restrict: 'A', 26 | controller: 'UibPagerController', 27 | controllerAs: 'pager', 28 | templateUrl: function(element, attrs) { 29 | return attrs.templateUrl || 'uib/template/pager/pager.html'; 30 | }, 31 | link: function(scope, element, attrs, ctrls) { 32 | element.addClass('pager'); 33 | var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1]; 34 | 35 | if (!ngModelCtrl) { 36 | return; // do nothing if no ng-model 37 | } 38 | 39 | paginationCtrl.init(ngModelCtrl, uibPagerConfig); 40 | } 41 | }; 42 | }]); 43 | -------------------------------------------------------------------------------- /src/pagination/docs/demo.html: -------------------------------------------------------------------------------- 1 |
    2 |

    Default

    3 |
      4 |
        5 |
          6 |
            7 |
            The selected page no: {{currentPage}}
            8 | 9 | 10 |
            11 |

            Limit the maximum visible buttons

            12 |
            rotate defaulted to true:
            13 |
              14 |
              rotate defaulted to true and force-ellipses set to true:
              15 |
                16 |
                rotate set to false:
                17 |
                  18 |
                  boundary-link-numbers set to true and rotate defaulted to true:
                  19 |
                    20 |
                    boundary-link-numbers set to true and rotate set to false:
                    21 |
                      22 |
                      Page: {{bigCurrentPage}} / {{numPages}}
                      23 | 24 |
                      25 | -------------------------------------------------------------------------------- /src/pagination/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('PaginationDemoCtrl', function ($scope, $log) { 2 | $scope.totalItems = 64; 3 | $scope.currentPage = 4; 4 | 5 | $scope.setPage = function (pageNo) { 6 | $scope.currentPage = pageNo; 7 | }; 8 | 9 | $scope.pageChanged = function() { 10 | $log.log('Page changed to: ' + $scope.currentPage); 11 | }; 12 | 13 | $scope.maxSize = 5; 14 | $scope.bigTotalItems = 175; 15 | $scope.bigCurrentPage = 1; 16 | }); 17 | -------------------------------------------------------------------------------- /src/pagination/index.js: -------------------------------------------------------------------------------- 1 | require('../paging'); 2 | require('../tabindex'); 3 | require('../../template/pagination/pagination.html.js'); 4 | require('./pagination'); 5 | 6 | var MODULE_NAME = 'ui.bootstrap.module.pagination'; 7 | 8 | angular.module(MODULE_NAME, ['ui.bootstrap.pagination', 'uib/template/pagination/pagination.html']); 9 | 10 | module.exports = MODULE_NAME; 11 | -------------------------------------------------------------------------------- /src/paging/index.js: -------------------------------------------------------------------------------- 1 | require('./paging'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.paging'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.paging']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/paging/paging.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.paging', []) 2 | /** 3 | * Helper internal service for generating common controller code between the 4 | * pager and pagination components 5 | */ 6 | .factory('uibPaging', ['$parse', function($parse) { 7 | return { 8 | create: function(ctrl, $scope, $attrs) { 9 | ctrl.setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop; 10 | ctrl.ngModelCtrl = { $setViewValue: angular.noop }; // nullModelCtrl 11 | ctrl._watchers = []; 12 | 13 | ctrl.init = function(ngModelCtrl, config) { 14 | ctrl.ngModelCtrl = ngModelCtrl; 15 | ctrl.config = config; 16 | 17 | ngModelCtrl.$render = function() { 18 | ctrl.render(); 19 | }; 20 | 21 | if ($attrs.itemsPerPage) { 22 | ctrl._watchers.push($scope.$parent.$watch($attrs.itemsPerPage, function(value) { 23 | ctrl.itemsPerPage = parseInt(value, 10); 24 | $scope.totalPages = ctrl.calculateTotalPages(); 25 | ctrl.updatePage(); 26 | })); 27 | } else { 28 | ctrl.itemsPerPage = config.itemsPerPage; 29 | } 30 | 31 | $scope.$watch('totalItems', function(newTotal, oldTotal) { 32 | if (angular.isDefined(newTotal) || newTotal !== oldTotal) { 33 | $scope.totalPages = ctrl.calculateTotalPages(); 34 | ctrl.updatePage(); 35 | } 36 | }); 37 | }; 38 | 39 | ctrl.calculateTotalPages = function() { 40 | var totalPages = ctrl.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / ctrl.itemsPerPage); 41 | return Math.max(totalPages || 0, 1); 42 | }; 43 | 44 | ctrl.render = function() { 45 | $scope.page = parseInt(ctrl.ngModelCtrl.$viewValue, 10) || 1; 46 | }; 47 | 48 | $scope.selectPage = function(page, evt) { 49 | if (evt) { 50 | evt.preventDefault(); 51 | } 52 | 53 | var clickAllowed = !$scope.ngDisabled || !evt; 54 | if (clickAllowed && $scope.page !== page && page > 0 && page <= $scope.totalPages) { 55 | if (evt && evt.target) { 56 | evt.target.blur(); 57 | } 58 | ctrl.ngModelCtrl.$setViewValue(page); 59 | ctrl.ngModelCtrl.$render(); 60 | } 61 | }; 62 | 63 | $scope.getText = function(key) { 64 | return $scope[key + 'Text'] || ctrl.config[key + 'Text']; 65 | }; 66 | 67 | $scope.noPrevious = function() { 68 | return $scope.page === 1; 69 | }; 70 | 71 | $scope.noNext = function() { 72 | return $scope.page === $scope.totalPages; 73 | }; 74 | 75 | ctrl.updatePage = function() { 76 | ctrl.setNumPages($scope.$parent, $scope.totalPages); // Readonly variable 77 | 78 | if ($scope.page > $scope.totalPages) { 79 | $scope.selectPage($scope.totalPages); 80 | } else { 81 | ctrl.ngModelCtrl.$render(); 82 | } 83 | }; 84 | 85 | $scope.$on('$destroy', function() { 86 | while (ctrl._watchers.length) { 87 | ctrl._watchers.shift()(); 88 | } 89 | }); 90 | } 91 | }; 92 | }]); 93 | -------------------------------------------------------------------------------- /src/popover/docs/demo.html: -------------------------------------------------------------------------------- 1 |
                      2 |

                      Dynamic

                      3 |
                      4 | 5 | 6 |
                      7 |
                      8 | 9 | 10 |
                      11 |
                      12 | 13 | 14 |
                      15 | 16 | 17 | 18 | 19 | 26 |
                      27 |

                      Positional

                      28 |
                      29 | 30 | 31 |
                      32 | 33 | 34 |
                      35 |

                      Triggers

                      36 |

                      37 | 38 |

                      39 | 40 | 41 |
                      42 |

                      Other

                      43 | 44 | 45 | 46 | 47 | 48 |
                      49 | -------------------------------------------------------------------------------- /src/popover/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) { 2 | $scope.dynamicPopover = { 3 | content: 'Hello, World!', 4 | templateUrl: 'myPopoverTemplate.html', 5 | title: 'Title' 6 | }; 7 | 8 | $scope.placement = { 9 | options: [ 10 | 'top', 11 | 'top-left', 12 | 'top-right', 13 | 'bottom', 14 | 'bottom-left', 15 | 'bottom-right', 16 | 'left', 17 | 'left-top', 18 | 'left-bottom', 19 | 'right', 20 | 'right-top', 21 | 'right-bottom' 22 | ], 23 | selected: 'top' 24 | }; 25 | 26 | $scope.htmlPopover = $sce.trustAsHtml('I can have
                      HTML
                      content'); 27 | }); 28 | -------------------------------------------------------------------------------- /src/popover/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../tooltip/index-nocss.js'); 2 | require('../../template/popover/popover.html.js'); 3 | require('../../template/popover/popover-html.html.js'); 4 | require('../../template/popover/popover-template.html.js'); 5 | require('./popover'); 6 | 7 | var MODULE_NAME = 'ui.bootstrap.module.popover'; 8 | 9 | angular.module(MODULE_NAME, ['ui.bootstrap.popover', 'uib/template/popover/popover.html', 'uib/template/popover/popover-html.html', 'uib/template/popover/popover-template.html']); 10 | 11 | module.exports = MODULE_NAME; 12 | -------------------------------------------------------------------------------- /src/popover/index.js: -------------------------------------------------------------------------------- 1 | require('../tooltip/tooltip.css'); 2 | module.exports = require('./index-nocss.js'); 3 | -------------------------------------------------------------------------------- /src/popover/popover.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The following features are still outstanding: popup delay, animation as a 3 | * function, placement as a function, inside, support for more triggers than 4 | * just mouse enter/leave, and selector delegatation. 5 | */ 6 | angular.module('ui.bootstrap.popover', ['ui.bootstrap.tooltip']) 7 | 8 | .directive('uibPopoverTemplatePopup', function() { 9 | return { 10 | restrict: 'A', 11 | scope: { uibTitle: '@', contentExp: '&', originScope: '&' }, 12 | templateUrl: 'uib/template/popover/popover-template.html' 13 | }; 14 | }) 15 | 16 | .directive('uibPopoverTemplate', ['$uibTooltip', function($uibTooltip) { 17 | return $uibTooltip('uibPopoverTemplate', 'popover', 'click', { 18 | placementClassPrefix: 'bs-popover-', 19 | useContentExp: true 20 | }); 21 | }]) 22 | 23 | .directive('uibPopoverHtmlPopup', function() { 24 | return { 25 | restrict: 'A', 26 | scope: { contentExp: '&', uibTitle: '@' }, 27 | templateUrl: 'uib/template/popover/popover-html.html' 28 | }; 29 | }) 30 | 31 | .directive('uibPopoverHtml', ['$uibTooltip', function($uibTooltip) { 32 | return $uibTooltip('uibPopoverHtml', 'popover', 'click', { 33 | placementClassPrefix: 'bs-popover-', 34 | useContentExp: true 35 | }); 36 | }]) 37 | 38 | .directive('uibPopoverPopup', function() { 39 | return { 40 | restrict: 'A', 41 | scope: { uibTitle: '@', content: '@' }, 42 | templateUrl: 'uib/template/popover/popover.html' 43 | }; 44 | }) 45 | 46 | .directive('uibPopover', ['$uibTooltip', function($uibTooltip) { 47 | return $uibTooltip('uibPopover', 'popover', 'click', { 48 | placementClassPrefix: 'bs-popover-' 49 | }); 50 | }]); 51 | -------------------------------------------------------------------------------- /src/position/docs/demo.html: -------------------------------------------------------------------------------- 1 |
                      2 |

                      $uibPosition service

                      3 |
                      4 |
                      5 | 8 |
                      9 |
                      10 | 13 |
                      14 | 15 | 16 |
                      17 | Demo element 18 |
                      19 |
                      20 |
                      21 | offsetParent: {{elemVals.offsetParent}} 22 |
                      23 | scrollParent: {{elemVals.scrollParent}} 24 |
                      25 | scrollbarWidth: {{scrollbarWidth}} 26 |
                      27 | position: {{elemVals.position}} 28 |
                      29 | offset: {{elemVals.offset}} 30 |
                      31 | viewportOffset: {{elemVals.viewportOffset}} 32 |
                      33 | positionElements: {{elemVals.positionElements}} 34 |
                      35 | -------------------------------------------------------------------------------- /src/position/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('PositionDemoCtrl', function ($scope, $window, $uibPosition) { 2 | 3 | $scope.elemVals = {}; 4 | $scope.parentScrollable = true; 5 | $scope.parentRelative = true; 6 | 7 | $scope.getValues = function() { 8 | var divEl = $window.document.querySelector('#posdemodiv'); 9 | var btnEl = $window.document.querySelector('#posdemobtn'); 10 | 11 | var offsetParent = $uibPosition.offsetParent(divEl); 12 | $scope.elemVals.offsetParent = 'type: ' + offsetParent.tagName + ', id: ' + offsetParent.id; 13 | 14 | var scrollParent = $uibPosition.scrollParent(divEl); 15 | $scope.elemVals.scrollParent = 'type: ' + scrollParent.tagName + ', id: ' + scrollParent.id; 16 | 17 | $scope.scrollbarWidth = $uibPosition.scrollbarWidth(); 18 | 19 | $scope.elemVals.position = $uibPosition.position(divEl); 20 | 21 | $scope.elemVals.offset = $uibPosition.offset(divEl); 22 | 23 | $scope.elemVals.viewportOffset = $uibPosition.viewportOffset(divEl); 24 | 25 | $scope.elemVals.positionElements = $uibPosition.positionElements(btnEl, divEl, 'auto bottom-left'); 26 | }; 27 | }); -------------------------------------------------------------------------------- /src/position/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('./position'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.position'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.position']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/position/index.js: -------------------------------------------------------------------------------- 1 | require('./position.css'); 2 | module.exports = require('./index-nocss.js'); 3 | -------------------------------------------------------------------------------- /src/position/position.css: -------------------------------------------------------------------------------- 1 | .uib-position-measure { 2 | display: block !important; 3 | visibility: hidden !important; 4 | position: absolute !important; 5 | top: -9999px !important; 6 | left: -9999px !important; 7 | } 8 | 9 | .uib-position-scrollbar-measure { 10 | position: absolute !important; 11 | top: -9999px !important; 12 | width: 50px !important; 13 | height: 50px !important; 14 | overflow: scroll !important; 15 | } 16 | 17 | .uib-position-body-scrollbar-measure { 18 | overflow: scroll !important; 19 | } -------------------------------------------------------------------------------- /src/progressbar/docs/demo.html: -------------------------------------------------------------------------------- 1 |
                      2 | 3 |

                      Static

                      4 |
                      5 |
                      6 |
                      22%
                      7 |
                      166 / 200
                      8 |
                      9 | 10 |
                      11 |

                      Dynamic

                      12 | {{dynamic}} / {{max}} 13 | 14 | No animation 15 | {{dynamic}}% 16 | 17 | Object (changes type based on value) 18 | {{type}} !!! Watch out !!! 19 | 20 |
                      21 |

                      Stacked

                      22 | {{bar.value}}% 23 | 24 |
                      -------------------------------------------------------------------------------- /src/progressbar/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('ProgressDemoCtrl', function ($scope) { 2 | $scope.max = 200; 3 | 4 | $scope.random = function() { 5 | var value = Math.floor(Math.random() * 100 + 1); 6 | var type; 7 | 8 | if (value < 25) { 9 | type = 'success'; 10 | } else if (value < 50) { 11 | type = 'info'; 12 | } else if (value < 75) { 13 | type = 'warning'; 14 | } else { 15 | type = 'danger'; 16 | } 17 | 18 | $scope.showWarning = type === 'danger' || type === 'warning'; 19 | 20 | $scope.dynamic = value; 21 | $scope.type = type; 22 | }; 23 | 24 | $scope.random(); 25 | 26 | $scope.randomStacked = function() { 27 | $scope.stacked = []; 28 | var types = ['success', 'info', 'warning', 'danger']; 29 | 30 | for (var i = 0, n = Math.floor(Math.random() * 4 + 1); i < n; i++) { 31 | var index = Math.floor(Math.random() * 4); 32 | $scope.stacked.push({ 33 | value: Math.floor(Math.random() * 30 + 1), 34 | type: types[index] 35 | }); 36 | } 37 | }; 38 | 39 | $scope.randomStacked(); 40 | }); 41 | -------------------------------------------------------------------------------- /src/progressbar/docs/readme.md: -------------------------------------------------------------------------------- 1 | A progress bar directive that is focused on providing feedback on the progress of a workflow or action. 2 | 3 | It supports multiple (stacked) `` into the same `` element or a single `` element with optional `max` attribute and transition animations. 4 | 5 | ### uib-progressbar settings 6 | 7 | * `value` 8 | $ 9 | - 10 | The current value of progress completed. 11 | 12 | * `type` 13 | _(Default: `null`)_ - 14 | Bootstrap style type. Possible values are 'success', 'info', 'warning', and, 'danger' to use Bootstrap's pre-existing styling, or any desired custom suffix. 15 | 16 | * `max` 17 | $ 18 | C 19 | 20 | _(Default: `100`)_ - 21 | A number that specifies the total value of bars that is required. 22 | 23 | * `animate` 24 | $ 25 | C 26 | _(Default: `true`)_ - 27 | Whether bars use transitions to achieve the width change. 28 | 29 | * `title` 30 | _(Default: `progressbar`)_ - 31 | Title to use as label (for accessibility). 32 | 33 | * `striped` 34 | $ 35 | C 36 | _(Default: `false`)_ 37 | 38 | ### uib-progress settings 39 | 40 | * `max` 41 | $ 42 | C 43 | 44 | _(Default: `100`)_ - 45 | A number that specifies the total value of bars that is required. 46 | 47 | * `animate` 48 | $ 49 | C 50 | _(Default: `true`)_ - 51 | Whether bars use transitions to achieve the width change. 52 | 53 | * `title` 54 | _(Default: `progressbar`)_ - 55 | Title to use as label (for accessibility). 56 | 57 | ### uib-bar settings 58 | 59 | * `value` 60 | $ 61 | - 62 | The current value of progress completed. 63 | 64 | * `type` 65 | _(Default: `null`)_ - 66 | Bootstrap style type. Possible values are 'success', 'info', 'warning', and, 'danger' to use Bootstrap's pre-existing styling, or any desired custom suffix. 67 | 68 | * `title` 69 | _(Default: `progressbar`)_ - 70 | Title to use as label (for accessibility). 71 | 72 | * `striped` 73 | $ 74 | C 75 | _(Default: `false`)_ 76 | -------------------------------------------------------------------------------- /src/progressbar/index.js: -------------------------------------------------------------------------------- 1 | require('../../template/progressbar/progressbar.html.js'); 2 | require('../../template/progressbar/progress.html.js'); 3 | require('../../template/progressbar/bar.html.js'); 4 | require('./progressbar'); 5 | 6 | var MODULE_NAME = 'ui.bootstrap.module.progressbar'; 7 | 8 | angular.module(MODULE_NAME, ['ui.bootstrap.progressbar', 'uib/template/progressbar/progressbar.html', 'uib/template/progressbar/progress.html', 'uib/template/progressbar/bar.html']); 9 | 10 | module.exports = MODULE_NAME; 11 | -------------------------------------------------------------------------------- /src/progressbar/progressbar.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.progressbar', []) 2 | 3 | .constant('uibProgressConfig', { 4 | animate: true, 5 | max: 100 6 | }) 7 | 8 | .controller('UibProgressController', ['$scope', '$attrs', 'uibProgressConfig', function($scope, $attrs, progressConfig) { 9 | var self = this, 10 | animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate; 11 | 12 | this.bars = []; 13 | $scope.max = getMaxOrDefault(); 14 | 15 | this.addBar = function(bar, element, attrs) { 16 | if (!animate) { 17 | element.css({'transition': 'none'}); 18 | } 19 | 20 | this.bars.push(bar); 21 | 22 | bar.max = getMaxOrDefault(); 23 | bar.title = attrs && angular.isDefined(attrs.title) ? attrs.title : 'progressbar'; 24 | 25 | bar.$watch('value', function(value) { 26 | bar.recalculatePercentage(); 27 | }); 28 | 29 | bar.recalculatePercentage = function() { 30 | var totalPercentage = self.bars.reduce(function(total, bar) { 31 | bar.percent = +(100 * bar.value / bar.max).toFixed(2); 32 | return total + bar.percent; 33 | }, 0); 34 | 35 | if (totalPercentage > 100) { 36 | bar.percent -= totalPercentage - 100; 37 | } 38 | }; 39 | 40 | bar.$on('$destroy', function() { 41 | element = null; 42 | self.removeBar(bar); 43 | }); 44 | }; 45 | 46 | this.removeBar = function(bar) { 47 | this.bars.splice(this.bars.indexOf(bar), 1); 48 | this.bars.forEach(function (bar) { 49 | bar.recalculatePercentage(); 50 | }); 51 | }; 52 | 53 | //$attrs.$observe('maxParam', function(maxParam) { 54 | $scope.$watch('maxParam', function(maxParam) { 55 | self.bars.forEach(function(bar) { 56 | bar.max = getMaxOrDefault(); 57 | bar.recalculatePercentage(); 58 | }); 59 | }); 60 | 61 | function getMaxOrDefault () { 62 | return angular.isDefined($scope.maxParam) ? $scope.maxParam : progressConfig.max; 63 | } 64 | }]) 65 | 66 | .directive('uibProgress', function() { 67 | return { 68 | replace: true, 69 | transclude: true, 70 | controller: 'UibProgressController', 71 | require: 'uibProgress', 72 | scope: { 73 | maxParam: '=?max' 74 | }, 75 | templateUrl: 'uib/template/progressbar/progress.html' 76 | }; 77 | }) 78 | 79 | .directive('uibBar', function() { 80 | return { 81 | replace: true, 82 | transclude: true, 83 | require: '^uibProgress', 84 | scope: { 85 | value: '=', 86 | type: '@', 87 | striped: '=?' 88 | }, 89 | templateUrl: 'uib/template/progressbar/bar.html', 90 | link: function(scope, element, attrs, progressCtrl) { 91 | progressCtrl.addBar(scope, element, attrs); 92 | } 93 | }; 94 | }) 95 | 96 | .directive('uibProgressbar', function() { 97 | return { 98 | replace: true, 99 | transclude: true, 100 | controller: 'UibProgressController', 101 | scope: { 102 | value: '=', 103 | maxParam: '=?max', 104 | type: '@', 105 | striped: '=?' 106 | }, 107 | templateUrl: 'uib/template/progressbar/progressbar.html', 108 | link: function(scope, element, attrs, progressCtrl) { 109 | progressCtrl.addBar(scope, angular.element(element.children()[0]), {title: attrs.title}); 110 | } 111 | }; 112 | }); 113 | -------------------------------------------------------------------------------- /src/rating/docs/demo.html: -------------------------------------------------------------------------------- 1 |
                      2 |

                      Default

                      3 | 4 | {{percent}}% 5 | 6 |
                      Rate: {{rate}} - Readonly is: {{isReadonly}} - Hovering over: {{overStar || "none"}}
                      7 | 8 | 9 | 10 |
                      11 | 12 |

                      Custom icons

                      13 |
                      (Rate: {{x}})
                      14 |
                      (Rate: {{y}})
                      15 |
                      16 | -------------------------------------------------------------------------------- /src/rating/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('RatingDemoCtrl', function ($scope) { 2 | $scope.rate = 7; 3 | $scope.max = 10; 4 | $scope.isReadonly = false; 5 | 6 | $scope.hoveringOver = function(value) { 7 | $scope.overStar = value; 8 | $scope.percent = 100 * (value / $scope.max); 9 | }; 10 | 11 | $scope.ratingStates = [ 12 | {stateOn: 'glyphicon-ok-sign', stateOff: 'glyphicon-ok-circle'}, 13 | {stateOn: 'glyphicon-star', stateOff: 'glyphicon-star-empty'}, 14 | {stateOn: 'glyphicon-heart', stateOff: 'glyphicon-ban-circle'}, 15 | {stateOn: 'glyphicon-heart'}, 16 | {stateOff: 'glyphicon-off'} 17 | ]; 18 | }); 19 | -------------------------------------------------------------------------------- /src/rating/docs/readme.md: -------------------------------------------------------------------------------- 1 | Rating directive that will take care of visualising a star rating bar. 2 | 3 | ### uib-rating settings 4 | 5 | * `max` 6 | $ 7 | C 8 | _(Default: `5`)_ - 9 | Changes the number of icons. 10 | 11 | * `ng-model` 12 | $ 13 | - 14 | The current rate. 15 | 16 | * `on-hover(value)` 17 | $ - 18 | An optional expression called when user's mouse is over a particular icon. 19 | 20 | * `on-leave()` 21 | $ - 22 | An optional expression called when user's mouse leaves the control altogether. 23 | 24 | * `rating-states` 25 | $ 26 | _(Default: `null`)_ - 27 | An array of objects defining properties for all icons. In default template, `stateOn` & `stateOff` property is used to specify the icon's class. 28 | 29 | * `read-only` 30 | $ 31 | 32 | _(Default: `false`)_ - 33 | Prevent user's interaction. 34 | 35 | * `titles` 36 | $ 37 | C 38 | _(Default: ['one', 'two', 'three', 'four', 'five']`)_ - 39 | An array of strings defining titles for all icons. 40 | 41 | * `enable-reset` 42 | $ 43 | _(Default: `true`)_ - 44 | Clicking the icon of the current rating will reset the rating to 0. 45 | 46 | * `state-off` 47 | $ 48 | C 49 | _(Default: `null`)_ - 50 | A variable used in the template to specify the state for unselected icons. 51 | 52 | * `state-on` 53 | $ 54 | C 55 | _(Default: `null`)_ - 56 | A variable used in the template to specify the state (class, src, etc) for selected icons. 57 | -------------------------------------------------------------------------------- /src/rating/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../../template/rating/rating.html.js'); 2 | require('./rating'); 3 | 4 | var MODULE_NAME = 'ui.bootstrap.module.rating'; 5 | 6 | angular.module(MODULE_NAME, ['ui.bootstrap.rating', 'uib/template/rating/rating.html']); 7 | 8 | module.exports = MODULE_NAME; 9 | -------------------------------------------------------------------------------- /src/rating/index.js: -------------------------------------------------------------------------------- 1 | require('../common/svg-icon.css'); 2 | module.exports = require('./index-nocss.js'); 3 | -------------------------------------------------------------------------------- /src/stackedMap/index.js: -------------------------------------------------------------------------------- 1 | require('./stackedMap'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.stackedMap'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.stackedMap']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/stackedMap/stackedMap.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.stackedMap', []) 2 | /** 3 | * A helper, internal data structure that acts as a map but also allows getting / removing 4 | * elements in the LIFO order 5 | */ 6 | .factory('$$stackedMap', function() { 7 | return { 8 | createNew: function() { 9 | var stack = []; 10 | 11 | return { 12 | add: function(key, value) { 13 | stack.push({ 14 | key: key, 15 | value: value 16 | }); 17 | }, 18 | get: function(key) { 19 | for (var i = 0; i < stack.length; i++) { 20 | if (key === stack[i].key) { 21 | return stack[i]; 22 | } 23 | } 24 | }, 25 | keys: function() { 26 | var keys = []; 27 | for (var i = 0; i < stack.length; i++) { 28 | keys.push(stack[i].key); 29 | } 30 | return keys; 31 | }, 32 | top: function() { 33 | return stack[stack.length - 1]; 34 | }, 35 | remove: function(key) { 36 | var idx = -1; 37 | for (var i = 0; i < stack.length; i++) { 38 | if (key === stack[i].key) { 39 | idx = i; 40 | break; 41 | } 42 | } 43 | return stack.splice(idx, 1)[0]; 44 | }, 45 | removeTop: function() { 46 | return stack.pop(); 47 | }, 48 | length: function() { 49 | return stack.length; 50 | } 51 | }; 52 | } 53 | }; 54 | }); -------------------------------------------------------------------------------- /src/stackedMap/test/stackedMap.spec.js: -------------------------------------------------------------------------------- 1 | describe('stacked map', function() { 2 | var stackedMap; 3 | 4 | beforeEach(module('ui.bootstrap.modal')); 5 | beforeEach(inject(function ($$stackedMap) { 6 | stackedMap = $$stackedMap.createNew(); 7 | })); 8 | 9 | it('should add and remove objects by key', function() { 10 | stackedMap.add('foo', 'foo_value'); 11 | expect(stackedMap.length()).toEqual(1); 12 | expect(stackedMap.get('foo').key).toEqual('foo'); 13 | expect(stackedMap.get('foo').value).toEqual('foo_value'); 14 | 15 | stackedMap.remove('foo'); 16 | expect(stackedMap.length()).toEqual(0); 17 | expect(stackedMap.get('foo')).toBeUndefined(); 18 | }); 19 | 20 | it('should support listing keys', function() { 21 | stackedMap.add('foo', 'foo_value'); 22 | stackedMap.add('bar', 'bar_value'); 23 | 24 | expect(stackedMap.keys()).toEqual(['foo', 'bar']); 25 | }); 26 | 27 | it('should get topmost element', function() { 28 | stackedMap.add('foo', 'foo_value'); 29 | stackedMap.add('bar', 'bar_value'); 30 | expect(stackedMap.length()).toEqual(2); 31 | 32 | expect(stackedMap.top().key).toEqual('bar'); 33 | expect(stackedMap.length()).toEqual(2); 34 | }); 35 | 36 | it('should remove topmost element', function() { 37 | stackedMap.add('foo', 'foo_value'); 38 | stackedMap.add('bar', 'bar_value'); 39 | 40 | expect(stackedMap.removeTop().key).toEqual('bar'); 41 | expect(stackedMap.removeTop().key).toEqual('foo'); 42 | }); 43 | 44 | it('should preserve semantic of an empty stackedMap', function() { 45 | expect(stackedMap.length()).toEqual(0); 46 | expect(stackedMap.top()).toBeUndefined(); 47 | }); 48 | 49 | it('should ignore removal of non-existing elements', function() { 50 | expect(stackedMap.remove('non-existing')).toBeUndefined(); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /src/tabindex/index.js: -------------------------------------------------------------------------------- 1 | require('./tabindex'); 2 | 3 | var MODULE_NAME = 'ui.bootstrap.module.tabindex'; 4 | 5 | angular.module(MODULE_NAME, ['ui.bootstrap.tabindex']); 6 | 7 | module.exports = MODULE_NAME; 8 | -------------------------------------------------------------------------------- /src/tabindex/tabindex.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.tabindex', []) 2 | 3 | .directive('uibTabindexToggle', function() { 4 | return { 5 | restrict: 'A', 6 | link: function(scope, elem, attrs) { 7 | attrs.$observe('disabled', function(disabled) { 8 | attrs.$set('tabindex', disabled ? -1 : null); 9 | }); 10 | } 11 | }; 12 | }); 13 | -------------------------------------------------------------------------------- /src/tabindex/test/tabindex.spec.js: -------------------------------------------------------------------------------- 1 | describe('tabindex toggle directive', function() { 2 | var $rootScope, element; 3 | beforeEach(module('ui.bootstrap.tabindex')); 4 | beforeEach(inject(function($compile, _$rootScope_) { 5 | $rootScope = _$rootScope_; 6 | element = $compile('foo')($rootScope); 7 | $rootScope.$digest(); 8 | })); 9 | 10 | it('should toggle the tabindex on disabled toggle', function() { 11 | expect(element.prop('tabindex')).toBe(0); 12 | 13 | $rootScope.disabled = true; 14 | $rootScope.$digest(); 15 | 16 | expect(element.prop('tabindex')).toBe(-1); 17 | 18 | $rootScope.disabled = false; 19 | $rootScope.$digest(); 20 | 21 | expect(element.prop('tabindex')).toBe(0); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/tabs/docs/demo.html: -------------------------------------------------------------------------------- 1 | 6 | 7 |
                      8 |

                      Select a tab by setting active binding to true:

                      9 |

                      10 | 11 | 12 |

                      13 |

                      14 | 15 |

                      16 |
                      17 | 18 | 19 | Static content 20 | 21 | {{tab.content}} 22 | 23 | 24 | 25 | 26 | 27 | 28 | Alert! 29 | 30 | I've got an HTML heading, and a select callback. Pretty cool! 31 | 32 | 33 | 34 |
                      35 | 36 | 37 | Vertical content 1 38 | Vertical content 2 39 | 40 | 41 |
                      42 | 43 | 44 | Justified content 45 | Short Labeled Justified content 46 | Long Labeled Justified content 47 | 48 | 49 |
                      50 | 51 | Tabbed pills with CSS classes 52 | 53 | Tab 1 content 54 | Tab 2 content 55 | 56 | 57 |
                      58 | 59 | Tabs using nested forms: 60 |
                      61 | 62 | 63 | 64 |
                      65 | 66 | 67 |
                      68 |
                      69 |
                      70 | 71 | Some Tab Content 72 | 73 | 74 | More Tab Content 75 | 76 |
                      77 |
                      78 | Model: 79 |
                      {{ model | json }}
                      80 | Nested Form: 81 |
                      {{ outerForm.nestedForm | json }}
                      82 |
                      83 | -------------------------------------------------------------------------------- /src/tabs/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('TabsDemoCtrl', function ($scope, $window) { 2 | $scope.tabs = [ 3 | { title:'Dynamic Title 1', content:'Dynamic content 1' }, 4 | { title:'Dynamic Title 2', content:'Dynamic content 2', disabled: true } 5 | ]; 6 | 7 | $scope.alertMe = function() { 8 | setTimeout(function() { 9 | $window.alert('You\'ve selected the alert tab!'); 10 | }); 11 | }; 12 | 13 | $scope.model = { 14 | name: 'Tabs' 15 | }; 16 | }); 17 | -------------------------------------------------------------------------------- /src/tabs/docs/readme.md: -------------------------------------------------------------------------------- 1 | AngularJS version of the tabs directive. 2 | 3 | ### uib-tabset settings 4 | 5 | * `active` 6 | 7 | _(Default: `Index of first tab`)_ - 8 | Active index of tab. Setting this to an existing tab index will make that tab active. 9 | 10 | * `justified` 11 | $ 12 | _(Default: `false`)_ - 13 | Whether tabs fill the container and have a consistent width. 14 | 15 | * `template-url` 16 | _(Default: `uib/template/tabs/tabset.html`)_ - 17 | A URL representing the location of a template to use for the main component. 18 | 19 | * `type` 20 | _(Defaults: `tabs`)_ - 21 | Navigation type. Possible values are 'tabs' and 'pills'. 22 | 23 | * `vertical` 24 | $ 25 | _(Default: `false`)_ - 26 | Whether tabs appear vertically stacked. 27 | 28 | ### uib-tab settings 29 | 30 | * `classes` 31 | $ - 32 | An optional string of space-separated CSS classes. 33 | 34 | * `deselect()` 35 | $ - 36 | An optional expression called when tab is deactivated. Supports `$event` and `$selectedIndex` in template for expression. You may call `$event.preventDefault()` in this event handler to prevent a tab change from occurring. The `$selectedIndex` can be used to determine which tab was attempted to be opened. 37 | 38 | * `disable` 39 | $ 40 | 41 | _(Default: `false`)_ - 42 | Whether tab is clickable and can be activated. 43 | 44 | * `heading` - 45 | Heading text. 46 | 47 | * `index` - 48 | Tab index. Must be unique number or string. 49 | 50 | * `select()` 51 | $ - 52 | An optional expression called when tab is activated. Supports $event in template for expression. 53 | 54 | * `template-url` 55 | _(Default: `uib/template/tabs/tab.html`)_ - 56 | A URL representing the location of a template to use for the tab heading. 57 | 58 | ### Tabset heading 59 | 60 | Instead of the `heading` attribute on the `uib-tabset`, you can use an `uib-tab-heading` element inside a tabset that will be used as the tabset's header. There you can use HTML as well. 61 | 62 | ### Known issues 63 | 64 | To use clickable elements within the tab, you have override the tab template to use div elements instead of anchor elements, and replicate the desired styles from Bootstrap's CSS. This is due to browsers interpreting anchor elements as the target of any click event, which triggers routing when certain elements such as buttons are nested inside the anchor element. 65 | -------------------------------------------------------------------------------- /src/tabs/index.js: -------------------------------------------------------------------------------- 1 | require('../../template/tabs/tab.html.js'); 2 | require('../../template/tabs/tabset.html.js'); 3 | require('./tabs'); 4 | 5 | var MODULE_NAME = 'ui.bootstrap.module.tabs'; 6 | 7 | angular.module(MODULE_NAME, ['ui.bootstrap.tabs', 'uib/template/tabs/tab.html', 'uib/template/tabs/tabset.html']); 8 | 9 | module.exports = MODULE_NAME; 10 | -------------------------------------------------------------------------------- /src/timepicker/docs/demo.html: -------------------------------------------------------------------------------- 1 |
                      2 | 3 |
                      4 | 5 |
                      Time is: {{mytime | date:'shortTime' }}
                      6 | 7 |
                      8 |
                      9 | Hours step is: 10 | 11 |
                      12 |
                      13 | Minutes step is: 14 | 15 |
                      16 |
                      17 | 18 |
                      19 | 20 | 21 | 22 | 23 | 24 |
                      25 | -------------------------------------------------------------------------------- /src/timepicker/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('TimepickerDemoCtrl', function ($scope, $log) { 2 | $scope.mytime = new Date(); 3 | 4 | $scope.hstep = 1; 5 | $scope.mstep = 15; 6 | 7 | $scope.options = { 8 | hstep: [1, 2, 3], 9 | mstep: [1, 5, 10, 15, 25, 30] 10 | }; 11 | 12 | $scope.ismeridian = true; 13 | $scope.toggleMode = function() { 14 | $scope.ismeridian = ! $scope.ismeridian; 15 | }; 16 | 17 | $scope.update = function() { 18 | var d = new Date(); 19 | d.setHours( 14 ); 20 | d.setMinutes( 0 ); 21 | $scope.mytime = d; 22 | }; 23 | 24 | $scope.changed = function () { 25 | $log.log('Time changed to: ' + $scope.mytime); 26 | }; 27 | 28 | $scope.clear = function() { 29 | $scope.mytime = null; 30 | }; 31 | }); 32 | -------------------------------------------------------------------------------- /src/timepicker/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../../template/timepicker/timepicker.html.js'); 2 | require('./timepicker'); 3 | 4 | var MODULE_NAME = 'ui.bootstrap.module.timepicker'; 5 | 6 | angular.module(MODULE_NAME, ['ui.bootstrap.timepicker', 'uib/template/timepicker/timepicker.html']); 7 | 8 | module.exports = MODULE_NAME; 9 | -------------------------------------------------------------------------------- /src/timepicker/index.js: -------------------------------------------------------------------------------- 1 | require('../common/svg-icon.css'); 2 | require('./timepicker.css'); 3 | module.exports = require('./index-nocss.js'); 4 | -------------------------------------------------------------------------------- /src/timepicker/timepicker.css: -------------------------------------------------------------------------------- 1 | .uib-time input { 2 | /* Bootstrap 4 overrides this otherwise */ 3 | width: 50px !important; 4 | } 5 | -------------------------------------------------------------------------------- /src/tooltip/docs/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('ui.bootstrap.demo').controller('TooltipDemoCtrl', function ($scope, $sce) { 2 | $scope.dynamicTooltip = 'Hello, World!'; 3 | $scope.dynamicTooltipText = 'dynamic'; 4 | $scope.htmlTooltip = $sce.trustAsHtml('I\'ve been made bold!'); 5 | $scope.placement = { 6 | options: [ 7 | 'top', 8 | 'top-left', 9 | 'top-right', 10 | 'bottom', 11 | 'bottom-left', 12 | 'bottom-right', 13 | 'left', 14 | 'left-top', 15 | 'left-bottom', 16 | 'right', 17 | 'right-top', 18 | 'right-bottom' 19 | ], 20 | selected: 'top' 21 | }; 22 | }); 23 | -------------------------------------------------------------------------------- /src/tooltip/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../position/index-nocss.js'); 2 | require('../stackedMap'); 3 | require('../../template/tooltip/tooltip-popup.html.js'); 4 | require('../../template/tooltip/tooltip-html-popup.html.js'); 5 | require('../../template/tooltip/tooltip-template-popup.html.js'); 6 | require('./tooltip'); 7 | 8 | var MODULE_NAME = 'ui.bootstrap.module.tooltip'; 9 | 10 | angular.module(MODULE_NAME, ['ui.bootstrap.tooltip', 'uib/template/tooltip/tooltip-popup.html', 'uib/template/tooltip/tooltip-html-popup.html', 'uib/template/tooltip/tooltip-template-popup.html']); 11 | 12 | module.exports = MODULE_NAME; 13 | -------------------------------------------------------------------------------- /src/tooltip/index.js: -------------------------------------------------------------------------------- 1 | require('../position/position.css'); 2 | require('./tooltip.css'); 3 | module.exports = require('./index-nocss.js'); 4 | -------------------------------------------------------------------------------- /src/tooltip/test/tooltip-template.spec.js: -------------------------------------------------------------------------------- 1 | describe('tooltip template', function() { 2 | var elm, 3 | elmBody, 4 | scope, 5 | elmScope, 6 | tooltipScope, 7 | $document; 8 | 9 | // load the popover code 10 | beforeEach(module('ui.bootstrap.tooltip')); 11 | 12 | // load the template 13 | beforeEach(module('uib/template/tooltip/tooltip-template-popup.html')); 14 | 15 | beforeEach(inject(function($templateCache) { 16 | $templateCache.put('myUrl', [200, '{{ myTemplateText }}', {}]); 17 | })); 18 | 19 | beforeEach(inject(function($rootScope, $compile, _$document_) { 20 | $document = _$document_; 21 | elmBody = angular.element( 22 | '
                      Selector Text
                      ' 23 | ); 24 | 25 | scope = $rootScope; 26 | $compile(elmBody)(scope); 27 | scope.templateUrl = 'myUrl'; 28 | 29 | scope.$digest(); 30 | elm = elmBody.find('span'); 31 | elmScope = elm.scope(); 32 | tooltipScope = elmScope.$$childTail; 33 | })); 34 | 35 | afterEach(function() { 36 | $document.off('keypress'); 37 | }); 38 | 39 | function trigger(element, evt) { 40 | element.trigger(evt); 41 | element.scope().$$childTail.$digest(); 42 | } 43 | 44 | it('should open on mouseenter', inject(function() { 45 | trigger(elm, 'mouseenter'); 46 | expect(tooltipScope.isOpen).toBe(true); 47 | 48 | expect(elmBody.children().length).toBe(2); 49 | })); 50 | 51 | it('should not open on mouseenter if templateUrl is empty', inject(function() { 52 | scope.templateUrl = null; 53 | scope.$digest(); 54 | 55 | trigger(elm, 'mouseenter'); 56 | expect(tooltipScope.isOpen).toBe(false); 57 | 58 | expect(elmBody.children().length).toBe(1); 59 | })); 60 | 61 | it('should show updated text', inject(function() { 62 | scope.myTemplateText = 'some text'; 63 | 64 | trigger(elm, 'mouseenter'); 65 | expect(tooltipScope.isOpen).toBe(true); 66 | scope.$digest(); 67 | 68 | expect(elmBody.children().eq(1).text().trim()).toBe('some text'); 69 | 70 | scope.myTemplateText = 'new text'; 71 | scope.$digest(); 72 | 73 | expect(elmBody.children().eq(1).text().trim()).toBe('new text'); 74 | })); 75 | 76 | it('should hide tooltip when template becomes empty', inject(function($timeout) { 77 | trigger(elm, 'mouseenter'); 78 | $timeout.flush(0); 79 | expect(tooltipScope.isOpen).toBe(true); 80 | 81 | scope.templateUrl = ''; 82 | scope.$digest(); 83 | 84 | expect(tooltipScope.isOpen).toBe(false); 85 | 86 | $timeout.flush(); 87 | expect(elmBody.children().length).toBe(1); 88 | })); 89 | }); 90 | -------------------------------------------------------------------------------- /src/tooltip/tooltip.css: -------------------------------------------------------------------------------- 1 | [uib-tooltip-popup].tooltip.top-left > .tooltip-arrow, 2 | [uib-tooltip-popup].tooltip.top-right > .tooltip-arrow, 3 | [uib-tooltip-popup].tooltip.bottom-left > .tooltip-arrow, 4 | [uib-tooltip-popup].tooltip.bottom-right > .tooltip-arrow, 5 | [uib-tooltip-popup].tooltip.left-top > .tooltip-arrow, 6 | [uib-tooltip-popup].tooltip.left-bottom > .tooltip-arrow, 7 | [uib-tooltip-popup].tooltip.right-top > .tooltip-arrow, 8 | [uib-tooltip-popup].tooltip.right-bottom > .tooltip-arrow, 9 | [uib-tooltip-html-popup].tooltip.top-left > .tooltip-arrow, 10 | [uib-tooltip-html-popup].tooltip.top-right > .tooltip-arrow, 11 | [uib-tooltip-html-popup].tooltip.bottom-left > .tooltip-arrow, 12 | [uib-tooltip-html-popup].tooltip.bottom-right > .tooltip-arrow, 13 | [uib-tooltip-html-popup].tooltip.left-top > .tooltip-arrow, 14 | [uib-tooltip-html-popup].tooltip.left-bottom > .tooltip-arrow, 15 | [uib-tooltip-html-popup].tooltip.right-top > .tooltip-arrow, 16 | [uib-tooltip-html-popup].tooltip.right-bottom > .tooltip-arrow, 17 | [uib-tooltip-template-popup].tooltip.top-left > .tooltip-arrow, 18 | [uib-tooltip-template-popup].tooltip.top-right > .tooltip-arrow, 19 | [uib-tooltip-template-popup].tooltip.bottom-left > .tooltip-arrow, 20 | [uib-tooltip-template-popup].tooltip.bottom-right > .tooltip-arrow, 21 | [uib-tooltip-template-popup].tooltip.left-top > .tooltip-arrow, 22 | [uib-tooltip-template-popup].tooltip.left-bottom > .tooltip-arrow, 23 | [uib-tooltip-template-popup].tooltip.right-top > .tooltip-arrow, 24 | [uib-tooltip-template-popup].tooltip.right-bottom > .tooltip-arrow, 25 | [uib-popover-popup].popover.top-left > .arrow, 26 | [uib-popover-popup].popover.top-right > .arrow, 27 | [uib-popover-popup].popover.bottom-left > .arrow, 28 | [uib-popover-popup].popover.bottom-right > .arrow, 29 | [uib-popover-popup].popover.left-top > .arrow, 30 | [uib-popover-popup].popover.left-bottom > .arrow, 31 | [uib-popover-popup].popover.right-top > .arrow, 32 | [uib-popover-popup].popover.right-bottom > .arrow, 33 | [uib-popover-html-popup].popover.top-left > .arrow, 34 | [uib-popover-html-popup].popover.top-right > .arrow, 35 | [uib-popover-html-popup].popover.bottom-left > .arrow, 36 | [uib-popover-html-popup].popover.bottom-right > .arrow, 37 | [uib-popover-html-popup].popover.left-top > .arrow, 38 | [uib-popover-html-popup].popover.left-bottom > .arrow, 39 | [uib-popover-html-popup].popover.right-top > .arrow, 40 | [uib-popover-html-popup].popover.right-bottom > .arrow, 41 | [uib-popover-template-popup].popover.top-left > .arrow, 42 | [uib-popover-template-popup].popover.top-right > .arrow, 43 | [uib-popover-template-popup].popover.bottom-left > .arrow, 44 | [uib-popover-template-popup].popover.bottom-right > .arrow, 45 | [uib-popover-template-popup].popover.left-top > .arrow, 46 | [uib-popover-template-popup].popover.left-bottom > .arrow, 47 | [uib-popover-template-popup].popover.right-top > .arrow, 48 | [uib-popover-template-popup].popover.right-bottom > .arrow { 49 | top: auto; 50 | bottom: auto; 51 | left: auto; 52 | right: auto; 53 | margin: 0; 54 | } 55 | 56 | [uib-popover-popup].popover, 57 | [uib-popover-html-popup].popover, 58 | [uib-popover-template-popup].popover { 59 | display: block !important; 60 | } 61 | -------------------------------------------------------------------------------- /src/typeahead/index-nocss.js: -------------------------------------------------------------------------------- 1 | require('../debounce'); 2 | require('../position/index-nocss.js'); 3 | require('../../template/typeahead/typeahead-match.html.js'); 4 | require('../../template/typeahead/typeahead-popup.html.js'); 5 | require('./typeahead'); 6 | 7 | var MODULE_NAME = 'ui.bootstrap.module.typeahead'; 8 | 9 | angular.module(MODULE_NAME, ['ui.bootstrap.typeahead', 'uib/template/typeahead/typeahead-match.html', 'uib/template/typeahead/typeahead-popup.html']); 10 | 11 | module.exports = MODULE_NAME; 12 | -------------------------------------------------------------------------------- /src/typeahead/index.js: -------------------------------------------------------------------------------- 1 | require('../position/position.css'); 2 | require('./typeahead.css'); 3 | module.exports = require('./index-nocss.js'); 4 | -------------------------------------------------------------------------------- /src/typeahead/test/typeahead-highlight-ngsanitize.spec.js: -------------------------------------------------------------------------------- 1 | describe('Security concerns', function() { 2 | var highlightFilter, $sanitize, logSpy; 3 | 4 | beforeEach(module('ui.bootstrap.typeahead', 'ngSanitize')); 5 | 6 | beforeEach(inject(function (uibTypeaheadHighlightFilter, _$sanitize_, $log) { 7 | highlightFilter = uibTypeaheadHighlightFilter; 8 | $sanitize = _$sanitize_; 9 | logSpy = spyOn($log, 'warn'); 10 | })); 11 | 12 | it('should not call the $log service when ngSanitize is present', function() { 13 | highlightFilter('before after', 'match'); 14 | expect(logSpy).not.toHaveBeenCalled(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/typeahead/test/typeahead-highlight.spec.js: -------------------------------------------------------------------------------- 1 | describe('typeaheadHighlight', function () { 2 | 3 | var highlightFilter, $log, $sce, logSpy; 4 | 5 | beforeEach(module('ui.bootstrap.typeahead')); 6 | 7 | beforeEach(inject(function(_$log_, _$sce_) { 8 | $log = _$log_; 9 | $sce = _$sce_; 10 | logSpy = spyOn($log, 'warn'); 11 | })); 12 | 13 | beforeEach(inject(function(uibTypeaheadHighlightFilter) { 14 | highlightFilter = uibTypeaheadHighlightFilter; 15 | })); 16 | 17 | it('should higlight a match', function() { 18 | expect($sce.getTrustedHtml(highlightFilter('before match after', 'match'))).toEqual('before match after'); 19 | }); 20 | 21 | it('should higlight a match with mixed case', function() { 22 | expect($sce.getTrustedHtml(highlightFilter('before MaTch after', 'match'))).toEqual('before MaTch after'); 23 | }); 24 | 25 | it('should higlight all matches', function() { 26 | expect($sce.getTrustedHtml(highlightFilter('before MaTch after match', 'match'))).toEqual('before MaTch after match'); 27 | }); 28 | 29 | it('should do nothing if no match', function() { 30 | expect($sce.getTrustedHtml(highlightFilter('before match after', 'nomatch'))).toEqual('before match after'); 31 | }); 32 | 33 | it('should do nothing if no or empty query', function() { 34 | expect($sce.getTrustedHtml(highlightFilter('before match after', ''))).toEqual('before match after'); 35 | expect($sce.getTrustedHtml(highlightFilter('before match after', null))).toEqual('before match after'); 36 | expect($sce.getTrustedHtml(highlightFilter('before match after', undefined))).toEqual('before match after'); 37 | }); 38 | 39 | it('issue 316 - should work correctly for regexp reserved words', function() { 40 | expect($sce.getTrustedHtml(highlightFilter('before (match after', '(match'))).toEqual('before (match after'); 41 | }); 42 | 43 | it('issue 1777 - should work correctly with numeric values', function() { 44 | expect($sce.getTrustedHtml(highlightFilter(123, '2'))).toEqual('123'); 45 | }); 46 | 47 | it('should show a warning when this component is being used unsafely', function() { 48 | highlightFilter('before match after', 'match'); 49 | expect(logSpy).toHaveBeenCalled(); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /src/typeahead/test/typeahead-parser.spec.js: -------------------------------------------------------------------------------- 1 | describe('syntax parser', function() { 2 | var typeaheadParser, scope, filterFilter; 3 | 4 | beforeEach(module('ui.bootstrap.typeahead')); 5 | beforeEach(inject(function(_$rootScope_, _filterFilter_, uibTypeaheadParser) { 6 | typeaheadParser = uibTypeaheadParser; 7 | scope = _$rootScope_; 8 | filterFilter = _filterFilter_; 9 | })); 10 | 11 | it('should parse the simplest array-based syntax', function() { 12 | scope.states = ['Alabama', 'California', 'Delaware']; 13 | var result = typeaheadParser.parse('state for state in states | filter:$viewValue'); 14 | 15 | var itemName = result.itemName; 16 | var locals = {$viewValue:'al'}; 17 | expect(result.source(scope, locals)).toEqual(['Alabama', 'California']); 18 | 19 | locals[itemName] = 'Alabama'; 20 | expect(result.viewMapper(scope, locals)).toEqual('Alabama'); 21 | expect(result.modelMapper(scope, locals)).toEqual('Alabama'); 22 | }); 23 | 24 | it('should parse the simplest function-based syntax', function() { 25 | scope.getStates = function($viewValue) { 26 | return filterFilter(['Alabama', 'California', 'Delaware'], $viewValue); 27 | }; 28 | var result = typeaheadParser.parse('state for state in getStates($viewValue)'); 29 | 30 | var itemName = result.itemName; 31 | var locals = {$viewValue:'al'}; 32 | expect(result.source(scope, locals)).toEqual(['Alabama', 'California']); 33 | 34 | locals[itemName] = 'Alabama'; 35 | expect(result.viewMapper(scope, locals)).toEqual('Alabama'); 36 | expect(result.modelMapper(scope, locals)).toEqual('Alabama'); 37 | }); 38 | 39 | it('should allow to specify custom model mapping that is used as a label as well', function () { 40 | scope.states = [ 41 | {code:'AL', name:'Alabama'}, 42 | {code:'CA', name:'California'}, 43 | {code:'DE', name:'Delaware'} 44 | ]; 45 | var result = typeaheadParser.parse('state.name for state in states | filter:$viewValue | orderBy:"name":true'); 46 | 47 | var itemName = result.itemName; 48 | expect(itemName).toEqual('state'); 49 | expect(result.source(scope, {$viewValue:'al'})).toEqual([ 50 | {code:'CA', name:'California'}, 51 | {code:'AL', name:'Alabama'} 52 | ]); 53 | 54 | var locals = {$viewValue:'al'}; 55 | locals[itemName] = {code:'AL', name:'Alabama'}; 56 | expect(result.viewMapper(scope, locals)).toEqual('Alabama'); 57 | expect(result.modelMapper(scope, locals)).toEqual('Alabama'); 58 | }); 59 | 60 | it('should allow to specify custom view and model mappers', function() { 61 | scope.states = [ 62 | {code:'AL', name:'Alabama'}, 63 | {code:'CA', name:'California'}, 64 | {code:'DE', name:'Delaware'} 65 | ]; 66 | var result = typeaheadParser.parse('state.code as state.name + " ("+state.code+")" for state in states | filter:$viewValue | orderBy:"name":true'); 67 | 68 | var itemName = result.itemName; 69 | expect(result.source(scope, {$viewValue:'al'})).toEqual([ 70 | {code:'CA', name:'California'}, 71 | {code:'AL', name:'Alabama'} 72 | ]); 73 | 74 | var locals = {$viewValue:'al'}; 75 | locals[itemName] = {code:'AL', name:'Alabama'}; 76 | expect(result.viewMapper(scope, locals)).toEqual('Alabama (AL)'); 77 | expect(result.modelMapper(scope, locals)).toEqual('AL'); 78 | }); 79 | }); -------------------------------------------------------------------------------- /src/typeahead/test/typeahead-popup.spec.js: -------------------------------------------------------------------------------- 1 | describe('typeaheadPopup - result rendering', function() { 2 | var scope, $rootScope, $compile; 3 | 4 | beforeEach(module('ui.bootstrap.typeahead')); 5 | beforeEach(module('uib/template/typeahead/typeahead-popup.html')); 6 | beforeEach(module('uib/template/typeahead/typeahead-match.html')); 7 | beforeEach(inject(function(_$rootScope_, _$compile_) { 8 | $rootScope = _$rootScope_; 9 | scope = $rootScope.$new(); 10 | $compile = _$compile_; 11 | })); 12 | 13 | it('should render initial results', function() { 14 | scope.matches = ['foo', 'bar', 'baz']; 15 | scope.active = 1; 16 | 17 | var el = $compile('
                      ')(scope); 18 | $rootScope.$digest(); 19 | 20 | var liElems = el.find('li'); 21 | expect(liElems.length).toEqual(3); 22 | expect(liElems.eq(0)).not.toHaveClass('active'); 23 | expect(liElems.eq(1)).toHaveClass('active'); 24 | expect(liElems.eq(2)).not.toHaveClass('active'); 25 | }); 26 | 27 | it('should change active item on mouseenter', function() { 28 | scope.matches = ['foo', 'bar', 'baz']; 29 | scope.active = 1; 30 | 31 | var el = $compile('
                      ')(scope); 32 | $rootScope.$digest(); 33 | 34 | var liElems = el.find('li'); 35 | expect(liElems.eq(1)).toHaveClass('active'); 36 | expect(liElems.eq(2)).not.toHaveClass('active'); 37 | 38 | liElems.eq(2).trigger('mouseenter'); 39 | 40 | expect(liElems.eq(1)).not.toHaveClass('active'); 41 | expect(liElems.eq(2)).toHaveClass('active'); 42 | }); 43 | 44 | it('should select an item on mouse click', function() { 45 | scope.matches = ['foo', 'bar', 'baz']; 46 | scope.active = 1; 47 | $rootScope.select = angular.noop; 48 | spyOn($rootScope, 'select'); 49 | 50 | var el = $compile('
                      ')(scope); 51 | $rootScope.$digest(); 52 | 53 | var liElems = el.find('li'); 54 | liElems.eq(2).find('a').trigger('click'); 55 | expect($rootScope.select).toHaveBeenCalledWith(2); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /src/typeahead/typeahead.css: -------------------------------------------------------------------------------- 1 | [uib-typeahead-popup].dropdown-menu { 2 | display: block; 3 | } 4 | -------------------------------------------------------------------------------- /template/accordion/accordion-group.html: -------------------------------------------------------------------------------- 1 | 6 |
                      7 |
                      8 |
                      9 | -------------------------------------------------------------------------------- /template/accordion/accordion.html: -------------------------------------------------------------------------------- 1 |
                      2 | -------------------------------------------------------------------------------- /template/alert/alert.html: -------------------------------------------------------------------------------- 1 | 5 |
                      6 | -------------------------------------------------------------------------------- /template/carousel/carousel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Previous 5 | 6 | 7 | 8 | Next 9 | 10 | 15 | -------------------------------------------------------------------------------- /template/carousel/slide.html: -------------------------------------------------------------------------------- 1 |
                      2 | -------------------------------------------------------------------------------- /template/datepicker/datepicker.html: -------------------------------------------------------------------------------- 1 |
                      2 |
                      3 |
                      4 |
                      5 |
                      6 | -------------------------------------------------------------------------------- /template/datepicker/day.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 42 | 43 | 44 |
                      5 | 11 | 14 | 20 |
                      {{::label.abbr}}
                      {{ weekNumbers[$index] }} 33 | 41 |
                      45 | -------------------------------------------------------------------------------- /template/datepicker/month.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 37 | 38 | 39 |
                      5 | 11 | 14 | 20 |
                      28 | 36 |
                      40 | -------------------------------------------------------------------------------- /template/datepicker/year.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 19 | 27 | 28 | 29 | 30 | 31 | 43 | 44 | 45 |
                      5 | 11 | 13 | 18 | 20 | 26 |
                      34 | 42 |
                      46 | -------------------------------------------------------------------------------- /template/datepickerPopup/popup.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /template/modal/window.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /template/pager/pager.html: -------------------------------------------------------------------------------- 1 |
                    • {{::getText('previous')}}
                    • 2 |
                    • {{::getText('next')}}
                    • 3 | -------------------------------------------------------------------------------- /template/pagination/pagination.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /template/popover/popover-html.html: -------------------------------------------------------------------------------- 1 |
                      2 |

                      3 |
                      4 | -------------------------------------------------------------------------------- /template/popover/popover-template.html: -------------------------------------------------------------------------------- 1 |
                      2 | 3 |

                      4 |
                      7 | -------------------------------------------------------------------------------- /template/popover/popover.html: -------------------------------------------------------------------------------- 1 |
                      2 |

                      3 |
                      4 | -------------------------------------------------------------------------------- /template/progressbar/bar.html: -------------------------------------------------------------------------------- 1 |
                      2 | -------------------------------------------------------------------------------- /template/progressbar/progress.html: -------------------------------------------------------------------------------- 1 |
                      -------------------------------------------------------------------------------- /template/progressbar/progressbar.html: -------------------------------------------------------------------------------- 1 |
                      2 |
                      3 |
                      4 | -------------------------------------------------------------------------------- /template/rating/rating.html: -------------------------------------------------------------------------------- 1 | 2 | ({{ $index < value ? '*' : ' ' }}) 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /template/tabs/tab.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /template/tabs/tabset.html: -------------------------------------------------------------------------------- 1 |
                      2 | 3 |
                      4 |
                      8 |
                      9 |
                      10 |
                      11 | -------------------------------------------------------------------------------- /template/tooltip/tooltip-html-popup.html: -------------------------------------------------------------------------------- 1 |
                      2 |
                      3 | -------------------------------------------------------------------------------- /template/tooltip/tooltip-popup.html: -------------------------------------------------------------------------------- 1 |
                      2 |
                      3 | -------------------------------------------------------------------------------- /template/tooltip/tooltip-template-popup.html: -------------------------------------------------------------------------------- 1 |
                      2 |
                      5 | -------------------------------------------------------------------------------- /template/typeahead/typeahead-match.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /template/typeahead/typeahead-popup.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /ui-bootstrap4: -------------------------------------------------------------------------------- 1 | docs --------------------------------------------------------------------------------