feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: upgrade Text and TextInput to 2716f53 - #227

Open
aleclarson wants to merge 143 commits into
masterfrom
text
Open

feat: upgrade Text and TextInput to 2716f53#227
aleclarson wants to merge 143 commits into
masterfrom
text

Conversation

@aleclarson

@aleclarsonaleclarson commented Feb 14, 2019

Copy link
Copy Markdown
Collaborator

🚧 Work in progress

Opening this PR now that its changes are compiled without error. I'll be testing it today, so I decided to share my progress in case anyone wants to help out.

2/27/2019: I've fixed all of the issues that will affect my current project. I don't have time to fix the remaining bugs, so it would be great if anyone could lend a hand! Simply direct any PRs toward the text branch of this repository. 👍 Once all of the known bugs are fixed, we can merge this! 🚀

Details

The ./React, ./ReactCommon and ./Libraries/Text directories have been updated to this commit: react/react-native@2716f53(from 01/09/2018 to 01/24/2018)

The goals are as follows:

  • Upgrade to the "new" rewrite of text-related native components
  • Fix all visual bugs in <TextInput>
  • Make the "tab" key focus the next editable <TextInput>
  • Make multiline <TextInput> scrollable when a maxHeight is used
  • Make <TextInput> placeholders more memory-efficient
  • Bunch of small fixes, probably

Known bugs

  • password prop not working
  • Styled Text inside multiline TextInput not working
  • Special fonts may have incorrect line height
  • focusRingType prop not working
  • selection prop not working
  • Tabbing to an offscreen TextInput does not scroll its enclosing scroll views
  • Scrollable TextInput jumps to top when a new line is added to the end via the "return" key
  • Caret is slightly thinner when the TextInput is empty

Related issues

Closes#216
Closes#148

Skipped commits

The following commits were skipped and may be cherry-picked in the future:

Cherry-picked commits

I also picked some commits ahead of react/react-native@2716f53 that fix some issues:

@ptmt

ptmt commented Feb 15, 2019

Copy link
Copy Markdown
Owner

Wow, this one is hard. Text inputs are particularly hard to keep up with RN for iOS due to differences between UIKit and AppKit.

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

Haha yep. It's been... a learning experience. 😆

The "mouseEnter" event in browsers does not bubble, while "mouseOver" does.
The "mouseLeave" event in browsers does not bubble, while "mouseOut" does.
By subclassing NSWindow and overriding the "sendEvent:" method, we can avoid using the NSGestureRecognizer class, which seems to cause issues with NSTextView event handling.
The RCTWindow class reimplements input event handling, which solves the following issues:
- Skip "touchStart" events that target a focused NSTextView
- Emit "mouseOut" event when the mouse leaves the RCTWindow
- Emit "touchCancel" when the mouse leaves the RCTWindow
- Support "mouseMove" events (which can be coalesced)
- Emit "mouseMove" event right after "mouseUp" events
- Blur the focused NSTextView when clicking outside it
- Support "contextMenu" events
- Add "altKey", "ctrlKey", "metaKey", and "shiftKey" properties to JS mouse events
- Use "convertPoint:toView:" to compute the relative mouse location
sherginand others added 19 commits February 27, 2019 15:29
Differential Revision: D6641403
fbshipit-source-id: f478810413aa49b44c060db898e7e8698bddb8e1
Reviewed By: emilsjolander
Differential Revision: D6682933
fbshipit-source-id: 0fd90fdaf5ca4f9b7a11cbd15d8c54c7d0ce8a03
Reviewed By: emilsjolander
Differential Revision: D6675111
fbshipit-source-id: 884659fabb05033b4d43d3aa6629e22481d39b7e
Summary:
Currently, we can dirty leaf nodes with `measure` function, we also can get `dirty` status for any node, but we cannot handle a moment when this change happen. This diff introduces a new call-back-manner handler for it.
We need this to plug Yoga inside and outside other layout systems without maintaining own dirty propagation infrastructure.
Consider using Yoga for flex-box layout in React Native where we can have deeply nested layout like `<View><Text><View><Text/></View></Text></View>` where all content of all <Text> nodes are laid out using native text/inline (not flex-box!) layout system. In this case, when some change dirties some deeply nested Yoga node, we have to propagate the dirty state down to outer one. Having this handler makes possible to wire up `on-dirty` handler on the root node and `setDirtied` for the leaf node.
Removing custom dirting mechanism from React Native should drastically simplify rendering layer and bring a huge performance win.
Reviewed By: emilsjolander
Differential Revision: D6597856
fbshipit-source-id: 6588cd712f9c1dede4af32f3d326f90103e48ff0
Reviewed By: emilsjolander
Differential Revision: D6682929
fbshipit-source-id: 3607aab1544b62b1126c5d75b2f6fb8f5ca2d45f
Reviewed By: emilsjolander
Differential Revision: D6682956
fbshipit-source-id: 31c60e0eae906e1434a6969f3cd786fcaf9097a5
Reviewed By: emilsjolander
Differential Revision: D6683190
fbshipit-source-id: c37e57d02cc4475eb8181a2bb003c555bdb0aaea
Reviewed By: emilsjolander
Differential Revision: D6683205
fbshipit-source-id: d30003d90d634c644d92c833e58165b073d4d13e
Reviewed By: emilsjolander
Differential Revision: D6683270
fbshipit-source-id: a26663006419e13cb783e9849183e3c665f59b3c
Reviewed By: emilsjolander
Differential Revision: D6683313
fbshipit-source-id: 5ee458c2f4698768724901df0e3f5d8805c7c8f5
Reviewed By: emilsjolander
Differential Revision: D6683387
fbshipit-source-id: 83f64101faa700933771c69b222056ec2a6b8d1e
Reviewed By: johnislarry
Differential Revision: D6701327
fbshipit-source-id: 17630f336e2b275c1de30ebfa32d1cbfbc1b9634
…re passed to nativeRequire
Differential Revision: D6695769
fbshipit-source-id: b578b9d52ed711fb5a3e51717ac555fa8a232d7a
Summary: Because setting `intrinsicContentSize` for `RCTSurfaceRootView` doesn't have much sense.
Reviewed By: mmmulani
Differential Revision: D6701107
fbshipit-source-id: 259cdd27339bba3e8c9f98b6ca34affeb87f298c
Summary: Now it actually works.
Reviewed By: mmmulani
Differential Revision: D6701105
fbshipit-source-id: 16f3f4e319f874f9a08867b784d13aad4fa22aeb
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6715229
fbshipit-source-id: 13ae84920c98e0d8e8f1b64aeadfa770b64ea3b4
Reviewed By: sahrens
Differential Revision: D6688488
fbshipit-source-id: da020b3510ac7163f63cb5cebc27ec4306b1136c
Summary: Trivial.
Reviewed By: sahrens
Differential Revision: D6690929
fbshipit-source-id: 82906cd4a0eec320f998661ed48b9352b9b72670
Reviewed By: sahrens
Differential Revision: D6690930
fbshipit-source-id: a6ce5f006b4e6d63feef0f9c0743fb19b0e546fa
The `selectedRange` is modified by the "mouseDown" event (after the call to "becomeFirstResponder").
To ensure that `selectTextOnFocus` is respected, we delay the "textFieldDidFocus" call until the next event loop.
The cursor still goes where the user clicked. This change affects programmatic focus and tabbing.
Between invalidating a bridge and suspending its JS thread, native modules may have their methods called.
Only warn when a native module has been invalidated, which happens right before its JS thread is suspended.
Avoid initializing a native module's instance if its bridge is invalidated.
This gives each RCTUITextField its own field editor.
This is required in order to fix paste detection and the blurOnSubmit prop.
The plan to preserve line numbers did not work out due to the amount of required changes,
so there's really no point in keeping this whitespace around.
When truthy, the example is not rendered.
This allows for less conflicts when merging examples from upstream.
Instead, replace the backedTextInputView based on the "password" prop.
@lhecker

Copy link
Copy Markdown

It's so nice seeing my old dusty project (NSLabel) being used like that... 🥰
Thanks again @aleclarson for the PRs you sent me! I already released it as version 1.1.0 on Cocoapods.
If you fix any other issues it'd be very kind of you if you could send me PRs for these as well. 🙂

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

@lhecker Of course! Thanks again for open-sourcing your work in 2015. 😉

@aleclarson

Copy link
Copy Markdown
CollaboratorAuthor

The remaining bugs are up to the community to fix; unless I ever need them fixed for my own project, that is! Until then, this PR will remain unmerged. 😝

@aleclarsonaleclarson added this to the 0.20.0 milestone Mar 3, 2019
@aleclarsonaleclarson mentioned this pull request Mar 14, 2019
@aleclarsonaleclarson mentioned this pull request Mar 25, 2019
@ptmt

ptmt commented Mar 25, 2019

Copy link
Copy Markdown
Owner

If only we have enough time to revive CI and tests. :(

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect Multiline TextInput Bounds/Scroll TextInput has not correct border

14 participants

@aleclarson@ptmt@lhecker@shergin@priteshrnandgaonkar@fromcelticpark@swolchok@bnham@reyalpsirc@hamaron@douglowder@fkgozali@magicien@zhongwuzw