Commit 44172086f46a3475713a5d99ea75dbb43e63bfb5

Authored by Edmar Moretti
1 parent d912f0b8

Aplicação do plugin de acessibilidade

admin1/head.php
... ... @@ -27,6 +27,8 @@ echo "
27 27 <!-- Custom styles for this template -->
28 28 <link href='" . ONDEI3GEO . "/pacotes/font-awesome/css/font-awesome.min.css' rel='stylesheet'>
29 29  
  30 + <link href='" . ONDEI3GEO . "/pacotes/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css' rel='stylesheet'>
  31 +
30 32 <script src='". ONDEI3GEO . "/admin1/headjs.php'></script>
31 33 ";
32 34 ?>
... ...
admin1/headjs.php
... ... @@ -16,6 +16,8 @@ include (ONDEI3GEO . &quot;/pacotes/bootstrap/js/ie10-viewport-bug-workaround.js&quot;);
16 16 echo "\n";
17 17 include (ONDEI3GEO . "/pacotes/bootstrap-material-design/dist/js/material.min.js");
18 18 echo "\n";
  19 +include (ONDEI3GEO . "/pacotes/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.min.js");
  20 +echo "\n";
19 21 include (ONDEI3GEO . "/pacotes/cpaint/cpaint2_compacto.inc.js");
20 22 echo "\n";
21 23 include (ONDEI3GEO . "/classesjs/compactados/dicionario_compacto.js");
... ...
init/head.php
... ... @@ -26,6 +26,8 @@ echo &quot;
26 26 <!-- Custom styles for this template -->
27 27 <link href='" . ONDEI3GEO . "/pacotes/font-awesome/css/font-awesome.min.css' rel='stylesheet'>
28 28  
  29 + <link href='" . ONDEI3GEO . "/pacotes/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css' rel='stylesheet'>
  30 +
29 31 <script src='" . ONDEI3GEO . "/init/headjs.php'></script>";
30 32 ?>
31 33 <style>
... ...
init/headjs.php
... ... @@ -13,6 +13,8 @@ include (ONDEI3GEO . &quot;/pacotes/bootstrap/js/ie10-viewport-bug-workaround.js&quot;);
13 13 echo "\n";
14 14 include (ONDEI3GEO . "/pacotes/bootstrap-material-design/dist/js/material.min.js");
15 15 echo "\n";
  16 +include (ONDEI3GEO . "/pacotes/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.min.js");
  17 +echo "\n";
16 18  
17 19 if (extension_loaded ( 'zlib' )) {
18 20 ob_end_flush ();
... ...
pacotes/bootstrap-accessibility-plugin/LICENSE.md 0 → 100755
... ... @@ -0,0 +1,27 @@
  1 +Copyright (c) 2014, PayPal
  2 +All rights reserved.
  3 +
  4 +Redistribution and use in source and binary forms, with or without modification,
  5 +are permitted provided that the following conditions are met:
  6 +
  7 +* Redistributions of source code must retain the above copyright notice, this
  8 + list of conditions and the following disclaimer.
  9 +
  10 +* Redistributions in binary form must reproduce the above copyright notice, this
  11 + list of conditions and the following disclaimer in the documentation and/or
  12 + other materials provided with the distribution.
  13 +
  14 +* Neither the name of the PayPal nor the names of its
  15 + contributors may be used to endorse or promote products derived from
  16 + this software without specific prior written permission.
  17 +
  18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  22 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23 +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24 +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  25 +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
... ...
pacotes/bootstrap-accessibility-plugin/README.md 0 → 100755
... ... @@ -0,0 +1,145 @@
  1 +<img src="images/logo/logo_347x50_PPa11y.png" alt="PayPal accessibility logo">
  2 +# Bootstrap Accessibility Plugin, v1.0
  3 +## by the PayPal Accessibility Team
  4 +See the [Authors](#authors) section below for more information.
  5 +
  6 +## What is it?
  7 +This plugin adds accessibility mark-up to the [default components of Bootstrap 3](http://getbootstrap.com/javascript/) to make them accessible for keyboard and screen reader users. Do not worry, the plugin does not affect the performance or the visual layout of your website. Let the magic remain magic!
  8 +
  9 +## Why do I want it?
  10 +If you use Bootstrap library (version 3.x) on your website, your pages will now be much more usable and navigable for and by keyboard and screen reader users with no work on your part. Believe us, for this they will thank you! Read on to learn about all the enhancements introduced by this plugin.
  11 +
  12 +## How do I get it on my website?
  13 +1. Download and include Bootstrap.js from [getbootstrap.com](http://getbootstrap.com/).
  14 +2. Download and include the [bootstrap accessibility plugin js](plugins/js).
  15 +3. Download and include the [bootstrap accessibility plugin css](plugins/css) to override css styles.
  16 +4. Optional: Lazily load the JavaScript plugin after the page is loaded ([example](demo.html)).
  17 +5. For basic implementation:
  18 +
  19 + ```html
  20 + <link rel="stylesheet" href="/css/bootstrap.min.css">
  21 + <link rel="stylesheet" href="/css/bootstrap-accessibility.css">
  22 +
  23 + <script src="http://code.jquery.com/jquery.js"></script>
  24 + <script src="/js/bootstrap.min.js"></script>
  25 + <script src="/js/bootstrap-accessibility.min.js"></script>
  26 + ```
  27 +6. You can also install it from npm or bower:
  28 +
  29 + ```sh
  30 + bower install bootstrapaccessibilityplugin
  31 + npm install bootstrap-accessibility-plugin
  32 + ```
  33 +
  34 +## Which components become accessible?
  35 +- Alert
  36 +- Tooltip
  37 +- Popover
  38 +- Modal dialog
  39 +- Dropdown menu
  40 +- Tab panel
  41 +- Collapse
  42 +- Carousel
  43 +
  44 +## Plugin Live Demo
  45 +Feel free to play with the [live demo](https://paypal.github.io/bootstrap-accessibility-plugin/demo.html) of the components listed above and the Bootstrap Accessibility Plugin in action. Seeing how "accessified" widgets work in this demo will help you verify whether the plugin is installed correctly on your website.
  46 +
  47 +## Details
  48 +
  49 +### Alert
  50 +1. Add role of Alert to Alert, Warning, and Success Bootstrap Messages.
  51 +2. Increase the color contrast. The foreground to background color contrast ratio for the message was too low.
  52 +3. Add instructions in message dialog, so that the developer using the alert knows to manage keyboard focus on alert dismissal.
  53 +4. Close button now accessible to screen readers.
  54 +
  55 +### Tooltip
  56 +1. Add role of Tooltip to tooltip div.
  57 +2. Generate a random id, assign it to the tooltip div, and reference it from the Tooltip element with the ARIA attribute "aria-describedby".
  58 +3. Remove aria-describedby when the tooltip is hidden.
  59 +
  60 +### Popover
  61 +1. Add role of Tooltip to popover div.
  62 +2. Generate a random id, assign it to Popover div, and reference it from the Tooltip element with the ARIA attribute "aria-describedby".
  63 +3. Remove aria-describedby when the popover is dismissed.
  64 +
  65 +### Modal Dialog
  66 +1. Add role of Document to content div inside dialog, so that NVDA can force document mode and read contents inside Dialog.
  67 +2. When the Modal is closed, return the focus to the element which opened the dialog.
  68 +3. Change the focus outline of close button to visible.
  69 +4. Close button now accessible to screen readers.
  70 +
  71 +### Dropdown
  72 +1. Add aria-haspopup and and aria-expanded attributes to dropdown toggle link.
  73 +2. Dynamically change aria-expanded when the dropdown closes or opens.
  74 +3. Focus to first item on activating dropdown.
  75 +4. Add ability to open dropdown with spacebar.
  76 +5. Close dropdown when tabbing out from dropdown.
  77 +6. Change the focus outline of dropdown to visible.
  78 +
  79 +### Tab Panel
  80 +1. Add ARIA roles like tablist, presentation, and tab for tabs UL, LI.
  81 +2. Add tabIndex, aria-expanded, aria-selected, aria-controls for tab.
  82 +3. Add ARIA roles of tabPanel, tabIndex, aria-hidden, and aria-labelledBy for tabPanel.
  83 +4. Add keydown event listener for the tab to work with keyboard.
  84 +5. Dynamically flip tabIndex, aria-selected, and aria-expanded for tab when it is activated and add aria-hidden to hide the previously visible tab.
  85 +
  86 +### Collapse
  87 +1. Add tab role, aria-selected, aria-expanded, aria-controls, and tabIndex for collapse tab.
  88 +2. Add ARIA roles of tabPanel, tabIndex, aria-hidden, and aria-labelledBy for collapsible panel.
  89 +3. Add role of tabList and aria-multiselectable for collapse container div.
  90 +4. Dynamically flip tabIndex, aria-selected, and aria-expanded for tab when it is activated and add aria-hidden to hide the previously visible collapse tabpanel.
  91 +5. Add keydown event listener for the collapse component to work with keyboard.
  92 +
  93 +### Carousel
  94 +1. Prevent automatic cycling of the carousel.
  95 +2. Prevent wrapping to first item on next button navigation or wrapping to last item on previous button navigation.
  96 +3. Add role of listbox for carousel div.
  97 +4. Add ARIA role of option, aria-selected, and tabIndex for individual carousel items.
  98 +5. Add role of button for previous and next anchor links and a hidden screen reader text of "Previous" and "Next".
  99 +6. Add keydown event listener for the carousel to work with keyboard.
  100 +7. Dynamically change tabIndex and aria-selected property of active and inactive tabs.
  101 +8. Remove display:none and hide (offscreen) of the inactive carousel items, so that screen readers can count the total number of carousel items.
  102 +
  103 +## Re-compiling
  104 +You may want to extend the plugin further or change some of the code. Here is how to do it:
  105 +
  106 +1. Get NodeJS from [http://nodejs.org](http://nodejs.org)
  107 +2. Clone the latest code from [https://github.com/paypal/bootstrap-accessibility-plugin.git](https://github.com/paypal/bootstrap-accessibility-plugin.git)
  108 +3. Go to the root of this project and install Compass and Sass:
  109 +
  110 + ```sh
  111 + cd bootstrap-accessibility-plugin
  112 + sudo gem install compass
  113 + ```
  114 +4. Install and run grunt:
  115 +
  116 + ```sh
  117 + sudo npm install grunt-cli -g
  118 + npm install
  119 + grunt
  120 + ```
  121 +5. To run the examples, initialize the git submodules:
  122 +
  123 + ```sh
  124 + git submodule init
  125 + git submodule update
  126 + ```
  127 +
  128 +## Feedback and Contributions
  129 +Please do not hesitate to open an issue or send a pull request if something doesn't work or you have ideas for improvement. For instructions on how to contribute to this project please read the [contribution guide](CONTRIBUTING.md).
  130 +
  131 +## Authors
  132 +
  133 + - Prem Nawaz Khan, primary developer || [https://github.com/mpnkhan](https://github.com/mpnkhan) || [@mpnkhan](https://twitter.com/mpnkhan)
  134 + - Victor Tsaran, project manager, user interaction, testing, documentation || [https://github.com/vick08](https://github.com/vick08) || [@vick08](https://twitter.com/vick08)
  135 + - Dennis Lembree, developer, user interaction, testing || [https://github.com/weboverhauls](https://github.com/weboverhauls) || [@dennisl](https://twitter.com/dennisl)
  136 + - Srinivasu Chakravarthula, user interaction, testing || [@csrinivasu](https://twitter.com/csrinivasu)
  137 + - Cathy O'Connor, design || [@cagocon](https://twitter.com/cagocon)
  138 +
  139 +## Related Resources
  140 +
  141 + - [Bootstrap a11y theme](https://github.com/bassjobsen/bootstrap-a11y-theme) - makes web accessibility easier for Bootstrap developers, a pure LESS/CSS solution.
  142 +
  143 +## Copyright and License
  144 +
  145 +Copyright 2015, PayPal under [the BSD license](LICENSE.md).
... ...
pacotes/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css 0 → 100755
... ... @@ -0,0 +1 @@
  1 +.btn:focus{outline:dotted 2px #000}div.active:focus{outline:dotted 1px #000}a:focus{outline:dotted 1px #000}.close:hover,.close:focus{outline:dotted 1px #000}.nav>li>a:hover,.nav>li>a:focus{outline:dotted 1px #000}.carousel-indicators li,.carousel-indicators li.active{height:18px;width:18px;border-width:2px;position:relative;box-shadow:0px 0px 0px 1px #808080}.carousel-indicators.active li{background-color:rgba(100,149,253,0.6)}.carousel-indicators.active li.active{background-color:white}.carousel-tablist-highlight{display:block;position:absolute;outline:2px solid transparent;background-color:transparent;box-shadow:0px 0px 0px 1px transparent}.carousel-tablist-highlight.focus{outline:2px solid #6495ED;background-color:rgba(0,0,0,0.4)}a.carousel-control:focus{outline:2px solid #6495ED;background-image:linear-gradient(to right, transparent 0px, rgba(0,0,0,0.5) 100%);box-shadow:0px 0px 0px 1px #000000}.carousel-pause-button{position:absolute;top:-30em;left:-300em;display:block}.carousel-pause-button.focus{top:0.5em;left:0.5em}.carousel:hover .carousel-caption,.carousel.contrast .carousel-caption{background-color:rgba(0,0,0,0.5);z-index:10}.alert-success{color:#2d4821}.alert-info{color:#214c62}.alert-warning{color:#6c4a00;background-color:#f9f1c6}.alert-danger{color:#d2322d}.alert-danger:hover{color:#a82824}
... ...
pacotes/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.js 0 → 100755
... ... @@ -0,0 +1,716 @@
  1 +/* ========================================================================
  2 +* Extends Bootstrap v3.1.1
  3 +
  4 +* Copyright (c) <2015> PayPal
  5 +
  6 +* All rights reserved.
  7 +
  8 +* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  9 +
  10 +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  11 +
  12 +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  13 +
  14 +* Neither the name of PayPal or any of its subsidiaries or affiliates nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  15 +
  16 +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17 +
  18 +* ======================================================================== */
  19 +
  20 +
  21 + (function($) {
  22 + "use strict";
  23 +
  24 + // GENERAL UTILITY FUNCTIONS
  25 + // ===============================
  26 +
  27 + var uniqueId = function(prefix) {
  28 + return (prefix || 'ui-id') + '-' + Math.floor((Math.random()*1000)+1)
  29 + }
  30 +
  31 +
  32 + var removeMultiValAttributes = function (el, attr, val) {
  33 + var describedby = (el.attr( attr ) || "").split( /\s+/ )
  34 + , index = $.inArray(val, describedby)
  35 + if ( index !== -1 ) {
  36 + describedby.splice( index, 1 )
  37 + }
  38 + describedby = $.trim( describedby.join( " " ) )
  39 + if (describedby ) {
  40 + el.attr( attr, describedby )
  41 + } else {
  42 + el.removeAttr( attr )
  43 + }
  44 + }
  45 +
  46 +// selectors Courtesy: https://github.com/jquery/jquery-ui/blob/master/ui/focusable.js and tabbable.js
  47 +/*
  48 +Copyright jQuery Foundation and other contributors, https://jquery.org/
  49 +
  50 +This software consists of voluntary contributions made by many
  51 +individuals. For exact contribution history, see the revision history
  52 +available at https://github.com/jquery/jquery-ui
  53 +
  54 +The following license applies to all parts of this software except as
  55 +documented below:
  56 +
  57 +====
  58 +
  59 +Permission is hereby granted, free of charge, to any person obtaining
  60 +a copy of this software and associated documentation files (the
  61 +"Software"), to deal in the Software without restriction, including
  62 +without limitation the rights to use, copy, modify, merge, publish,
  63 +distribute, sublicense, and/or sell copies of the Software, and to
  64 +permit persons to whom the Software is furnished to do so, subject to
  65 +the following conditions:
  66 +
  67 +The above copyright notice and this permission notice shall be
  68 +included in all copies or substantial portions of the Software.
  69 +
  70 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  71 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  72 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  73 +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  74 +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  75 +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  76 +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  77 +
  78 +====
  79 +
  80 +Copyright and related rights for sample code are waived via CC0. Sample
  81 +code is defined as all source code contained within the demos directory.
  82 +
  83 +CC0: http://creativecommons.org/publicdomain/zero/1.0/
  84 +
  85 +====
  86 +*/
  87 +
  88 + var focusable = function ( element, isTabIndexNotNaN ) {
  89 + var map, mapName, img,
  90 + nodeName = element.nodeName.toLowerCase();
  91 + if ( "area" === nodeName ) {
  92 + map = element.parentNode;
  93 + mapName = map.name;
  94 + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
  95 + return false;
  96 + }
  97 + img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
  98 + return !!img && visible( img );
  99 + }
  100 + return ( /input|select|textarea|button|object/.test( nodeName ) ?
  101 + !element.disabled :
  102 + "a" === nodeName ?
  103 + element.href || isTabIndexNotNaN :isTabIndexNotNaN) && visible( element ); // the element and all of its ancestors must be visible
  104 + }
  105 + var visible = function ( element ) {
  106 + return $.expr.filters.visible( element ) &&
  107 + !$( element ).parents().addBack().filter(function() {
  108 + return $.css( this, "visibility" ) === "hidden";
  109 + }).length;
  110 + }
  111 +
  112 + $.extend( $.expr[ ":" ], {
  113 + data: $.expr.createPseudo ?
  114 + $.expr.createPseudo(function( dataName ) {
  115 + return function( elem ) {
  116 + return !!$.data( elem, dataName );
  117 + };
  118 + }) :
  119 + // support: jQuery <1.8
  120 + function( elem, i, match ) {
  121 + return !!$.data( elem, match[ 3 ] );
  122 + },
  123 +
  124 + focusable: function( element ) {
  125 + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
  126 + },
  127 +
  128 + tabbable: function( element ) {
  129 + var tabIndex = $.attr( element, "tabindex" ),
  130 + isTabIndexNaN = isNaN( tabIndex );
  131 + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
  132 + }
  133 + });
  134 +
  135 + // Modal Extension
  136 + // ===============================
  137 +
  138 + $('.modal-dialog').attr( {'role' : 'document'})
  139 + var modalhide = $.fn.modal.Constructor.prototype.hide
  140 + $.fn.modal.Constructor.prototype.hide = function(){
  141 + modalhide.apply(this, arguments)
  142 + $(document).off('keydown.bs.modal')
  143 + }
  144 +
  145 + var modalfocus = $.fn.modal.Constructor.prototype.enforceFocus
  146 + $.fn.modal.Constructor.prototype.enforceFocus = function(){
  147 + var $content = this.$element.find(".modal-content")
  148 + var focEls = $content.find(":tabbable")
  149 + , $lastEl = $(focEls[focEls.length-1])
  150 + , $firstEl = $(focEls[0])
  151 + $lastEl.on('keydown.bs.modal', $.proxy(function (ev) {
  152 + if(ev.keyCode === 9 && !(ev.shiftKey | ev.ctrlKey | ev.metaKey | ev.altKey)) { // TAB pressed
  153 + ev.preventDefault();
  154 + $firstEl.focus();
  155 + }
  156 + }, this))
  157 + $firstEl.on('keydown.bs.modal', $.proxy(function (ev) {
  158 + if(ev.keyCode === 9 && ev.shiftKey) { // SHIFT-TAB pressed
  159 + ev.preventDefault();
  160 + $lastEl.focus();
  161 + }
  162 + }, this))
  163 + modalfocus.apply(this, arguments)
  164 + }
  165 +
  166 + // DROPDOWN Extension
  167 + // ===============================
  168 +
  169 + var toggle = '[data-toggle=dropdown]'
  170 + , $par
  171 + , firstItem
  172 + , focusDelay = 200
  173 + , menus = $(toggle).parent().find('ul').attr('role','menu')
  174 + , lis = menus.find('li').attr('role','presentation')
  175 +
  176 + // add menuitem role and tabIndex to dropdown links
  177 + lis.find('a').attr({'role':'menuitem', 'tabIndex':'-1'})
  178 + // add aria attributes to dropdown toggle
  179 + $(toggle).attr({ 'aria-haspopup':'true', 'aria-expanded': 'false'})
  180 +
  181 + $(toggle).parent()
  182 + // Update aria-expanded when open
  183 + .on('shown.bs.dropdown',function(e){
  184 + $par = $(this)
  185 + var $toggle = $par.find(toggle)
  186 + $toggle.attr('aria-expanded','true')
  187 + $toggle.on('keydown.bs.dropdown', $.proxy(function (ev) {
  188 + setTimeout(function() {
  189 + firstItem = $('.dropdown-menu [role=menuitem]:visible', $par)[0]
  190 + try{ firstItem.focus()} catch(ex) {}
  191 + }, focusDelay)
  192 + }, this))
  193 +
  194 + })
  195 + // Update aria-expanded when closed
  196 + .on('hidden.bs.dropdown',function(e){
  197 + $par = $(this)
  198 + var $toggle = $par.find(toggle)
  199 + $toggle.attr('aria-expanded','false')
  200 + })
  201 +
  202 + // Close the dropdown if tabbed away from
  203 + $(document)
  204 + .on('focusout.dropdown.data-api', '.dropdown-menu', function(e){
  205 + var $this = $(this)
  206 + , that = this;
  207 + // since we're trying to close when appropriate,
  208 + // make sure the dropdown is open
  209 + if (!$this.parent().hasClass('open')) {
  210 + return;
  211 + }
  212 + setTimeout(function() {
  213 + if(!$.contains(that, document.activeElement)){
  214 + $this.parent().find('[data-toggle=dropdown]').dropdown('toggle')
  215 + }
  216 + }, 150)
  217 + })
  218 + .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , $.fn.dropdown.Constructor.prototype.keydown);
  219 +
  220 + // Tab Extension
  221 + // ===============================
  222 +
  223 + var $tablist = $('.nav-tabs, .nav-pills')
  224 + , $lis = $tablist.children('li')
  225 + , $tabs = $tablist.find('[data-toggle="tab"], [data-toggle="pill"]')
  226 +
  227 + if($tabs){
  228 + $tablist.attr('role', 'tablist')
  229 + $lis.attr('role', 'presentation')
  230 + $tabs.attr('role', 'tab')
  231 + }
  232 +
  233 + $tabs.each(function( index ) {
  234 + var tabpanel = $($(this).attr('href'))
  235 + , tab = $(this)
  236 + , tabid = tab.attr('id') || uniqueId('ui-tab')
  237 +
  238 + tab.attr('id', tabid)
  239 +
  240 + if(tab.parent().hasClass('active')){
  241 + tab.attr( { 'tabIndex' : '0', 'aria-selected' : 'true', 'aria-controls': tab.attr('href').substr(1) } )
  242 + tabpanel.attr({ 'role' : 'tabpanel', 'tabIndex' : '0', 'aria-hidden' : 'false', 'aria-labelledby':tabid })
  243 + }else{
  244 + tab.attr( { 'tabIndex' : '-1', 'aria-selected' : 'false', 'aria-controls': tab.attr('href').substr(1) } )
  245 + tabpanel.attr( { 'role' : 'tabpanel', 'tabIndex' : '-1', 'aria-hidden' : 'true', 'aria-labelledby':tabid } )
  246 + }
  247 + })
  248 +
  249 + $.fn.tab.Constructor.prototype.keydown = function (e) {
  250 + var $this = $(this)
  251 + , $items
  252 + , $ul = $this.closest('ul[role=tablist] ')
  253 + , index
  254 + , k = e.which || e.keyCode
  255 +
  256 + $this = $(this)
  257 + if (!/(37|38|39|40)/.test(k)) return
  258 +
  259 + $items = $ul.find('[role=tab]:visible')
  260 + index = $items.index($items.filter(':focus'))
  261 +
  262 + if (k == 38 || k == 37) index-- // up & left
  263 + if (k == 39 || k == 40) index++ // down & right
  264 +
  265 +
  266 + if(index < 0) index = $items.length -1
  267 + if(index == $items.length) index = 0
  268 +
  269 + var nextTab = $items.eq(index)
  270 + if(nextTab.attr('role') ==='tab'){
  271 +
  272 + nextTab.tab('show') //Comment this line for dynamically loaded tabPabels, to save Ajax requests on arrow key navigation
  273 + .focus()
  274 + }
  275 + // nextTab.focus()
  276 +
  277 + e.preventDefault()
  278 + e.stopPropagation()
  279 + }
  280 +
  281 + $(document).on('keydown.tab.data-api','[data-toggle="tab"], [data-toggle="pill"]' , $.fn.tab.Constructor.prototype.keydown)
  282 +
  283 + var tabactivate = $.fn.tab.Constructor.prototype.activate;
  284 + $.fn.tab.Constructor.prototype.activate = function (element, container, callback) {
  285 + var $active = container.find('> .active')
  286 + $active.find('[data-toggle=tab], [data-toggle=pill]').attr({ 'tabIndex' : '-1','aria-selected' : false })
  287 + $active.filter('.tab-pane').attr({ 'aria-hidden' : true,'tabIndex' : '-1' })
  288 +
  289 + tabactivate.apply(this, arguments)
  290 +
  291 + element.addClass('active')
  292 + element.find('[data-toggle=tab], [data-toggle=pill]').attr({ 'tabIndex' : '0','aria-selected' : true })
  293 + element.filter('.tab-pane').attr({ 'aria-hidden' : false,'tabIndex' : '0' })
  294 + }
  295 +
  296 + // Collapse Extension
  297 + // ===============================
  298 +
  299 + var $colltabs = $('[data-toggle="collapse"]')
  300 + $colltabs.each(function( index ) {
  301 + var colltab = $(this)
  302 + , collpanel = (colltab.attr('data-target')) ? $(colltab.attr('data-target')) : $(colltab.attr('href'))
  303 + , parent = colltab.attr('data-parent')
  304 + , collparent = parent && $(parent)
  305 + , collid = colltab.attr('id') || uniqueId('ui-collapse')
  306 +
  307 + colltab.attr('id', collid)
  308 +
  309 + if(collparent){
  310 + colltab.attr({ 'role':'tab', 'aria-selected':'false', 'aria-expanded':'false' })
  311 + $(collparent).find('div:not(.collapse,.panel-body), h4').attr('role','presentation')
  312 + collparent.attr({ 'role' : 'tablist', 'aria-multiselectable' : 'true' })
  313 +
  314 + if(collpanel.hasClass('in')){
  315 + colltab.attr({ 'aria-controls': collpanel.attr('id'), 'aria-selected':'true', 'aria-expanded':'true', 'tabindex':'0' })
  316 + collpanel.attr({ 'role':'tabpanel', 'tabindex':'0', 'aria-labelledby':collid, 'aria-hidden':'false' })
  317 + }else{
  318 + colltab.attr({'aria-controls' : collpanel.attr('id'), 'tabindex':'-1' })
  319 + collpanel.attr({ 'role':'tabpanel', 'tabindex':'-1', 'aria-labelledby':collid, 'aria-hidden':'true' })
  320 + }
  321 + }
  322 + })
  323 +
  324 + var collToggle = $.fn.collapse.Constructor.prototype.toggle
  325 + $.fn.collapse.Constructor.prototype.toggle = function(){
  326 + var prevTab = this.$parent && this.$parent.find('[aria-expanded="true"]') , href
  327 +
  328 + if(prevTab){
  329 + var prevPanel = prevTab.attr('data-target') || (href = prevTab.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')
  330 + , $prevPanel = $(prevPanel)
  331 + , $curPanel = this.$element
  332 + , par = this.$parent
  333 + , curTab
  334 +
  335 + if (this.$parent) curTab = this.$parent.find('[data-toggle=collapse][href="#' + this.$element.attr('id') + '"]')
  336 +
  337 + collToggle.apply(this, arguments)
  338 +
  339 + if ($.support.transition) {
  340 + this.$element.one($.support.transition.end, function(){
  341 +
  342 + prevTab.attr({ 'aria-selected':'false','aria-expanded':'false', 'tabIndex':'-1' })
  343 + $prevPanel.attr({ 'aria-hidden' : 'true','tabIndex' : '-1'})
  344 +
  345 + curTab.attr({ 'aria-selected':'true','aria-expanded':'true', 'tabIndex':'0' })
  346 +
  347 + if($curPanel.hasClass('in')){
  348 + $curPanel.attr({ 'aria-hidden' : 'false','tabIndex' : '0' })
  349 + }else{
  350 + curTab.attr({ 'aria-selected':'false','aria-expanded':'false'})
  351 + $curPanel.attr({ 'aria-hidden' : 'true','tabIndex' : '-1' })
  352 + }
  353 + })
  354 + }
  355 + }else{
  356 + collToggle.apply(this, arguments)
  357 + }
  358 + }
  359 +
  360 + $.fn.collapse.Constructor.prototype.keydown = function (e) {
  361 + var $this = $(this)
  362 + , $items
  363 + , $tablist = $this.closest('div[role=tablist] ')
  364 + , index
  365 + , k = e.which || e.keyCode
  366 +
  367 + $this = $(this)
  368 + if (!/(32|37|38|39|40)/.test(k)) return
  369 + if(k==32) $this.click()
  370 +
  371 + $items = $tablist.find('[role=tab]')
  372 + index = $items.index($items.filter(':focus'))
  373 +
  374 + if (k == 38 || k == 37) index-- // up & left
  375 + if (k == 39 || k == 40) index++ // down & right
  376 + if(index < 0) index = $items.length -1
  377 + if(index == $items.length) index = 0
  378 +
  379 + $items.eq(index).focus()
  380 +
  381 + e.preventDefault()
  382 + e.stopPropagation()
  383 +
  384 + }
  385 +
  386 + $(document).on('keydown.collapse.data-api','[data-toggle="collapse"]' , $.fn.collapse.Constructor.prototype.keydown);
  387 +
  388 +
  389 +// Carousel Extension
  390 + // ===============================
  391 +
  392 + $('.carousel').each(function (index) {
  393 +
  394 + // This function positions a highlight box around the tabs in the tablist to use in focus styling
  395 +
  396 + function setTablistHighlightBox() {
  397 +
  398 + var $tab
  399 + , offset
  400 + , height
  401 + , width
  402 + , highlightBox = {}
  403 +
  404 + highlightBox.top = 0
  405 + highlightBox.left = 32000
  406 + highlightBox.height = 0
  407 + highlightBox.width = 0
  408 +
  409 + for (var i = 0; i < $tabs.length; i++) {
  410 + $tab = $tabs[i]
  411 + offset = $($tab).offset()
  412 + height = $($tab).height()
  413 + width = $($tab).width()
  414 +
  415 +// console.log(" Top: " + offset.top + " Left: " + offset.left + " Height: " + height + " Width: " + width)
  416 +
  417 + if (highlightBox.top < offset.top) {
  418 + highlightBox.top = Math.round(offset.top)
  419 + }
  420 +
  421 + if (highlightBox.height < height) {
  422 + highlightBox.height = Math.round(height)
  423 + }
  424 +
  425 + if (highlightBox.left > offset.left) {
  426 + highlightBox.left = Math.round(offset.left)
  427 + }
  428 +
  429 + var w = (offset.left - highlightBox.left) + Math.round(width)
  430 +
  431 + if (highlightBox.width < w) {
  432 + highlightBox.width = w
  433 + }
  434 +
  435 + } // end for
  436 +
  437 +// console.log("[HIGHLIGHT] Top: " + highlightBox.top + " Left: " + highlightBox.left + " Height: " + highlightBox.height + " Width: " + highlightBox.width)
  438 +
  439 + $tablistHighlight.style.top = (highlightBox.top - 2) + 'px'
  440 + $tablistHighlight.style.left = (highlightBox.left - 2) + 'px'
  441 + $tablistHighlight.style.height = (highlightBox.height + 7) + 'px'
  442 + $tablistHighlight.style.width = (highlightBox.width + 8) + 'px'
  443 +
  444 + } // end function
  445 +
  446 + var $this = $(this)
  447 + , $prev = $this.find('[data-slide="prev"]')
  448 + , $next = $this.find('[data-slide="next"]')
  449 + , $tablist = $this.find('.carousel-indicators')
  450 + , $tabs = $this.find('.carousel-indicators li')
  451 + , $tabpanels = $this.find('.item')
  452 + , $tabpanel
  453 + , $tablistHighlight
  454 + , $pauseCarousel
  455 + , $complementaryLandmark
  456 + , $tab
  457 + , $is_paused = false
  458 + , offset
  459 + , height
  460 + , width
  461 + , i
  462 + , id_title = 'id_title'
  463 + , id_desc = 'id_desc'
  464 +
  465 +
  466 + $tablist.attr('role', 'tablist')
  467 +
  468 + $tabs.focus(function() {
  469 + $this.carousel('pause')
  470 + $is_paused = true
  471 + $pauseCarousel.innerHTML = "Play Carousel"
  472 + $(this).parent().addClass('active');
  473 +// $(this).addClass('focus')
  474 + setTablistHighlightBox()
  475 + $($tablistHighlight).addClass('focus')
  476 + $(this).parents('.carousel').addClass('contrast')
  477 + })
  478 +
  479 + $tabs.blur(function(event) {
  480 + $(this).parent().removeClass('active');
  481 +// $(this).removeClass('focus')
  482 + $($tablistHighlight).removeClass('focus')
  483 + $(this).parents('.carousel').removeClass('contrast')
  484 + })
  485 +
  486 +
  487 + for (i = 0; i < $tabpanels.length; i++) {
  488 + $tabpanel = $tabpanels[i]
  489 + $tabpanel.setAttribute('role', 'tabpanel')
  490 + $tabpanel.setAttribute('id', 'tabpanel-' + index + '-' + i)
  491 + $tabpanel.setAttribute('aria-labelledby', 'tab-' + index + '-' + i)
  492 + }
  493 +
  494 + if (typeof $this.attr('role') !== 'string') {
  495 + $this.attr('role', 'complementary');
  496 + $this.attr('aria-labelledby', id_title);
  497 + $this.attr('aria-describedby', id_desc);
  498 + $this.prepend('<p id="' + id_desc + '" class="sr-only">A carousel is a rotating set of images, rotation stops on keyboard focus on carousel tab controls or hovering the mouse pointer over images. Use the tabs or the previous and next buttons to change the displayed slide.</p>')
  499 + $this.prepend('<h2 id="' + id_title + '" class="sr-only">Carousel content with ' + $tabpanels.length + ' slides.</h2>')
  500 + }
  501 +
  502 +
  503 + for (i = 0; i < $tabs.length; i++) {
  504 + $tab = $tabs[i]
  505 +
  506 + $tab.setAttribute('role', 'tab')
  507 + $tab.setAttribute('id', 'tab-' + index + '-' + i)
  508 + $tab.setAttribute('aria-controls', 'tabpanel-' + index + '-' + i)
  509 +
  510 + var tpId = '#tabpanel-' + index + '-' + i
  511 + var caption = $this.find(tpId).find('h1').text()
  512 +
  513 + if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).text()
  514 + if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h3').text()
  515 + if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h4').text()
  516 + if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h5').text()
  517 + if ((typeof caption !== 'string') || (caption.length === 0)) caption = $this.find(tpId).find('h6').text()
  518 + if ((typeof caption !== 'string') || (caption.length === 0)) caption = "no title";
  519 +
  520 +// console.log("CAPTION: " + caption )
  521 +
  522 + var tabName = document.createElement('span')
  523 + tabName.setAttribute('class', 'sr-only')
  524 + tabName.innerHTML='Slide ' + (i+1)
  525 + if (caption) tabName.innerHTML += ": " + caption
  526 + $tab.appendChild(tabName)
  527 +
  528 + }
  529 +
  530 + // create div for focus styling of tablist
  531 + $tablistHighlight = document.createElement('div')
  532 + $tablistHighlight.className = 'carousel-tablist-highlight'
  533 + document.body.appendChild($tablistHighlight)
  534 +
  535 + // create button for screen reader users to stop rotation of carousel
  536 +
  537 + // create button for screen reader users to pause carousel for virtual mode review
  538 + $complementaryLandmark = document.createElement('aside')
  539 + $complementaryLandmark.setAttribute('class', 'carousel-aside-pause')
  540 + $complementaryLandmark.setAttribute('aria-label', 'carousel pause/play control')
  541 + $this.prepend($complementaryLandmark)
  542 +
  543 + $pauseCarousel = document.createElement('button')
  544 + $pauseCarousel.className = "carousel-pause-button"
  545 + $pauseCarousel.innerHTML = "Pause Carousel"
  546 + $pauseCarousel.setAttribute('title', "Pause/Play carousel button can be used by screen reader users to stop carousel animations")
  547 + $($complementaryLandmark).append($pauseCarousel)
  548 +
  549 + $($pauseCarousel).click(function() {
  550 + if ($is_paused) {
  551 + $pauseCarousel.innerHTML = "Pause Carousel"
  552 + $this.carousel('cycle')
  553 + $is_paused = false
  554 + }
  555 + else {
  556 + $pauseCarousel.innerHTML = "Play Carousel"
  557 + $this.carousel('pause')
  558 + $is_paused = true
  559 + }
  560 + })
  561 + $($pauseCarousel).focus(function() {
  562 + $(this).addClass('focus')
  563 + })
  564 +
  565 + $($pauseCarousel).blur(function() {
  566 + $(this).removeClass('focus')
  567 + })
  568 +
  569 + setTablistHighlightBox()
  570 +
  571 + $( window ).resize(function() {
  572 + setTablistHighlightBox()
  573 + })
  574 +
  575 + // Add space bar behavior to prev and next buttons for SR compatibility
  576 + $prev.attr('aria-label', 'Previous Slide')
  577 + $prev.keydown(function(e) {
  578 + var k = e.which || e.keyCode
  579 + if (/(13|32)/.test(k)) {
  580 + e.preventDefault()
  581 + e.stopPropagation()
  582 + $prev.trigger('click');
  583 + }
  584 + });
  585 +
  586 + $prev.focus(function() {
  587 + $(this).parents('.carousel').addClass('contrast')
  588 + })
  589 +
  590 + $prev.blur(function() {
  591 + $(this).parents('.carousel').removeClass('contrast')
  592 + })
  593 +
  594 + $next.attr('aria-label', 'Next Slide')
  595 + $next.keydown(function(e) {
  596 + var k = e.which || e.keyCode
  597 + if (/(13|32)/.test(k)) {
  598 + e.preventDefault()
  599 + e.stopPropagation()
  600 + $next.trigger('click');
  601 + }
  602 + });
  603 +
  604 + $next.focus(function() {
  605 + $(this).parents('.carousel').addClass('contrast')
  606 + })
  607 +
  608 + $next.blur(function() {
  609 + $(this).parents('.carousel').removeClass('contrast')
  610 + })
  611 +
  612 + $('.carousel-inner a').focus(function() {
  613 + $(this).parents('.carousel').addClass('contrast')
  614 + })
  615 +
  616 + $('.carousel-inner a').blur(function() {
  617 + $(this).parents('.carousel').removeClass('contrast')
  618 + })
  619 +
  620 + $tabs.each(function () {
  621 + var item = $(this)
  622 + if(item.hasClass('active')) {
  623 + item.attr({ 'aria-selected': 'true', 'tabindex' : '0' })
  624 + }else{
  625 + item.attr({ 'aria-selected': 'false', 'tabindex' : '-1' })
  626 + }
  627 + })
  628 + })
  629 +
  630 + var slideCarousel = $.fn.carousel.Constructor.prototype.slide
  631 + $.fn.carousel.Constructor.prototype.slide = function (type, next) {
  632 + var $element = this.$element
  633 + , $active = $element.find('[role=tabpanel].active')
  634 + , $next = next || $active[type]()
  635 + , $tab
  636 + , $tab_count = $element.find('[role=tabpanel]').size()
  637 + , $prev_side = $element.find('[data-slide="prev"]')
  638 + , $next_side = $element.find('[data-slide="next"]')
  639 + , $index = 0
  640 + , $prev_index = $tab_count -1
  641 + , $next_index = 1
  642 + , $id
  643 +
  644 + if ($next && $next.attr('id')) {
  645 + $id = $next.attr('id')
  646 + $index = $id.lastIndexOf("-")
  647 + if ($index >= 0) $index = parseInt($id.substring($index+1), 10)
  648 +
  649 + $prev_index = $index - 1
  650 + if ($prev_index < 1) $prev_index = $tab_count - 1
  651 +
  652 + $next_index = $index + 1
  653 + if ($next_index >= $tab_count) $next_index = 0
  654 + }
  655 +
  656 + $prev_side.attr('aria-label', 'Show slide ' + ($prev_index+1) + ' of ' + $tab_count)
  657 + $next_side.attr('aria-label', 'Show slide ' + ($next_index+1) + ' of ' + $tab_count)
  658 +
  659 +
  660 + slideCarousel.apply(this, arguments)
  661 +
  662 + $active
  663 + .one('bsTransitionEnd', function () {
  664 + var $tab
  665 +
  666 + $tab = $element.find('li[aria-controls="' + $active.attr('id') + '"]')
  667 + if ($tab) $tab.attr({'aria-selected':false, 'tabIndex': '-1'})
  668 +
  669 + $tab = $element.find('li[aria-controls="' + $next.attr('id') + '"]')
  670 + if ($tab) $tab.attr({'aria-selected': true, 'tabIndex': '0'})
  671 +
  672 + })
  673 + }
  674 +
  675 + var $this;
  676 + $.fn.carousel.Constructor.prototype.keydown = function (e) {
  677 +
  678 + $this = $this || $(this)
  679 + if(this instanceof Node) $this = $(this)
  680 +
  681 + function selectTab(index) {
  682 + if (index >= $tabs.length) return
  683 + if (index < 0) return
  684 +
  685 + $carousel.carousel(index)
  686 + setTimeout(function () {
  687 + $tabs[index].focus()
  688 + // $this.prev().focus()
  689 + }, 150)
  690 + }
  691 +
  692 + var $carousel = $(e.target).closest('.carousel')
  693 + , $tabs = $carousel.find('[role=tab]')
  694 + , k = e.which || e.keyCode
  695 + , index
  696 +
  697 + if (!/(37|38|39|40)/.test(k)) return
  698 +
  699 + index = $tabs.index($tabs.filter('.active'))
  700 + if (k == 37 || k == 38) { // Up
  701 + index--
  702 + selectTab(index);
  703 + }
  704 +
  705 + if (k == 39 || k == 40) { // Down
  706 + index++
  707 + selectTab(index);
  708 + }
  709 +
  710 + e.preventDefault()
  711 + e.stopPropagation()
  712 + }
  713 + $(document).on('keydown.carousel.data-api', 'li[role=tab]', $.fn.carousel.Constructor.prototype.keydown);
  714 +
  715 +
  716 + })(jQuery);
0 717 \ No newline at end of file
... ...
pacotes/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.min.js 0 → 100755
... ... @@ -0,0 +1,4 @@
  1 +/*! bootstrap-accessibility-plugin - v1.0.5 - 2016-07-19
  2 +* https://github.com/paypal/bootstrap-accessibility-plugin
  3 +* Copyright (c) 2016 PayPal Accessibility Team; Licensed BSD */
  4 +!function($){"use strict";var uniqueId=function(prefix){return(prefix||"ui-id")+"-"+Math.floor(1e3*Math.random()+1)},focusable=function(element,isTabIndexNotNaN){var map,mapName,img,nodeName=element.nodeName.toLowerCase();return"area"===nodeName?(map=element.parentNode,mapName=map.name,element.href&&mapName&&"map"===map.nodeName.toLowerCase()?(img=$("img[usemap='#"+mapName+"']")[0],!!img&&visible(img)):!1):(/input|select|textarea|button|object/.test(nodeName)?!element.disabled:"a"===nodeName?element.href||isTabIndexNotNaN:isTabIndexNotNaN)&&visible(element)},visible=function(element){return $.expr.filters.visible(element)&&!$(element).parents().addBack().filter(function(){return"hidden"===$.css(this,"visibility")}).length};$.extend($.expr[":"],{data:$.expr.createPseudo?$.expr.createPseudo(function(dataName){return function(elem){return!!$.data(elem,dataName)}}):function(elem,i,match){return!!$.data(elem,match[3])},focusable:function(element){return focusable(element,!isNaN($.attr(element,"tabindex")))},tabbable:function(element){var tabIndex=$.attr(element,"tabindex"),isTabIndexNaN=isNaN(tabIndex);return(isTabIndexNaN||tabIndex>=0)&&focusable(element,!isTabIndexNaN)}}),$(".modal-dialog").attr({role:"document"});var modalhide=$.fn.modal.Constructor.prototype.hide;$.fn.modal.Constructor.prototype.hide=function(){modalhide.apply(this,arguments),$(document).off("keydown.bs.modal")};var modalfocus=$.fn.modal.Constructor.prototype.enforceFocus;$.fn.modal.Constructor.prototype.enforceFocus=function(){var $content=this.$element.find(".modal-content"),focEls=$content.find(":tabbable"),$lastEl=$(focEls[focEls.length-1]),$firstEl=$(focEls[0]);$lastEl.on("keydown.bs.modal",$.proxy(function(ev){9!==ev.keyCode||ev.shiftKey|ev.ctrlKey|ev.metaKey|ev.altKey||(ev.preventDefault(),$firstEl.focus())},this)),$firstEl.on("keydown.bs.modal",$.proxy(function(ev){9===ev.keyCode&&ev.shiftKey&&(ev.preventDefault(),$lastEl.focus())},this)),modalfocus.apply(this,arguments)};var $par,firstItem,toggle="[data-toggle=dropdown]",focusDelay=200,menus=$(toggle).parent().find("ul").attr("role","menu"),lis=menus.find("li").attr("role","presentation");lis.find("a").attr({role:"menuitem",tabIndex:"-1"}),$(toggle).attr({"aria-haspopup":"true","aria-expanded":"false"}),$(toggle).parent().on("shown.bs.dropdown",function(e){$par=$(this);var $toggle=$par.find(toggle);$toggle.attr("aria-expanded","true"),$toggle.on("keydown.bs.dropdown",$.proxy(function(ev){setTimeout(function(){firstItem=$(".dropdown-menu [role=menuitem]:visible",$par)[0];try{firstItem.focus()}catch(ex){}},focusDelay)},this))}).on("hidden.bs.dropdown",function(e){$par=$(this);var $toggle=$par.find(toggle);$toggle.attr("aria-expanded","false")}),$(document).on("focusout.dropdown.data-api",".dropdown-menu",function(e){var $this=$(this),that=this;$this.parent().hasClass("open")&&setTimeout(function(){$.contains(that,document.activeElement)||$this.parent().find("[data-toggle=dropdown]").dropdown("toggle")},150)}).on("keydown.bs.dropdown.data-api",toggle+", [role=menu]",$.fn.dropdown.Constructor.prototype.keydown);var $tablist=$(".nav-tabs, .nav-pills"),$lis=$tablist.children("li"),$tabs=$tablist.find('[data-toggle="tab"], [data-toggle="pill"]');$tabs&&($tablist.attr("role","tablist"),$lis.attr("role","presentation"),$tabs.attr("role","tab")),$tabs.each(function(index){var tabpanel=$($(this).attr("href")),tab=$(this),tabid=tab.attr("id")||uniqueId("ui-tab");tab.attr("id",tabid),tab.parent().hasClass("active")?(tab.attr({tabIndex:"0","aria-selected":"true","aria-controls":tab.attr("href").substr(1)}),tabpanel.attr({role:"tabpanel",tabIndex:"0","aria-hidden":"false","aria-labelledby":tabid})):(tab.attr({tabIndex:"-1","aria-selected":"false","aria-controls":tab.attr("href").substr(1)}),tabpanel.attr({role:"tabpanel",tabIndex:"-1","aria-hidden":"true","aria-labelledby":tabid}))}),$.fn.tab.Constructor.prototype.keydown=function(e){var $items,index,$this=$(this),$ul=$this.closest("ul[role=tablist] "),k=e.which||e.keyCode;if($this=$(this),/(37|38|39|40)/.test(k)){$items=$ul.find("[role=tab]:visible"),index=$items.index($items.filter(":focus")),(38==k||37==k)&&index--,(39==k||40==k)&&index++,0>index&&(index=$items.length-1),index==$items.length&&(index=0);var nextTab=$items.eq(index);"tab"===nextTab.attr("role")&&nextTab.tab("show").focus(),e.preventDefault(),e.stopPropagation()}},$(document).on("keydown.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',$.fn.tab.Constructor.prototype.keydown);var tabactivate=$.fn.tab.Constructor.prototype.activate;$.fn.tab.Constructor.prototype.activate=function(element,container,callback){var $active=container.find("> .active");$active.find("[data-toggle=tab], [data-toggle=pill]").attr({tabIndex:"-1","aria-selected":!1}),$active.filter(".tab-pane").attr({"aria-hidden":!0,tabIndex:"-1"}),tabactivate.apply(this,arguments),element.addClass("active"),element.find("[data-toggle=tab], [data-toggle=pill]").attr({tabIndex:"0","aria-selected":!0}),element.filter(".tab-pane").attr({"aria-hidden":!1,tabIndex:"0"})};var $colltabs=$('[data-toggle="collapse"]');$colltabs.each(function(index){var colltab=$(this),collpanel=$(colltab.attr("data-target")?colltab.attr("data-target"):colltab.attr("href")),parent=colltab.attr("data-parent"),collparent=parent&&$(parent),collid=colltab.attr("id")||uniqueId("ui-collapse");colltab.attr("id",collid),collparent&&(colltab.attr({role:"tab","aria-selected":"false","aria-expanded":"false"}),$(collparent).find("div:not(.collapse,.panel-body), h4").attr("role","presentation"),collparent.attr({role:"tablist","aria-multiselectable":"true"}),collpanel.hasClass("in")?(colltab.attr({"aria-controls":collpanel.attr("id"),"aria-selected":"true","aria-expanded":"true",tabindex:"0"}),collpanel.attr({role:"tabpanel",tabindex:"0","aria-labelledby":collid,"aria-hidden":"false"})):(colltab.attr({"aria-controls":collpanel.attr("id"),tabindex:"-1"}),collpanel.attr({role:"tabpanel",tabindex:"-1","aria-labelledby":collid,"aria-hidden":"true"})))});var collToggle=$.fn.collapse.Constructor.prototype.toggle;$.fn.collapse.Constructor.prototype.toggle=function(){var href,prevTab=this.$parent&&this.$parent.find('[aria-expanded="true"]');if(prevTab){var curTab,prevPanel=prevTab.attr("data-target")||(href=prevTab.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),$prevPanel=$(prevPanel),$curPanel=this.$element;this.$parent;this.$parent&&(curTab=this.$parent.find('[data-toggle=collapse][href="#'+this.$element.attr("id")+'"]')),collToggle.apply(this,arguments),$.support.transition&&this.$element.one($.support.transition.end,function(){prevTab.attr({"aria-selected":"false","aria-expanded":"false",tabIndex:"-1"}),$prevPanel.attr({"aria-hidden":"true",tabIndex:"-1"}),curTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:"0"}),$curPanel.hasClass("in")?$curPanel.attr({"aria-hidden":"false",tabIndex:"0"}):(curTab.attr({"aria-selected":"false","aria-expanded":"false"}),$curPanel.attr({"aria-hidden":"true",tabIndex:"-1"}))})}else collToggle.apply(this,arguments)},$.fn.collapse.Constructor.prototype.keydown=function(e){var $items,index,$this=$(this),$tablist=$this.closest("div[role=tablist] "),k=e.which||e.keyCode;$this=$(this),/(32|37|38|39|40)/.test(k)&&(32==k&&$this.click(),$items=$tablist.find("[role=tab]"),index=$items.index($items.filter(":focus")),(38==k||37==k)&&index--,(39==k||40==k)&&index++,0>index&&(index=$items.length-1),index==$items.length&&(index=0),$items.eq(index).focus(),e.preventDefault(),e.stopPropagation())},$(document).on("keydown.collapse.data-api",'[data-toggle="collapse"]',$.fn.collapse.Constructor.prototype.keydown),$(".carousel").each(function(index){function setTablistHighlightBox(){var $tab,offset,height,width,highlightBox={};highlightBox.top=0,highlightBox.left=32e3,highlightBox.height=0,highlightBox.width=0;for(var i=0;i<$tabs.length;i++){$tab=$tabs[i],offset=$($tab).offset(),height=$($tab).height(),width=$($tab).width(),highlightBox.top<offset.top&&(highlightBox.top=Math.round(offset.top)),highlightBox.height<height&&(highlightBox.height=Math.round(height)),highlightBox.left>offset.left&&(highlightBox.left=Math.round(offset.left));var w=offset.left-highlightBox.left+Math.round(width);highlightBox.width<w&&(highlightBox.width=w)}$tablistHighlight.style.top=highlightBox.top-2+"px",$tablistHighlight.style.left=highlightBox.left-2+"px",$tablistHighlight.style.height=highlightBox.height+7+"px",$tablistHighlight.style.width=highlightBox.width+8+"px"}var $tabpanel,$tablistHighlight,$pauseCarousel,$complementaryLandmark,$tab,i,$this=$(this),$prev=$this.find('[data-slide="prev"]'),$next=$this.find('[data-slide="next"]'),$tablist=$this.find(".carousel-indicators"),$tabs=$this.find(".carousel-indicators li"),$tabpanels=$this.find(".item"),$is_paused=!1,id_title="id_title",id_desc="id_desc";for($tablist.attr("role","tablist"),$tabs.focus(function(){$this.carousel("pause"),$is_paused=!0,$pauseCarousel.innerHTML="Play Carousel",$(this).parent().addClass("active"),setTablistHighlightBox(),$($tablistHighlight).addClass("focus"),$(this).parents(".carousel").addClass("contrast")}),$tabs.blur(function(event){$(this).parent().removeClass("active"),$($tablistHighlight).removeClass("focus"),$(this).parents(".carousel").removeClass("contrast")}),i=0;i<$tabpanels.length;i++)$tabpanel=$tabpanels[i],$tabpanel.setAttribute("role","tabpanel"),$tabpanel.setAttribute("id","tabpanel-"+index+"-"+i),$tabpanel.setAttribute("aria-labelledby","tab-"+index+"-"+i);for("string"!=typeof $this.attr("role")&&($this.attr("role","complementary"),$this.attr("aria-labelledby",id_title),$this.attr("aria-describedby",id_desc),$this.prepend('<p id="'+id_desc+'" class="sr-only">A carousel is a rotating set of images, rotation stops on keyboard focus on carousel tab controls or hovering the mouse pointer over images. Use the tabs or the previous and next buttons to change the displayed slide.</p>'),$this.prepend('<h2 id="'+id_title+'" class="sr-only">Carousel content with '+$tabpanels.length+" slides.</h2>")),i=0;i<$tabs.length;i++){$tab=$tabs[i],$tab.setAttribute("role","tab"),$tab.setAttribute("id","tab-"+index+"-"+i),$tab.setAttribute("aria-controls","tabpanel-"+index+"-"+i);var tpId="#tabpanel-"+index+"-"+i,caption=$this.find(tpId).find("h1").text();("string"!=typeof caption||0===caption.length)&&(caption=$this.find(tpId).text()),("string"!=typeof caption||0===caption.length)&&(caption=$this.find(tpId).find("h3").text()),("string"!=typeof caption||0===caption.length)&&(caption=$this.find(tpId).find("h4").text()),("string"!=typeof caption||0===caption.length)&&(caption=$this.find(tpId).find("h5").text()),("string"!=typeof caption||0===caption.length)&&(caption=$this.find(tpId).find("h6").text()),("string"!=typeof caption||0===caption.length)&&(caption="no title");var tabName=document.createElement("span");tabName.setAttribute("class","sr-only"),tabName.innerHTML="Slide "+(i+1),caption&&(tabName.innerHTML+=": "+caption),$tab.appendChild(tabName)}$tablistHighlight=document.createElement("div"),$tablistHighlight.className="carousel-tablist-highlight",document.body.appendChild($tablistHighlight),$complementaryLandmark=document.createElement("aside"),$complementaryLandmark.setAttribute("class","carousel-aside-pause"),$complementaryLandmark.setAttribute("aria-label","carousel pause/play control"),$this.prepend($complementaryLandmark),$pauseCarousel=document.createElement("button"),$pauseCarousel.className="carousel-pause-button",$pauseCarousel.innerHTML="Pause Carousel",$pauseCarousel.setAttribute("title","Pause/Play carousel button can be used by screen reader users to stop carousel animations"),$($complementaryLandmark).append($pauseCarousel),$($pauseCarousel).click(function(){$is_paused?($pauseCarousel.innerHTML="Pause Carousel",$this.carousel("cycle"),$is_paused=!1):($pauseCarousel.innerHTML="Play Carousel",$this.carousel("pause"),$is_paused=!0)}),$($pauseCarousel).focus(function(){$(this).addClass("focus")}),$($pauseCarousel).blur(function(){$(this).removeClass("focus")}),setTablistHighlightBox(),$(window).resize(function(){setTablistHighlightBox()}),$prev.attr("aria-label","Previous Slide"),$prev.keydown(function(e){var k=e.which||e.keyCode;/(13|32)/.test(k)&&(e.preventDefault(),e.stopPropagation(),$prev.trigger("click"))}),$prev.focus(function(){$(this).parents(".carousel").addClass("contrast")}),$prev.blur(function(){$(this).parents(".carousel").removeClass("contrast")}),$next.attr("aria-label","Next Slide"),$next.keydown(function(e){var k=e.which||e.keyCode;/(13|32)/.test(k)&&(e.preventDefault(),e.stopPropagation(),$next.trigger("click"))}),$next.focus(function(){$(this).parents(".carousel").addClass("contrast")}),$next.blur(function(){$(this).parents(".carousel").removeClass("contrast")}),$(".carousel-inner a").focus(function(){$(this).parents(".carousel").addClass("contrast")}),$(".carousel-inner a").blur(function(){$(this).parents(".carousel").removeClass("contrast")}),$tabs.each(function(){var item=$(this);item.hasClass("active")?item.attr({"aria-selected":"true",tabindex:"0"}):item.attr({"aria-selected":"false",tabindex:"-1"})})});var slideCarousel=$.fn.carousel.Constructor.prototype.slide;$.fn.carousel.Constructor.prototype.slide=function(type,next){var $id,$element=this.$element,$active=$element.find("[role=tabpanel].active"),$next=next||$active[type](),$tab_count=$element.find("[role=tabpanel]").size(),$prev_side=$element.find('[data-slide="prev"]'),$next_side=$element.find('[data-slide="next"]'),$index=0,$prev_index=$tab_count-1,$next_index=1;$next&&$next.attr("id")&&($id=$next.attr("id"),$index=$id.lastIndexOf("-"),$index>=0&&($index=parseInt($id.substring($index+1),10)),$prev_index=$index-1,1>$prev_index&&($prev_index=$tab_count-1),$next_index=$index+1,$next_index>=$tab_count&&($next_index=0)),$prev_side.attr("aria-label","Show slide "+($prev_index+1)+" of "+$tab_count),$next_side.attr("aria-label","Show slide "+($next_index+1)+" of "+$tab_count),slideCarousel.apply(this,arguments),$active.one("bsTransitionEnd",function(){var $tab;$tab=$element.find('li[aria-controls="'+$active.attr("id")+'"]'),$tab&&$tab.attr({"aria-selected":!1,tabIndex:"-1"}),$tab=$element.find('li[aria-controls="'+$next.attr("id")+'"]'),$tab&&$tab.attr({"aria-selected":!0,tabIndex:"0"})})};var $this;$.fn.carousel.Constructor.prototype.keydown=function(e){function selectTab(index){index>=$tabs.length||0>index||($carousel.carousel(index),setTimeout(function(){$tabs[index].focus()},150))}$this=$this||$(this),this instanceof Node&&($this=$(this));var index,$carousel=$(e.target).closest(".carousel"),$tabs=$carousel.find("[role=tab]"),k=e.which||e.keyCode;/(37|38|39|40)/.test(k)&&(index=$tabs.index($tabs.filter(".active")),(37==k||38==k)&&(index--,selectTab(index)),(39==k||40==k)&&(index++,selectTab(index)),e.preventDefault(),e.stopPropagation())},$(document).on("keydown.carousel.data-api","li[role=tab]",$.fn.carousel.Constructor.prototype.keydown)}(jQuery);
0 5 \ No newline at end of file
... ...
utilitarios/index.js
... ... @@ -22,6 +22,10 @@ botoesIni = [
22 22 {
23 23 "link":"http://codebeautify.org/",
24 24 "corpo": "Free Online Tools For Developers - To Beautify, Validate, Minify, Analyse and Convert"
  25 + },
  26 + {
  27 + "link":"http://www.dasplankton.de/ContrastA/",
  28 + "corpo": "Contrast-A - find accessible color combinations"
25 29 }
26 30 ];
27 31  
... ...