OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache()) | 475 if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache()) |
476 cache->postNotification(node, AXObjectCache::AXValueChanged, false); | 476 cache->postNotification(node, AXObjectCache::AXValueChanged, false); |
477 } | 477 } |
478 | 478 |
479 updateMarkersForWordsAffectedByEditing(true); | 479 updateMarkersForWordsAffectedByEditing(true); |
480 | 480 |
481 if (client()) | 481 if (client()) |
482 client()->respondToChangedContents(); | 482 client()->respondToChangedContents(); |
483 } | 483 } |
484 | 484 |
485 bool Editor::hasBidiSelection() const | |
486 { | |
487 if (m_frame->selection()->isNone()) | |
488 return false; | |
489 | |
490 Node* startNode; | |
491 if (m_frame->selection()->isRange()) { | |
492 startNode = m_frame->selection()->selection().start().downstream().depre
catedNode(); | |
493 Node* endNode = m_frame->selection()->selection().end().upstream().depre
catedNode(); | |
494 if (enclosingBlock(startNode) != enclosingBlock(endNode)) | |
495 return false; | |
496 } else | |
497 startNode = m_frame->selection()->selection().visibleStart().deepEquival
ent().deprecatedNode(); | |
498 | |
499 RenderObject* renderer = startNode->renderer(); | |
500 while (renderer && !renderer->isRenderBlock()) | |
501 renderer = renderer->parent(); | |
502 | |
503 if (!renderer) | |
504 return false; | |
505 | |
506 RenderStyle* style = renderer->style(); | |
507 if (!style->isLeftToRightDirection()) | |
508 return true; | |
509 | |
510 return toRenderBlock(renderer)->containsNonZeroBidiLevel(); | |
511 } | |
512 | |
513 TriState Editor::selectionUnorderedListState() const | 485 TriState Editor::selectionUnorderedListState() const |
514 { | 486 { |
515 if (m_frame->selection()->isCaret()) { | 487 if (m_frame->selection()->isCaret()) { |
516 if (enclosingNodeWithTag(m_frame->selection()->selection().start(), ulTa
g)) | 488 if (enclosingNodeWithTag(m_frame->selection()->selection().start(), ulTa
g)) |
517 return TrueTriState; | 489 return TrueTriState; |
518 } else if (m_frame->selection()->isRange()) { | 490 } else if (m_frame->selection()->isRange()) { |
519 Node* startNode = enclosingNodeWithTag(m_frame->selection()->selection()
.start(), ulTag); | 491 Node* startNode = enclosingNodeWithTag(m_frame->selection()->selection()
.start(), ulTag); |
520 Node* endNode = enclosingNodeWithTag(m_frame->selection()->selection().e
nd(), ulTag); | 492 Node* endNode = enclosingNodeWithTag(m_frame->selection()->selection().e
nd(), ulTag); |
521 if (startNode && endNode && startNode == endNode) | 493 if (startNode && endNode && startNode == endNode) |
522 return TrueTriState; | 494 return TrueTriState; |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 if (client()) | 1069 if (client()) |
1098 client()->didBeginEditing(); | 1070 client()->didBeginEditing(); |
1099 } | 1071 } |
1100 | 1072 |
1101 void Editor::didEndEditing() | 1073 void Editor::didEndEditing() |
1102 { | 1074 { |
1103 if (client()) | 1075 if (client()) |
1104 client()->didEndEditing(); | 1076 client()->didEndEditing(); |
1105 } | 1077 } |
1106 | 1078 |
1107 void Editor::toggleBold() | |
1108 { | |
1109 command("ToggleBold").execute(); | |
1110 } | |
1111 | |
1112 void Editor::toggleUnderline() | |
1113 { | |
1114 command("ToggleUnderline").execute(); | |
1115 } | |
1116 | |
1117 void Editor::setBaseWritingDirection(WritingDirection direction) | 1079 void Editor::setBaseWritingDirection(WritingDirection direction) |
1118 { | 1080 { |
1119 Node* focusedNode = frame()->document()->focusedNode(); | 1081 Node* focusedNode = frame()->document()->focusedNode(); |
1120 if (focusedNode && isHTMLTextFormControlElement(focusedNode)) { | 1082 if (focusedNode && isHTMLTextFormControlElement(focusedNode)) { |
1121 if (direction == NaturalWritingDirection) | 1083 if (direction == NaturalWritingDirection) |
1122 return; | 1084 return; |
1123 toHTMLElement(focusedNode)->setAttribute(dirAttr, direction == LeftToRig
htWritingDirection ? "ltr" : "rtl"); | 1085 toHTMLElement(focusedNode)->setAttribute(dirAttr, direction == LeftToRig
htWritingDirection ? "ltr" : "rtl"); |
1124 focusedNode->dispatchInputEvent(); | 1086 focusedNode->dispatchInputEvent(); |
1125 frame()->document()->updateStyleIfNeeded(); | 1087 frame()->document()->updateStyleIfNeeded(); |
1126 return; | 1088 return; |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 void Editor::ignoreSpelling() | 1311 void Editor::ignoreSpelling() |
1350 { | 1312 { |
1351 if (!client()) | 1313 if (!client()) |
1352 return; | 1314 return; |
1353 | 1315 |
1354 RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange(); | 1316 RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange(); |
1355 if (selectedRange) | 1317 if (selectedRange) |
1356 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Spelling); | 1318 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Spelling); |
1357 } | 1319 } |
1358 | 1320 |
1359 void Editor::learnSpelling() | |
1360 { | |
1361 if (!client()) | |
1362 return; | |
1363 | |
1364 RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange(); | |
1365 if (selectedRange) | |
1366 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Spelling); | |
1367 } | |
1368 | |
1369 void Editor::advanceToNextMisspelling(bool startBeforeSelection) | 1321 void Editor::advanceToNextMisspelling(bool startBeforeSelection) |
1370 { | 1322 { |
1371 // The basic approach is to search in two phases - from the selection end to
the end of the doc, and | 1323 // The basic approach is to search in two phases - from the selection end to
the end of the doc, and |
1372 // then we wrap and search from the doc start to (approximately) where we st
arted. | 1324 // then we wrap and search from the doc start to (approximately) where we st
arted. |
1373 | 1325 |
1374 // Start at the end of the selection, search to edge of document. Starting
at the selection end makes | 1326 // Start at the end of the selection, search to edge of document. Starting
at the selection end makes |
1375 // repeated "check spelling" commands work. | 1327 // repeated "check spelling" commands work. |
1376 VisibleSelection selection(frame()->selection()->selection()); | 1328 VisibleSelection selection(frame()->selection()->selection()); |
1377 RefPtr<Range> spellingSearchRange(rangeOfContents(frame()->document())); | 1329 RefPtr<Range> spellingSearchRange(rangeOfContents(frame()->document())); |
1378 | 1330 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 return String(); | 1501 return String(); |
1550 | 1502 |
1551 int wordLength = word.length(); | 1503 int wordLength = word.length(); |
1552 int misspellingLocation = -1; | 1504 int misspellingLocation = -1; |
1553 int misspellingLength = 0; | 1505 int misspellingLength = 0; |
1554 textChecker()->checkSpellingOfString(word.characters(), wordLength, &misspel
lingLocation, &misspellingLength); | 1506 textChecker()->checkSpellingOfString(word.characters(), wordLength, &misspel
lingLocation, &misspellingLength); |
1555 | 1507 |
1556 return misspellingLength == wordLength ? word : String(); | 1508 return misspellingLength == wordLength ? word : String(); |
1557 } | 1509 } |
1558 | 1510 |
1559 String Editor::misspelledSelectionString() const | |
1560 { | |
1561 String selectedString = selectedText(); | |
1562 int length = selectedString.length(); | |
1563 if (!length || !client()) | |
1564 return String(); | |
1565 | |
1566 int misspellingLocation = -1; | |
1567 int misspellingLength = 0; | |
1568 textChecker()->checkSpellingOfString(selectedString.characters(), length, &m
isspellingLocation, &misspellingLength); | |
1569 | |
1570 // The selection only counts as misspelled if the selected text is exactly o
ne misspelled word | |
1571 if (misspellingLength != length) | |
1572 return String(); | |
1573 | |
1574 // Update the spelling panel to be displaying this error (whether or not the
spelling panel is on screen). | |
1575 // This is necessary to make a subsequent call to [NSSpellChecker ignoreWord
:inSpellDocumentWithTag:] work | |
1576 // correctly; that call behaves differently based on whether the spelling pa
nel is displaying a misspelling | |
1577 // or a grammar error. | |
1578 client()->updateSpellingUIWithMisspelledWord(selectedString); | |
1579 | |
1580 return selectedString; | |
1581 } | |
1582 | |
1583 bool Editor::isSelectionUngrammatical() | |
1584 { | |
1585 Vector<String> ignoredGuesses; | |
1586 RefPtr<Range> range = frame()->selection()->toNormalizedRange(); | |
1587 if (!range) | |
1588 return false; | |
1589 return TextCheckingHelper(client(), range).isUngrammatical(ignoredGuesses); | |
1590 } | |
1591 | |
1592 Vector<String> Editor::guessesForUngrammaticalSelection() | |
1593 { | |
1594 Vector<String> guesses; | |
1595 RefPtr<Range> range = frame()->selection()->toNormalizedRange(); | |
1596 if (!range) | |
1597 return guesses; | |
1598 // Ignore the result of isUngrammatical; we just want the guesses, whether o
r not there are any | |
1599 TextCheckingHelper(client(), range).isUngrammatical(guesses); | |
1600 return guesses; | |
1601 } | |
1602 | |
1603 Vector<String> Editor::guessesForMisspelledOrUngrammatical(bool& misspelled, boo
l& ungrammatical) | |
1604 { | |
1605 if (unifiedTextCheckerEnabled()) { | |
1606 FrameSelection* frameSelection = frame()->selection(); | |
1607 if (RefPtr<Range> range = frameSelection->toNormalizedRange()) | |
1608 return TextCheckingHelper(client(), range).guessesForMisspelledOrUng
rammaticalRange(isGrammarCheckingEnabled(), misspelled, ungrammatical); | |
1609 return Vector<String>(); | |
1610 } | |
1611 | |
1612 String misspelledWord = misspelledSelectionString(); | |
1613 misspelled = !misspelledWord.isEmpty(); | |
1614 | |
1615 if (misspelled) { | |
1616 ungrammatical = false; | |
1617 return Vector<String>(); | |
1618 } | |
1619 if (isGrammarCheckingEnabled() && isSelectionUngrammatical()) { | |
1620 ungrammatical = true; | |
1621 return guessesForUngrammaticalSelection(); | |
1622 } | |
1623 ungrammatical = false; | |
1624 return Vector<String>(); | |
1625 } | |
1626 | |
1627 void Editor::showSpellingGuessPanel() | 1511 void Editor::showSpellingGuessPanel() |
1628 { | 1512 { |
1629 if (!client()) { | 1513 if (!client()) { |
1630 LOG_ERROR("No NSSpellChecker"); | 1514 LOG_ERROR("No NSSpellChecker"); |
1631 return; | 1515 return; |
1632 } | 1516 } |
1633 | 1517 |
1634 if (client()->spellingUIIsShowing()) { | 1518 if (client()->spellingUIIsShowing()) { |
1635 client()->showSpellingUI(false); | 1519 client()->showSpellingUI(false); |
1636 return; | 1520 return; |
1637 } | 1521 } |
1638 | 1522 |
1639 advanceToNextMisspelling(true); | 1523 advanceToNextMisspelling(true); |
1640 client()->showSpellingUI(true); | 1524 client()->showSpellingUI(true); |
1641 } | 1525 } |
1642 | 1526 |
1643 bool Editor::spellingPanelIsShowing() | |
1644 { | |
1645 if (!client()) | |
1646 return false; | |
1647 return client()->spellingUIIsShowing(); | |
1648 } | |
1649 | |
1650 void Editor::clearMisspellingsAndBadGrammar(const VisibleSelection &movingSelect
ion) | 1527 void Editor::clearMisspellingsAndBadGrammar(const VisibleSelection &movingSelect
ion) |
1651 { | 1528 { |
1652 RefPtr<Range> selectedRange = movingSelection.toNormalizedRange(); | 1529 RefPtr<Range> selectedRange = movingSelection.toNormalizedRange(); |
1653 if (selectedRange) { | 1530 if (selectedRange) { |
1654 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Spelling); | 1531 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Spelling); |
1655 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Grammar); | 1532 frame()->document()->markers()->removeMarkers(selectedRange.get(), Docum
entMarker::Grammar); |
1656 } | 1533 } |
1657 } | 1534 } |
1658 | 1535 |
1659 void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelecti
on) | 1536 void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelecti
on) |
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2485 | 2362 |
2486 return checkingTypes; | 2363 return checkingTypes; |
2487 } | 2364 } |
2488 | 2365 |
2489 bool Editor::unifiedTextCheckerEnabled() const | 2366 bool Editor::unifiedTextCheckerEnabled() const |
2490 { | 2367 { |
2491 return WebCore::unifiedTextCheckerEnabled(m_frame); | 2368 return WebCore::unifiedTextCheckerEnabled(m_frame); |
2492 } | 2369 } |
2493 | 2370 |
2494 } // namespace WebCore | 2371 } // namespace WebCore |
OLD | NEW |