12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/values.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/accessibility/browser_accessibility.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass WebContents;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A utility class for formatting platform-specific accessibility information,
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// for use in testing, debugging, and developer tools.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is extended by a subclass for each platform where accessibility is
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// implemented.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT AccessibilityTreeFormatter {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit AccessibilityTreeFormatter(BrowserAccessibility* root);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~AccessibilityTreeFormatter();
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  static AccessibilityTreeFormatter* Create(WebContents* wc);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Populates the given DictionaryValue with the accessibility tree.
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The dictionary contains a key/value pair for each attribute of the node,
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // plus a "children" attribute containing a list of all child nodes.
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   "AXName": "node",  /* actual attributes will vary by platform */
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   "position": {  /* some attributes may be dictionaries */
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     "x": 0,
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     "y": 0
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   },
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   /* ... more attributes of |node| */
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   "children": [ {  /* list of children created recursively */
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     "AXName": "child node 1",
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     /* ... more attributes */
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     "children": [ ]
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   }, {
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     "AXName": "child name 2",
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     /* ... more attributes */
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //     "children": [ ]
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //   } ]
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // }
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> BuildAccessibilityTree();
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Dumps a BrowserAccessibility tree into a string.
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void FormatAccessibilityTree(base::string16* contents);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A single filter specification. See GetAllowString() and GetDenyString()
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for more information.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct Filter {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    enum Type {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ALLOW,
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ALLOW_EMPTY,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DENY
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 match_str;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Type type;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Filter(base::string16 match_str, Type type)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : match_str(match_str), type(type) {}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set regular expression filters that apply to each component of every
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // line before it's output.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetFilters(const std::vector<Filter>& filters);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Suffix of the expectation file corresponding to html file.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Example:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTML test:      test-file.html
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Expected:       test-file-expected-mac.txt.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Auto-generated: test-file-actual-mac.txt
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const base::FilePath::StringType GetActualFileSuffix();
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const base::FilePath::StringType GetExpectedFileSuffix();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A platform-specific string that indicates a given line in a file
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is an allow-empty, allow or deny filter. Example:
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Mac values:
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   GetAllowEmptyString() -> "@MAC-ALLOW-EMPTY:"
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   GetAllowString() -> "@MAC-ALLOW:"
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   GetDenyString() -> "@MAC-DENY:"
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Example html:
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // <!--
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // @MAC-ALLOW-EMPTY:description*
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // @MAC-ALLOW:roleDescription*
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // @MAC-DENY:subrole*
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // -->
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // <p>Text</p>
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const std::string GetAllowEmptyString();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const std::string GetAllowString();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const std::string GetDenyString();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RecursiveFormatAccessibilityTree(const BrowserAccessibility& node,
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        base::string16* contents,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        int indent);
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void RecursiveBuildAccessibilityTree(const BrowserAccessibility& node,
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       base::DictionaryValue* tree_node);
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RecursiveFormatAccessibilityTree(const base::DictionaryValue& tree_node,
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                        base::string16* contents,
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        int depth = 0);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overridden by each platform to add the required attributes for each node
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // into the given dict.
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void AddProperties(const BrowserAccessibility& node,
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                     base::DictionaryValue* dict);
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 FormatCoordinates(const char* name,
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   const char* x_name,
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   const char* y_name,
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   const base::DictionaryValue& value);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a platform specific representation of a BrowserAccessibility.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Should be zero or more complete lines, each with |prefix| prepended
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (to indent each line).
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 ToString(const base::DictionaryValue& node,
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          const base::string16& indent);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Initialize();
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool MatchesFilters(const base::string16& text, bool default_result) const;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Writes the given attribute string out to |line| if it matches the filters.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAttribute(bool include_by_default,
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      const base::string16& attr,
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      base::string16* line);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void WriteAttribute(bool include_by_default,
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      const std::string& attr,
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      base::string16* line);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BrowserAccessibility* root_;
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Filters used when formatting the accessibility tree as text.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<Filter> filters_;
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AccessibilityTreeFormatter);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace content
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_H_
150