OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/editing/InputMethodController.h" | 5 #include "core/editing/InputMethodController.h" |
6 | 6 |
7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/dom/Element.h" | 8 #include "core/dom/Element.h" |
9 #include "core/dom/Range.h" | 9 #include "core/dom/Range.h" |
10 #include "core/editing/Editor.h" | 10 #include "core/editing/Editor.h" |
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1283 | 1283 |
1284 // Make sure that caret is still at the end of the inserted text. | 1284 // Make sure that caret is still at the end of the inserted text. |
1285 EXPECT_FALSE(controller().hasComposition()); | 1285 EXPECT_FALSE(controller().hasComposition()); |
1286 EXPECT_EQ(7, frame() | 1286 EXPECT_EQ(7, frame() |
1287 .selection() | 1287 .selection() |
1288 .computeVisibleSelectionInDOMTreeDeprecated() | 1288 .computeVisibleSelectionInDOMTreeDeprecated() |
1289 .start() | 1289 .start() |
1290 .computeOffsetInContainerNode()); | 1290 .computeOffsetInContainerNode()); |
1291 } | 1291 } |
1292 | 1292 |
1293 static String getMarkedText(DocumentMarkerController& documentMarkerController, | |
1294 Node* node, | |
1295 int markerIndex) { | |
1296 DocumentMarker* marker = documentMarkerController.markers()[markerIndex]; | |
1297 return node->textContent().substring( | |
1298 marker->startOffset(), marker->endOffset() - marker->startOffset()); | |
1299 } | |
1300 | |
1301 TEST_F(InputMethodControllerTest, WhitespaceFixupAroundMarker) { | |
1302 Element* div = insertHTMLElement( | |
1303 "<div id='sample' contenteditable>Initial text blah</div>", "sample"); | |
1304 | |
1305 // Add marker under "text" (use TextMatch since Composition markers don't | |
1306 // persist across editing operations) | |
1307 EphemeralRange markerRange = PlainTextRange(8, 12).createRange(*div); | |
1308 document().markers().addMarker(markerRange.startPosition(), | |
1309 markerRange.endPosition(), | |
1310 DocumentMarker::TextMatch); | |
1311 // Delete "Initial" | |
1312 Vector<CompositionUnderline> emptyUnderlines; | |
1313 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); | |
1314 controller().commitText(String(""), emptyUnderlines, 0); | |
1315 | |
1316 // Delete "blah" | |
1317 controller().setCompositionFromExistingText(emptyUnderlines, 5, 9); | |
rlanday
2017/02/24 20:23:45
I actually did end up changing the offsets here af
Changwan Ryu
2017/02/27 13:55:57
Hmm... I think something's wrong here.
The text be
rlanday
2017/02/27 18:29:09
This must be a pre-existing issue since this test
Xiaocheng
2017/02/27 19:31:23
I think the bug is in IMC::commitText, instead of
rlanday
2017/02/28 00:49:24
I think what's going on is that if you go through
| |
1318 controller().commitText(String(""), emptyUnderlines, 0); | |
1319 | |
1320 ASSERT_STREQ(div->innerHTML().utf8().data(), " text "); | |
Changwan Ryu
2017/02/27 13:55:58
Normally the order is: ASSERT_STREQ(expected, actu
| |
1321 | |
1322 // Check that the marker is still attached to "text" and doesn't include | |
1323 // either space around it | |
1324 EXPECT_EQ(1u, document().markers().markersFor(div->firstChild()).size()); | |
1325 ASSERT_STREQ( | |
1326 "text", | |
1327 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1328 } | |
1329 | |
1330 TEST_F(InputMethodControllerTest, WhitespaceFixupAroundMarker2) { | |
1331 Element* div = insertHTMLElement( | |
1332 "<div id='sample' contenteditable>Initial text blah</div>", "sample"); | |
1333 | |
1334 // Add marker under " text" (use TextMatch since Composition markers don't | |
1335 // persist across editing operations) | |
1336 EphemeralRange markerRange = PlainTextRange(7, 12).createRange(*div); | |
1337 document().markers().addMarker(markerRange.startPosition(), | |
1338 markerRange.endPosition(), | |
1339 DocumentMarker::TextMatch); | |
1340 // Delete "Initial" | |
1341 Vector<CompositionUnderline> emptyUnderlines; | |
1342 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); | |
1343 controller().commitText(String(""), emptyUnderlines, 0); | |
1344 | |
1345 // Delete "blah" | |
1346 controller().setCompositionFromExistingText(emptyUnderlines, 5, 9); | |
1347 controller().commitText(String(""), emptyUnderlines, 0); | |
1348 | |
1349 ASSERT_STREQ(div->innerHTML().utf8().data(), " text "); | |
1350 | |
1351 // before "text" but not the space after | |
1352 EXPECT_EQ(1u, document().markers().markers().size()); | |
1353 ASSERT_STREQ( | |
1354 " text", | |
1355 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1356 } | |
1357 | |
1358 TEST_F(InputMethodControllerTest, WhitespaceFixupAroundMarker3) { | |
1359 Element* div = insertHTMLElement( | |
1360 "<div id='sample' contenteditable>Initial text blah</div>", "sample"); | |
1361 | |
1362 // Add marker under "text " (use TextMatch since Composition markers don't | |
1363 // persist across editing operations) | |
1364 EphemeralRange markerRange = PlainTextRange(8, 13).createRange(*div); | |
1365 document().markers().addMarker(markerRange.startPosition(), | |
1366 markerRange.endPosition(), | |
1367 DocumentMarker::TextMatch); | |
1368 // Delete "Initial" | |
1369 Vector<CompositionUnderline> emptyUnderlines; | |
1370 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); | |
1371 controller().commitText(String(""), emptyUnderlines, 0); | |
1372 | |
1373 // Delete "blah" | |
1374 controller().setCompositionFromExistingText(emptyUnderlines, 5, 9); | |
1375 controller().commitText(String(""), emptyUnderlines, 0); | |
1376 | |
1377 ASSERT_STREQ(div->innerHTML().utf8().data(), " text "); | |
1378 | |
1379 // Check that the marker is still attached to "text " and includes the space | |
1380 // after "text" but not the space before | |
1381 EXPECT_EQ(1u, document().markers().markers().size()); | |
1382 ASSERT_STREQ( | |
1383 "text ", | |
1384 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1385 } | |
1386 | |
1387 TEST_F(InputMethodControllerTest, WhitespaceFixupAroundMarker4) { | |
1388 Element* div = insertHTMLElement( | |
1389 "<div id='sample' contenteditable>Initial text blah</div>", "sample"); | |
1390 | |
1391 // Add marker under " text " (use TextMatch since Composition markers don't | |
1392 // persist across editing operations) | |
1393 EphemeralRange markerRange = PlainTextRange(7, 13).createRange(*div); | |
1394 document().markers().addMarker(markerRange.startPosition(), | |
1395 markerRange.endPosition(), | |
1396 DocumentMarker::TextMatch); | |
1397 | |
1398 // Delete "Initial" | |
1399 Vector<CompositionUnderline> emptyUnderlines; | |
1400 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); | |
1401 controller().commitText(String(""), emptyUnderlines, 0); | |
1402 | |
1403 // Delete "blah" | |
1404 controller().setCompositionFromExistingText(emptyUnderlines, 5, 9); | |
1405 controller().commitText(String(""), emptyUnderlines, 0); | |
1406 | |
1407 ASSERT_STREQ(div->innerHTML().utf8().data(), " text "); | |
1408 | |
1409 // Check that the marker is still attached to " text " and includes both the | |
1410 // space before "text" and the space after | |
1411 EXPECT_EQ(1u, document().markers().markers().size()); | |
1412 ASSERT_STREQ( | |
1413 " text ", | |
1414 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1415 } | |
1416 | |
1417 TEST_F(InputMethodControllerTest, ReplaceStartOfMarker) { | |
1418 Element* div = insertHTMLElement( | |
1419 "<div id='sample' contenteditable>Initial text</div>", "sample"); | |
1420 | |
1421 // Add marker under "Initial text" | |
1422 EphemeralRange markerRange = PlainTextRange(0, 12).createRange(*div); | |
1423 document().markers().addMarker(markerRange.startPosition(), | |
1424 markerRange.endPosition(), | |
1425 DocumentMarker::TextMatch); | |
1426 | |
1427 // Replace "Initial" with "Original" | |
1428 Vector<CompositionUnderline> emptyUnderlines; | |
1429 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); | |
1430 controller().commitText(String("Original"), emptyUnderlines, 0); | |
1431 | |
1432 ASSERT_STREQ(div->innerHTML().utf8().data(), "Original text"); | |
1433 | |
1434 // Verify marker is under "Original text" | |
1435 EXPECT_EQ(1u, document().markers().markers().size()); | |
1436 ASSERT_STREQ( | |
1437 "Original text", | |
1438 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1439 } | |
1440 | |
1441 TEST_F(InputMethodControllerTest, ReplaceBeforeAndAfterStartOfMarker) { | |
1442 Element* div = insertHTMLElement( | |
1443 "<div id='sample' contenteditable>This is some initial text</div>", | |
1444 "sample"); | |
1445 | |
1446 // Add marker under "initial text" | |
1447 EphemeralRange markerRange = PlainTextRange(13, 25).createRange(*div); | |
1448 document().markers().addMarker(markerRange.startPosition(), | |
1449 markerRange.endPosition(), | |
1450 DocumentMarker::TextMatch); | |
1451 | |
1452 // Replace "some initial" with "boring" | |
1453 Vector<CompositionUnderline> emptyUnderlines; | |
1454 controller().setCompositionFromExistingText(emptyUnderlines, 8, 20); | |
1455 controller().commitText(String("boring"), emptyUnderlines, 0); | |
1456 | |
1457 ASSERT_STREQ(div->innerHTML().utf8().data(), "This is boring text"); | |
1458 | |
1459 // Verify marker is under " text" | |
1460 EXPECT_EQ(1u, document().markers().markers().size()); | |
1461 ASSERT_STREQ( | |
1462 " text", | |
1463 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1464 } | |
1465 | |
1466 TEST_F(InputMethodControllerTest, ReplaceEndOfMarker) { | |
1467 Element* div = insertHTMLElement( | |
1468 "<div id='sample' contenteditable>Initial text</div>", "sample"); | |
1469 | |
1470 // Add marker under "Initial text" | |
1471 EphemeralRange markerRange = PlainTextRange(0, 12).createRange(*div); | |
1472 document().markers().addMarker(markerRange.startPosition(), | |
1473 markerRange.endPosition(), | |
1474 DocumentMarker::TextMatch); | |
1475 | |
1476 // Replace "text" with "string" | |
1477 Vector<CompositionUnderline> emptyUnderlines; | |
1478 controller().setCompositionFromExistingText(emptyUnderlines, 8, 12); | |
1479 controller().commitText(String("string"), emptyUnderlines, 0); | |
1480 | |
1481 ASSERT_STREQ(div->innerHTML().utf8().data(), "Initial string"); | |
1482 | |
1483 // Verify marker is under "Initial string" | |
1484 EXPECT_EQ(1u, document().markers().markers().size()); | |
1485 ASSERT_STREQ( | |
1486 "Initial string", | |
1487 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1488 } | |
1489 | |
1490 TEST_F(InputMethodControllerTest, ReplaceBeforeAndAfterEndOfMarker) { | |
1491 Element* div = insertHTMLElement( | |
1492 "<div id='sample' contenteditable>This is some initial text</div>", | |
1493 "sample"); | |
1494 | |
1495 // Add marker under "some initial" | |
1496 EphemeralRange markerRange = PlainTextRange(8, 20).createRange(*div); | |
1497 document().markers().addMarker(markerRange.startPosition(), | |
1498 markerRange.endPosition(), | |
1499 DocumentMarker::TextMatch); | |
1500 | |
1501 // Replace "initial text" with "content" | |
1502 Vector<CompositionUnderline> emptyUnderlines; | |
1503 controller().setCompositionFromExistingText(emptyUnderlines, 13, 25); | |
1504 controller().commitText(String("content"), emptyUnderlines, 0); | |
1505 | |
1506 ASSERT_STREQ(div->innerHTML().utf8().data(), "This is some content"); | |
1507 | |
1508 // Verify marker is under "some " | |
1509 EXPECT_EQ(1u, document().markers().markers().size()); | |
1510 ASSERT_STREQ( | |
1511 "some ", | |
1512 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1513 } | |
1514 | |
1515 TEST_F(InputMethodControllerTest, ReplaceEntireMarker) { | |
1516 Element* div = insertHTMLElement( | |
1517 "<div id='sample' contenteditable>Initial text</div>", "sample"); | |
1518 | |
1519 // Add marker under "text" | |
1520 EphemeralRange markerRange = PlainTextRange(8, 12).createRange(*div); | |
1521 document().markers().addMarker(markerRange.startPosition(), | |
1522 markerRange.endPosition(), | |
1523 DocumentMarker::TextMatch); | |
1524 | |
1525 // Replace "text" with "string" | |
1526 Vector<CompositionUnderline> emptyUnderlines; | |
1527 controller().setCompositionFromExistingText(emptyUnderlines, 8, 12); | |
1528 controller().commitText(String("string"), emptyUnderlines, 0); | |
1529 | |
1530 ASSERT_STREQ(div->innerHTML().utf8().data(), "Initial string"); | |
1531 | |
1532 // Verify marker is under "string" | |
1533 EXPECT_EQ(1u, document().markers().markers().size()); | |
1534 ASSERT_STREQ( | |
1535 "string", | |
1536 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); | |
1537 } | |
1538 | |
1539 TEST_F(InputMethodControllerTest, ReplaceTextWithMarkerAtBeginning) { | |
1540 Element* div = insertHTMLElement( | |
1541 "<div id='sample' contenteditable>Initial text</div>", "sample"); | |
1542 | |
1543 // Add marker under "Initial" | |
1544 EphemeralRange markerRange = PlainTextRange(0, 7).createRange(*div); | |
1545 document().markers().addMarker(markerRange.startPosition(), | |
1546 markerRange.endPosition(), | |
1547 DocumentMarker::TextMatch); | |
1548 | |
1549 EXPECT_EQ(1u, document().markers().markers().size()); | |
1550 | |
1551 // Replace "Initial text" with "New string" | |
1552 Vector<CompositionUnderline> emptyUnderlines; | |
1553 controller().setCompositionFromExistingText(emptyUnderlines, 0, 12); | |
1554 controller().commitText(String("New string"), emptyUnderlines, 0); | |
1555 | |
1556 ASSERT_STREQ(div->innerHTML().utf8().data(), "New string"); | |
1557 | |
1558 // Verify marker was removed | |
1559 EXPECT_EQ(0u, document().markers().markers().size()); | |
1560 } | |
1561 | |
1562 TEST_F(InputMethodControllerTest, ReplaceTextWithMarkerAtEnd) { | |
1563 Element* div = insertHTMLElement( | |
1564 "<div id='sample' contenteditable>Initial text</div>", "sample"); | |
1565 | |
1566 // Add marker under "text" | |
1567 EphemeralRange markerRange = PlainTextRange(8, 12).createRange(*div); | |
1568 document().markers().addMarker(markerRange.startPosition(), | |
1569 markerRange.endPosition(), | |
1570 DocumentMarker::TextMatch); | |
1571 | |
1572 EXPECT_EQ(1u, document().markers().markers().size()); | |
1573 | |
1574 // Replace "Initial text" with "New string" | |
1575 Vector<CompositionUnderline> emptyUnderlines; | |
1576 controller().setCompositionFromExistingText(emptyUnderlines, 0, 12); | |
1577 controller().commitText(String("New string"), emptyUnderlines, 0); | |
1578 | |
1579 ASSERT_STREQ(div->innerHTML().utf8().data(), "New string"); | |
1580 | |
1581 // Verify marker was removed | |
1582 EXPECT_EQ(0u, document().markers().markers().size()); | |
1583 } | |
1584 | |
1293 } // namespace blink | 1585 } // namespace blink |
OLD | NEW |