| OLD | NEW |
| 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 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1580 textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects, | 1580 textAlternative = nativeTextAlternative(visited, nameFrom, relatedObjects, |
| 1581 nameSources, &foundTextAlternative); | 1581 nameSources, &foundTextAlternative); |
| 1582 if (!textAlternative.isEmpty() && !nameSources) | 1582 if (!textAlternative.isEmpty() && !nameSources) |
| 1583 return textAlternative; | 1583 return textAlternative; |
| 1584 | 1584 |
| 1585 // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1 | 1585 // Step 2F / 2G from: http://www.w3.org/TR/accname-aam-1.1 |
| 1586 if (recursive || nameFromContents()) { | 1586 if (recursive || nameFromContents()) { |
| 1587 nameFrom = AXNameFromContents; | 1587 nameFrom = AXNameFromContents; |
| 1588 if (nameSources) { | 1588 if (nameSources) { |
| 1589 nameSources->append(NameSource(foundTextAlternative)); | 1589 nameSources->append(NameSource(foundTextAlternative)); |
| 1590 nameSources->last().type = nameFrom; | 1590 nameSources->back().type = nameFrom; |
| 1591 } | 1591 } |
| 1592 | 1592 |
| 1593 Node* node = this->getNode(); | 1593 Node* node = this->getNode(); |
| 1594 if (node && node->isTextNode()) | 1594 if (node && node->isTextNode()) |
| 1595 textAlternative = toText(node)->wholeText(); | 1595 textAlternative = toText(node)->wholeText(); |
| 1596 else if (isHTMLBRElement(node)) | 1596 else if (isHTMLBRElement(node)) |
| 1597 textAlternative = String("\n"); | 1597 textAlternative = String("\n"); |
| 1598 else | 1598 else |
| 1599 textAlternative = textFromDescendants(visited, false); | 1599 textAlternative = textFromDescendants(visited, false); |
| 1600 | 1600 |
| 1601 if (!textAlternative.isEmpty()) { | 1601 if (!textAlternative.isEmpty()) { |
| 1602 if (nameSources) { | 1602 if (nameSources) { |
| 1603 foundTextAlternative = true; | 1603 foundTextAlternative = true; |
| 1604 nameSources->last().text = textAlternative; | 1604 nameSources->back().text = textAlternative; |
| 1605 } else { | 1605 } else { |
| 1606 return textAlternative; | 1606 return textAlternative; |
| 1607 } | 1607 } |
| 1608 } | 1608 } |
| 1609 } | 1609 } |
| 1610 | 1610 |
| 1611 // Step 2H from: http://www.w3.org/TR/accname-aam-1.1 | 1611 // Step 2H from: http://www.w3.org/TR/accname-aam-1.1 |
| 1612 nameFrom = AXNameFromTitle; | 1612 nameFrom = AXNameFromTitle; |
| 1613 if (nameSources) { | 1613 if (nameSources) { |
| 1614 nameSources->append(NameSource(foundTextAlternative, titleAttr)); | 1614 nameSources->append(NameSource(foundTextAlternative, titleAttr)); |
| 1615 nameSources->last().type = nameFrom; | 1615 nameSources->back().type = nameFrom; |
| 1616 } | 1616 } |
| 1617 const AtomicString& title = getAttribute(titleAttr); | 1617 const AtomicString& title = getAttribute(titleAttr); |
| 1618 if (!title.isEmpty()) { | 1618 if (!title.isEmpty()) { |
| 1619 textAlternative = title; | 1619 textAlternative = title; |
| 1620 if (nameSources) { | 1620 if (nameSources) { |
| 1621 foundTextAlternative = true; | 1621 foundTextAlternative = true; |
| 1622 nameSources->last().text = textAlternative; | 1622 nameSources->back().text = textAlternative; |
| 1623 } else { | 1623 } else { |
| 1624 return textAlternative; | 1624 return textAlternative; |
| 1625 } | 1625 } |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 nameFrom = AXNameFromUninitialized; | 1628 nameFrom = AXNameFromUninitialized; |
| 1629 | 1629 |
| 1630 if (nameSources && foundTextAlternative) { | 1630 if (nameSources && foundTextAlternative) { |
| 1631 for (size_t i = 0; i < nameSources->size(); ++i) { | 1631 for (size_t i = 0; i < nameSources->size(); ++i) { |
| 1632 if (!(*nameSources)[i].text.isNull() && !(*nameSources)[i].superseded) { | 1632 if (!(*nameSources)[i].text.isNull() && !(*nameSources)[i].superseded) { |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 // 5.1/5.5 Text inputs, Other labelable Elements | 2239 // 5.1/5.5 Text inputs, Other labelable Elements |
| 2240 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. | 2240 // If you change this logic, update AXNodeObject::nameFromLabelElement, too. |
| 2241 HTMLElement* htmlElement = nullptr; | 2241 HTMLElement* htmlElement = nullptr; |
| 2242 if (getNode()->isHTMLElement()) | 2242 if (getNode()->isHTMLElement()) |
| 2243 htmlElement = toHTMLElement(getNode()); | 2243 htmlElement = toHTMLElement(getNode()); |
| 2244 | 2244 |
| 2245 if (htmlElement && htmlElement->isLabelable()) { | 2245 if (htmlElement && htmlElement->isLabelable()) { |
| 2246 nameFrom = AXNameFromRelatedElement; | 2246 nameFrom = AXNameFromRelatedElement; |
| 2247 if (nameSources) { | 2247 if (nameSources) { |
| 2248 nameSources->append(NameSource(*foundTextAlternative)); | 2248 nameSources->append(NameSource(*foundTextAlternative)); |
| 2249 nameSources->last().type = nameFrom; | 2249 nameSources->back().type = nameFrom; |
| 2250 nameSources->last().nativeSource = AXTextFromNativeHTMLLabel; | 2250 nameSources->back().nativeSource = AXTextFromNativeHTMLLabel; |
| 2251 } | 2251 } |
| 2252 | 2252 |
| 2253 LabelsNodeList* labels = toLabelableElement(htmlElement)->labels(); | 2253 LabelsNodeList* labels = toLabelableElement(htmlElement)->labels(); |
| 2254 if (labels && labels->length() > 0) { | 2254 if (labels && labels->length() > 0) { |
| 2255 HeapVector<Member<Element>> labelElements; | 2255 HeapVector<Member<Element>> labelElements; |
| 2256 for (unsigned labelIndex = 0; labelIndex < labels->length(); | 2256 for (unsigned labelIndex = 0; labelIndex < labels->length(); |
| 2257 ++labelIndex) { | 2257 ++labelIndex) { |
| 2258 Element* label = labels->item(labelIndex); | 2258 Element* label = labels->item(labelIndex); |
| 2259 if (nameSources) { | 2259 if (nameSources) { |
| 2260 if (label->getAttribute(forAttr) == htmlElement->getIdAttribute()) | 2260 if (label->getAttribute(forAttr) == htmlElement->getIdAttribute()) |
| 2261 nameSources->last().nativeSource = AXTextFromNativeHTMLLabelFor; | 2261 nameSources->back().nativeSource = AXTextFromNativeHTMLLabelFor; |
| 2262 else | 2262 else |
| 2263 nameSources->last().nativeSource = AXTextFromNativeHTMLLabelWrapped; | 2263 nameSources->back().nativeSource = AXTextFromNativeHTMLLabelWrapped; |
| 2264 } | 2264 } |
| 2265 labelElements.append(label); | 2265 labelElements.append(label); |
| 2266 } | 2266 } |
| 2267 | 2267 |
| 2268 textAlternative = | 2268 textAlternative = |
| 2269 textFromElements(false, visited, labelElements, relatedObjects); | 2269 textFromElements(false, visited, labelElements, relatedObjects); |
| 2270 if (!textAlternative.isNull()) { | 2270 if (!textAlternative.isNull()) { |
| 2271 *foundTextAlternative = true; | 2271 *foundTextAlternative = true; |
| 2272 if (nameSources) { | 2272 if (nameSources) { |
| 2273 NameSource& source = nameSources->last(); | 2273 NameSource& source = nameSources->back(); |
| 2274 source.relatedObjects = *relatedObjects; | 2274 source.relatedObjects = *relatedObjects; |
| 2275 source.text = textAlternative; | 2275 source.text = textAlternative; |
| 2276 } else { | 2276 } else { |
| 2277 return textAlternative; | 2277 return textAlternative; |
| 2278 } | 2278 } |
| 2279 } else if (nameSources) { | 2279 } else if (nameSources) { |
| 2280 nameSources->last().invalid = true; | 2280 nameSources->back().invalid = true; |
| 2281 } | 2281 } |
| 2282 } | 2282 } |
| 2283 } | 2283 } |
| 2284 | 2284 |
| 2285 // 5.2 input type="button", input type="submit" and input type="reset" | 2285 // 5.2 input type="button", input type="submit" and input type="reset" |
| 2286 if (inputElement && inputElement->isTextButton()) { | 2286 if (inputElement && inputElement->isTextButton()) { |
| 2287 // value attribue | 2287 // value attribue |
| 2288 nameFrom = AXNameFromValue; | 2288 nameFrom = AXNameFromValue; |
| 2289 if (nameSources) { | 2289 if (nameSources) { |
| 2290 nameSources->append(NameSource(*foundTextAlternative, valueAttr)); | 2290 nameSources->append(NameSource(*foundTextAlternative, valueAttr)); |
| 2291 nameSources->last().type = nameFrom; | 2291 nameSources->back().type = nameFrom; |
| 2292 } | 2292 } |
| 2293 String value = inputElement->value(); | 2293 String value = inputElement->value(); |
| 2294 if (!value.isNull()) { | 2294 if (!value.isNull()) { |
| 2295 textAlternative = value; | 2295 textAlternative = value; |
| 2296 if (nameSources) { | 2296 if (nameSources) { |
| 2297 NameSource& source = nameSources->last(); | 2297 NameSource& source = nameSources->back(); |
| 2298 source.text = textAlternative; | 2298 source.text = textAlternative; |
| 2299 *foundTextAlternative = true; | 2299 *foundTextAlternative = true; |
| 2300 } else { | 2300 } else { |
| 2301 return textAlternative; | 2301 return textAlternative; |
| 2302 } | 2302 } |
| 2303 } | 2303 } |
| 2304 return textAlternative; | 2304 return textAlternative; |
| 2305 } | 2305 } |
| 2306 | 2306 |
| 2307 // 5.3 input type="image" | 2307 // 5.3 input type="image" |
| 2308 if (inputElement && | 2308 if (inputElement && |
| 2309 inputElement->getAttribute(typeAttr) == InputTypeNames::image) { | 2309 inputElement->getAttribute(typeAttr) == InputTypeNames::image) { |
| 2310 // alt attr | 2310 // alt attr |
| 2311 nameFrom = AXNameFromAttribute; | 2311 nameFrom = AXNameFromAttribute; |
| 2312 if (nameSources) { | 2312 if (nameSources) { |
| 2313 nameSources->append(NameSource(*foundTextAlternative, altAttr)); | 2313 nameSources->append(NameSource(*foundTextAlternative, altAttr)); |
| 2314 nameSources->last().type = nameFrom; | 2314 nameSources->back().type = nameFrom; |
| 2315 } | 2315 } |
| 2316 const AtomicString& alt = inputElement->getAttribute(altAttr); | 2316 const AtomicString& alt = inputElement->getAttribute(altAttr); |
| 2317 if (!alt.isNull()) { | 2317 if (!alt.isNull()) { |
| 2318 textAlternative = alt; | 2318 textAlternative = alt; |
| 2319 if (nameSources) { | 2319 if (nameSources) { |
| 2320 NameSource& source = nameSources->last(); | 2320 NameSource& source = nameSources->back(); |
| 2321 source.attributeValue = alt; | 2321 source.attributeValue = alt; |
| 2322 source.text = textAlternative; | 2322 source.text = textAlternative; |
| 2323 *foundTextAlternative = true; | 2323 *foundTextAlternative = true; |
| 2324 } else { | 2324 } else { |
| 2325 return textAlternative; | 2325 return textAlternative; |
| 2326 } | 2326 } |
| 2327 } | 2327 } |
| 2328 | 2328 |
| 2329 // value attr | 2329 // value attr |
| 2330 if (nameSources) { | 2330 if (nameSources) { |
| 2331 nameSources->append(NameSource(*foundTextAlternative, valueAttr)); | 2331 nameSources->append(NameSource(*foundTextAlternative, valueAttr)); |
| 2332 nameSources->last().type = nameFrom; | 2332 nameSources->back().type = nameFrom; |
| 2333 } | 2333 } |
| 2334 nameFrom = AXNameFromAttribute; | 2334 nameFrom = AXNameFromAttribute; |
| 2335 String value = inputElement->value(); | 2335 String value = inputElement->value(); |
| 2336 if (!value.isNull()) { | 2336 if (!value.isNull()) { |
| 2337 textAlternative = value; | 2337 textAlternative = value; |
| 2338 if (nameSources) { | 2338 if (nameSources) { |
| 2339 NameSource& source = nameSources->last(); | 2339 NameSource& source = nameSources->back(); |
| 2340 source.text = textAlternative; | 2340 source.text = textAlternative; |
| 2341 *foundTextAlternative = true; | 2341 *foundTextAlternative = true; |
| 2342 } else { | 2342 } else { |
| 2343 return textAlternative; | 2343 return textAlternative; |
| 2344 } | 2344 } |
| 2345 } | 2345 } |
| 2346 | 2346 |
| 2347 // localised default value ("Submit") | 2347 // localised default value ("Submit") |
| 2348 nameFrom = AXNameFromValue; | 2348 nameFrom = AXNameFromValue; |
| 2349 textAlternative = inputElement->locale().queryString( | 2349 textAlternative = inputElement->locale().queryString( |
| 2350 WebLocalizedString::SubmitButtonDefaultLabel); | 2350 WebLocalizedString::SubmitButtonDefaultLabel); |
| 2351 if (nameSources) { | 2351 if (nameSources) { |
| 2352 nameSources->append(NameSource(*foundTextAlternative, typeAttr)); | 2352 nameSources->append(NameSource(*foundTextAlternative, typeAttr)); |
| 2353 NameSource& source = nameSources->last(); | 2353 NameSource& source = nameSources->back(); |
| 2354 source.attributeValue = inputElement->getAttribute(typeAttr); | 2354 source.attributeValue = inputElement->getAttribute(typeAttr); |
| 2355 source.type = nameFrom; | 2355 source.type = nameFrom; |
| 2356 source.text = textAlternative; | 2356 source.text = textAlternative; |
| 2357 *foundTextAlternative = true; | 2357 *foundTextAlternative = true; |
| 2358 } else { | 2358 } else { |
| 2359 return textAlternative; | 2359 return textAlternative; |
| 2360 } | 2360 } |
| 2361 return textAlternative; | 2361 return textAlternative; |
| 2362 } | 2362 } |
| 2363 | 2363 |
| 2364 // 5.1 Text inputs - step 3 (placeholder attribute) | 2364 // 5.1 Text inputs - step 3 (placeholder attribute) |
| 2365 if (htmlElement && htmlElement->isTextControl()) { | 2365 if (htmlElement && htmlElement->isTextControl()) { |
| 2366 nameFrom = AXNameFromPlaceholder; | 2366 nameFrom = AXNameFromPlaceholder; |
| 2367 if (nameSources) { | 2367 if (nameSources) { |
| 2368 nameSources->append(NameSource(*foundTextAlternative, placeholderAttr)); | 2368 nameSources->append(NameSource(*foundTextAlternative, placeholderAttr)); |
| 2369 NameSource& source = nameSources->last(); | 2369 NameSource& source = nameSources->back(); |
| 2370 source.type = nameFrom; | 2370 source.type = nameFrom; |
| 2371 } | 2371 } |
| 2372 HTMLElement* element = toHTMLElement(getNode()); | 2372 HTMLElement* element = toHTMLElement(getNode()); |
| 2373 const AtomicString& placeholder = | 2373 const AtomicString& placeholder = |
| 2374 element->fastGetAttribute(placeholderAttr); | 2374 element->fastGetAttribute(placeholderAttr); |
| 2375 if (!placeholder.isEmpty()) { | 2375 if (!placeholder.isEmpty()) { |
| 2376 textAlternative = placeholder; | 2376 textAlternative = placeholder; |
| 2377 if (nameSources) { | 2377 if (nameSources) { |
| 2378 NameSource& source = nameSources->last(); | 2378 NameSource& source = nameSources->back(); |
| 2379 source.text = textAlternative; | 2379 source.text = textAlternative; |
| 2380 source.attributeValue = placeholder; | 2380 source.attributeValue = placeholder; |
| 2381 } else { | 2381 } else { |
| 2382 return textAlternative; | 2382 return textAlternative; |
| 2383 } | 2383 } |
| 2384 } | 2384 } |
| 2385 return textAlternative; | 2385 return textAlternative; |
| 2386 } | 2386 } |
| 2387 | 2387 |
| 2388 // 5.7 figure and figcaption Elements | 2388 // 5.7 figure and figcaption Elements |
| 2389 if (getNode()->hasTagName(figureTag)) { | 2389 if (getNode()->hasTagName(figureTag)) { |
| 2390 // figcaption | 2390 // figcaption |
| 2391 nameFrom = AXNameFromRelatedElement; | 2391 nameFrom = AXNameFromRelatedElement; |
| 2392 if (nameSources) { | 2392 if (nameSources) { |
| 2393 nameSources->append(NameSource(*foundTextAlternative)); | 2393 nameSources->append(NameSource(*foundTextAlternative)); |
| 2394 nameSources->last().type = nameFrom; | 2394 nameSources->back().type = nameFrom; |
| 2395 nameSources->last().nativeSource = AXTextFromNativeHTMLFigcaption; | 2395 nameSources->back().nativeSource = AXTextFromNativeHTMLFigcaption; |
| 2396 } | 2396 } |
| 2397 Element* figcaption = nullptr; | 2397 Element* figcaption = nullptr; |
| 2398 for (Element& element : ElementTraversal::descendantsOf(*(getNode()))) { | 2398 for (Element& element : ElementTraversal::descendantsOf(*(getNode()))) { |
| 2399 if (element.hasTagName(figcaptionTag)) { | 2399 if (element.hasTagName(figcaptionTag)) { |
| 2400 figcaption = &element; | 2400 figcaption = &element; |
| 2401 break; | 2401 break; |
| 2402 } | 2402 } |
| 2403 } | 2403 } |
| 2404 if (figcaption) { | 2404 if (figcaption) { |
| 2405 AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaption); | 2405 AXObject* figcaptionAXObject = axObjectCache().getOrCreate(figcaption); |
| 2406 if (figcaptionAXObject) { | 2406 if (figcaptionAXObject) { |
| 2407 textAlternative = | 2407 textAlternative = |
| 2408 recursiveTextAlternative(*figcaptionAXObject, false, visited); | 2408 recursiveTextAlternative(*figcaptionAXObject, false, visited); |
| 2409 | 2409 |
| 2410 if (relatedObjects) { | 2410 if (relatedObjects) { |
| 2411 localRelatedObjects.append( | 2411 localRelatedObjects.append( |
| 2412 new NameSourceRelatedObject(figcaptionAXObject, textAlternative)); | 2412 new NameSourceRelatedObject(figcaptionAXObject, textAlternative)); |
| 2413 *relatedObjects = localRelatedObjects; | 2413 *relatedObjects = localRelatedObjects; |
| 2414 localRelatedObjects.clear(); | 2414 localRelatedObjects.clear(); |
| 2415 } | 2415 } |
| 2416 | 2416 |
| 2417 if (nameSources) { | 2417 if (nameSources) { |
| 2418 NameSource& source = nameSources->last(); | 2418 NameSource& source = nameSources->back(); |
| 2419 source.relatedObjects = *relatedObjects; | 2419 source.relatedObjects = *relatedObjects; |
| 2420 source.text = textAlternative; | 2420 source.text = textAlternative; |
| 2421 *foundTextAlternative = true; | 2421 *foundTextAlternative = true; |
| 2422 } else { | 2422 } else { |
| 2423 return textAlternative; | 2423 return textAlternative; |
| 2424 } | 2424 } |
| 2425 } | 2425 } |
| 2426 } | 2426 } |
| 2427 return textAlternative; | 2427 return textAlternative; |
| 2428 } | 2428 } |
| 2429 | 2429 |
| 2430 // 5.8 img or area Element | 2430 // 5.8 img or area Element |
| 2431 if (isHTMLImageElement(getNode()) || isHTMLAreaElement(getNode()) || | 2431 if (isHTMLImageElement(getNode()) || isHTMLAreaElement(getNode()) || |
| 2432 (getLayoutObject() && getLayoutObject()->isSVGImage())) { | 2432 (getLayoutObject() && getLayoutObject()->isSVGImage())) { |
| 2433 // alt | 2433 // alt |
| 2434 nameFrom = AXNameFromAttribute; | 2434 nameFrom = AXNameFromAttribute; |
| 2435 if (nameSources) { | 2435 if (nameSources) { |
| 2436 nameSources->append(NameSource(*foundTextAlternative, altAttr)); | 2436 nameSources->append(NameSource(*foundTextAlternative, altAttr)); |
| 2437 nameSources->last().type = nameFrom; | 2437 nameSources->back().type = nameFrom; |
| 2438 } | 2438 } |
| 2439 const AtomicString& alt = getAttribute(altAttr); | 2439 const AtomicString& alt = getAttribute(altAttr); |
| 2440 if (!alt.isNull()) { | 2440 if (!alt.isNull()) { |
| 2441 textAlternative = alt; | 2441 textAlternative = alt; |
| 2442 if (nameSources) { | 2442 if (nameSources) { |
| 2443 NameSource& source = nameSources->last(); | 2443 NameSource& source = nameSources->back(); |
| 2444 source.attributeValue = alt; | 2444 source.attributeValue = alt; |
| 2445 source.text = textAlternative; | 2445 source.text = textAlternative; |
| 2446 *foundTextAlternative = true; | 2446 *foundTextAlternative = true; |
| 2447 } else { | 2447 } else { |
| 2448 return textAlternative; | 2448 return textAlternative; |
| 2449 } | 2449 } |
| 2450 } | 2450 } |
| 2451 return textAlternative; | 2451 return textAlternative; |
| 2452 } | 2452 } |
| 2453 | 2453 |
| 2454 // 5.9 table Element | 2454 // 5.9 table Element |
| 2455 if (isHTMLTableElement(getNode())) { | 2455 if (isHTMLTableElement(getNode())) { |
| 2456 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); | 2456 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); |
| 2457 | 2457 |
| 2458 // caption | 2458 // caption |
| 2459 nameFrom = AXNameFromCaption; | 2459 nameFrom = AXNameFromCaption; |
| 2460 if (nameSources) { | 2460 if (nameSources) { |
| 2461 nameSources->append(NameSource(*foundTextAlternative)); | 2461 nameSources->append(NameSource(*foundTextAlternative)); |
| 2462 nameSources->last().type = nameFrom; | 2462 nameSources->back().type = nameFrom; |
| 2463 nameSources->last().nativeSource = AXTextFromNativeHTMLTableCaption; | 2463 nameSources->back().nativeSource = AXTextFromNativeHTMLTableCaption; |
| 2464 } | 2464 } |
| 2465 HTMLTableCaptionElement* caption = tableElement->caption(); | 2465 HTMLTableCaptionElement* caption = tableElement->caption(); |
| 2466 if (caption) { | 2466 if (caption) { |
| 2467 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); | 2467 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); |
| 2468 if (captionAXObject) { | 2468 if (captionAXObject) { |
| 2469 textAlternative = | 2469 textAlternative = |
| 2470 recursiveTextAlternative(*captionAXObject, false, visited); | 2470 recursiveTextAlternative(*captionAXObject, false, visited); |
| 2471 if (relatedObjects) { | 2471 if (relatedObjects) { |
| 2472 localRelatedObjects.append( | 2472 localRelatedObjects.append( |
| 2473 new NameSourceRelatedObject(captionAXObject, textAlternative)); | 2473 new NameSourceRelatedObject(captionAXObject, textAlternative)); |
| 2474 *relatedObjects = localRelatedObjects; | 2474 *relatedObjects = localRelatedObjects; |
| 2475 localRelatedObjects.clear(); | 2475 localRelatedObjects.clear(); |
| 2476 } | 2476 } |
| 2477 | 2477 |
| 2478 if (nameSources) { | 2478 if (nameSources) { |
| 2479 NameSource& source = nameSources->last(); | 2479 NameSource& source = nameSources->back(); |
| 2480 source.relatedObjects = *relatedObjects; | 2480 source.relatedObjects = *relatedObjects; |
| 2481 source.text = textAlternative; | 2481 source.text = textAlternative; |
| 2482 *foundTextAlternative = true; | 2482 *foundTextAlternative = true; |
| 2483 } else { | 2483 } else { |
| 2484 return textAlternative; | 2484 return textAlternative; |
| 2485 } | 2485 } |
| 2486 } | 2486 } |
| 2487 } | 2487 } |
| 2488 | 2488 |
| 2489 // summary | 2489 // summary |
| 2490 nameFrom = AXNameFromAttribute; | 2490 nameFrom = AXNameFromAttribute; |
| 2491 if (nameSources) { | 2491 if (nameSources) { |
| 2492 nameSources->append(NameSource(*foundTextAlternative, summaryAttr)); | 2492 nameSources->append(NameSource(*foundTextAlternative, summaryAttr)); |
| 2493 nameSources->last().type = nameFrom; | 2493 nameSources->back().type = nameFrom; |
| 2494 } | 2494 } |
| 2495 const AtomicString& summary = getAttribute(summaryAttr); | 2495 const AtomicString& summary = getAttribute(summaryAttr); |
| 2496 if (!summary.isNull()) { | 2496 if (!summary.isNull()) { |
| 2497 textAlternative = summary; | 2497 textAlternative = summary; |
| 2498 if (nameSources) { | 2498 if (nameSources) { |
| 2499 NameSource& source = nameSources->last(); | 2499 NameSource& source = nameSources->back(); |
| 2500 source.attributeValue = summary; | 2500 source.attributeValue = summary; |
| 2501 source.text = textAlternative; | 2501 source.text = textAlternative; |
| 2502 *foundTextAlternative = true; | 2502 *foundTextAlternative = true; |
| 2503 } else { | 2503 } else { |
| 2504 return textAlternative; | 2504 return textAlternative; |
| 2505 } | 2505 } |
| 2506 } | 2506 } |
| 2507 | 2507 |
| 2508 return textAlternative; | 2508 return textAlternative; |
| 2509 } | 2509 } |
| 2510 | 2510 |
| 2511 // Per SVG AAM 1.0's modifications to 2D of this algorithm. | 2511 // Per SVG AAM 1.0's modifications to 2D of this algorithm. |
| 2512 if (getNode()->isSVGElement()) { | 2512 if (getNode()->isSVGElement()) { |
| 2513 nameFrom = AXNameFromRelatedElement; | 2513 nameFrom = AXNameFromRelatedElement; |
| 2514 if (nameSources) { | 2514 if (nameSources) { |
| 2515 nameSources->append(NameSource(*foundTextAlternative)); | 2515 nameSources->append(NameSource(*foundTextAlternative)); |
| 2516 nameSources->last().type = nameFrom; | 2516 nameSources->back().type = nameFrom; |
| 2517 nameSources->last().nativeSource = AXTextFromNativeHTMLTitleElement; | 2517 nameSources->back().nativeSource = AXTextFromNativeHTMLTitleElement; |
| 2518 } | 2518 } |
| 2519 ASSERT(getNode()->isContainerNode()); | 2519 ASSERT(getNode()->isContainerNode()); |
| 2520 Element* title = ElementTraversal::firstChild( | 2520 Element* title = ElementTraversal::firstChild( |
| 2521 toContainerNode(*(getNode())), HasTagName(SVGNames::titleTag)); | 2521 toContainerNode(*(getNode())), HasTagName(SVGNames::titleTag)); |
| 2522 | 2522 |
| 2523 if (title) { | 2523 if (title) { |
| 2524 AXObject* titleAXObject = axObjectCache().getOrCreate(title); | 2524 AXObject* titleAXObject = axObjectCache().getOrCreate(title); |
| 2525 if (titleAXObject && !visited.contains(titleAXObject)) { | 2525 if (titleAXObject && !visited.contains(titleAXObject)) { |
| 2526 textAlternative = | 2526 textAlternative = |
| 2527 recursiveTextAlternative(*titleAXObject, false, visited); | 2527 recursiveTextAlternative(*titleAXObject, false, visited); |
| 2528 if (relatedObjects) { | 2528 if (relatedObjects) { |
| 2529 localRelatedObjects.append( | 2529 localRelatedObjects.append( |
| 2530 new NameSourceRelatedObject(titleAXObject, textAlternative)); | 2530 new NameSourceRelatedObject(titleAXObject, textAlternative)); |
| 2531 *relatedObjects = localRelatedObjects; | 2531 *relatedObjects = localRelatedObjects; |
| 2532 localRelatedObjects.clear(); | 2532 localRelatedObjects.clear(); |
| 2533 } | 2533 } |
| 2534 } | 2534 } |
| 2535 if (nameSources) { | 2535 if (nameSources) { |
| 2536 NameSource& source = nameSources->last(); | 2536 NameSource& source = nameSources->back(); |
| 2537 source.text = textAlternative; | 2537 source.text = textAlternative; |
| 2538 source.relatedObjects = *relatedObjects; | 2538 source.relatedObjects = *relatedObjects; |
| 2539 *foundTextAlternative = true; | 2539 *foundTextAlternative = true; |
| 2540 } else { | 2540 } else { |
| 2541 return textAlternative; | 2541 return textAlternative; |
| 2542 } | 2542 } |
| 2543 } | 2543 } |
| 2544 } | 2544 } |
| 2545 | 2545 |
| 2546 // Fieldset / legend. | 2546 // Fieldset / legend. |
| 2547 if (isHTMLFieldSetElement(getNode())) { | 2547 if (isHTMLFieldSetElement(getNode())) { |
| 2548 nameFrom = AXNameFromRelatedElement; | 2548 nameFrom = AXNameFromRelatedElement; |
| 2549 if (nameSources) { | 2549 if (nameSources) { |
| 2550 nameSources->append(NameSource(*foundTextAlternative)); | 2550 nameSources->append(NameSource(*foundTextAlternative)); |
| 2551 nameSources->last().type = nameFrom; | 2551 nameSources->back().type = nameFrom; |
| 2552 nameSources->last().nativeSource = AXTextFromNativeHTMLLegend; | 2552 nameSources->back().nativeSource = AXTextFromNativeHTMLLegend; |
| 2553 } | 2553 } |
| 2554 HTMLElement* legend = toHTMLFieldSetElement(getNode())->legend(); | 2554 HTMLElement* legend = toHTMLFieldSetElement(getNode())->legend(); |
| 2555 if (legend) { | 2555 if (legend) { |
| 2556 AXObject* legendAXObject = axObjectCache().getOrCreate(legend); | 2556 AXObject* legendAXObject = axObjectCache().getOrCreate(legend); |
| 2557 // Avoid an infinite loop | 2557 // Avoid an infinite loop |
| 2558 if (legendAXObject && !visited.contains(legendAXObject)) { | 2558 if (legendAXObject && !visited.contains(legendAXObject)) { |
| 2559 textAlternative = | 2559 textAlternative = |
| 2560 recursiveTextAlternative(*legendAXObject, false, visited); | 2560 recursiveTextAlternative(*legendAXObject, false, visited); |
| 2561 | 2561 |
| 2562 if (relatedObjects) { | 2562 if (relatedObjects) { |
| 2563 localRelatedObjects.append( | 2563 localRelatedObjects.append( |
| 2564 new NameSourceRelatedObject(legendAXObject, textAlternative)); | 2564 new NameSourceRelatedObject(legendAXObject, textAlternative)); |
| 2565 *relatedObjects = localRelatedObjects; | 2565 *relatedObjects = localRelatedObjects; |
| 2566 localRelatedObjects.clear(); | 2566 localRelatedObjects.clear(); |
| 2567 } | 2567 } |
| 2568 | 2568 |
| 2569 if (nameSources) { | 2569 if (nameSources) { |
| 2570 NameSource& source = nameSources->last(); | 2570 NameSource& source = nameSources->back(); |
| 2571 source.relatedObjects = *relatedObjects; | 2571 source.relatedObjects = *relatedObjects; |
| 2572 source.text = textAlternative; | 2572 source.text = textAlternative; |
| 2573 *foundTextAlternative = true; | 2573 *foundTextAlternative = true; |
| 2574 } else { | 2574 } else { |
| 2575 return textAlternative; | 2575 return textAlternative; |
| 2576 } | 2576 } |
| 2577 } | 2577 } |
| 2578 } | 2578 } |
| 2579 } | 2579 } |
| 2580 | 2580 |
| 2581 // Document. | 2581 // Document. |
| 2582 if (isWebArea()) { | 2582 if (isWebArea()) { |
| 2583 Document* document = this->getDocument(); | 2583 Document* document = this->getDocument(); |
| 2584 if (document) { | 2584 if (document) { |
| 2585 nameFrom = AXNameFromAttribute; | 2585 nameFrom = AXNameFromAttribute; |
| 2586 if (nameSources) { | 2586 if (nameSources) { |
| 2587 nameSources->append(NameSource(foundTextAlternative, aria_labelAttr)); | 2587 nameSources->append(NameSource(foundTextAlternative, aria_labelAttr)); |
| 2588 nameSources->last().type = nameFrom; | 2588 nameSources->back().type = nameFrom; |
| 2589 } | 2589 } |
| 2590 if (Element* documentElement = document->documentElement()) { | 2590 if (Element* documentElement = document->documentElement()) { |
| 2591 const AtomicString& ariaLabel = | 2591 const AtomicString& ariaLabel = |
| 2592 documentElement->getAttribute(aria_labelAttr); | 2592 documentElement->getAttribute(aria_labelAttr); |
| 2593 if (!ariaLabel.isEmpty()) { | 2593 if (!ariaLabel.isEmpty()) { |
| 2594 textAlternative = ariaLabel; | 2594 textAlternative = ariaLabel; |
| 2595 | 2595 |
| 2596 if (nameSources) { | 2596 if (nameSources) { |
| 2597 NameSource& source = nameSources->last(); | 2597 NameSource& source = nameSources->back(); |
| 2598 source.text = textAlternative; | 2598 source.text = textAlternative; |
| 2599 source.attributeValue = ariaLabel; | 2599 source.attributeValue = ariaLabel; |
| 2600 *foundTextAlternative = true; | 2600 *foundTextAlternative = true; |
| 2601 } else { | 2601 } else { |
| 2602 return textAlternative; | 2602 return textAlternative; |
| 2603 } | 2603 } |
| 2604 } | 2604 } |
| 2605 } | 2605 } |
| 2606 | 2606 |
| 2607 nameFrom = AXNameFromRelatedElement; | 2607 nameFrom = AXNameFromRelatedElement; |
| 2608 if (nameSources) { | 2608 if (nameSources) { |
| 2609 nameSources->append(NameSource(*foundTextAlternative)); | 2609 nameSources->append(NameSource(*foundTextAlternative)); |
| 2610 nameSources->last().type = nameFrom; | 2610 nameSources->back().type = nameFrom; |
| 2611 nameSources->last().nativeSource = AXTextFromNativeHTMLTitleElement; | 2611 nameSources->back().nativeSource = AXTextFromNativeHTMLTitleElement; |
| 2612 } | 2612 } |
| 2613 | 2613 |
| 2614 textAlternative = document->title(); | 2614 textAlternative = document->title(); |
| 2615 | 2615 |
| 2616 Element* titleElement = document->titleElement(); | 2616 Element* titleElement = document->titleElement(); |
| 2617 AXObject* titleAXObject = axObjectCache().getOrCreate(titleElement); | 2617 AXObject* titleAXObject = axObjectCache().getOrCreate(titleElement); |
| 2618 if (titleAXObject) { | 2618 if (titleAXObject) { |
| 2619 if (relatedObjects) { | 2619 if (relatedObjects) { |
| 2620 localRelatedObjects.append( | 2620 localRelatedObjects.append( |
| 2621 new NameSourceRelatedObject(titleAXObject, textAlternative)); | 2621 new NameSourceRelatedObject(titleAXObject, textAlternative)); |
| 2622 *relatedObjects = localRelatedObjects; | 2622 *relatedObjects = localRelatedObjects; |
| 2623 localRelatedObjects.clear(); | 2623 localRelatedObjects.clear(); |
| 2624 } | 2624 } |
| 2625 | 2625 |
| 2626 if (nameSources) { | 2626 if (nameSources) { |
| 2627 NameSource& source = nameSources->last(); | 2627 NameSource& source = nameSources->back(); |
| 2628 source.relatedObjects = *relatedObjects; | 2628 source.relatedObjects = *relatedObjects; |
| 2629 source.text = textAlternative; | 2629 source.text = textAlternative; |
| 2630 *foundTextAlternative = true; | 2630 *foundTextAlternative = true; |
| 2631 } else { | 2631 } else { |
| 2632 return textAlternative; | 2632 return textAlternative; |
| 2633 } | 2633 } |
| 2634 } | 2634 } |
| 2635 } | 2635 } |
| 2636 } | 2636 } |
| 2637 | 2637 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2667 if (!getNode()) | 2667 if (!getNode()) |
| 2668 return String(); | 2668 return String(); |
| 2669 | 2669 |
| 2670 String description; | 2670 String description; |
| 2671 bool foundDescription = false; | 2671 bool foundDescription = false; |
| 2672 | 2672 |
| 2673 descriptionFrom = AXDescriptionFromRelatedElement; | 2673 descriptionFrom = AXDescriptionFromRelatedElement; |
| 2674 if (descriptionSources) { | 2674 if (descriptionSources) { |
| 2675 descriptionSources->append( | 2675 descriptionSources->append( |
| 2676 DescriptionSource(foundDescription, aria_describedbyAttr)); | 2676 DescriptionSource(foundDescription, aria_describedbyAttr)); |
| 2677 descriptionSources->last().type = descriptionFrom; | 2677 descriptionSources->back().type = descriptionFrom; |
| 2678 } | 2678 } |
| 2679 | 2679 |
| 2680 // aria-describedby overrides any other accessible description, from: | 2680 // aria-describedby overrides any other accessible description, from: |
| 2681 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 2681 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 2682 const AtomicString& ariaDescribedby = getAttribute(aria_describedbyAttr); | 2682 const AtomicString& ariaDescribedby = getAttribute(aria_describedbyAttr); |
| 2683 if (!ariaDescribedby.isNull()) { | 2683 if (!ariaDescribedby.isNull()) { |
| 2684 if (descriptionSources) | 2684 if (descriptionSources) |
| 2685 descriptionSources->last().attributeValue = ariaDescribedby; | 2685 descriptionSources->back().attributeValue = ariaDescribedby; |
| 2686 | 2686 |
| 2687 description = textFromAriaDescribedby(relatedObjects); | 2687 description = textFromAriaDescribedby(relatedObjects); |
| 2688 | 2688 |
| 2689 if (!description.isNull()) { | 2689 if (!description.isNull()) { |
| 2690 if (descriptionSources) { | 2690 if (descriptionSources) { |
| 2691 DescriptionSource& source = descriptionSources->last(); | 2691 DescriptionSource& source = descriptionSources->back(); |
| 2692 source.type = descriptionFrom; | 2692 source.type = descriptionFrom; |
| 2693 source.relatedObjects = *relatedObjects; | 2693 source.relatedObjects = *relatedObjects; |
| 2694 source.text = description; | 2694 source.text = description; |
| 2695 foundDescription = true; | 2695 foundDescription = true; |
| 2696 } else { | 2696 } else { |
| 2697 return description; | 2697 return description; |
| 2698 } | 2698 } |
| 2699 } else if (descriptionSources) { | 2699 } else if (descriptionSources) { |
| 2700 descriptionSources->last().invalid = true; | 2700 descriptionSources->back().invalid = true; |
| 2701 } | 2701 } |
| 2702 } | 2702 } |
| 2703 | 2703 |
| 2704 HTMLElement* htmlElement = nullptr; | 2704 HTMLElement* htmlElement = nullptr; |
| 2705 if (getNode()->isHTMLElement()) | 2705 if (getNode()->isHTMLElement()) |
| 2706 htmlElement = toHTMLElement(getNode()); | 2706 htmlElement = toHTMLElement(getNode()); |
| 2707 | 2707 |
| 2708 // placeholder, 5.1.2 from: | 2708 // placeholder, 5.1.2 from: |
| 2709 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 2709 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 2710 if (nameFrom != AXNameFromPlaceholder && htmlElement && | 2710 if (nameFrom != AXNameFromPlaceholder && htmlElement && |
| 2711 htmlElement->isTextControl()) { | 2711 htmlElement->isTextControl()) { |
| 2712 descriptionFrom = AXDescriptionFromPlaceholder; | 2712 descriptionFrom = AXDescriptionFromPlaceholder; |
| 2713 if (descriptionSources) { | 2713 if (descriptionSources) { |
| 2714 descriptionSources->append( | 2714 descriptionSources->append( |
| 2715 DescriptionSource(foundDescription, placeholderAttr)); | 2715 DescriptionSource(foundDescription, placeholderAttr)); |
| 2716 DescriptionSource& source = descriptionSources->last(); | 2716 DescriptionSource& source = descriptionSources->back(); |
| 2717 source.type = descriptionFrom; | 2717 source.type = descriptionFrom; |
| 2718 } | 2718 } |
| 2719 HTMLElement* element = toHTMLElement(getNode()); | 2719 HTMLElement* element = toHTMLElement(getNode()); |
| 2720 const AtomicString& placeholder = | 2720 const AtomicString& placeholder = |
| 2721 element->fastGetAttribute(placeholderAttr); | 2721 element->fastGetAttribute(placeholderAttr); |
| 2722 if (!placeholder.isEmpty()) { | 2722 if (!placeholder.isEmpty()) { |
| 2723 description = placeholder; | 2723 description = placeholder; |
| 2724 if (descriptionSources) { | 2724 if (descriptionSources) { |
| 2725 DescriptionSource& source = descriptionSources->last(); | 2725 DescriptionSource& source = descriptionSources->back(); |
| 2726 source.text = description; | 2726 source.text = description; |
| 2727 source.attributeValue = placeholder; | 2727 source.attributeValue = placeholder; |
| 2728 foundDescription = true; | 2728 foundDescription = true; |
| 2729 } else { | 2729 } else { |
| 2730 return description; | 2730 return description; |
| 2731 } | 2731 } |
| 2732 } | 2732 } |
| 2733 } | 2733 } |
| 2734 | 2734 |
| 2735 const HTMLInputElement* inputElement = nullptr; | 2735 const HTMLInputElement* inputElement = nullptr; |
| 2736 if (isHTMLInputElement(getNode())) | 2736 if (isHTMLInputElement(getNode())) |
| 2737 inputElement = toHTMLInputElement(getNode()); | 2737 inputElement = toHTMLInputElement(getNode()); |
| 2738 | 2738 |
| 2739 // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 2739 // value, 5.2.2 from: http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 2740 if (nameFrom != AXNameFromValue && inputElement && | 2740 if (nameFrom != AXNameFromValue && inputElement && |
| 2741 inputElement->isTextButton()) { | 2741 inputElement->isTextButton()) { |
| 2742 descriptionFrom = AXDescriptionFromAttribute; | 2742 descriptionFrom = AXDescriptionFromAttribute; |
| 2743 if (descriptionSources) { | 2743 if (descriptionSources) { |
| 2744 descriptionSources->append( | 2744 descriptionSources->append( |
| 2745 DescriptionSource(foundDescription, valueAttr)); | 2745 DescriptionSource(foundDescription, valueAttr)); |
| 2746 descriptionSources->last().type = descriptionFrom; | 2746 descriptionSources->back().type = descriptionFrom; |
| 2747 } | 2747 } |
| 2748 String value = inputElement->value(); | 2748 String value = inputElement->value(); |
| 2749 if (!value.isNull()) { | 2749 if (!value.isNull()) { |
| 2750 description = value; | 2750 description = value; |
| 2751 if (descriptionSources) { | 2751 if (descriptionSources) { |
| 2752 DescriptionSource& source = descriptionSources->last(); | 2752 DescriptionSource& source = descriptionSources->back(); |
| 2753 source.text = description; | 2753 source.text = description; |
| 2754 foundDescription = true; | 2754 foundDescription = true; |
| 2755 } else { | 2755 } else { |
| 2756 return description; | 2756 return description; |
| 2757 } | 2757 } |
| 2758 } | 2758 } |
| 2759 } | 2759 } |
| 2760 | 2760 |
| 2761 // table caption, 5.9.2 from: | 2761 // table caption, 5.9.2 from: |
| 2762 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 2762 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 2763 if (nameFrom != AXNameFromCaption && isHTMLTableElement(getNode())) { | 2763 if (nameFrom != AXNameFromCaption && isHTMLTableElement(getNode())) { |
| 2764 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); | 2764 HTMLTableElement* tableElement = toHTMLTableElement(getNode()); |
| 2765 | 2765 |
| 2766 descriptionFrom = AXDescriptionFromRelatedElement; | 2766 descriptionFrom = AXDescriptionFromRelatedElement; |
| 2767 if (descriptionSources) { | 2767 if (descriptionSources) { |
| 2768 descriptionSources->append(DescriptionSource(foundDescription)); | 2768 descriptionSources->append(DescriptionSource(foundDescription)); |
| 2769 descriptionSources->last().type = descriptionFrom; | 2769 descriptionSources->back().type = descriptionFrom; |
| 2770 descriptionSources->last().nativeSource = | 2770 descriptionSources->back().nativeSource = |
| 2771 AXTextFromNativeHTMLTableCaption; | 2771 AXTextFromNativeHTMLTableCaption; |
| 2772 } | 2772 } |
| 2773 HTMLTableCaptionElement* caption = tableElement->caption(); | 2773 HTMLTableCaptionElement* caption = tableElement->caption(); |
| 2774 if (caption) { | 2774 if (caption) { |
| 2775 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); | 2775 AXObject* captionAXObject = axObjectCache().getOrCreate(caption); |
| 2776 if (captionAXObject) { | 2776 if (captionAXObject) { |
| 2777 AXObjectSet visited; | 2777 AXObjectSet visited; |
| 2778 description = | 2778 description = |
| 2779 recursiveTextAlternative(*captionAXObject, false, visited); | 2779 recursiveTextAlternative(*captionAXObject, false, visited); |
| 2780 if (relatedObjects) | 2780 if (relatedObjects) |
| 2781 relatedObjects->append( | 2781 relatedObjects->append( |
| 2782 new NameSourceRelatedObject(captionAXObject, description)); | 2782 new NameSourceRelatedObject(captionAXObject, description)); |
| 2783 | 2783 |
| 2784 if (descriptionSources) { | 2784 if (descriptionSources) { |
| 2785 DescriptionSource& source = descriptionSources->last(); | 2785 DescriptionSource& source = descriptionSources->back(); |
| 2786 source.relatedObjects = *relatedObjects; | 2786 source.relatedObjects = *relatedObjects; |
| 2787 source.text = description; | 2787 source.text = description; |
| 2788 foundDescription = true; | 2788 foundDescription = true; |
| 2789 } else { | 2789 } else { |
| 2790 return description; | 2790 return description; |
| 2791 } | 2791 } |
| 2792 } | 2792 } |
| 2793 } | 2793 } |
| 2794 } | 2794 } |
| 2795 | 2795 |
| 2796 // summary, 5.6.2 from: | 2796 // summary, 5.6.2 from: |
| 2797 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 2797 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 2798 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(getNode())) { | 2798 if (nameFrom != AXNameFromContents && isHTMLSummaryElement(getNode())) { |
| 2799 descriptionFrom = AXDescriptionFromContents; | 2799 descriptionFrom = AXDescriptionFromContents; |
| 2800 if (descriptionSources) { | 2800 if (descriptionSources) { |
| 2801 descriptionSources->append(DescriptionSource(foundDescription)); | 2801 descriptionSources->append(DescriptionSource(foundDescription)); |
| 2802 descriptionSources->last().type = descriptionFrom; | 2802 descriptionSources->back().type = descriptionFrom; |
| 2803 } | 2803 } |
| 2804 | 2804 |
| 2805 AXObjectSet visited; | 2805 AXObjectSet visited; |
| 2806 description = textFromDescendants(visited, false); | 2806 description = textFromDescendants(visited, false); |
| 2807 | 2807 |
| 2808 if (!description.isEmpty()) { | 2808 if (!description.isEmpty()) { |
| 2809 if (descriptionSources) { | 2809 if (descriptionSources) { |
| 2810 foundDescription = true; | 2810 foundDescription = true; |
| 2811 descriptionSources->last().text = description; | 2811 descriptionSources->back().text = description; |
| 2812 } else { | 2812 } else { |
| 2813 return description; | 2813 return description; |
| 2814 } | 2814 } |
| 2815 } | 2815 } |
| 2816 } | 2816 } |
| 2817 | 2817 |
| 2818 // title attribute, from: | 2818 // title attribute, from: |
| 2819 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html | 2819 // http://rawgit.com/w3c/aria/master/html-aam/html-aam.html |
| 2820 if (nameFrom != AXNameFromTitle) { | 2820 if (nameFrom != AXNameFromTitle) { |
| 2821 descriptionFrom = AXDescriptionFromAttribute; | 2821 descriptionFrom = AXDescriptionFromAttribute; |
| 2822 if (descriptionSources) { | 2822 if (descriptionSources) { |
| 2823 descriptionSources->append( | 2823 descriptionSources->append( |
| 2824 DescriptionSource(foundDescription, titleAttr)); | 2824 DescriptionSource(foundDescription, titleAttr)); |
| 2825 descriptionSources->last().type = descriptionFrom; | 2825 descriptionSources->back().type = descriptionFrom; |
| 2826 } | 2826 } |
| 2827 const AtomicString& title = getAttribute(titleAttr); | 2827 const AtomicString& title = getAttribute(titleAttr); |
| 2828 if (!title.isEmpty()) { | 2828 if (!title.isEmpty()) { |
| 2829 description = title; | 2829 description = title; |
| 2830 if (descriptionSources) { | 2830 if (descriptionSources) { |
| 2831 foundDescription = true; | 2831 foundDescription = true; |
| 2832 descriptionSources->last().text = description; | 2832 descriptionSources->back().text = description; |
| 2833 } else { | 2833 } else { |
| 2834 return description; | 2834 return description; |
| 2835 } | 2835 } |
| 2836 } | 2836 } |
| 2837 } | 2837 } |
| 2838 | 2838 |
| 2839 // aria-help. | 2839 // aria-help. |
| 2840 // FIXME: this is not part of the official standard, but it's needed because | 2840 // FIXME: this is not part of the official standard, but it's needed because |
| 2841 // the built-in date/time controls use it. | 2841 // the built-in date/time controls use it. |
| 2842 descriptionFrom = AXDescriptionFromAttribute; | 2842 descriptionFrom = AXDescriptionFromAttribute; |
| 2843 if (descriptionSources) { | 2843 if (descriptionSources) { |
| 2844 descriptionSources->append( | 2844 descriptionSources->append( |
| 2845 DescriptionSource(foundDescription, aria_helpAttr)); | 2845 DescriptionSource(foundDescription, aria_helpAttr)); |
| 2846 descriptionSources->last().type = descriptionFrom; | 2846 descriptionSources->back().type = descriptionFrom; |
| 2847 } | 2847 } |
| 2848 const AtomicString& help = getAttribute(aria_helpAttr); | 2848 const AtomicString& help = getAttribute(aria_helpAttr); |
| 2849 if (!help.isEmpty()) { | 2849 if (!help.isEmpty()) { |
| 2850 description = help; | 2850 description = help; |
| 2851 if (descriptionSources) { | 2851 if (descriptionSources) { |
| 2852 foundDescription = true; | 2852 foundDescription = true; |
| 2853 descriptionSources->last().text = description; | 2853 descriptionSources->back().text = description; |
| 2854 } else { | 2854 } else { |
| 2855 return description; | 2855 return description; |
| 2856 } | 2856 } |
| 2857 } | 2857 } |
| 2858 | 2858 |
| 2859 descriptionFrom = AXDescriptionFromUninitialized; | 2859 descriptionFrom = AXDescriptionFromUninitialized; |
| 2860 | 2860 |
| 2861 if (foundDescription) { | 2861 if (foundDescription) { |
| 2862 for (size_t i = 0; i < descriptionSources->size(); ++i) { | 2862 for (size_t i = 0; i < descriptionSources->size(); ++i) { |
| 2863 if (!(*descriptionSources)[i].text.isNull() && | 2863 if (!(*descriptionSources)[i].text.isNull() && |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2895 } | 2895 } |
| 2896 return placeholder; | 2896 return placeholder; |
| 2897 } | 2897 } |
| 2898 | 2898 |
| 2899 DEFINE_TRACE(AXNodeObject) { | 2899 DEFINE_TRACE(AXNodeObject) { |
| 2900 visitor->trace(m_node); | 2900 visitor->trace(m_node); |
| 2901 AXObject::trace(visitor); | 2901 AXObject::trace(visitor); |
| 2902 } | 2902 } |
| 2903 | 2903 |
| 2904 } // namespace blink | 2904 } // namespace blink |
| OLD | NEW |