diff --git a/.eslintrc.js b/.eslintrc.js index 030e5b738..0c62d1a5d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -31,8 +31,15 @@ module.exports = { }, settings: { "import/resolver": { - "eslint-import-resolver-lerna": { - packages: path.resolve(__dirname, "packages") + [path.resolve( + __dirname, + "./packages/react-native-dom/scripts/eslint-module-resolver-haste" + )]: {}, + node: { + paths: [ + path.resolve(__dirname, "node_modules"), + path.resolve(__dirname, "./packages/react-native-dom/node_modules") + ] } } } diff --git a/packages/react-native-dom/.eslintrc.js b/packages/react-native-dom/.eslintrc.js index 60f260c0c..9d80ceba6 100644 --- a/packages/react-native-dom/.eslintrc.js +++ b/packages/react-native-dom/.eslintrc.js @@ -12,18 +12,5 @@ module.exports = { browser: true, worker: true }, - settings: { - "import/resolver": { - [path.resolve(__dirname, "./scripts/eslint-module-resolver-haste")]: {}, - "eslint-import-resolver-lerna": { - packages: path.resolve(__dirname, "../") - }, - node: { - paths: [ - path.resolve(__dirname, "node_modules"), - path.resolve(__dirname, "../../node_modules") - ] - } - } - } + settings: {} }; diff --git a/packages/react-native-dom/ReactDom/base/UIView.js b/packages/react-native-dom/ReactDom/base/UIView.js index c46e1f257..704e578af 100644 --- a/packages/react-native-dom/ReactDom/base/UIView.js +++ b/packages/react-native-dom/ReactDom/base/UIView.js @@ -166,7 +166,8 @@ class UIView extends HTMLElement implements RCTComponent { contain: "size layout style", boxSizing: "border-box", userSelect: "inherit", - overflow: "visible" + overflow: "visible", + touchAction: "manipulation" }) ); diff --git a/packages/react-native-dom/ReactDom/modules/RCTTouchHandler.js b/packages/react-native-dom/ReactDom/modules/RCTTouchHandler.js index 5927885c1..b66bc1834 100644 --- a/packages/react-native-dom/ReactDom/modules/RCTTouchHandler.js +++ b/packages/react-native-dom/ReactDom/modules/RCTTouchHandler.js @@ -10,6 +10,7 @@ import type RCTBridge from "RCTBridge"; import UIView, { UIChildContainerView } from "UIView"; import RCTEventDispatcher from "RCTEventDispatcher"; import RCTTouchEvent from "RCTTouchEvent"; +import isIOS from "isIOS"; import guid from "Guid"; type UITouch = { @@ -35,7 +36,7 @@ type ReactTouch = { let mouseTouchCounter = 1; const TOUCH_LISTENER_OPTIONS = detectIt.passiveEvents - ? { passive: true, capture: false } + ? { passive: false, capture: false } : false; function getFirstParentUIView(target: any) { @@ -71,6 +72,8 @@ class RCTTouchHandler { } static RCTNormalizeInteractionEvent(rawEvent: PointerEvent): ?Array { + rawEvent.stopPropagation(); + const target: UIView = getFirstParentUIView(rawEvent.target); if ("which" in rawEvent && rawEvent.which === 3) { @@ -92,6 +95,9 @@ class RCTTouchHandler { ]; } + stopPropagation = (e: TouchEvent) => e.stopPropagation(); + preventDefault = (e: TouchEvent) => e.preventDefault(); + attachToView(view: UIView) { this.view = view; view.addGestureRecognizer( @@ -99,11 +105,41 @@ class RCTTouchHandler { detectIt.deviceType, TOUCH_LISTENER_OPTIONS ); + + if (isIOS) { + view.addEventListener( + "touchmove", + this.stopPropagation, + TOUCH_LISTENER_OPTIONS + ); + + view.parentElement && + view.parentElement.addEventListener( + "touchmove", + this.preventDefault, + TOUCH_LISTENER_OPTIONS + ); + } } detachFromView(view: UIView) { this.view = undefined; view.removeGestureRecognizer(this, TOUCH_LISTENER_OPTIONS); + + if (isIOS) { + view.removeEventListener( + "touchmove", + this.stopPropagation, + TOUCH_LISTENER_OPTIONS + ); + + view.parentElement && + view.parentElement.removeEventListener( + "touchmove", + this.preventDefault, + TOUCH_LISTENER_OPTIONS + ); + } } recordNewTouches(touches: Array) { diff --git a/packages/react-native-dom/ReactDom/modules/RedBox/RCTRedBox.js b/packages/react-native-dom/ReactDom/modules/RedBox/RCTRedBox.js index b29248084..2d1384277 100644 --- a/packages/react-native-dom/ReactDom/modules/RedBox/RCTRedBox.js +++ b/packages/react-native-dom/ReactDom/modules/RedBox/RCTRedBox.js @@ -3,12 +3,13 @@ * @flow */ +import RedBox from "rndom-redbox"; + import RCTBridge, { RCTFunctionTypeNormal, RCT_EXPORT_METHOD, RCT_EXPORT_MODULE } from "RCTBridge"; -import RedBox from "rndom-redbox"; import type { StackEntry } from "RCTExceptionsManager"; function getFileName(path) { diff --git a/packages/react-native-dom/ReactDom/views/RCTScrollView.js b/packages/react-native-dom/ReactDom/views/RCTScrollView.js index 74e29857f..57a4bd995 100644 --- a/packages/react-native-dom/ReactDom/views/RCTScrollView.js +++ b/packages/react-native-dom/ReactDom/views/RCTScrollView.js @@ -349,6 +349,10 @@ class RCTScrollView extends RCTView { return updatedChildFrames; } + connectedCallback() { + this.correctScrollPosition(); + } + boundsDidChange(contentView: RCTView) { this.coalescingKey++; const childFrames = this.calculateChildFramesData(); @@ -482,6 +486,35 @@ class RCTScrollView extends RCTView { ...eventArgs ); this.bridge.eventDispatcher.sendEvent(momentumScrollEvent); + this.correctScrollPosition(); + } + + correctScrollPosition() { + const scrollNudge = 1; + + if (isIOS) { + if (!this._horizontal) { + const endTopPosition = this.scrollTop + this.contentSize.height; + if (this.scrollTop <= 0 && this.scrollTop >= -0.1) { + this.scrollTop = scrollNudge; + } else if ( + endTopPosition >= this.scrollHeight && + endTopPosition <= this.scrollHeight + 0.1 + ) { + this.scrollTop = this.scrollTop - scrollNudge; + } + } else { + const endLeftPosition = this.scrollLeft + this.contentSize.width; + if (this.scrollLeft <= 0 && this.scrollLeft >= -0.1) { + this.scrollLeft = scrollNudge; + } else if ( + endLeftPosition >= this.scrollWidth && + endLeftPosition <= this.scrollWidth + 0.1 + ) { + this.scrollLeft = this.scrollLeft - scrollNudge; + } + } + } } handleScrollTick(...eventArgs: ScrollEventArgs) { diff --git a/packages/react-native-dom/ReactDom/views/Switch/RCTSwitch.js b/packages/react-native-dom/ReactDom/views/Switch/RCTSwitch.js index 3a2841658..9c3aa32ba 100644 --- a/packages/react-native-dom/ReactDom/views/Switch/RCTSwitch.js +++ b/packages/react-native-dom/ReactDom/views/Switch/RCTSwitch.js @@ -3,12 +3,13 @@ * @flow */ +import Switch from "rndom-switch"; + import type { Frame } from "InternalLib"; import RCTView from "RCTView"; import type RCTBridge from "RCTBridge"; import CustomElement from "CustomElement"; import ColorArrayFromHexARGB from "ColorArrayFromHexARGB"; -import Switch from "rndom-switch"; @CustomElement("rct-switch") class RCTSwitch extends RCTView { diff --git a/yarn.lock b/yarn.lock index 46ad2a363..41b2075bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -591,10 +591,14 @@ acorn@^4.0.4: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" -acorn@^5.0.0, acorn@^5.0.3, acorn@^5.4.1, acorn@^5.5.0: +acorn@^5.0.0, acorn@^5.0.3, acorn@^5.4.1: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" +acorn@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -3020,8 +3024,8 @@ eslint-module-utils@^2.2.0: pkg-dir "^1.0.0" eslint-plugin-import@^2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.11.0.tgz#15aeea37a67499d848e8e981806d4627b5503816" + version "2.13.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.13.0.tgz#df24f241175e312d91662dc91ca84064caec14ed" dependencies: contains-path "^0.1.0" debug "^2.6.8" @@ -3035,8 +3039,8 @@ eslint-plugin-import@^2.11.0: resolve "^1.6.0" eslint-plugin-prettier@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.0.tgz#33e4e228bdb06142d03c560ce04ec23f6c767dd7" + version "2.6.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.1.tgz#de902b4a66b7bca24296429a59a1cc04020ccbbd" dependencies: fast-diff "^1.1.1" jest-docblock "^21.0.0" @@ -3798,7 +3802,11 @@ global@^4.3.0: min-document "^2.19.0" process "~0.5.1" -globals@^11.0.1, globals@^11.1.0: +globals@^11.0.1: + version "11.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" + +globals@^11.1.0: version "11.5.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.5.0.tgz#6bc840de6771173b191f13d3a9c94d441ee92642" @@ -4829,13 +4837,20 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.7.0, js-yaml@^3.9.0, js-yaml@^3.9.1: +js-yaml@^3.7.0, js-yaml@^3.9.0: version "3.11.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" dependencies: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.9.1: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"