AccessibilityHandler.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /********************************************************************************************************************************
  2. * Licensed Materials - Property of IBM *
  3. * *
  4. * IBM Cognos Products: AGS *
  5. * *
  6. * (C) Copyright IBM Corp. 2005, 2014 *
  7. * *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *
  9. *********************************************************************************************************************************/
  10. /*-----------------------------------------------------------------------------------------------------
  11. Class : AccessibilityHandler
  12. Description :
  13. -----------------------------------------------------------------------------------------------------*/
  14. // Switch for keyboard support: true-turn on, false-turn off
  15. var m_bSupportAccessibility = false;
  16. // supported key code Tab-Enter-Esc-Space-Left-Up-Right-Down
  17. var m_aSupportedKeycode = [9, 13, 27, 32, 37, 38, 39, 40];
  18. var m_aTabMenuItems;
  19. var m_aSummaryBarItems;
  20. var m_oMetadataTree;
  21. var m_oSourceTab;
  22. var AccessibilityHandler = {};
  23. AccessibilityHandler.isEnabled = function () {
  24. // check if user enable accessibility
  25. this.checkCookie();
  26. if(m_bSupportAccessibility && !document.all)
  27. return true;
  28. return false;
  29. }
  30. AccessibilityHandler.checkCookie = function () {
  31. var accessibility_cookie = getCookie("AGS_ACCESSIBILITY_ENABLED");
  32. if (accessibility_cookie != null && accessibility_cookie == "true") {
  33. m_bSupportAccessibility = true;
  34. }
  35. }
  36. AccessibilityHandler.enableAccessibility = function () {
  37. var cf = window.parent.getConfigFrame();
  38. var b_confirm = confirm(cf.enableAccessibility_string);
  39. if (b_confirm) {
  40. setCookie("AGS_ACCESSIBILITY_ENABLED","true");
  41. }
  42. }
  43. AccessibilityHandler.disableAccessibility = function () {
  44. var cf = window.parent.getConfigFrame();
  45. var b_confirm = confirm(cf.disableAccessibility_string);
  46. if (b_confirm) {
  47. setCookie("AGS_ACCESSIBILITY_ENABLED","false");
  48. }
  49. }
  50. AccessibilityHandler.initKeyboard = function () {
  51. if(this.isEnabled()) {
  52. this.initTaskMenu();
  53. this.initTabMenu();
  54. // register key down handler for CTRL key press
  55. document.body.onkeydown = this.onkeydown;
  56. }
  57. }
  58. AccessibilityHandler.initTaskMenu = function () {
  59. var taskMenuHTML = document.getElementById("taskContents_tableID");
  60. var taskMenuData = new CMenuExtractor(taskMenuHTML,"tr");
  61. taskMenuData.initTaskMenuItem();
  62. }
  63. AccessibilityHandler.initTabMenu = function () {
  64. var tabMenuHTML = document.getElementById("menuTabs_and_Props");
  65. var tabMenuData = new CMenuExtractor(tabMenuHTML,"img");
  66. m_aTabMenuItems = tabMenuData.getTabMenuItems();
  67. for (var i=0; i<m_aTabMenuItems.length; i++) {
  68. for (var j=0; j<m_aTabMenuItems[i].length; j++) {
  69. m_aTabMenuItems[i][j].onkeypress = this.tabMenuKeypress;
  70. m_aTabMenuItems[i][j].onfocus = this.tabMenuOnfocus;
  71. m_aTabMenuItems[i][j].onblur = this.tabMenuOnblur;
  72. }
  73. }
  74. }
  75. AccessibilityHandler.initSummaryBar = function () {
  76. var summaryBarHTML = document.getElementById("SummaryBarScrollpane");
  77. var summaryBarData = new CMenuExtractor(summaryBarHTML,"table");
  78. m_aSummaryBarItems = summaryBarData.getSummaryBarItems();
  79. for (var i=0; i<m_aSummaryBarItems.length; i++) {
  80. m_aSummaryBarItems[i].onkeypress = this.summaryBarKeypress;
  81. }
  82. // enable summary bar event condition item tabindex value
  83. m_aSummaryBarItems[0].setAttribute("tabindex", "0");
  84. }
  85. AccessibilityHandler.refreshCtrlTabItems = function() {
  86. // get metadata tree root element
  87. m_oMetadataTree = document.getElementById("metadataTreelabelText");
  88. for (var i=0; i< m_aTabMenuItems.length; i++) {
  89. if (isVisible(m_aTabMenuItems[i][0])) {
  90. m_oSourceTab = m_aTabMenuItems[i][0];
  91. break;
  92. }
  93. }
  94. }
  95. AccessibilityHandler.tabMenuOnfocus = function (evt) {
  96. this.className = "selectedTabImage";
  97. }
  98. AccessibilityHandler.tabMenuOnblur = function (evt) {
  99. this.className = "normalTabImage";
  100. }
  101. AccessibilityHandler.onkeydown = function (evt) {
  102. evt = (evt) ? evt : ((event) ? event : null);
  103. var keyCode = evt.keyCode || evt.which;
  104. // check for Ctrl + Tab key press
  105. if (keyCode == 9 && evt.ctrlKey) {
  106. AccessibilityHandler.refreshCtrlTabItems();
  107. // check if metadata tree is visible
  108. if (isVisible(m_oMetadataTree))
  109. m_oMetadataTree.focus();
  110. else
  111. m_oSourceTab.click();
  112. }
  113. }
  114. AccessibilityHandler.tabMenuKeypress = function (evt) {
  115. evt = (evt) ? evt : ((event) ? event : null);
  116. var keyCode = evt.keyCode || evt.which;
  117. var currentTabMenu, index;
  118. for (var i=0; i<m_aTabMenuItems.length; i++) {
  119. if (AccessibilityHandler.contains(m_aTabMenuItems[i], this)) {
  120. currentTabMenu = m_aTabMenuItems[i];
  121. for (var j=0; j<currentTabMenu.length; j++) {
  122. if (this == currentTabMenu[j]) {
  123. index = j;
  124. break;
  125. }
  126. }
  127. break;
  128. }
  129. }
  130. AccessibilityHandler.toggleItem(this, currentTabMenu, index, keyCode);
  131. }
  132. AccessibilityHandler.summaryBarKeypress = function (evt) {
  133. evt = (evt) ? evt : ((event) ? event : null);
  134. var keyCode = evt.keyCode || evt.which;
  135. var index;
  136. for (var i=0; i<m_aSummaryBarItems.length; i++) {
  137. if (this == m_aSummaryBarItems[i]) {
  138. index = i;
  139. break;
  140. }
  141. }
  142. AccessibilityHandler.toggleItem(this, m_aSummaryBarItems, index, keyCode);
  143. }
  144. AccessibilityHandler.toggleItem = function (currentItem,currentMenu,index,keyCode) {
  145. // check for Right key press
  146. if (keyCode == 39) {
  147. if (index != currentMenu.length -1) {
  148. currentMenu[index + 1].focus();
  149. }
  150. }
  151. // check for Left key press
  152. else if (keyCode == 37) {
  153. if (index != 0) {
  154. currentMenu[index - 1].focus();
  155. }
  156. }
  157. // check for Enter key press
  158. else if (keyCode == 13) {
  159. currentItem.click();
  160. }
  161. }
  162. AccessibilityHandler.setTabMenuFocus = function (currentTab) {
  163. var tab_modelItem = document.getElementById("metadataTreelabelText");
  164. var tab_dataItem = document.getElementById("agentItemsTree0labelText");
  165. var tab_functionItem = document.getElementById("functionsTreelabelText");
  166. var tab_parameterItem = document.getElementById("agentParameterTree0labelText");
  167. var tab_historyItem = document.getElementById("historyTree0labelText");
  168. // if currentTab has items, focus on the first one, if not, focus on itself.
  169. switch (currentTab) {
  170. case TAB_MODEL:
  171. if (tab_modelItem != null)
  172. tab_modelItem.focus();
  173. else
  174. m_aTabMenuItems[0][0].focus();
  175. break;
  176. case TAB_DATAITEMS:
  177. if (tab_dataItem != null)
  178. tab_dataItem.focus();
  179. else
  180. m_aTabMenuItems[1][1].focus();
  181. break;
  182. case TAB_FUNCTIONS:
  183. if (tab_functionItem != null)
  184. tab_functionItem.focus();
  185. else
  186. m_aTabMenuItems[2][2].focus();
  187. break;
  188. case TAB_PARAMETERS:
  189. if (tab_parameterItem != null)
  190. tab_parameterItem.focus();
  191. else
  192. m_aTabMenuItems[3][3].focus();
  193. break;
  194. case TAB_HISTORY:
  195. if (tab_historyItem != null)
  196. tab_historyItem.focus();
  197. else
  198. m_aTabMenuItems[4][4].focus();
  199. break;
  200. case TAB_MEMBERS:
  201. m_aTabMenuItems[5][5].focus();
  202. break;
  203. }
  204. }
  205. AccessibilityHandler.getTabindex = function (item) {
  206. var parent = item.getParent();
  207. var current;
  208. if (parent.getParent() == null) {
  209. for (var i=0; i<parent.getNumItems(); i++) {
  210. if (item == parent.get(i)) {
  211. current = i;
  212. break;
  213. }
  214. }
  215. }
  216. if (current != 0)
  217. return -1;
  218. else
  219. return 0;
  220. }
  221. AccessibilityHandler.setTabindex = function (item) {
  222. if (this.isEnabled()) {
  223. var parent = item.getParent();
  224. if (parent.getParent() == null) {
  225. for (var i=0; i<parent.getNumItems(); i++) {
  226. if (item == parent.get(i)) {
  227. parent.get(i).enableTabindex();
  228. }
  229. else {
  230. parent.get(i).disableTabindex();
  231. }
  232. // just ensure to close the menu when mouse interrupted
  233. if (parent.get(i).getMenu().isVisible()) {
  234. parent.get(i).getMenu().remove(true);
  235. }
  236. }
  237. }
  238. }
  239. }
  240. AccessibilityHandler.setRolloverState = function (item) {
  241. if (this.isEnabled() && item.getMenuType() == "dropDown") {
  242. var htmlElement;
  243. var parent = item.getParent();
  244. for (var i=0; i<parent.getNumItems(); i++) {
  245. if (item != parent.get(i)) {
  246. htmlElement = parent.get(i).getHTMLElement();
  247. htmlElement.className = item.getStyle().getNormalState();
  248. }
  249. }
  250. }
  251. }
  252. AccessibilityHandler.isSupportedKeycode = function (keycode) {
  253. if (this.contains(m_aSupportedKeycode, keycode))
  254. return true;
  255. return false;
  256. }
  257. AccessibilityHandler.contains = function (array, obj) {
  258. for (var i = 0; i < array.length; i++) {
  259. if (array[i] === obj) {
  260. return true;
  261. }
  262. }
  263. return false;
  264. }
  265. AccessibilityHandler.getNextItem = function (item,keyCode) {
  266. var current, next, first = 0;
  267. var parent = item.getParent();
  268. var last = parent.getNumItems()-1;
  269. var count = 0;
  270. for (var i=0; i<parent.getNumItems(); i++) {
  271. if (item == parent.get(i)) {
  272. current = i;
  273. break;
  274. }
  275. }
  276. // get next item for Right or Down key press
  277. if (keyCode == 39 || keyCode == 40) {
  278. next = current + 1;
  279. if (current == last) {
  280. next = first;
  281. }
  282. while(this.isNextAvailable(parent.get(next))) {
  283. count ++;
  284. if (next < last) {
  285. next = next + 1;
  286. } else {
  287. next = first;
  288. }
  289. // only retrieve one circle
  290. if(count == last)
  291. break;
  292. }
  293. }
  294. // get next item for Left or Up key press
  295. else if (keyCode == 37 || keyCode == 38) {
  296. next = current - 1;
  297. if (current == first) {
  298. next = last;
  299. }
  300. while(this.isNextAvailable(parent.get(next))) {
  301. count ++;
  302. if (next > first) {
  303. next = next - 1;
  304. } else {
  305. next = last;
  306. }
  307. // only retrieve one circle
  308. if(count == last)
  309. break;
  310. }
  311. }
  312. return parent.get(next);
  313. }
  314. AccessibilityHandler.isNextAvailable = function (item) {
  315. if (item instanceof CToolbarButton) {
  316. return false;
  317. }
  318. else if (item instanceof CMenuItem && item.getMenuType() == "dynamic") {
  319. var style = item.getHTMLElement().getAttribute("style");
  320. if (style == null || style.indexOf("none") == -1) {
  321. return false;
  322. }
  323. }
  324. else if (item instanceof CMenuItem && item.isVisible()) {
  325. return false;
  326. }
  327. return true;
  328. }
  329. function setCookie(c_name,value,expiredays) {
  330. var exdate = new Date();
  331. if (expiredays != null) {
  332. exdate.setDate(exdate.getDate()+expiredays);
  333. } else {
  334. exdate.setUTCFullYear(exdate.getUTCFullYear() + 1);
  335. }
  336. document.cookie = c_name+ "=" + escape(value) + ";expires=" + exdate.toGMTString();
  337. }
  338. function getCookie(c_name) {
  339. if (document.cookie.length>0) {
  340. c_start=document.cookie.indexOf(c_name + "=");
  341. if (c_start!=-1) {
  342. c_start=c_start + c_name.length+1;
  343. c_end=document.cookie.indexOf(";",c_start);
  344. if (c_end==-1) {
  345. c_end=document.cookie.length;
  346. }
  347. return unescape(document.cookie.substring(c_start,c_end));
  348. }
  349. }
  350. return "";
  351. }
  352. function isVisible(element) {
  353. var rect = element.getBoundingClientRect();
  354. return !!(rect.bottom - rect.top);
  355. }