AccessibilityUIElementAtk.cpp 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054
  1. /*
  2. * Copyright (C) 2008 Apple Inc. All Rights Reserved.
  3. * Copyright (C) 2009 Jan Michael Alonzo
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  17. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  18. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  19. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  20. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  21. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  22. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "config.h"
  27. #include "AccessibilityUIElement.h"
  28. #if HAVE(ACCESSIBILITY)
  29. #include <JavaScriptCore/JSStringRef.h>
  30. #include <atk/atk.h>
  31. #include <wtf/Assertions.h>
  32. #include <wtf/gobject/GOwnPtr.h>
  33. #include <wtf/gobject/GRefPtr.h>
  34. #include <wtf/text/CString.h>
  35. #include <wtf/text/WTFString.h>
  36. #include <wtf/unicode/CharacterNames.h>
  37. static String coreAttributeToAtkAttribute(JSStringRef attribute)
  38. {
  39. size_t bufferSize = JSStringGetMaximumUTF8CStringSize(attribute);
  40. GOwnPtr<gchar> buffer(static_cast<gchar*>(g_malloc(bufferSize)));
  41. JSStringGetUTF8CString(attribute, buffer.get(), bufferSize);
  42. String attributeString = String::fromUTF8(buffer.get());
  43. if (attributeString == "AXPlaceholderValue")
  44. return "placeholder-text";
  45. return "";
  46. }
  47. static inline String roleToString(AtkRole role)
  48. {
  49. switch (role) {
  50. case ATK_ROLE_ALERT:
  51. return "AXRole: AXAlert";
  52. case ATK_ROLE_CANVAS:
  53. return "AXRole: AXCanvas";
  54. case ATK_ROLE_CHECK_BOX:
  55. return "AXRole: AXCheckBox";
  56. case ATK_ROLE_COLUMN_HEADER:
  57. return "AXRole: AXColumnHeader";
  58. case ATK_ROLE_COMBO_BOX:
  59. return "AXRole: AXComboBox";
  60. case ATK_ROLE_DOCUMENT_FRAME:
  61. return "AXRole: AXWebArea";
  62. case ATK_ROLE_ENTRY:
  63. return "AXRole: AXTextField";
  64. case ATK_ROLE_FOOTER:
  65. return "AXRole: AXFooter";
  66. case ATK_ROLE_FORM:
  67. return "AXRole: AXForm";
  68. case ATK_ROLE_GROUPING:
  69. return "AXRole: AXGroup";
  70. case ATK_ROLE_HEADING:
  71. return "AXRole: AXHeading";
  72. case ATK_ROLE_IMAGE:
  73. return "AXRole: AXImage";
  74. case ATK_ROLE_IMAGE_MAP:
  75. return "AXRole: AXImageMap";
  76. case ATK_ROLE_LABEL:
  77. return "AXRole: AXLabel";
  78. case ATK_ROLE_LINK:
  79. return "AXRole: AXLink";
  80. case ATK_ROLE_LIST:
  81. return "AXRole: AXList";
  82. case ATK_ROLE_LIST_BOX:
  83. return "AXRole: AXListBox";
  84. case ATK_ROLE_LIST_ITEM:
  85. return "AXRole: AXListItem";
  86. case ATK_ROLE_MENU:
  87. return "AXRole: AXMenu";
  88. case ATK_ROLE_MENU_BAR:
  89. return "AXRole: AXMenuBar";
  90. case ATK_ROLE_MENU_ITEM:
  91. return "AXRole: AXMenuItem";
  92. case ATK_ROLE_PAGE_TAB:
  93. return "AXRole: AXTab";
  94. case ATK_ROLE_PAGE_TAB_LIST:
  95. return "AXRole: AXTabGroup";
  96. case ATK_ROLE_PANEL:
  97. return "AXRole: AXGroup";
  98. case ATK_ROLE_PARAGRAPH:
  99. return "AXRole: AXParagraph";
  100. case ATK_ROLE_PASSWORD_TEXT:
  101. return "AXRole: AXPasswordField";
  102. case ATK_ROLE_PUSH_BUTTON:
  103. return "AXRole: AXButton";
  104. case ATK_ROLE_RADIO_BUTTON:
  105. return "AXRole: AXRadioButton";
  106. case ATK_ROLE_ROW_HEADER:
  107. return "AXRole: AXRowHeader";
  108. case ATK_ROLE_RULER:
  109. return "AXRole: AXRuler";
  110. case ATK_ROLE_SCROLL_BAR:
  111. return "AXRole: AXScrollBar";
  112. case ATK_ROLE_SCROLL_PANE:
  113. return "AXRole: AXScrollArea";
  114. case ATK_ROLE_SECTION:
  115. return "AXRole: AXDiv";
  116. case ATK_ROLE_SEPARATOR:
  117. return "AXRole: AXHorizontalRule";
  118. case ATK_ROLE_SLIDER:
  119. return "AXRole: AXSlider";
  120. case ATK_ROLE_SPIN_BUTTON:
  121. return "AXRole: AXSpinButton";
  122. case ATK_ROLE_TABLE:
  123. return "AXRole: AXTable";
  124. case ATK_ROLE_TABLE_CELL:
  125. return "AXRole: AXCell";
  126. case ATK_ROLE_TABLE_COLUMN_HEADER:
  127. return "AXRole: AXColumnHeader";
  128. case ATK_ROLE_TABLE_ROW:
  129. return "AXRole: AXRow";
  130. case ATK_ROLE_TABLE_ROW_HEADER:
  131. return "AXRole: AXRowHeader";
  132. case ATK_ROLE_TOGGLE_BUTTON:
  133. return "AXRole: AXToggleButton";
  134. case ATK_ROLE_TOOL_BAR:
  135. return "AXRole: AXToolbar";
  136. case ATK_ROLE_TOOL_TIP:
  137. return "AXRole: AXUserInterfaceTooltip";
  138. case ATK_ROLE_TREE:
  139. return "AXRole: AXTree";
  140. case ATK_ROLE_TREE_TABLE:
  141. return "AXRole: AXTreeGrid";
  142. case ATK_ROLE_TREE_ITEM:
  143. return "AXRole: AXTreeItem";
  144. case ATK_ROLE_WINDOW:
  145. return "AXRole: AXWindow";
  146. case ATK_ROLE_UNKNOWN:
  147. return "AXRole: AXUnknown";
  148. default:
  149. // We want to distinguish ATK_ROLE_UNKNOWN from a known AtkRole which
  150. // our DRT isn't properly handling.
  151. return "AXRole: FIXME not identified";
  152. }
  153. }
  154. static inline gchar* replaceCharactersForResults(gchar* str)
  155. {
  156. String uString = String::fromUTF8(str);
  157. // The object replacement character is passed along to ATs so we need to be
  158. // able to test for their presence and do so without causing test failures.
  159. uString.replace(objectReplacementCharacter, "<obj>");
  160. // The presence of newline characters in accessible text of a single object
  161. // is appropriate, but it makes test results (especially the accessible tree)
  162. // harder to read.
  163. uString.replace("\n", "<\\n>");
  164. return g_strdup(uString.utf8().data());
  165. }
  166. static bool checkElementState(PlatformUIElement element, AtkStateType stateType)
  167. {
  168. if (!ATK_IS_OBJECT(element))
  169. return false;
  170. GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(element)));
  171. return atk_state_set_contains_state(stateSet.get(), stateType);
  172. }
  173. AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
  174. : m_element(element)
  175. {
  176. if (m_element)
  177. g_object_ref(m_element);
  178. }
  179. AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
  180. : m_element(other.m_element)
  181. {
  182. if (m_element)
  183. g_object_ref(m_element);
  184. }
  185. AccessibilityUIElement::~AccessibilityUIElement()
  186. {
  187. if (m_element)
  188. g_object_unref(m_element);
  189. }
  190. void AccessibilityUIElement::getLinkedUIElements(Vector<AccessibilityUIElement>& elements)
  191. {
  192. // FIXME: implement
  193. }
  194. void AccessibilityUIElement::getDocumentLinks(Vector<AccessibilityUIElement>&)
  195. {
  196. // FIXME: implement
  197. }
  198. void AccessibilityUIElement::getChildren(Vector<AccessibilityUIElement>& children)
  199. {
  200. int count = childrenCount();
  201. for (int i = 0; i < count; i++) {
  202. AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
  203. children.append(AccessibilityUIElement(child));
  204. }
  205. }
  206. void AccessibilityUIElement::getChildrenWithRange(Vector<AccessibilityUIElement>& elementVector, unsigned start, unsigned end)
  207. {
  208. for (unsigned i = start; i < end; i++) {
  209. AtkObject* child = atk_object_ref_accessible_child(ATK_OBJECT(m_element), i);
  210. elementVector.append(AccessibilityUIElement(child));
  211. }
  212. }
  213. int AccessibilityUIElement::rowCount()
  214. {
  215. if (!m_element)
  216. return 0;
  217. ASSERT(ATK_IS_TABLE(m_element));
  218. return atk_table_get_n_rows(ATK_TABLE(m_element));
  219. }
  220. int AccessibilityUIElement::columnCount()
  221. {
  222. if (!m_element)
  223. return 0;
  224. ASSERT(ATK_IS_TABLE(m_element));
  225. return atk_table_get_n_columns(ATK_TABLE(m_element));
  226. }
  227. int AccessibilityUIElement::childrenCount()
  228. {
  229. if (!m_element)
  230. return 0;
  231. ASSERT(ATK_IS_OBJECT(m_element));
  232. return atk_object_get_n_accessible_children(ATK_OBJECT(m_element));
  233. }
  234. AccessibilityUIElement AccessibilityUIElement::elementAtPoint(int x, int y)
  235. {
  236. if (!m_element)
  237. return 0;
  238. return AccessibilityUIElement(atk_component_ref_accessible_at_point(ATK_COMPONENT(m_element), x, y, ATK_XY_WINDOW));
  239. }
  240. AccessibilityUIElement AccessibilityUIElement::linkedUIElementAtIndex(unsigned index)
  241. {
  242. // FIXME: implement
  243. return 0;
  244. }
  245. AccessibilityUIElement AccessibilityUIElement::getChildAtIndex(unsigned index)
  246. {
  247. Vector<AccessibilityUIElement> children;
  248. getChildrenWithRange(children, index, index + 1);
  249. if (children.size() == 1)
  250. return children.at(0);
  251. return 0;
  252. }
  253. unsigned AccessibilityUIElement::indexOfChild(AccessibilityUIElement* element)
  254. {
  255. // FIXME: implement
  256. return 0;
  257. }
  258. gchar* attributeSetToString(AtkAttributeSet* attributeSet)
  259. {
  260. GString* str = g_string_new(0);
  261. for (GSList* attributes = attributeSet; attributes; attributes = attributes->next) {
  262. AtkAttribute* attribute = static_cast<AtkAttribute*>(attributes->data);
  263. GOwnPtr<gchar> attributeData(g_strconcat(attribute->name, ":", attribute->value, NULL));
  264. g_string_append(str, attributeData.get());
  265. if (attributes->next)
  266. g_string_append(str, ", ");
  267. }
  268. return g_string_free(str, FALSE);
  269. }
  270. JSStringRef AccessibilityUIElement::allAttributes()
  271. {
  272. if (!m_element)
  273. return JSStringCreateWithCharacters(0, 0);
  274. ASSERT(ATK_IS_OBJECT(m_element));
  275. GOwnPtr<gchar> attributeData(attributeSetToString(atk_object_get_attributes(ATK_OBJECT(m_element))));
  276. return JSStringCreateWithUTF8CString(attributeData.get());
  277. }
  278. JSStringRef AccessibilityUIElement::attributesOfLinkedUIElements()
  279. {
  280. // FIXME: implement
  281. return JSStringCreateWithCharacters(0, 0);
  282. }
  283. JSStringRef AccessibilityUIElement::attributesOfDocumentLinks()
  284. {
  285. // FIXME: implement
  286. return JSStringCreateWithCharacters(0, 0);
  287. }
  288. AccessibilityUIElement AccessibilityUIElement::titleUIElement()
  289. {
  290. if (!m_element)
  291. return 0;
  292. AtkRelationSet* set = atk_object_ref_relation_set(ATK_OBJECT(m_element));
  293. if (!set)
  294. return 0;
  295. AtkObject* target = 0;
  296. int count = atk_relation_set_get_n_relations(set);
  297. for (int i = 0; i < count; i++) {
  298. AtkRelation* relation = atk_relation_set_get_relation(set, i);
  299. if (atk_relation_get_relation_type(relation) == ATK_RELATION_LABELLED_BY) {
  300. GPtrArray* targetList = atk_relation_get_target(relation);
  301. if (targetList->len)
  302. target = static_cast<AtkObject*>(g_ptr_array_index(targetList, 0));
  303. }
  304. }
  305. g_object_unref(set);
  306. return target ? AccessibilityUIElement(target) : 0;
  307. }
  308. AccessibilityUIElement AccessibilityUIElement::parentElement()
  309. {
  310. if (!m_element)
  311. return 0;
  312. ASSERT(ATK_IS_OBJECT(m_element));
  313. AtkObject* parent = atk_object_get_parent(ATK_OBJECT(m_element));
  314. return parent ? AccessibilityUIElement(parent) : 0;
  315. }
  316. JSStringRef AccessibilityUIElement::attributesOfChildren()
  317. {
  318. // FIXME: implement
  319. return JSStringCreateWithCharacters(0, 0);
  320. }
  321. JSStringRef AccessibilityUIElement::parameterizedAttributeNames()
  322. {
  323. // FIXME: implement
  324. return JSStringCreateWithCharacters(0, 0);
  325. }
  326. JSStringRef AccessibilityUIElement::role()
  327. {
  328. AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
  329. if (!role)
  330. return JSStringCreateWithCharacters(0, 0);
  331. String roleString = roleToString(role);
  332. return JSStringCreateWithUTF8CString(roleString.utf8().data());
  333. }
  334. JSStringRef AccessibilityUIElement::subrole()
  335. {
  336. return 0;
  337. }
  338. JSStringRef AccessibilityUIElement::roleDescription()
  339. {
  340. return 0;
  341. }
  342. JSStringRef AccessibilityUIElement::title()
  343. {
  344. const gchar* name = atk_object_get_name(ATK_OBJECT(m_element));
  345. GOwnPtr<gchar> axTitle(g_strdup_printf("AXTitle: %s", name ? name : ""));
  346. return JSStringCreateWithUTF8CString(axTitle.get());
  347. }
  348. JSStringRef AccessibilityUIElement::description()
  349. {
  350. const gchar* description = atk_object_get_description(ATK_OBJECT(m_element));
  351. if (!description)
  352. return JSStringCreateWithCharacters(0, 0);
  353. GOwnPtr<gchar> axDesc(g_strdup_printf("AXDescription: %s", description));
  354. return JSStringCreateWithUTF8CString(axDesc.get());
  355. }
  356. JSStringRef AccessibilityUIElement::stringValue()
  357. {
  358. if (!m_element || !ATK_IS_TEXT(m_element))
  359. return JSStringCreateWithCharacters(0, 0);
  360. gchar* text = atk_text_get_text(ATK_TEXT(m_element), 0, -1);
  361. GOwnPtr<gchar> axValue(g_strdup_printf("AXValue: %s", replaceCharactersForResults(text)));
  362. g_free(text);
  363. return JSStringCreateWithUTF8CString(axValue.get());
  364. }
  365. JSStringRef AccessibilityUIElement::language()
  366. {
  367. if (!m_element)
  368. return JSStringCreateWithCharacters(0, 0);
  369. const gchar* locale = atk_object_get_object_locale(ATK_OBJECT(m_element));
  370. if (!locale)
  371. return JSStringCreateWithCharacters(0, 0);
  372. return JSStringCreateWithUTF8CString(g_strdup_printf("AXLanguage: %s", locale));
  373. }
  374. double AccessibilityUIElement::x()
  375. {
  376. int x, y;
  377. atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
  378. return x;
  379. }
  380. double AccessibilityUIElement::y()
  381. {
  382. int x, y;
  383. atk_component_get_position(ATK_COMPONENT(m_element), &x, &y, ATK_XY_SCREEN);
  384. return y;
  385. }
  386. double AccessibilityUIElement::width()
  387. {
  388. int width, height;
  389. atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
  390. return width;
  391. }
  392. double AccessibilityUIElement::height()
  393. {
  394. int width, height;
  395. atk_component_get_size(ATK_COMPONENT(m_element), &width, &height);
  396. return height;
  397. }
  398. double AccessibilityUIElement::clickPointX()
  399. {
  400. // Note: This is not something we have in ATK.
  401. return 0.f;
  402. }
  403. double AccessibilityUIElement::clickPointY()
  404. {
  405. // Note: This is not something we have in ATK.
  406. return 0.f;
  407. }
  408. JSStringRef AccessibilityUIElement::orientation() const
  409. {
  410. if (!m_element || !ATK_IS_OBJECT(m_element))
  411. return JSStringCreateWithCharacters(0, 0);
  412. const char* axOrientation = 0;
  413. if (checkElementState(m_element, ATK_STATE_HORIZONTAL))
  414. axOrientation = "AXOrientation: AXHorizontalOrientation";
  415. else if (checkElementState(m_element, ATK_STATE_VERTICAL))
  416. axOrientation = "AXOrientation: AXVerticalOrientation";
  417. if (!axOrientation)
  418. return JSStringCreateWithCharacters(0, 0);
  419. return JSStringCreateWithUTF8CString(axOrientation);
  420. }
  421. double AccessibilityUIElement::intValue() const
  422. {
  423. GValue value = { 0, { { 0 } } };
  424. if (!ATK_IS_VALUE(m_element))
  425. return 0.0f;
  426. atk_value_get_current_value(ATK_VALUE(m_element), &value);
  427. if (!G_VALUE_HOLDS_FLOAT(&value))
  428. return 0.0f;
  429. return g_value_get_float(&value);
  430. }
  431. double AccessibilityUIElement::minValue()
  432. {
  433. GValue value = { 0, { { 0 } } };
  434. if (!ATK_IS_VALUE(m_element))
  435. return 0.0f;
  436. atk_value_get_minimum_value(ATK_VALUE(m_element), &value);
  437. if (!G_VALUE_HOLDS_FLOAT(&value))
  438. return 0.0f;
  439. return g_value_get_float(&value);
  440. }
  441. double AccessibilityUIElement::maxValue()
  442. {
  443. GValue value = { 0, { { 0 } } };
  444. if (!ATK_IS_VALUE(m_element))
  445. return 0.0f;
  446. atk_value_get_maximum_value(ATK_VALUE(m_element), &value);
  447. if (!G_VALUE_HOLDS_FLOAT(&value))
  448. return 0.0f;
  449. return g_value_get_float(&value);
  450. }
  451. JSStringRef AccessibilityUIElement::valueDescription()
  452. {
  453. // FIXME: implement after it has been implemented in ATK.
  454. // See: https://bugzilla.gnome.org/show_bug.cgi?id=684576
  455. return JSStringCreateWithCharacters(0, 0);
  456. }
  457. bool AccessibilityUIElement::isEnabled()
  458. {
  459. return checkElementState(m_element, ATK_STATE_ENABLED);
  460. }
  461. int AccessibilityUIElement::insertionPointLineNumber()
  462. {
  463. // FIXME: implement
  464. return 0;
  465. }
  466. bool AccessibilityUIElement::isPressActionSupported()
  467. {
  468. // FIXME: implement
  469. return false;
  470. }
  471. bool AccessibilityUIElement::isIncrementActionSupported()
  472. {
  473. // FIXME: implement
  474. return false;
  475. }
  476. bool AccessibilityUIElement::isDecrementActionSupported()
  477. {
  478. // FIXME: implement
  479. return false;
  480. }
  481. bool AccessibilityUIElement::isRequired() const
  482. {
  483. // FIXME: implement
  484. return false;
  485. }
  486. bool AccessibilityUIElement::isFocused() const
  487. {
  488. if (!ATK_IS_OBJECT(m_element))
  489. return false;
  490. GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
  491. gboolean isFocused = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSED);
  492. return isFocused;
  493. }
  494. bool AccessibilityUIElement::isSelected() const
  495. {
  496. return checkElementState(m_element, ATK_STATE_SELECTED);
  497. }
  498. int AccessibilityUIElement::hierarchicalLevel() const
  499. {
  500. // FIXME: implement
  501. return 0;
  502. }
  503. bool AccessibilityUIElement::ariaIsGrabbed() const
  504. {
  505. return false;
  506. }
  507. JSStringRef AccessibilityUIElement::ariaDropEffects() const
  508. {
  509. return 0;
  510. }
  511. bool AccessibilityUIElement::isExpanded() const
  512. {
  513. if (!ATK_IS_OBJECT(m_element))
  514. return false;
  515. GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
  516. gboolean isExpanded = atk_state_set_contains_state(stateSet.get(), ATK_STATE_EXPANDED);
  517. return isExpanded;
  518. }
  519. bool AccessibilityUIElement::isChecked() const
  520. {
  521. if (!ATK_IS_OBJECT(m_element))
  522. return false;
  523. GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
  524. gboolean isChecked = atk_state_set_contains_state(stateSet.get(), ATK_STATE_CHECKED);
  525. return isChecked;
  526. }
  527. JSStringRef AccessibilityUIElement::attributesOfColumnHeaders()
  528. {
  529. // FIXME: implement
  530. return JSStringCreateWithCharacters(0, 0);
  531. }
  532. JSStringRef AccessibilityUIElement::attributesOfRowHeaders()
  533. {
  534. // FIXME: implement
  535. return JSStringCreateWithCharacters(0, 0);
  536. }
  537. JSStringRef AccessibilityUIElement::attributesOfColumns()
  538. {
  539. // FIXME: implement
  540. return JSStringCreateWithCharacters(0, 0);
  541. }
  542. JSStringRef AccessibilityUIElement::attributesOfRows()
  543. {
  544. // FIXME: implement
  545. return JSStringCreateWithCharacters(0, 0);
  546. }
  547. JSStringRef AccessibilityUIElement::attributesOfVisibleCells()
  548. {
  549. // FIXME: implement
  550. return JSStringCreateWithCharacters(0, 0);
  551. }
  552. JSStringRef AccessibilityUIElement::attributesOfHeader()
  553. {
  554. // FIXME: implement
  555. return JSStringCreateWithCharacters(0, 0);
  556. }
  557. int AccessibilityUIElement::indexInTable()
  558. {
  559. // FIXME: implement
  560. return 0;
  561. }
  562. static JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange)
  563. {
  564. GOwnPtr<gchar> rangeString(g_strdup("{0, 0}"));
  565. if (!element)
  566. return JSStringCreateWithUTF8CString(rangeString.get());
  567. ASSERT(ATK_IS_OBJECT(element));
  568. AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element));
  569. if (!axTable || !ATK_IS_TABLE(axTable))
  570. return JSStringCreateWithUTF8CString(rangeString.get());
  571. // Look for the cell in the table.
  572. gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element));
  573. if (indexInParent == -1)
  574. return JSStringCreateWithUTF8CString(rangeString.get());
  575. int row = -1;
  576. int column = -1;
  577. row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent);
  578. column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent);
  579. // Get the actual values, if row and columns are valid values.
  580. if (row != -1 && column != -1) {
  581. int base = 0;
  582. int length = 0;
  583. if (isRowRange) {
  584. base = row;
  585. length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column);
  586. } else {
  587. base = column;
  588. length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column);
  589. }
  590. rangeString.set(g_strdup_printf("{%d, %d}", base, length));
  591. }
  592. return JSStringCreateWithUTF8CString(rangeString.get());
  593. }
  594. JSStringRef AccessibilityUIElement::rowIndexRange()
  595. {
  596. // Range in table for rows.
  597. return indexRangeInTable(m_element, true);
  598. }
  599. JSStringRef AccessibilityUIElement::columnIndexRange()
  600. {
  601. // Range in table for columns.
  602. return indexRangeInTable(m_element, false);
  603. }
  604. int AccessibilityUIElement::lineForIndex(int)
  605. {
  606. // FIXME: implement
  607. return 0;
  608. }
  609. JSStringRef AccessibilityUIElement::boundsForRange(unsigned location, unsigned length)
  610. {
  611. // FIXME: implement
  612. return JSStringCreateWithCharacters(0, 0);
  613. }
  614. JSStringRef AccessibilityUIElement::stringForRange(unsigned, unsigned)
  615. {
  616. // FIXME: implement
  617. return JSStringCreateWithCharacters(0, 0);
  618. }
  619. JSStringRef AccessibilityUIElement::attributedStringForRange(unsigned, unsigned)
  620. {
  621. // FIXME: implement
  622. return JSStringCreateWithCharacters(0, 0);
  623. }
  624. bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location, unsigned length)
  625. {
  626. // FIXME: implement
  627. return false;
  628. }
  629. AccessibilityUIElement AccessibilityUIElement::uiElementForSearchPredicate(JSContextRef context, AccessibilityUIElement* startElement, bool isDirectionNext, JSValueRef searchKey, JSStringRef searchText, bool visibleOnly)
  630. {
  631. // FIXME: implement
  632. return 0;
  633. }
  634. AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row)
  635. {
  636. if (!m_element)
  637. return 0;
  638. ASSERT(ATK_IS_TABLE(m_element));
  639. // Adopt the AtkObject representing the cell because
  640. // at_table_ref_at() transfers full ownership.
  641. GRefPtr<AtkObject> foundCell = adoptGRef(atk_table_ref_at(ATK_TABLE(m_element), row, column));
  642. return foundCell ? AccessibilityUIElement(foundCell.get()) : 0;
  643. }
  644. JSStringRef AccessibilityUIElement::selectedTextRange()
  645. {
  646. // FIXME: implement
  647. return JSStringCreateWithCharacters(0, 0);
  648. }
  649. void AccessibilityUIElement::setSelectedTextRange(unsigned location, unsigned length)
  650. {
  651. // FIXME: implement
  652. }
  653. JSStringRef AccessibilityUIElement::stringAttributeValue(JSStringRef attribute)
  654. {
  655. if (!m_element)
  656. return JSStringCreateWithCharacters(0, 0);
  657. String atkAttributeName = coreAttributeToAtkAttribute(attribute);
  658. if (atkAttributeName.isEmpty())
  659. return JSStringCreateWithCharacters(0, 0);
  660. for (GSList* atkAttributes = atk_object_get_attributes(ATK_OBJECT(m_element)); atkAttributes; atkAttributes = atkAttributes->next) {
  661. AtkAttribute* atkAttribute = static_cast<AtkAttribute*>(atkAttributes->data);
  662. if (!strcmp(atkAttribute->name, atkAttributeName.utf8().data()))
  663. return JSStringCreateWithUTF8CString(atkAttribute->value);
  664. }
  665. return JSStringCreateWithCharacters(0, 0);
  666. }
  667. double AccessibilityUIElement::numberAttributeValue(JSStringRef attribute)
  668. {
  669. // FIXME: implement
  670. return 0.0f;
  671. }
  672. bool AccessibilityUIElement::boolAttributeValue(JSStringRef attribute)
  673. {
  674. // FIXME: implement
  675. return false;
  676. }
  677. bool AccessibilityUIElement::isAttributeSettable(JSStringRef attribute)
  678. {
  679. // FIXME: implement
  680. return false;
  681. }
  682. bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute)
  683. {
  684. return false;
  685. }
  686. static void alterCurrentValue(PlatformUIElement element, int factor)
  687. {
  688. if (!element)
  689. return;
  690. ASSERT(ATK_IS_VALUE(element));
  691. GValue currentValue = G_VALUE_INIT;
  692. atk_value_get_current_value(ATK_VALUE(element), &currentValue);
  693. GValue increment = G_VALUE_INIT;
  694. atk_value_get_minimum_increment(ATK_VALUE(element), &increment);
  695. GValue newValue = G_VALUE_INIT;
  696. g_value_init(&newValue, G_TYPE_FLOAT);
  697. g_value_set_float(&newValue, g_value_get_float(&currentValue) + factor * g_value_get_float(&increment));
  698. atk_value_set_current_value(ATK_VALUE(element), &newValue);
  699. g_value_unset(&newValue);
  700. g_value_unset(&increment);
  701. g_value_unset(&currentValue);
  702. }
  703. void AccessibilityUIElement::increment()
  704. {
  705. alterCurrentValue(m_element, 1);
  706. }
  707. void AccessibilityUIElement::decrement()
  708. {
  709. alterCurrentValue(m_element, -1);
  710. }
  711. void AccessibilityUIElement::press()
  712. {
  713. if (!m_element)
  714. return;
  715. ASSERT(ATK_IS_OBJECT(m_element));
  716. if (!ATK_IS_ACTION(m_element))
  717. return;
  718. // Only one action per object is supported so far.
  719. atk_action_do_action(ATK_ACTION(m_element), 0);
  720. }
  721. void AccessibilityUIElement::showMenu()
  722. {
  723. // FIXME: implement
  724. }
  725. AccessibilityUIElement AccessibilityUIElement::disclosedRowAtIndex(unsigned index)
  726. {
  727. return 0;
  728. }
  729. AccessibilityUIElement AccessibilityUIElement::ariaOwnsElementAtIndex(unsigned index)
  730. {
  731. return 0;
  732. }
  733. AccessibilityUIElement AccessibilityUIElement::ariaFlowToElementAtIndex(unsigned index)
  734. {
  735. return 0;
  736. }
  737. AccessibilityUIElement AccessibilityUIElement::selectedRowAtIndex(unsigned index)
  738. {
  739. return 0;
  740. }
  741. AccessibilityUIElement AccessibilityUIElement::rowAtIndex(unsigned index)
  742. {
  743. return 0;
  744. }
  745. AccessibilityUIElement AccessibilityUIElement::disclosedByRow()
  746. {
  747. return 0;
  748. }
  749. JSStringRef AccessibilityUIElement::accessibilityValue() const
  750. {
  751. // FIXME: implement
  752. return JSStringCreateWithCharacters(0, 0);
  753. }
  754. JSStringRef AccessibilityUIElement::documentEncoding()
  755. {
  756. AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
  757. if (role != ATK_ROLE_DOCUMENT_FRAME)
  758. return JSStringCreateWithCharacters(0, 0);
  759. return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "Encoding"));
  760. }
  761. JSStringRef AccessibilityUIElement::documentURI()
  762. {
  763. AtkRole role = atk_object_get_role(ATK_OBJECT(m_element));
  764. if (role != ATK_ROLE_DOCUMENT_FRAME)
  765. return JSStringCreateWithCharacters(0, 0);
  766. return JSStringCreateWithUTF8CString(atk_document_get_attribute_value(ATK_DOCUMENT(m_element), "URI"));
  767. }
  768. JSStringRef AccessibilityUIElement::url()
  769. {
  770. // FIXME: implement
  771. return JSStringCreateWithCharacters(0, 0);
  772. }
  773. bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
  774. {
  775. // FIXME: implement
  776. return false;
  777. }
  778. void AccessibilityUIElement::removeNotificationListener()
  779. {
  780. // FIXME: implement
  781. }
  782. bool AccessibilityUIElement::isFocusable() const
  783. {
  784. if (!ATK_IS_OBJECT(m_element))
  785. return false;
  786. GRefPtr<AtkStateSet> stateSet = adoptGRef(atk_object_ref_state_set(ATK_OBJECT(m_element)));
  787. gboolean isFocusable = atk_state_set_contains_state(stateSet.get(), ATK_STATE_FOCUSABLE);
  788. return isFocusable;
  789. }
  790. bool AccessibilityUIElement::isSelectable() const
  791. {
  792. return checkElementState(m_element, ATK_STATE_SELECTABLE);
  793. }
  794. bool AccessibilityUIElement::isMultiSelectable() const
  795. {
  796. return checkElementState(m_element, ATK_STATE_MULTISELECTABLE);
  797. }
  798. bool AccessibilityUIElement::isSelectedOptionActive() const
  799. {
  800. // FIXME: implement
  801. return false;
  802. }
  803. bool AccessibilityUIElement::isVisible() const
  804. {
  805. // FIXME: implement
  806. return false;
  807. }
  808. bool AccessibilityUIElement::isOffScreen() const
  809. {
  810. // FIXME: implement
  811. return false;
  812. }
  813. bool AccessibilityUIElement::isCollapsed() const
  814. {
  815. // FIXME: implement
  816. return false;
  817. }
  818. bool AccessibilityUIElement::isIgnored() const
  819. {
  820. // FIXME: implement
  821. return false;
  822. }
  823. bool AccessibilityUIElement::hasPopup() const
  824. {
  825. // FIXME: implement
  826. return false;
  827. }
  828. void AccessibilityUIElement::takeFocus()
  829. {
  830. // FIXME: implement
  831. }
  832. void AccessibilityUIElement::takeSelection()
  833. {
  834. // FIXME: implement
  835. }
  836. void AccessibilityUIElement::addSelection()
  837. {
  838. // FIXME: implement
  839. }
  840. void AccessibilityUIElement::removeSelection()
  841. {
  842. // FIXME: implement
  843. }
  844. void AccessibilityUIElement::scrollToMakeVisible()
  845. {
  846. // FIXME: implement
  847. }
  848. void AccessibilityUIElement::scrollToMakeVisibleWithSubFocus(int x, int y, int width, int height)
  849. {
  850. // FIXME: implement
  851. }
  852. void AccessibilityUIElement::scrollToGlobalPoint(int x, int y)
  853. {
  854. // FIXME: implement
  855. }
  856. #endif