Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp

Issue 2805493002: Boolean properties for Accessibility Object Model Phase 1 (Closed)
Patch Set: Address feedback Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012, Google Inc. All rights reserved. 2 * Copyright (C) 2012, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 Element* descendant = 256 Element* descendant =
257 element->GetTreeScope().GetElementById(active_descendant_attr); 257 element->GetTreeScope().GetElementById(active_descendant_attr);
258 if (!descendant) 258 if (!descendant)
259 return nullptr; 259 return nullptr;
260 260
261 AXObject* ax_descendant = AxObjectCache().GetOrCreate(descendant); 261 AXObject* ax_descendant = AxObjectCache().GetOrCreate(descendant);
262 return ax_descendant; 262 return ax_descendant;
263 } 263 }
264 264
265 bool AXNodeObject::ComputeAccessibilityIsIgnored( 265 bool AXNodeObject::ComputeAccessibilityIsIgnored(
266 IgnoredReasons* ignored_reasons) const { 266 IgnoredReasons* ignoredReasons) const {
267 #if DCHECK_IS_ON() 267 #if DCHECK_IS_ON()
268 // Double-check that an AXObject is never accessed before 268 // Double-check that an AXObject is never accessed before
269 // it's been initialized. 269 // it's been initialized.
270 DCHECK(initialized_); 270 DCHECK(m_initialized);
271 #endif 271 #endif
272 272
273 // If this element is within a parent that cannot have children, it should not 273 // If this element is within a parent that cannot have children, it should not
274 // be exposed. 274 // be exposed.
275 if (IsDescendantOfLeafNode()) { 275 if (IsDescendantOfLeafNode()) {
276 if (ignored_reasons) 276 if (ignoredReasons)
277 ignored_reasons->push_back( 277 ignoredReasons->push_back(
278 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor())); 278 IgnoredReason(kAXAncestorIsLeafNode, LeafNodeAncestor()));
279 return true; 279 return true;
280 } 280 }
281 281
282 // Ignore labels that are already referenced by a control. 282 // Ignore labels that are already referenced by a control.
283 AXObject* control_object = CorrespondingControlForLabelElement(); 283 AXObject* control_object = CorrespondingControlForLabelElement();
284 if (control_object && control_object->IsCheckboxOrRadio() && 284 if (control_object && control_object->IsCheckboxOrRadio() &&
285 control_object->NameFromLabelElement()) { 285 control_object->NameFromLabelElement()) {
286 if (ignored_reasons) { 286 if (ignoredReasons) {
287 HTMLLabelElement* label = LabelElementContainer(); 287 HTMLLabelElement* label = LabelElementContainer();
288 if (label && label != GetNode()) { 288 if (label && label != GetNode()) {
289 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label); 289 AXObject* label_ax_object = AxObjectCache().GetOrCreate(label);
290 ignored_reasons->push_back( 290 ignoredReasons->push_back(
291 IgnoredReason(kAXLabelContainer, label_ax_object)); 291 IgnoredReason(kAXLabelContainer, label_ax_object));
292 } 292 }
293 293
294 ignored_reasons->push_back(IgnoredReason(kAXLabelFor, control_object)); 294 ignoredReasons->push_back(IgnoredReason(kAXLabelFor, control_object));
295 } 295 }
296 return true; 296 return true;
297 } 297 }
298 298
299 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode()) 299 Element* element = GetNode()->IsElementNode() ? ToElement(GetNode())
300 : GetNode()->parentElement(); 300 : GetNode()->parentElement();
301 if (!GetLayoutObject() && (!element || !element->IsInCanvasSubtree()) && 301 if (!GetLayoutObject() && (!element || !element->IsInCanvasSubtree()) &&
302 !EqualIgnoringASCIICase(GetAttribute(aria_hiddenAttr), "false")) { 302 !AOMPropertyOrARIAAttributeIsFalse(AOMBooleanProperty::kHidden)) {
303 if (ignored_reasons) 303 if (ignoredReasons)
304 ignored_reasons->push_back(IgnoredReason(kAXNotRendered)); 304 ignoredReasons->push_back(IgnoredReason(kAXNotRendered));
305 return true; 305 return true;
306 } 306 }
307 307
308 if (role_ == kUnknownRole) { 308 if (role_ == kUnknownRole) {
309 if (ignored_reasons) 309 if (ignoredReasons)
310 ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); 310 ignoredReasons->push_back(IgnoredReason(kAXUninteresting));
311 return true; 311 return true;
312 } 312 }
313 return false; 313 return false;
314 } 314 }
315 315
316 static bool IsListElement(Node* node) { 316 static bool IsListElement(Node* node) {
317 return isHTMLUListElement(*node) || isHTMLOListElement(*node) || 317 return isHTMLUListElement(*node) || isHTMLOListElement(*node) ||
318 isHTMLDListElement(*node); 318 isHTMLDListElement(*node);
319 } 319 }
320 320
321 static bool IsPresentationalInTable(AXObject* parent, 321 static bool IsPresentationalInTable(AXObject* parent,
322 HTMLElement* current_element) { 322 HTMLElement* currentElement) {
323 if (!current_element) 323 if (!currentElement)
324 return false; 324 return false;
325 325
326 Node* parent_node = parent->GetNode(); 326 Node* parent_node = parent->GetNode();
327 if (!parent_node || !parent_node->IsHTMLElement()) 327 if (!parent_node || !parent_node->IsHTMLElement())
328 return false; 328 return false;
329 329
330 // AXTable determines the role as checking isTableXXX. 330 // AXTable determines the role as checking isTableXXX.
331 // If Table has explicit role including presentation, AXTable doesn't assign 331 // If Table has explicit role including presentation, AXTable doesn't assign
332 // implicit Role to a whole Table. That's why we should check it based on 332 // implicit Role to a whole Table. That's why we should check it based on
333 // node. 333 // node.
334 // Normal Table Tree is that 334 // Normal Table Tree is that
335 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) -> 335 // cell(its role)-> tr(tr role)-> tfoot, tbody, thead(ignored role) ->
336 // table(table role). 336 // table(table role).
337 // If table has presentation role, it will be like 337 // If table has presentation role, it will be like
338 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) -> 338 // cell(group)-> tr(unknown) -> tfoot, tbody, thead(ignored) ->
339 // table(presentation). 339 // table(presentation).
340 if (IsHTMLTableCellElement(*current_element) && 340 if (IsHTMLTableCellElement(*currentElement) &&
341 isHTMLTableRowElement(*parent_node)) 341 isHTMLTableRowElement(*parent_node))
342 return parent->HasInheritedPresentationalRole(); 342 return parent->HasInheritedPresentationalRole();
343 343
344 if (isHTMLTableRowElement(*current_element) && 344 if (isHTMLTableRowElement(*currentElement) &&
345 IsHTMLTableSectionElement(ToHTMLElement(*parent_node))) { 345 IsHTMLTableSectionElement(ToHTMLElement(*parent_node))) {
346 // Because TableSections have ignored role, presentation should be checked 346 // Because TableSections have ignored role, presentation should be checked
347 // with its parent node. 347 // with its parent node.
348 AXObject* table_object = parent->ParentObject(); 348 AXObject* table_object = parent->ParentObject();
349 Node* table_node = table_object ? table_object->GetNode() : 0; 349 Node* table_node = table_object ? table_object->GetNode() : 0;
350 return isHTMLTableElement(table_node) && 350 return isHTMLTableElement(table_node) &&
351 table_object->HasInheritedPresentationalRole(); 351 table_object->HasInheritedPresentationalRole();
352 } 352 }
353 return false; 353 return false;
354 } 354 }
355 355
356 static bool IsRequiredOwnedElement(AXObject* parent, 356 static bool IsRequiredOwnedElement(AXObject* parent,
357 AccessibilityRole current_role, 357 AccessibilityRole currentRole,
358 HTMLElement* current_element) { 358 HTMLElement* currentElement) {
359 Node* parent_node = parent->GetNode(); 359 Node* parent_node = parent->GetNode();
360 if (!parent_node || !parent_node->IsHTMLElement()) 360 if (!parent_node || !parent_node->IsHTMLElement())
361 return false; 361 return false;
362 362
363 if (current_role == kListItemRole) 363 if (currentRole == kListItemRole)
364 return IsListElement(parent_node); 364 return IsListElement(parent_node);
365 if (current_role == kListMarkerRole) 365 if (currentRole == kListMarkerRole)
366 return isHTMLLIElement(*parent_node); 366 return isHTMLLIElement(*parent_node);
367 if (current_role == kMenuItemCheckBoxRole || current_role == kMenuItemRole || 367 if (currentRole == kMenuItemCheckBoxRole || currentRole == kMenuItemRole ||
368 current_role == kMenuItemRadioRole) 368 currentRole == kMenuItemRadioRole)
369 return isHTMLMenuElement(*parent_node); 369 return isHTMLMenuElement(*parent_node);
370 370
371 if (!current_element) 371 if (!currentElement)
372 return false; 372 return false;
373 if (IsHTMLTableCellElement(*current_element)) 373 if (IsHTMLTableCellElement(*currentElement))
374 return isHTMLTableRowElement(*parent_node); 374 return isHTMLTableRowElement(*parent_node);
375 if (isHTMLTableRowElement(*current_element)) 375 if (isHTMLTableRowElement(*currentElement))
376 return IsHTMLTableSectionElement(ToHTMLElement(*parent_node)); 376 return IsHTMLTableSectionElement(ToHTMLElement(*parent_node));
377 377
378 // In case of ListboxRole and its child, ListBoxOptionRole, inheritance of 378 // In case of ListboxRole and its child, ListBoxOptionRole, inheritance of
379 // presentation role is handled in AXListBoxOption because ListBoxOption Role 379 // presentation role is handled in AXListBoxOption because ListBoxOption Role
380 // doesn't have any child. 380 // doesn't have any child.
381 // If it's just ignored because of presentation, we can't see any AX tree 381 // If it's just ignored because of presentation, we can't see any AX tree
382 // related to ListBoxOption. 382 // related to ListBoxOption.
383 return false; 383 return false;
384 } 384 }
385 385
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 landmark_roles_not_allowed.insert(detailsTag); 439 landmark_roles_not_allowed.insert(detailsTag);
440 landmark_roles_not_allowed.insert(fieldsetTag); 440 landmark_roles_not_allowed.insert(fieldsetTag);
441 landmark_roles_not_allowed.insert(figureTag); 441 landmark_roles_not_allowed.insert(figureTag);
442 landmark_roles_not_allowed.insert(tdTag); 442 landmark_roles_not_allowed.insert(tdTag);
443 landmark_roles_not_allowed.insert(mainTag); 443 landmark_roles_not_allowed.insert(mainTag);
444 } 444 }
445 return landmark_roles_not_allowed; 445 return landmark_roles_not_allowed;
446 } 446 }
447 447
448 bool AXNodeObject::IsDescendantOfElementType( 448 bool AXNodeObject::IsDescendantOfElementType(
449 HashSet<QualifiedName>& tag_names) const { 449 HashSet<QualifiedName>& tagNames) const {
450 if (!GetNode()) 450 if (!GetNode())
451 return false; 451 return false;
452 452
453 for (Element* parent = GetNode()->parentElement(); parent; 453 for (Element* parent = GetNode()->parentElement(); parent;
454 parent = parent->parentElement()) { 454 parent = parent->parentElement()) {
455 if (tag_names.Contains(parent->TagQName())) 455 if (tagNames.Contains(parent->TagQName()))
456 return true; 456 return true;
457 } 457 }
458 return false; 458 return false;
459 } 459 }
460 460
461 AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const { 461 AccessibilityRole AXNodeObject::NativeAccessibilityRoleIgnoringAria() const {
462 if (!GetNode()) 462 if (!GetNode())
463 return kUnknownRole; 463 return kUnknownRole;
464 464
465 // |HTMLAnchorElement| sets isLink only when it has hrefAttr. 465 // |HTMLAnchorElement| sets isLink only when it has hrefAttr.
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 // searching up the chain. 897 // searching up the chain.
898 if (parent_aria_role) 898 if (parent_aria_role)
899 break; 899 break;
900 } 900 }
901 901
902 return role; 902 return role;
903 } 903 }
904 904
905 void AXNodeObject::Init() { 905 void AXNodeObject::Init() {
906 #if DCHECK_IS_ON() 906 #if DCHECK_IS_ON()
907 DCHECK(!initialized_); 907 DCHECK(!m_initialized);
908 initialized_ = true; 908 m_initialized = true;
909 #endif 909 #endif
910 role_ = DetermineAccessibilityRole(); 910 role_ = DetermineAccessibilityRole();
911 } 911 }
912 912
913 void AXNodeObject::Detach() { 913 void AXNodeObject::Detach() {
914 AXObject::Detach(); 914 AXObject::Detach();
915 node_ = nullptr; 915 node_ = nullptr;
916 } 916 }
917 917
918 void AXNodeObject::GetSparseAXAttributes( 918 void AXNodeObject::GetSparseAXAttributes(
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 1036
1037 bool AXNodeObject::IsMenuButton() const { 1037 bool AXNodeObject::IsMenuButton() const {
1038 return RoleValue() == kMenuButtonRole; 1038 return RoleValue() == kMenuButtonRole;
1039 } 1039 }
1040 1040
1041 bool AXNodeObject::IsMeter() const { 1041 bool AXNodeObject::IsMeter() const {
1042 return RoleValue() == kMeterRole; 1042 return RoleValue() == kMeterRole;
1043 } 1043 }
1044 1044
1045 bool AXNodeObject::IsMultiSelectable() const { 1045 bool AXNodeObject::IsMultiSelectable() const {
1046 const AtomicString& aria_multi_selectable = 1046 bool multiselectable = false;
1047 GetAttribute(aria_multiselectableAttr); 1047 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kMultiselectable,
1048 if (EqualIgnoringASCIICase(aria_multi_selectable, "true")) 1048 multiselectable)) {
1049 return true; 1049 return multiselectable;
1050 if (EqualIgnoringASCIICase(aria_multi_selectable, "false")) 1050 }
1051 return false;
1052 1051
1053 return isHTMLSelectElement(GetNode()) && 1052 return isHTMLSelectElement(GetNode()) &&
1054 toHTMLSelectElement(*GetNode()).IsMultiple(); 1053 toHTMLSelectElement(*GetNode()).IsMultiple();
1055 } 1054 }
1056 1055
1057 bool AXNodeObject::IsNativeCheckboxOrRadio() const { 1056 bool AXNodeObject::IsNativeCheckboxOrRadio() const {
1058 Node* node = this->GetNode(); 1057 Node* node = this->GetNode();
1059 if (!isHTMLInputElement(node)) 1058 if (!isHTMLInputElement(node))
1060 return false; 1059 return false;
1061 1060
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 1173
1175 AccessibilityExpanded AXNodeObject::IsExpanded() const { 1174 AccessibilityExpanded AXNodeObject::IsExpanded() const {
1176 if (GetNode() && isHTMLSummaryElement(*GetNode())) { 1175 if (GetNode() && isHTMLSummaryElement(*GetNode())) {
1177 if (GetNode()->parentNode() && 1176 if (GetNode()->parentNode() &&
1178 isHTMLDetailsElement(GetNode()->parentNode())) 1177 isHTMLDetailsElement(GetNode()->parentNode()))
1179 return ToElement(GetNode()->parentNode())->hasAttribute(openAttr) 1178 return ToElement(GetNode()->parentNode())->hasAttribute(openAttr)
1180 ? kExpandedExpanded 1179 ? kExpandedExpanded
1181 : kExpandedCollapsed; 1180 : kExpandedCollapsed;
1182 } 1181 }
1183 1182
1184 const AtomicString& expanded = GetAttribute(aria_expandedAttr); 1183 bool expanded = false;
1185 if (EqualIgnoringASCIICase(expanded, "true")) 1184 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kExpanded, expanded)) {
1186 return kExpandedExpanded; 1185 return expanded ? kExpandedExpanded : kExpandedCollapsed;
1187 if (EqualIgnoringASCIICase(expanded, "false")) 1186 }
1188 return kExpandedCollapsed;
1189 1187
1190 return kExpandedUndefined; 1188 return kExpandedUndefined;
1191 } 1189 }
1192 1190
1193 bool AXNodeObject::IsModal() const { 1191 bool AXNodeObject::IsModal() const {
1194 if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole) 1192 if (RoleValue() != kDialogRole && RoleValue() != kAlertDialogRole)
1195 return false; 1193 return false;
1196 1194
1197 if (HasAttribute(aria_modalAttr)) { 1195 bool modal = false;
1198 const AtomicString& modal = GetAttribute(aria_modalAttr); 1196 if (HasAOMPropertyOrARIAAttribute(AOMBooleanProperty::kModal, modal))
1199 if (EqualIgnoringASCIICase(modal, "true")) 1197 return modal;
1200 return true;
1201 if (EqualIgnoringASCIICase(modal, "false"))
1202 return false;
1203 }
1204 1198
1205 if (GetNode() && isHTMLDialogElement(*GetNode())) 1199 if (GetNode() && isHTMLDialogElement(*GetNode()))
1206 return ToElement(GetNode())->IsInTopLayer(); 1200 return ToElement(GetNode())->IsInTopLayer();
1207 1201
1208 return false; 1202 return false;
1209 } 1203 }
1210 1204
1211 bool AXNodeObject::IsPressed() const { 1205 bool AXNodeObject::IsPressed() const {
1212 if (!IsButton()) 1206 if (!IsButton())
1213 return false; 1207 return false;
(...skipping 30 matching lines...) Expand all
1244 1238
1245 return !HasEditableStyle(*node); 1239 return !HasEditableStyle(*node);
1246 } 1240 }
1247 1241
1248 bool AXNodeObject::IsRequired() const { 1242 bool AXNodeObject::IsRequired() const {
1249 Node* n = this->GetNode(); 1243 Node* n = this->GetNode();
1250 if (n && (n->IsElementNode() && ToElement(n)->IsFormControlElement()) && 1244 if (n && (n->IsElementNode() && ToElement(n)->IsFormControlElement()) &&
1251 HasAttribute(requiredAttr)) 1245 HasAttribute(requiredAttr))
1252 return ToHTMLFormControlElement(n)->IsRequired(); 1246 return ToHTMLFormControlElement(n)->IsRequired();
1253 1247
1254 if (EqualIgnoringASCIICase(GetAttribute(aria_requiredAttr), "true")) 1248 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kRequired))
1255 return true; 1249 return true;
1256 1250
1257 return false; 1251 return false;
1258 } 1252 }
1259 1253
1260 bool AXNodeObject::CanSetFocusAttribute() const { 1254 bool AXNodeObject::CanSetFocusAttribute() const {
1261 Node* node = GetNode(); 1255 Node* node = GetNode();
1262 if (!node) 1256 if (!node)
1263 return false; 1257 return false;
1264 1258
1265 if (IsWebArea()) 1259 if (IsWebArea())
1266 return true; 1260 return true;
1267 1261
1268 // Children of elements with an aria-activedescendant attribute should be 1262 // Children of elements with an aria-activedescendant attribute should be
1269 // focusable if they have a (non-presentational) ARIA role. 1263 // focusable if they have a (non-presentational) ARIA role.
1270 if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole && 1264 if (!IsPresentational() && AriaRoleAttribute() != kUnknownRole &&
1271 AncestorExposesActiveDescendant()) 1265 AncestorExposesActiveDescendant())
1272 return true; 1266 return true;
1273 1267
1274 // NOTE: It would be more accurate to ask the document whether 1268 // NOTE: It would be more accurate to ask the document whether
1275 // setFocusedNode() would do anything. For example, setFocusedNode() will do 1269 // setFocusedNode() would do anything. For example, setFocusedNode() will do
1276 // nothing if the current focused node will not relinquish the focus. 1270 // nothing if the current focused node will not relinquish the focus.
1277 if (IsDisabledFormControl(node)) 1271 if (IsDisabledFormControl(node))
1278 return false; 1272 return false;
1279 1273
1280 return node->IsElementNode() && ToElement(node)->SupportsFocus(); 1274 return node->IsElementNode() && ToElement(node)->SupportsFocus();
1281 } 1275 }
1282 1276
1283 bool AXNodeObject::CanSetValueAttribute() const { 1277 bool AXNodeObject::CanSetValueAttribute() const {
1284 if (EqualIgnoringASCIICase(GetAttribute(aria_readonlyAttr), "true")) 1278 if (AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kReadOnly))
1285 return false; 1279 return false;
1286 1280
1287 if (IsProgressIndicator() || IsSlider()) 1281 if (IsProgressIndicator() || IsSlider())
1288 return true; 1282 return true;
1289 1283
1290 if (IsTextControl() && !IsNativeTextControl()) 1284 if (IsTextControl() && !IsNativeTextControl())
1291 return true; 1285 return true;
1292 1286
1293 // Any node could be contenteditable, so isReadOnly should be relied upon 1287 // Any node could be contenteditable, so isReadOnly should be relied upon
1294 // for this information for all elements. 1288 // for this information for all elements.
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 } 1939 }
1946 for (const auto& owned_child : owned_children) 1940 for (const auto& owned_child : owned_children)
1947 children.push_back(owned_child); 1941 children.push_back(owned_child);
1948 1942
1949 for (AXObject* child : children) { 1943 for (AXObject* child : children) {
1950 // Don't recurse into children that are explicitly marked as aria-hidden. 1944 // Don't recurse into children that are explicitly marked as aria-hidden.
1951 // Note that we don't call isInertOrAriaHidden because that would return 1945 // Note that we don't call isInertOrAriaHidden because that would return
1952 // true if any ancestor is hidden, but we need to be able to compute the 1946 // true if any ancestor is hidden, but we need to be able to compute the
1953 // accessible name of object inside hidden subtrees (for example, if 1947 // accessible name of object inside hidden subtrees (for example, if
1954 // aria-labelledby points to an object that's hidden). 1948 // aria-labelledby points to an object that's hidden).
1955 if (EqualIgnoringASCIICase(child->GetAttribute(aria_hiddenAttr), "true")) 1949 if (child->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden))
1956 continue; 1950 continue;
1957 1951
1958 // If we're going between two layoutObjects that are in separate 1952 // If we're going between two layoutObjects that are in separate
1959 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if 1953 // LayoutBoxes, add whitespace if it wasn't there already. Intuitively if
1960 // you have <span>Hello</span><span>World</span>, those are part of the same 1954 // you have <span>Hello</span><span>World</span>, those are part of the same
1961 // LayoutBox so we should return "HelloWorld", but given 1955 // LayoutBox so we should return "HelloWorld", but given
1962 // <div>Hello</div><div>World</div> the strings are in separate boxes so we 1956 // <div>Hello</div><div>World</div> the strings are in separate boxes so we
1963 // should return "Hello World". 1957 // should return "Hello World".
1964 if (previous && accumulated_text.length() && 1958 if (previous && accumulated_text.length() &&
1965 !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) { 1959 !IsHTMLSpace(accumulated_text[accumulated_text.length() - 1])) {
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after
3219 return String(); 3213 return String();
3220 return ToTextControlElement(node)->StrippedPlaceholder(); 3214 return ToTextControlElement(node)->StrippedPlaceholder();
3221 } 3215 }
3222 3216
3223 DEFINE_TRACE(AXNodeObject) { 3217 DEFINE_TRACE(AXNodeObject) {
3224 visitor->Trace(node_); 3218 visitor->Trace(node_);
3225 AXObject::Trace(visitor); 3219 AXObject::Trace(visitor);
3226 } 3220 }
3227 3221
3228 } // namespace blink 3222 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698