diff options
36 files changed, 800 insertions, 87 deletions
@@ -92,6 +92,7 @@ LOCAL_C_INCLUDES := \ external/icu4c/common \ external/icu4c/i18n \ external/libxml2/include \ + external/libxslt \ external/skia/emoji \ external/skia/include/core \ external/skia/include/effects \ @@ -294,7 +295,7 @@ include external/stlport/libstlport.mk endif # Build the list of static libraries -LOCAL_STATIC_LIBRARIES := libxml2 +LOCAL_STATIC_LIBRARIES := libxml2 libxslt ifeq ($(JAVASCRIPT_ENGINE),v8) LOCAL_STATIC_LIBRARIES += libv8 endif diff --git a/CleanSpec.mk b/CleanSpec.mk index cf1cd55..7b7b3c9 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -50,6 +50,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_int $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libwebcore_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libwebcore_intermediates) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h index 8e93ee8..089e8ff 100644 --- a/JavaScriptCore/wtf/MathExtras.h +++ b/JavaScriptCore/wtf/MathExtras.h @@ -186,8 +186,6 @@ inline float deg2turn(float d) { return d / 360.0f; } inline float rad2grad(float r) { return r * 200.0f / piFloat; } inline float grad2rad(float g) { return g * piFloat / 200.0f; } -// ANDROID -// TODO: Upstream to webkit.org #if !COMPILER(MSVC) && !COMPILER(RVCT) && !COMPILER(WINSCW) using std::isfinite; using std::isinf; diff --git a/LayoutTests/fast/events/touch/basic-touch-events-expected.txt b/LayoutTests/fast/events/touch/basic-touch-events-expected.txt new file mode 100644 index 0000000..7ae4527 --- /dev/null +++ b/LayoutTests/fast/events/touch/basic-touch-events-expected.txt @@ -0,0 +1,148 @@ +This tests basic touch event support. +single touch sequence +PASS lastEvent.type is "touchstart" +PASS lastEvent.touches.length is 1 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 1 +PASS lastEvent.shiftKey is false +PASS lastEvent.touches[0].target.id is "touchtarget" +PASS lastEvent.touches[0].pageX is 10 +PASS lastEvent.touches[0].pageY is 10 +PASS lastEvent.touches[0].clientX is 10 +PASS lastEvent.touches[0].clientY is 10 +PASS lastEvent.touches[0].identifier is 0 +PASS lastEvent.changedTouches[0].pageX is 10 +PASS lastEvent.changedTouches[0].pageY is 10 +PASS lastEvent.changedTouches[0].clientX is 10 +PASS lastEvent.changedTouches[0].clientY is 10 +PASS lastEvent.changedTouches[0].identifier is 0 +PASS lastEvent.targetTouches[0].pageX is 10 +PASS lastEvent.targetTouches[0].pageY is 10 +PASS lastEvent.targetTouches[0].clientX is 10 +PASS lastEvent.targetTouches[0].clientY is 10 +PASS lastEvent.targetTouches[0].identifier is 0 +PASS lastEvent.type is "touchmove" +PASS lastEvent.touches.length is 1 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 1 +PASS lastEvent.touches[0].pageX is 20 +PASS lastEvent.touches[0].pageY is 15 +PASS lastEvent.touches[0].clientX is 20 +PASS lastEvent.touches[0].clientY is 15 +PASS lastEvent.touches[0].identifier is 0 +PASS lastEvent.shiftKey is true +PASS lastEvent.altKey is true +PASS lastEvent.ctrlKey is false +PASS lastEvent.metaKey is false +PASS lastEvent.type is "touchend" +PASS lastEvent.touches.length is 0 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 0 +PASS lastEvent.changedTouches[0].pageX is 20 +PASS lastEvent.changedTouches[0].pageY is 15 +PASS lastEvent.changedTouches[0].clientX is 20 +PASS lastEvent.changedTouches[0].clientY is 15 +PASS lastEvent.changedTouches[0].identifier is 0 +PASS lastEvent.shiftKey is false +PASS lastEvent.altKey is false +multi touch sequence +Two touchpoints pressed +PASS lastEvent.type is "touchstart" +PASS lastEvent.touches.length is 2 +PASS lastEvent.changedTouches.length is 2 +PASS lastEvent.targetTouches.length is 2 +PASS lastEvent.touches[0].pageX is 10 +PASS lastEvent.touches[0].pageY is 10 +PASS lastEvent.touches[0].clientX is 10 +PASS lastEvent.touches[0].clientY is 10 +PASS lastEvent.touches[0].identifier is 0 +PASS lastEvent.touches[1].pageX is 20 +PASS lastEvent.touches[1].pageY is 30 +PASS lastEvent.touches[1].clientX is 20 +PASS lastEvent.touches[1].clientY is 30 +PASS lastEvent.touches[1].identifier is 1 +PASS lastEvent.changedTouches[0].pageX is 10 +PASS lastEvent.changedTouches[0].pageY is 10 +PASS lastEvent.changedTouches[0].clientX is 10 +PASS lastEvent.changedTouches[0].clientY is 10 +PASS lastEvent.changedTouches[0].identifier is 0 +PASS lastEvent.changedTouches[1].pageX is 20 +PASS lastEvent.changedTouches[1].pageY is 30 +PASS lastEvent.changedTouches[1].clientX is 20 +PASS lastEvent.changedTouches[1].clientY is 30 +PASS lastEvent.changedTouches[1].identifier is 1 +PASS lastEvent.targetTouches[0].pageX is 10 +PASS lastEvent.targetTouches[0].pageY is 10 +PASS lastEvent.targetTouches[0].clientX is 10 +PASS lastEvent.targetTouches[0].clientY is 10 +PASS lastEvent.targetTouches[0].identifier is 0 +PASS lastEvent.targetTouches[1].pageX is 20 +PASS lastEvent.targetTouches[1].pageY is 30 +PASS lastEvent.targetTouches[1].clientX is 20 +PASS lastEvent.targetTouches[1].clientY is 30 +PASS lastEvent.targetTouches[1].identifier is 1 +First touchpoint moved +PASS lastEvent.type is "touchmove" +PASS lastEvent.touches.length is 2 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 2 +PASS lastEvent.touches[0].pageX is 15 +PASS lastEvent.touches[0].pageY is 15 +PASS lastEvent.touches[0].clientX is 15 +PASS lastEvent.touches[0].clientY is 15 +PASS lastEvent.touches[0].identifier is 0 +PASS lastEvent.changedTouches[0].pageX is 15 +PASS lastEvent.changedTouches[0].pageY is 15 +PASS lastEvent.changedTouches[0].clientX is 15 +PASS lastEvent.changedTouches[0].clientY is 15 +PASS lastEvent.changedTouches[0].identifier is 0 +PASS lastEvent.touches[1].pageX is 20 +PASS lastEvent.touches[1].pageY is 30 +PASS lastEvent.touches[1].clientX is 20 +PASS lastEvent.touches[1].clientY is 30 +PASS lastEvent.touches[1].identifier is 1 +First touchpoint is released +PASS lastEvent.type is "touchend" +PASS lastEvent.touches.length is 1 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 1 +PASS lastEvent.touches[0].pageX is 20 +PASS lastEvent.touches[0].pageY is 30 +PASS lastEvent.touches[0].clientX is 20 +PASS lastEvent.touches[0].clientY is 30 +PASS lastEvent.touches[0].identifier is 1 +PASS lastEvent.changedTouches[0].pageX is 15 +PASS lastEvent.changedTouches[0].pageY is 15 +PASS lastEvent.changedTouches[0].clientX is 15 +PASS lastEvent.changedTouches[0].clientY is 15 +PASS lastEvent.changedTouches[0].identifier is 0 +PASS lastEvent.targetTouches[0].pageX is 20 +PASS lastEvent.targetTouches[0].pageY is 30 +PASS lastEvent.targetTouches[0].clientX is 20 +PASS lastEvent.targetTouches[0].clientY is 30 +PASS lastEvent.targetTouches[0].identifier is 1 +Last remaining touchpoint is released +PASS lastEvent.type is "touchend" +PASS lastEvent.touches.length is 0 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 0 +PASS lastEvent.changedTouches[0].pageX is 20 +PASS lastEvent.changedTouches[0].pageY is 30 +PASS lastEvent.changedTouches[0].clientX is 20 +PASS lastEvent.changedTouches[0].clientY is 30 +PASS lastEvent.changedTouches[0].identifier is 1 +verify touch targets +PASS lastEvent.type is "touchstart" +PASS lastEvent.touches.length is 1 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 1 +PASS lastEvent.targetTouches[0].target.tagName is "DIV" +PASS lastEvent.type is "touchmove" +PASS lastEvent.touches.length is 1 +PASS lastEvent.changedTouches.length is 1 +PASS lastEvent.targetTouches.length is 0 +PASS lastEvent.touches[0].target.tagName is "HTML" +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/basic-touch-events.html b/LayoutTests/fast/events/touch/basic-touch-events.html new file mode 100644 index 0000000..c50c6fc --- /dev/null +++ b/LayoutTests/fast/events/touch/basic-touch-events.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> +<head> +<link rel="stylesheet" href="../../js/resources/js-test-style.css"> +<script src="../../js/resources/js-test-pre.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> +<script src="script-tests/basic-touch-events.js"></script> +<script src="../../js/resources/js-test-post.js"></script> +</body> +</html> diff --git a/LayoutTests/fast/events/touch/create-touch-event-expected.txt b/LayoutTests/fast/events/touch/create-touch-event-expected.txt new file mode 100644 index 0000000..8dddc5c --- /dev/null +++ b/LayoutTests/fast/events/touch/create-touch-event-expected.txt @@ -0,0 +1,6 @@ +This tests whether the DOM can create TouchEvents. +PASS event is non-null. +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/create-touch-event.html b/LayoutTests/fast/events/touch/create-touch-event.html new file mode 100644 index 0000000..ace4459 --- /dev/null +++ b/LayoutTests/fast/events/touch/create-touch-event.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> +<head> +<link rel="stylesheet" href="../../js/resources/js-test-style.css"> +<script src="../../js/resources/js-test-pre.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> +<script src="script-tests/create-touch-event.js"></script> +<script src="../../js/resources/js-test-post.js"></script> +</body> +</html> diff --git a/LayoutTests/fast/events/touch/resources/touch-inside-iframe2.html b/LayoutTests/fast/events/touch/resources/touch-inside-iframe2.html new file mode 100644 index 0000000..34bc461 --- /dev/null +++ b/LayoutTests/fast/events/touch/resources/touch-inside-iframe2.html @@ -0,0 +1,8 @@ +<html> +<body onload="parent.runTest()"> +<div id='mydiv' style='width:100px;height:100px;position:absolute;top:0px; left:0px; background-color:blue;'></div> +<script type='text/javascript'> +document.getElementById('mydiv').addEventListener('touchstart', function() { parent.testComplete(event); }, false); +</script> +</body> +</html> diff --git a/LayoutTests/fast/events/touch/script-tests/TEMPLATE.html b/LayoutTests/fast/events/touch/script-tests/TEMPLATE.html new file mode 100644 index 0000000..1951c43 --- /dev/null +++ b/LayoutTests/fast/events/touch/script-tests/TEMPLATE.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> +<head> +<link rel="stylesheet" href="../../js/resources/js-test-style.css"> +<script src="../../js/resources/js-test-pre.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> +<script src="YOUR_JS_FILE_HERE"></script> +<script src="../../js/resources/js-test-post.js"></script> +</body> +</html> diff --git a/LayoutTests/fast/events/touch/script-tests/basic-touch-events.js b/LayoutTests/fast/events/touch/script-tests/basic-touch-events.js new file mode 100644 index 0000000..6766abc --- /dev/null +++ b/LayoutTests/fast/events/touch/script-tests/basic-touch-events.js @@ -0,0 +1,154 @@ +description = "This tests basic touch event support."; + +var div = document.createElement("div"); +div.id = "touchtarget"; +div.style.width = "100px"; +div.style.height = "100px"; +div.style.backgroundColor = "blue"; + +var lastEvent = null; + +function appendEventLog() { + if (window.eventSender) { + lastEvent = event; + } else { + debug(event.type); + } +} + +div.addEventListener("touchstart", appendEventLog, false); +div.addEventListener("touchmove", appendEventLog, false); +div.addEventListener("touchend", appendEventLog, false); +document.body.insertBefore(div, document.body.firstChild); + +function verifyTouchEvent(type, totalTouchCount, changedTouchCount, targetTouchCount) +{ + shouldBeEqualToString("lastEvent.type", type); + shouldBe("lastEvent.touches.length", totalTouchCount.toString()); + shouldBe("lastEvent.changedTouches.length", changedTouchCount.toString()); + shouldBe("lastEvent.targetTouches.length", targetTouchCount.toString()); +} + +function verifyTouchPoint(list, point, x, y, id) +{ + shouldBe("lastEvent." + list + "[" + point + "].pageX", x.toString()); + shouldBe("lastEvent." + list + "[" + point + "].pageY", y.toString()); + shouldBe("lastEvent." + list + "[" + point + "].clientX", x.toString()); + shouldBe("lastEvent." + list + "[" + point + "].clientY", y.toString()); + shouldBe("lastEvent." + list + "[" + point + "].identifier", id.toString()); +} + +function singleTouchSequence() +{ + debug("single touch sequence"); + + eventSender.addTouchPoint(10, 10); + eventSender.touchStart(); + + verifyTouchEvent("touchstart", 1, 1, 1); + shouldBe("lastEvent.shiftKey", "false"); + shouldBeEqualToString("lastEvent.touches[0].target.id", "touchtarget"); + verifyTouchPoint("touches", 0, 10, 10, 0); + verifyTouchPoint("changedTouches", 0, 10, 10, 0); + verifyTouchPoint("targetTouches", 0, 10, 10, 0); + + eventSender.updateTouchPoint(0, 20, 15); + eventSender.setTouchModifier("shift", true); + eventSender.setTouchModifier("alt", true); + eventSender.touchMove(); + + verifyTouchEvent("touchmove", 1, 1, 1); + verifyTouchPoint("touches", 0, 20, 15, 0); + shouldBe("lastEvent.shiftKey", "true"); + shouldBe("lastEvent.altKey", "true"); + shouldBe("lastEvent.ctrlKey", "false"); + shouldBe("lastEvent.metaKey", "false"); + + eventSender.setTouchModifier("shift", false); + eventSender.setTouchModifier("alt", false); + + eventSender.releaseTouchPoint(0); + eventSender.touchEnd(); + + verifyTouchEvent("touchend", 0, 1, 0); + verifyTouchPoint("changedTouches", 0, 20, 15, 0); + shouldBe("lastEvent.shiftKey", "false"); + shouldBe("lastEvent.altKey", "false"); +} + +function multiTouchSequence() +{ + debug("multi touch sequence"); + + debug("Two touchpoints pressed"); + eventSender.addTouchPoint(10, 10); + eventSender.addTouchPoint(20, 30); + eventSender.touchStart(); + verifyTouchEvent("touchstart", 2, 2, 2); + verifyTouchPoint("touches", 0, 10, 10, 0); + verifyTouchPoint("touches", 1, 20, 30, 1); + verifyTouchPoint("changedTouches", 0, 10, 10, 0); + verifyTouchPoint("changedTouches", 1, 20, 30, 1); + verifyTouchPoint("targetTouches", 0, 10, 10, 0); + verifyTouchPoint("targetTouches", 1, 20, 30, 1); + + debug("First touchpoint moved"); + eventSender.updateTouchPoint(0, 15, 15); + eventSender.touchMove(); + verifyTouchEvent("touchmove", 2, 1, 2); + verifyTouchPoint("touches", 0, 15, 15, 0); + verifyTouchPoint("changedTouches", 0, 15, 15, 0); + verifyTouchPoint("touches", 1, 20, 30, 1); + + debug("First touchpoint is released"); + eventSender.releaseTouchPoint(0); + eventSender.touchEnd(); + verifyTouchEvent("touchend", 1, 1, 1); + verifyTouchPoint("touches", 0, 20, 30, 1); + verifyTouchPoint("changedTouches", 0, 15, 15, 0); + verifyTouchPoint("targetTouches", 0, 20, 30, 1); + + debug("Last remaining touchpoint is released"); + eventSender.releaseTouchPoint(0); + eventSender.touchEnd(); + verifyTouchEvent("touchend", 0, 1, 0); + verifyTouchPoint("changedTouches", 0, 20, 30, 1); +} + +function touchTargets() +{ + debug("verify touch targets"); + + eventSender.addTouchPoint(10, 10); + eventSender.touchStart(); + + verifyTouchEvent("touchstart", 1, 1, 1); + shouldBeEqualToString("lastEvent.targetTouches[0].target.tagName", "DIV"); + + eventSender.updateTouchPoint(0, 1000, 1000); + eventSender.touchMove(); + + verifyTouchEvent("touchmove", 1, 1, 0); + shouldBeEqualToString("lastEvent.touches[0].target.tagName", "HTML"); +} + +if (window.eventSender) { + debug(description); + + lastEvent = null; + eventSender.clearTouchPoints(); + singleTouchSequence(); + + lastEvent = null; + eventSender.clearTouchPoints(); + multiTouchSequence(); + + lastEvent = null; + eventSender.clearTouchPoints(); + touchTargets(); + +} else { + debug("This test requires DumpRenderTree. Tap on the blue rect to log.") +} + +var successfullyParsed = true; diff --git a/LayoutTests/fast/events/touch/script-tests/create-touch-event.js b/LayoutTests/fast/events/touch/script-tests/create-touch-event.js new file mode 100644 index 0000000..78295d6 --- /dev/null +++ b/LayoutTests/fast/events/touch/script-tests/create-touch-event.js @@ -0,0 +1,17 @@ +description = "This tests whether the DOM can create TouchEvents."; + +debug(description); + +var event = null; + +try +{ + event = document.createEvent("TouchEvent"); + shouldBeNonNull("event"); +} +catch (e) +{ + testFailed("An exception was thrown: " + e.message); +} + +successfullyParsed = true; diff --git a/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js b/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js new file mode 100644 index 0000000..c83daa4 --- /dev/null +++ b/LayoutTests/fast/events/touch/script-tests/send-oncancel-event.js @@ -0,0 +1,32 @@ +description("Tests that the cancel touch event is sent correctly."); + +var touchX = 25; +var touchY = 25; + +var cancelEvent = null; + +function touchcancelHandler() { + shouldBeEqualToString("event.type", "touchcancel"); + cancelEvent = event.changedTouches[0]; + shouldBeNonNull("cancelEvent"); + shouldBe("cancelEvent.pageX", touchX.toString()); + shouldBe("cancelEvent.pageY", touchY.toString()); + if (window.layoutTestController) { + layoutTestController.notifyDone(); + isSuccessfullyParsed(); + } +} + +if (window.layoutTestController) + window.layoutTestController.waitUntilDone(); + +if (window.eventSender) { + document.addEventListener("touchcancel", touchcancelHandler, false); + eventSender.addTouchPoint(touchX, touchY); + eventSender.touchStart(); + eventSender.cancelTouchPoint(0); + eventSender.touchCancel(); +} else + debug("This test requires DumpRenderTree."); + +var successfullyParsed = true; diff --git a/LayoutTests/fast/events/touch/send-oncancel-event-expected.txt b/LayoutTests/fast/events/touch/send-oncancel-event-expected.txt new file mode 100644 index 0000000..75b4cb2 --- /dev/null +++ b/LayoutTests/fast/events/touch/send-oncancel-event-expected.txt @@ -0,0 +1,13 @@ +Tests that the cancel touch event is sent correctly. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS event.type is "touchcancel" +PASS cancelEvent is non-null. +PASS cancelEvent.pageX is 25 +PASS cancelEvent.pageY is 25 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/send-oncancel-event.html b/LayoutTests/fast/events/touch/send-oncancel-event.html new file mode 100644 index 0000000..5665c0c --- /dev/null +++ b/LayoutTests/fast/events/touch/send-oncancel-event.html @@ -0,0 +1,13 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html> +<head> +<link rel="stylesheet" href="../../js/resources/js-test-style.css"> +<script src="../../js/resources/js-test-pre.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> +<script src="script-tests/send-oncancel-event.js"></script> +<script src="../../js/resources/js-test-post.js"></script> +</body> +</html> diff --git a/LayoutTests/fast/events/touch/touch-coords-in-zoom-and-scroll-expected.txt b/LayoutTests/fast/events/touch/touch-coords-in-zoom-and-scroll-expected.txt new file mode 100644 index 0000000..83823f4 --- /dev/null +++ b/LayoutTests/fast/events/touch/touch-coords-in-zoom-and-scroll-expected.txt @@ -0,0 +1,27 @@ +Base +PASS event.touches[0].clientX is 100 +PASS event.touches[0].clientY is 100 +PASS event.touches[0].pageX is 100 +PASS event.touches[0].pageY is 100 + +Just zoomed +PASS event.touches[0].clientX is 83 +PASS event.touches[0].clientY is 83 +PASS event.touches[0].pageX is 83 +PASS event.touches[0].pageY is 83 + +Just scrolled +PASS event.touches[0].clientX is 100 +PASS event.touches[0].clientY is 100 +PASS event.touches[0].pageX is 150 +PASS event.touches[0].pageY is 150 + +Zoomed and scrolled +PASS event.touches[0].clientX is 84 +PASS event.touches[0].clientY is 84 +PASS event.touches[0].pageX is 133 +PASS event.touches[0].pageY is 133 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/touch-coords-in-zoom-and-scroll.html b/LayoutTests/fast/events/touch/touch-coords-in-zoom-and-scroll.html new file mode 100644 index 0000000..00cd162 --- /dev/null +++ b/LayoutTests/fast/events/touch/touch-coords-in-zoom-and-scroll.html @@ -0,0 +1,129 @@ +<link rel="stylesheet" href="../../js/resources/js-test-style.css"> +<script src="../../js/resources/js-test-pre.js"></script> +<style> + #pusher { + width: 1000px; + height: 1000px; + outline: 1px solid black; + } +</style> +<div id="console"></div> +<div id="testArea"> + <div id="pusher">This box is here to create scrollbars.</div> +</div> +<script src="../../js/resources/js-test-post-function.js"></script> +<script> + var event; + + function sendTouchStart(x, y) + { + if (window.eventSender) { + eventSender.clearTouchPoints(); + eventSender.addTouchPoint(x, y); + eventSender.touchStart(); + } + } + + function zoomPageIn() + { + if (window.eventSender) { + eventSender.zoomPageIn(); + } + } + + function zoomPageOut() + { + if (window.eventSender) { + eventSender.zoomPageOut(); + } + } + + function scrollPage(x, y) + { + window.scrollTo(x, y); + } + + if (window.layoutTestController) { + layoutTestController.dumpAsText(); + layoutTestController.waitUntilDone(); + } + + // Default. + function base(e) + { + event = e; + debug("Base"); + shouldBe("event.touches[0].clientX", "100"); + shouldBe("event.touches[0].clientY", "100"); + shouldBe("event.touches[0].pageX", "100"); + shouldBe("event.touches[0].pageY", "100"); + } + + window.addEventListener("touchstart", base, false); + + sendTouchStart(100, 100); + window.removeEventListener("touchstart", base, false); + + // Just zoomed. + function justZoomed(e) + { + event = e; + debug("\nJust zoomed"); + shouldBe("event.touches[0].clientX", "83"); + shouldBe("event.touches[0].clientY", "83"); + shouldBe("event.touches[0].pageX", "83"); + shouldBe("event.touches[0].pageY", "83"); + } + window.addEventListener("touchstart", justZoomed, false); + zoomPageIn(); + sendTouchStart(100, 100); + zoomPageOut(); + window.removeEventListener("touchstart", justZoomed, false); + + // Just scrolled. + function justScrolled(e) + { + event = e; + debug("\nJust scrolled"); + shouldBe("event.touches[0].clientX", "100"); + shouldBe("event.touches[0].clientY", "100"); + shouldBe("event.touches[0].pageX", "150"); + shouldBe("event.touches[0].pageY", "150"); + } + window.addEventListener("touchstart", justScrolled, false); + scrollPage(50, 50); + sendTouchStart(100, 100); + scrollPage(0, 0); + window.removeEventListener("touchstart", justScrolled, false); + + // Zoomed and scrolled. + function zoomedAndScrolled(e) + { + event = e; + debug("\nZoomed and scrolled"); + shouldBe("event.touches[0].clientX", "84"); + shouldBe("event.touches[0].clientY", "84"); + shouldBe("event.touches[0].pageX", "133"); + shouldBe("event.touches[0].pageY", "133"); + } + window.addEventListener("touchstart", zoomedAndScrolled, false); + zoomPageIn(); + scrollPage(50, 50); + sendTouchStart(100, 100); + zoomPageOut(); + scrollPage(0, 0); + window.removeEventListener("touchstart", zoomedAndScrolled, false); + + if (window.eventSender) { + eventSender.touchEnd(); + eventSender.clearTouchPoints(); + } + + if (window.layoutTestController) { + var area = document.getElementById('testArea'); + area.parentNode.removeChild(area); + successfullyParsed = true; + isSuccessfullyParsed(); + layoutTestController.notifyDone(); + } +</script> diff --git a/LayoutTests/fast/events/touch/touch-inside-iframe-expected.txt b/LayoutTests/fast/events/touch/touch-inside-iframe-expected.txt new file mode 100644 index 0000000..17b655e --- /dev/null +++ b/LayoutTests/fast/events/touch/touch-inside-iframe-expected.txt @@ -0,0 +1,12 @@ + +Test iframes receive touches correctly. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS touch.pageX is 50 +PASS touch.pageY is 50 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/touch-inside-iframe.html b/LayoutTests/fast/events/touch/touch-inside-iframe.html new file mode 100644 index 0000000..b9162c3 --- /dev/null +++ b/LayoutTests/fast/events/touch/touch-inside-iframe.html @@ -0,0 +1,42 @@ +<html> +<link rel="stylesheet" href="../../js/resources/js-test-style.css"> +<script src="../../js/resources/js-test-pre.js"></script> +<script src="../../js/resources/js-test-post-function.js"></script> +<body> +<iframe style="position:absolute; top:100px; left:100px;" src="./resources/touch-inside-iframe2.html"></iframe> +<p id="description"></p> +<div id="console"></div> +<script type="text/javascript"> +description('Test iframes receive touches correctly.'); + +var touch = null; + +function testComplete(event) +{ + touch = event.touches[0]; + shouldBe("touch.pageX", "50"); + shouldBe("touch.pageY", "50"); + isSuccessfullyParsed(); + layoutTestController.notifyDone(); +} + +function runTest() { + if (window.eventSender) { + // Touch the center of the div in the iframe. + // 100px is offset to iframe in main frame, + // 2px for the iframe border, 50px to get to centre of the div. + eventSender.addTouchPoint(152, 152); + eventSender.touchStart(); + } else { + debug('This test requires DRT.'); + } +} + +if (window.layoutTestController) { + layoutTestController.waitUntilDone(); +} + +var successfullyParsed = true; +</script> +</body> +</html> diff --git a/WebCore/Android.derived.jscbindings.mk b/WebCore/Android.derived.jscbindings.mk index 00f272a..b06a0f2 100644 --- a/WebCore/Android.derived.jscbindings.mk +++ b/WebCore/Android.derived.jscbindings.mk @@ -49,7 +49,7 @@ js_binding_scripts := $(addprefix $(LOCAL_PATH)/,\ bindings/scripts/generate-bindings.pl \ ) -FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 +FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 # CSS GEN := \ diff --git a/WebCore/Android.derived.v8bindings.mk b/WebCore/Android.derived.v8bindings.mk index d043842..18e8d68 100644 --- a/WebCore/Android.derived.v8bindings.mk +++ b/WebCore/Android.derived.v8bindings.mk @@ -31,7 +31,7 @@ js_binding_scripts := \ $(LOCAL_PATH)/bindings/scripts/generate-bindings.pl # Add ACCELERATED_COMPOSITING=1 and ENABLE_3D_RENDERING=1 for layers support -FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 V8_BINDING ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 +FEATURE_DEFINES := ENABLE_ORIENTATION_EVENTS=1 ENABLE_TOUCH_EVENTS=1 V8_BINDING ENABLE_DATABASE=1 ENABLE_OFFLINE_WEB_APPLICATIONS=1 ENABLE_DOM_STORAGE=1 ENABLE_VIDEO=1 ENABLE_GEOLOCATION=1 ENABLE_CONNECTION=1 ENABLE_APPLICATION_INSTALLED=1 ENABLE_XPATH=1 ENABLE_XSLT=1 # CSS GEN := \ @@ -542,6 +542,7 @@ GEN := \ $(intermediates)/bindings/V8XMLHttpRequestProgressEvent.h \ $(intermediates)/bindings/V8XMLHttpRequestUpload.h \ $(intermediates)/bindings/V8XMLSerializer.h \ + $(intermediates)/bindings/V8XSLTProcessor.h \ $(intermediates)/bindings/V8XPathException.h \ $(intermediates)/bindings/V8XPathExpression.h \ $(intermediates)/bindings/V8XPathEvaluator.h \ diff --git a/WebCore/Android.mk b/WebCore/Android.mk index 54c11f0..9af1bae 100644 --- a/WebCore/Android.mk +++ b/WebCore/Android.mk @@ -958,3 +958,14 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ xml/XPathValue.cpp \ xml/XPathVariableReference.cpp \ xml/NativeXPathNSResolver.cpp + +# For XSLT +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + xml/XSLTExtensions.cpp \ + xml/XSLTProcessorLibxslt.cpp \ + xml/XSLTProcessor.cpp \ + xml/XSLTUnicodeSort.cpp \ + xml/XSLStyleSheetLibxslt.cpp \ + xml/XSLImportRule.cpp \ + loader/CachedXSLStyleSheet.cpp \ + dom/TransformSourceLibxslt.cpp diff --git a/WebCore/Android.v8bindings.mk b/WebCore/Android.v8bindings.mk index 29ae3f9..603ca74 100644 --- a/WebCore/Android.v8bindings.mk +++ b/WebCore/Android.v8bindings.mk @@ -204,3 +204,7 @@ LOCAL_SRC_FILES += \ # For XPath. LOCAL_SRC_FILES += \ bindings/v8/custom/V8CustomXPathNSResolver.cpp + +# For XSLT. +LOCAL_SRC_FILES += \ + bindings/v8/custom/V8XSLTProcessorCustom.cpp diff --git a/WebCore/config.h b/WebCore/config.h index 00b5d05..863423b 100644 --- a/WebCore/config.h +++ b/WebCore/config.h @@ -111,7 +111,7 @@ #define ENABLE_XBL 0 #define ENABLE_XHTMLMP 0 #define ENABLE_XPATH 1 -#define ENABLE_XSLT 0 +#define ENABLE_XSLT 1 #undef ENABLE_ARCHIVE // Enabled by default in Platform.h #define ENABLE_ARCHIVE 0 #define ENABLE_OFFLINE_WEB_APPLICATIONS 1 diff --git a/WebCore/loader/SubresourceLoader.cpp b/WebCore/loader/SubresourceLoader.cpp index ebb943a..57293ee 100644 --- a/WebCore/loader/SubresourceLoader.cpp +++ b/WebCore/loader/SubresourceLoader.cpp @@ -78,14 +78,10 @@ PassRefPtr<SubresourceLoader> SubresourceLoader::create(Frame* frame, Subresourc FrameLoader::reportLocalLoadFailed(frame, request.url().string()); return 0; } - + if (SecurityOrigin::shouldHideReferrer(request.url(), fl->outgoingReferrer())) newRequest.clearHTTPReferrer(); -#ifdef ANDROID_FIX - else if (request.httpReferrer().isEmpty()) -#else else if (!request.httpReferrer()) -#endif newRequest.setHTTPReferrer(fl->outgoingReferrer()); FrameLoader::addHTTPOriginIfNeeded(newRequest, fl->outgoingOrigin()); diff --git a/WebCore/platform/android/RenderThemeAndroid.cpp b/WebCore/platform/android/RenderThemeAndroid.cpp index 4c5cff5..7085bf4 100644 --- a/WebCore/platform/android/RenderThemeAndroid.cpp +++ b/WebCore/platform/android/RenderThemeAndroid.cpp @@ -334,7 +334,10 @@ void RenderThemeAndroid::adjustListboxStyle(CSSStyleSelector*, RenderStyle* styl static void adjustMenuListStyleCommon(RenderStyle* style, Element* e) { - // Added to make room for our arrow. + // Added to make room for our arrow and make the touch target less cramped. + style->setPaddingLeft(Length(RenderSkinCombo::padding(), Fixed)); + style->setPaddingTop(Length(RenderSkinCombo::padding(), Fixed)); + style->setPaddingBottom(Length(RenderSkinCombo::padding(), Fixed)); style->setPaddingRight(Length(RenderSkinCombo::extraWidth(), Fixed)); } diff --git a/WebKit/android/RenderSkinAndroid.cpp b/WebKit/android/RenderSkinAndroid.cpp index d148262..31c327a 100644 --- a/WebKit/android/RenderSkinAndroid.cpp +++ b/WebKit/android/RenderSkinAndroid.cpp @@ -45,7 +45,7 @@ RenderSkinAndroid::RenderSkinAndroid() void RenderSkinAndroid::Init(android::AssetManager* am, String drawableDirectory) { RenderSkinButton::Init(am, drawableDirectory); - RenderSkinCombo::Init(am); + RenderSkinCombo::Init(am, drawableDirectory); RenderSkinRadio::Init(am, drawableDirectory); } diff --git a/WebKit/android/RenderSkinCombo.cpp b/WebKit/android/RenderSkinCombo.cpp index 6f88ee3..4378371 100644 --- a/WebKit/android/RenderSkinCombo.cpp +++ b/WebKit/android/RenderSkinCombo.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "RenderSkinCombo.h" +#include "CString.h" #include "Document.h" #include "Element.h" #include "Node.h" @@ -36,43 +37,85 @@ namespace WebCore { -static SkBitmap s_bitmap[2]; // Collection of assets for a combo box -static bool s_decoded; // True if all assets were decoded -static const int s_margin = 2; -static const SkIRect s_mar = { s_margin, s_margin, - RenderSkinCombo::extraWidth(), s_margin }; -static SkIRect s_subset; +// Indicates if the entire asset is being drawn, or if the border is being +// excluded and just the arrow drawn. +enum BorderStyle { + FullAsset, + NoBorder +}; +// There are 2.5 different concepts of a 'border' here, which results +// in rather a lot of magic constants. In each case, there are 2 +// numbers, one for medium res and one for high-res. All sizes are in pixels. -RenderSkinCombo::RenderSkinCombo() -{ -} +// Firstly, we have the extra padding that webkit needs to know about, +// which defines how much bigger this element is made by the +// asset. This is actually a bit broader than the actual border on the +// asset, to make things look less cramped. The border is the same +// width on all sides, except on the right when it's significantly +// wider to allow for the arrow. +const int RenderSkinCombo::arrowMargin[2] = {22, 34}; +const int RenderSkinCombo::padMargin[2] = {2, 5}; + +// Then we have the borders used for the 9-patch stretch. The +// rectangle at the centre of these borders is entirely below and to +// the left of the arrow in the asset. Hence the border widths are the +// same for the bottom and left, but are different for the top. The +// right hand border width happens to be the same as arrowMargin +// defined above. +static const int stretchMargin[2] = {3, 5}; // border width for the bottom and left of the 9-patch +static const int stretchTop[2] = {15, 23}; // border width for the top of the 9-patch + +// Finally, if the border is defined by the CSS, we only draw the +// arrow and not the border. We do this by drawing the relevant subset +// of the bitmap, which must now be precisely determined by what's in +// the asset with no extra padding to make things look properly +// spaced. The border to remove at the top, right and bottom of the +// image is the same as stretchMargin above, but we need to know the width +// of the arrow. +static const int arrowWidth[2] = {22, 31}; + +RenderSkinCombo::Resolution RenderSkinCombo::resolution = MedRes; + +const SkIRect RenderSkinCombo::margin[2][2] = {{{ stretchMargin[MedRes], stretchTop[MedRes], + RenderSkinCombo::arrowMargin[MedRes] + stretchMargin[MedRes], stretchMargin[MedRes] }, + {0, stretchTop[MedRes], 0, stretchMargin[MedRes]}}, + {{ stretchMargin[HighRes], stretchTop[HighRes], + RenderSkinCombo::arrowMargin[HighRes] + stretchMargin[HighRes], stretchMargin[HighRes] }, + {0, stretchTop[HighRes], 0, stretchMargin[HighRes]}}}; +static SkBitmap bitmaps[2][2]; // Collection of assets for a combo box +static bool isDecoded; // True if all assets were decoded -void RenderSkinCombo::Init(android::AssetManager* am) +void RenderSkinCombo::Init(android::AssetManager* am, String drawableDirectory) { - if (s_decoded) + if (isDecoded) return; - // Maybe short circuiting is fine, since I don't even draw if one state is not decoded properly - // but is that necessary in the final version? - s_decoded = RenderSkinAndroid::DecodeBitmap(am, "images/combobox-noHighlight.png", &s_bitmap[kNormal]); - s_decoded = RenderSkinAndroid::DecodeBitmap(am, "images/combobox-disabled.png", &s_bitmap[kDisabled]) && s_decoded; - - int width = s_bitmap[kNormal].width(); - int height = s_bitmap[kNormal].height(); - s_subset.set(width - RenderSkinCombo::extraWidth() + s_margin, 0, width, height); + + if (drawableDirectory[drawableDirectory.length() - 5] == 'h') + resolution = HighRes; + + isDecoded = RenderSkinAndroid::DecodeBitmap(am, (drawableDirectory + "combobox_nohighlight.png").utf8().data(), &bitmaps[kNormal][FullAsset]); + isDecoded &= RenderSkinAndroid::DecodeBitmap(am, (drawableDirectory + "combobox_disabled.png").utf8().data(), &bitmaps[kDisabled][FullAsset]); + + int width = bitmaps[kNormal][FullAsset].width(); + int height = bitmaps[kNormal][FullAsset].height(); + SkIRect subset; + subset.set(width - arrowWidth[resolution], 0, width, height); + bitmaps[kNormal][FullAsset].extractSubset(&bitmaps[kNormal][NoBorder], subset); + bitmaps[kDisabled][FullAsset].extractSubset(&bitmaps[kDisabled][NoBorder], subset); } bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int width, int height) { - if (!s_decoded) + if (!isDecoded) return true; State state = (element->isElementNode() && static_cast<Element*>(element)->isEnabledFormControl()) ? kNormal : kDisabled; - if (height < (s_margin<<1) + 1) { - height = (s_margin<<1) + 1; - } + height = std::max(height, (stretchMargin[resolution]<<1) + 1); + SkRect bounds; + BorderStyle drawBorder = FullAsset; bounds.set(SkIntToScalar(x+1), SkIntToScalar(y+1), SkIntToScalar(x + width-1), SkIntToScalar(y + height-1)); RenderStyle* style = element->renderStyle(); @@ -90,10 +133,9 @@ bool RenderSkinCombo::Draw(SkCanvas* canvas, Node* element, int x, int y, int wi bounds.fRight -= SkIntToScalar(style->borderRightWidth()); bounds.fTop += SkIntToScalar(style->borderTopWidth()); bounds.fBottom -= SkIntToScalar(style->borderBottomWidth()); - canvas->drawBitmapRect(s_bitmap[state], &s_subset, bounds); - } else { - SkNinePatch::DrawNine(canvas, bounds, s_bitmap[state], s_mar); + drawBorder = NoBorder; } + SkNinePatch::DrawNine(canvas, bounds, bitmaps[state][drawBorder], margin[resolution][drawBorder]); return false; } diff --git a/WebKit/android/RenderSkinCombo.h b/WebKit/android/RenderSkinCombo.h index 91c9367..38cd048 100644 --- a/WebKit/android/RenderSkinCombo.h +++ b/WebKit/android/RenderSkinCombo.h @@ -37,13 +37,10 @@ namespace WebCore { class RenderSkinCombo : public RenderSkinAndroid { public: - RenderSkinCombo(); - virtual ~RenderSkinCombo() {} - /** * Initialize the class before use. Uses the AssetManager to initialize any bitmaps the class may use. */ - static void Init(android::AssetManager*); + static void Init(android::AssetManager*, String drawableDirectory); /** * Draw the provided Node on the SkCanvas, using the dimensions provided by @@ -53,11 +50,18 @@ public: static bool Draw(SkCanvas* , Node* , int x, int y, int w, int h); // The image is wider than the RenderObject, so this accounts for that. - static int extraWidth() { return arrowMargin; } - + static int extraWidth() { return arrowMargin[resolution]; } + static int padding() { return padMargin[resolution]; } + + enum Resolution { + MedRes, + HighRes + }; private: - - static const int arrowMargin = 22; + static Resolution resolution; + const static int arrowMargin[2]; + const static int padMargin[2]; + const static SkIRect margin[2][2]; }; } // WebCore diff --git a/WebKit/android/jni/MockGeolocation.cpp b/WebKit/android/jni/MockGeolocation.cpp index df580c3..1c236c3 100755 --- a/WebKit/android/jni/MockGeolocation.cpp +++ b/WebKit/android/jni/MockGeolocation.cpp @@ -53,7 +53,7 @@ static void setPosition(JNIEnv* env, jobject, double latitude, double longitude, false, 0.0, // altitudeAccuracy, false, 0.0, // heading false, 0.0); // speed - RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTime()); + RefPtr<Geoposition> position = Geoposition::create(coordinates.release(), WTF::currentTimeMS()); GeolocationServiceMock::setPosition(position.release()); } diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp index 21a4115..ce5600b 100644 --- a/WebKit/android/nav/CachedFrame.cpp +++ b/WebKit/android/nav/CachedFrame.cpp @@ -928,28 +928,27 @@ int CachedFrame::maxWorkingVertical() const } const CachedNode* CachedFrame::nextTextField(const CachedNode* start, - const CachedFrame** framePtr) const + const CachedFrame** framePtr, bool* startFound) const { - CachedNode* test; - if (start) { - test = const_cast<CachedNode*>(start); - test++; - } else { - test = const_cast<CachedNode*>(mCachedNodes.begin()); - } - while (test != mCachedNodes.end()) { - CachedFrame* frame = const_cast<CachedFrame*>(hasFrame(test)); + const CachedNode* test = mCachedNodes.begin(); + while ((test = test->traverseNextNode())) { + const CachedFrame* frame = hasFrame(test); if (frame) { + if (!frame->validDocument()) + continue; const CachedNode* node - = frame->nextTextField(0, framePtr); + = frame->nextTextField(start, framePtr, startFound); if (node) return node; } else if (test->isTextInput()) { - if (framePtr) - *framePtr = this; - return test; + if (test == start) + *startFound = true; + else if (*startFound) { + if (framePtr) + *framePtr = this; + return test; + } } - test++; } return 0; } diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h index ed76583..9334707 100644 --- a/WebKit/android/nav/CachedFrame.h +++ b/WebKit/android/nav/CachedFrame.h @@ -120,16 +120,6 @@ public: #endif WebCore::IntRect localBounds(const CachedNode* , const WebCore::IntRect& ) const; - /** - * Find the next textfield/textarea - * @param start Must be a CachedNode in this CachedFrame's tree, or - * null, in which case we start from the beginning. - * @param framePtr If not null, and a textfield/textarea is found, its - * CachedFrame will be pointed to by this pointer. - * @return CachedNode* Next textfield (or area) - */ - const CachedNode* nextTextField(const CachedNode* start, - const CachedFrame** framePtr) const; const CachedFrame* parent() const { return mParent; } CachedFrame* parent() { return mParent; } SkPicture* picture(const CachedNode* ) const; @@ -152,6 +142,8 @@ public: } const CachedNode* validDocument() const; protected: + const CachedNode* nextTextField(const CachedNode* start, + const CachedFrame** framePtr, bool* found) const; struct BestData { int mDistance; int mSideDistance; diff --git a/WebKit/android/nav/CachedInput.cpp b/WebKit/android/nav/CachedInput.cpp index 924bbca..dcd9ccd 100644 --- a/WebKit/android/nav/CachedInput.cpp +++ b/WebKit/android/nav/CachedInput.cpp @@ -28,6 +28,11 @@ namespace android { +void CachedInput::init() { + bzero(this, sizeof(CachedInput)); + mName = WebCore::String(); +} + #if DUMP_NAV_CACHE #define DEBUG_PRINT_BOOL(field) \ diff --git a/WebKit/android/nav/CachedInput.h b/WebKit/android/nav/CachedInput.h index 42cadf1..a3d6b10 100644 --- a/WebKit/android/nav/CachedInput.h +++ b/WebKit/android/nav/CachedInput.h @@ -39,10 +39,7 @@ public: // constructor } void* formPointer() const { return mForm; } - void init() { - bzero(this, sizeof(CachedInput)); - mName = WebCore::String(); - } + void init(); WebCore::HTMLInputElement::InputType inputType() const { return mInputType; } bool isRtlText() const { return mIsRtlText; } bool isTextField() const { return mIsTextField; } diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp index 71c0993..2d37a2a 100644 --- a/WebKit/android/nav/CachedRoot.cpp +++ b/WebKit/android/nav/CachedRoot.cpp @@ -1083,7 +1083,7 @@ WebCore::String CachedRoot::imageURI(int x, int y) const bool CachedRoot::maskIfHidden(BestData* best) const { const CachedNode* bestNode = best->mNode; - if (bestNode->isUnclipped()) + if (bestNode->isUnclipped() || bestNode->isTransparent()) return false; const CachedFrame* frame = best->mFrame; SkPicture* picture = frame->picture(bestNode); @@ -1288,6 +1288,13 @@ const CachedNode* CachedRoot::moveCursor(Direction direction, const CachedFrame* return const_cast<CachedNode*>(bestData.mNode); } +const CachedNode* CachedRoot::nextTextField(const CachedNode* start, + const CachedFrame** framePtr) const +{ + bool startFound = false; + return CachedFrame::nextTextField(start, framePtr, &startFound); +} + SkPicture* CachedRoot::pictureAt(int x, int y) const { #if USE(ACCELERATED_COMPOSITING) diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h index 735f23b..6e9fff0 100644 --- a/WebKit/android/nav/CachedRoot.h +++ b/WebKit/android/nav/CachedRoot.h @@ -75,6 +75,14 @@ public: WebCore::String imageURI(int x, int y) const; bool maskIfHidden(BestData* ) const; const CachedNode* moveCursor(Direction , const CachedFrame** , WebCore::IntPoint* scroll); + /** + * Find the next textfield/textarea + * @param start The textfield/textarea to search from. + * @param framePtr If non-zero, returns CachedFrame* containing result. + * @return CachedNode* Next textfield/textarea or null (0) if none. + */ + const CachedNode* nextTextField(const CachedNode* start, + const CachedFrame** framePtr) const; SkPicture* pictureAt(int x, int y) const; void reset(); CachedHistory* rootHistory() const { return mHistory; } diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 0ac6bd6..bdcafbf 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -1223,10 +1223,15 @@ static const CachedNode* getFocusCandidate(JNIEnv *env, jobject obj, static bool focusCandidateHasNextTextfield(JNIEnv *env, jobject obj) { - const CachedFrame* frame; - const CachedNode* cursor = getFocusCandidate(env, obj, &frame); + WebView* view = GET_NATIVE_VIEW(env, obj); + CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); + if (!root) + return false; + const CachedNode* cursor = root->currentCursor(); + if (!cursor || !cursor->isTextInput()) + cursor = root->currentFocus(); if (!cursor || !cursor->isTextInput()) return false; - return frame->nextTextField(cursor, 0); + return root->nextTextField(cursor, 0); } static const CachedNode* getFocusNode(JNIEnv *env, jobject obj) @@ -1760,14 +1765,13 @@ static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer); if (!root) return false; - const CachedFrame* containingFrame; - const CachedNode* current = root->currentCursor(&containingFrame); - if (!current) - current = root->currentFocus(&containingFrame); - if (!current) + const CachedNode* current = root->currentCursor(); + if (!current || !current->isTextInput()) + current = root->currentFocus(); + if (!current || !current->isTextInput()) return false; const CachedFrame* frame; - const CachedNode* next = containingFrame->nextTextField(current, &frame); + const CachedNode* next = root->nextTextField(current, &frame); if (!next) return false; const WebCore::IntRect& bounds = next->bounds(frame); |