| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007 Apple 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 int comparePositions(const PositionWithAffinity& a, const PositionWithAffinity&
b) | 248 int comparePositions(const PositionWithAffinity& a, const PositionWithAffinity&
b) |
| 249 { | 249 { |
| 250 return comparePositions(a.position(), b.position()); | 250 return comparePositions(a.position(), b.position()); |
| 251 } | 251 } |
| 252 | 252 |
| 253 int comparePositions(const VisiblePosition& a, const VisiblePosition& b) | 253 int comparePositions(const VisiblePosition& a, const VisiblePosition& b) |
| 254 { | 254 { |
| 255 return comparePositions(a.deepEquivalent(), b.deepEquivalent()); | 255 return comparePositions(a.deepEquivalent(), b.deepEquivalent()); |
| 256 } | 256 } |
| 257 | 257 |
| 258 enum EditableLevel { Editable, RichlyEditable }; |
| 259 static bool hasEditableStyle(const Node& node, EditableLevel editableLevel) |
| 260 { |
| 261 if (node.isPseudoElement()) |
| 262 return false; |
| 263 |
| 264 // Ideally we'd call DCHECK(!needsStyleRecalc()) here, but |
| 265 // ContainerNode::setFocus() calls setNeedsStyleRecalc(), so the assertion |
| 266 // would fire in the middle of Document::setFocusedNode(). |
| 267 |
| 268 for (const Node& ancestor : NodeTraversal::inclusiveAncestorsOf(node)) { |
| 269 if ((ancestor.isHTMLElement() || ancestor.isDocumentNode()) && ancestor.
layoutObject()) { |
| 270 switch (ancestor.layoutObject()->style()->userModify()) { |
| 271 case READ_ONLY: |
| 272 return false; |
| 273 case READ_WRITE: |
| 274 return true; |
| 275 case READ_WRITE_PLAINTEXT_ONLY: |
| 276 return editableLevel != RichlyEditable; |
| 277 } |
| 278 NOTREACHED(); |
| 279 return false; |
| 280 } |
| 281 } |
| 282 |
| 283 return false; |
| 284 } |
| 285 |
| 286 static bool isEditableToAccessibility(const Node& node, EditableLevel editableLe
vel) |
| 287 { |
| 288 if (blink::hasEditableStyle(node, editableLevel)) |
| 289 return true; |
| 290 |
| 291 // FIXME: Respect editableLevel for ARIA editable elements. |
| 292 if (editableLevel == RichlyEditable) |
| 293 return false; |
| 294 |
| 295 // FIXME(dmazzoni): support ScopedAXObjectCache (crbug/489851). |
| 296 if (AXObjectCache* cache = node.document().existingAXObjectCache()) |
| 297 return cache->rootAXEditableElement(&node); |
| 298 |
| 299 return false; |
| 300 } |
| 301 |
| 302 bool isContentEditable(const Node& node) |
| 303 { |
| 304 node.document().updateStyleAndLayoutTree(); |
| 305 return blink::hasEditableStyle(node, Editable); |
| 306 } |
| 307 |
| 308 bool isContentRichlyEditable(const Node& node) |
| 309 { |
| 310 node.document().updateStyleAndLayoutTree(); |
| 311 return blink::hasEditableStyle(node, RichlyEditable); |
| 312 } |
| 313 |
| 314 bool hasEditableStyle(const Node& node, EditableType editableType) |
| 315 { |
| 316 switch (editableType) { |
| 317 case ContentIsEditable: |
| 318 return blink::hasEditableStyle(node, Editable); |
| 319 case HasEditableAXRole: |
| 320 return isEditableToAccessibility(node, Editable); |
| 321 } |
| 322 NOTREACHED(); |
| 323 return false; |
| 324 } |
| 325 |
| 326 bool layoutObjectIsRichlyEditable(const Node& node, EditableType editableType) |
| 327 { |
| 328 switch (editableType) { |
| 329 case ContentIsEditable: |
| 330 return blink::hasEditableStyle(node, RichlyEditable); |
| 331 case HasEditableAXRole: |
| 332 return isEditableToAccessibility(node, RichlyEditable); |
| 333 } |
| 334 NOTREACHED(); |
| 335 return false; |
| 336 } |
| 337 |
| 338 bool isRootEditableElement(const Node& node) |
| 339 { |
| 340 return hasEditableStyle(node) && node.isElementNode() && (!node.parentNode()
|| !hasEditableStyle(*node.parentNode()) |
| 341 || !node.parentNode()->isElementNode() || &node == node.document().body(
)); |
| 342 } |
| 343 |
| 344 Element* rootEditableElement(const Node& node) |
| 345 { |
| 346 const Node* result = nullptr; |
| 347 for (const Node* n = &node; n && hasEditableStyle(*n); n = n->parentNode())
{ |
| 348 if (n->isElementNode()) |
| 349 result = n; |
| 350 if (node.document().body() == n) |
| 351 break; |
| 352 } |
| 353 return toElement(const_cast<Node*>(result)); |
| 354 } |
| 355 |
| 356 Element* rootEditableElement(const Node& node, EditableType editableType) |
| 357 { |
| 358 if (editableType == HasEditableAXRole) { |
| 359 if (AXObjectCache* cache = node.document().existingAXObjectCache()) |
| 360 return const_cast<Element*>(cache->rootAXEditableElement(&node)); |
| 361 } |
| 362 |
| 363 return rootEditableElement(node); |
| 364 } |
| 365 |
| 258 ContainerNode* highestEditableRoot(const Position& position, EditableType editab
leType) | 366 ContainerNode* highestEditableRoot(const Position& position, EditableType editab
leType) |
| 259 { | 367 { |
| 260 if (position.isNull()) | 368 if (position.isNull()) |
| 261 return 0; | 369 return 0; |
| 262 | 370 |
| 263 ContainerNode* highestRoot = rootEditableElementOf(position, editableType); | 371 ContainerNode* highestRoot = rootEditableElementOf(position, editableType); |
| 264 if (!highestRoot) | 372 if (!highestRoot) |
| 265 return 0; | 373 return 0; |
| 266 | 374 |
| 267 if (isHTMLBodyElement(*highestRoot)) | 375 if (isHTMLBodyElement(*highestRoot)) |
| (...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 { | 1924 { |
| 1817 if (!RuntimeEnabledFeatures::inputEventEnabled()) | 1925 if (!RuntimeEnabledFeatures::inputEventEnabled()) |
| 1818 return DispatchEventResult::NotCanceled; | 1926 return DispatchEventResult::NotCanceled; |
| 1819 if (!target) | 1927 if (!target) |
| 1820 return DispatchEventResult::NotCanceled; | 1928 return DispatchEventResult::NotCanceled; |
| 1821 InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data
, InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotCo
mposing, ranges); | 1929 InputEvent* beforeInputEvent = InputEvent::createBeforeInput(inputType, data
, InputEvent::EventCancelable::IsCancelable, InputEvent::EventIsComposing::NotCo
mposing, ranges); |
| 1822 return target->dispatchEvent(beforeInputEvent); | 1930 return target->dispatchEvent(beforeInputEvent); |
| 1823 } | 1931 } |
| 1824 | 1932 |
| 1825 } // namespace blink | 1933 } // namespace blink |
| OLD | NEW |