wordpress-mobile / gutenberg-mobile Goto Github PK
View Code? Open in Web Editor NEWMobile version of Gutenberg - native iOS and Android
License: GNU General Public License v2.0
Mobile version of Gutenberg - native iOS and Android
License: GNU General Public License v2.0
Bring the iOS implementation to a similar point than the Android one.
Estimated: 5
If we modify the tests or the app to have at least one focused block when tests are run, the following error appears:
console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Uncaught [TypeError: Cannot read property '__getValue' of undefined]
at reportException (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
at invokeEventListeners (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
at HTMLUnknownElementImpl._dispatch (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1649:16)
at invokeGuardedCallback (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1506:29)
at renderRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6149:7)
at performWorkOnRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6797:24) TypeError: Cannot read property '__getValue' of undefined
at AnimatedComponent.render (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-native/Libraries/Animated/src/createAnimatedComponent.js:152:31)
at finishClassComponent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3656:31)
at updateClassComponent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3633:12)
at beginWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4008:16)
at performUnitOfWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6007:16)
at workLoop (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6071:26)
at HTMLUnknownElement.callCallback (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1610:14)
at invokeEventListeners (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
at HTMLUnknownElementImpl._dispatch (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1649:16)
at invokeGuardedCallback (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1506:29)
at renderRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6149:7)
at performWorkOnRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6797:24)
at performWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6750:7)
at requestWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6661:7)
at scheduleWorkImpl (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6515:11)
at scheduleWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6472:12)
at scheduleTopLevelUpdate (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6976:5)
at Object.updateContainer (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7014:7)
at Object.create (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7637:18)
at Object.<anonymous> (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/src/app/App.test.js:27:37)
at Object.asyncFn (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
at resolve (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
at new Promise (<anonymous>)
at mapper (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
at promise.then (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5530
The above error occurred in the <AnimatedComponent> component:
in AnimatedComponent (created by TouchableOpacity)
in TouchableOpacity (created by Toolbar)
in View (created by Component)
in Component (created by Toolbar)
in Toolbar (created by BlockHolder)
in View (created by Component)
in Component (created by BlockHolder)
in TouchableWithoutFeedback (created by BlockHolder)
in BlockHolder (created by RecyclerViewItem)
in RecyclerViewItemView (created by _class)
in _class (created by RecyclerViewItem)
in RecyclerViewItem (created by RecyclerView)
in AndroidRecyclerViewBackedScrollView (created by _class)
in _class (created by RecyclerView)
in RecyclerView (created by BlockManager)
in View (created by Component)
in Component (created by BlockManager)
in BlockManager (created by MainScreen)
in MainScreen (created by Connect(MainScreen))
in Connect(MainScreen) (created by AppProvider)
in Provider (created by AppProvider)
in AppProvider
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Uncaught [TypeError: Cannot read property '__getValue' of undefined]
at reportException (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
at invokeEventListeners (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:209:9)
at HTMLUnknownElementImpl._dispatch (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1649:16)
at invokeGuardedCallback (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1506:29)
at renderRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6149:7)
at performWorkOnRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6797:24) TypeError: Cannot read property '__getValue' of undefined
at AnimatedComponent.render (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-native/Libraries/Animated/src/createAnimatedComponent.js:152:31)
at finishClassComponent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3656:31)
at updateClassComponent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3633:12)
at beginWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4008:16)
at performUnitOfWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6007:16)
at workLoop (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6071:26)
at HTMLUnknownElement.callCallback (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1610:14)
at invokeEventListeners (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
at HTMLUnknownElementImpl._dispatch (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1649:16)
at invokeGuardedCallback (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1506:29)
at renderRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6149:7)
at performWorkOnRoot (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6797:24)
at performWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6750:7)
at requestWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6661:7)
at scheduleWorkImpl (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6515:11)
at scheduleWork (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6472:12)
at scheduleTopLevelUpdate (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6976:5)
at Object.updateContainer (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7014:7)
at Object.create (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7637:18)
at Object.<anonymous> (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/src/app/App.test.js:36:1)
at Object.asyncFn (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/jasmine_async.js:82:37)
at resolve (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/queue_runner.js:52:12)
at new Promise (<anonymous>)
at mapper (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/queue_runner.js:39:19)
at promise.then (/Users/stefanos/proj/a8c/rn/gutenberg-mobile/node_modules/jest-jasmine2/build/queue_runner.js:73:82)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:5530
The above error occurred in the <AnimatedComponent> component:
in AnimatedComponent (created by TouchableOpacity)
in TouchableOpacity (created by Toolbar)
in View (created by Component)
in Component (created by Toolbar)
in Toolbar (created by BlockHolder)
in View (created by Component)
in Component (created by BlockHolder)
in TouchableWithoutFeedback (created by BlockHolder)
in BlockHolder (created by RecyclerViewItem)
in RecyclerViewItemView (created by _class)
in _class (created by RecyclerViewItem)
in RecyclerViewItem (created by RecyclerView)
in AndroidRecyclerViewBackedScrollView (created by _class)
in _class (created by RecyclerView)
in RecyclerView (created by BlockManager)
in View (created by Component)
in Component (created by BlockManager)
in BlockManager (created by MainScreen)
in MainScreen (created by Connect(MainScreen))
in Connect(MainScreen) (created by AppProvider)
in Provider (created by AppProvider)
FAIL src/app/App.test.js (18.289s)
App
✓ renders without crashing (1010ms)
✕ renders without crashing with a block focused (3035ms)
✕ Code block is a TextInput (8ms)
● App › renders without crashing with a block focused
TypeError: Cannot read property '__getValue' of undefined
25 |
26 | // render an App using the specified Store
> 27 | const app = renderer.create( <AppProvider store={ store } /> );
28 | const rendered = app.toJSON();
29 |
30 | // App should be rendered OK
at AnimatedComponent.render (node_modules/react-native/Libraries/Animated/src/createAnimatedComponent.js:152:31)
at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3656:31)
at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3633:12)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4008:16)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6007:16)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6071:26)
at HTMLUnknownElement.callCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1610:14)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1649:16)
at invokeGuardedCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1506:29)
at renderRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6149:7)
at performWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6797:24)
at performWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6750:7)
at requestWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6661:7)
at scheduleWorkImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6515:11)
at scheduleWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6472:12)
at scheduleTopLevelUpdate (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6976:5)
at Object.updateContainer (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7014:7)
at Object.create (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7637:18)
at Object.<anonymous> (src/app/App.test.js:27:37)
● App › Code block is a TextInput
TypeError: Cannot read property '__getValue' of undefined
34 | it( 'Code block is a TextInput', () => {
35 | renderer
> 36 | .create( <App /> )
37 | .root.findAllByType( BlockHolder )
38 | .forEach( ( blockHolder ) => {
39 | if ( 'core/code' === blockHolder.props.name ) {
at AnimatedComponent.render (node_modules/react-native/Libraries/Animated/src/createAnimatedComponent.js:152:31)
at finishClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3656:31)
at updateClassComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:3633:12)
at beginWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:4008:16)
at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6007:16)
at workLoop (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6071:26)
at HTMLUnknownElement.callCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1610:14)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
at Object.invokeGuardedCallbackDev (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1649:16)
at invokeGuardedCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:1506:29)
at renderRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6149:7)
at performWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6797:24)
at performWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6750:7)
at requestWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6661:7)
at scheduleWorkImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6515:11)
at scheduleWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6472:12)
at scheduleTopLevelUpdate (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6976:5)
at Object.updateContainer (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7014:7)
at Object.create (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7637:18)
at Object.<anonymous> (src/app/App.test.js:36:1)
Selecting a word in the first line of a block may cause the native iOS contextual menu to cover our format bar, making it impossible to click on the format buttons.
Seems to affect iOS only, as in Android I could not get a similar menu to come up.
Options I can think of:
Ping @iamthomasbishop
Add the existing react-native-aztec component as a dependency to gutenberg-mobile and ensure it renders on the list.
Estimated: 5
Users should be able to undo their changes and redo them. We'll have two buttons in the toolbar for this.
Some requirements:
Users should be able to focus each block using the keyboard (or native accessibility features).
We should probably set the accessible
attribute to true
on the root BlockHolder
element.
More info here: https://facebook.github.io/react-native/docs/accessibility.html
This issue is meant to track progress on the Editable HTML view
feature:
I ran yarn run iOS
on a new machine and I got an unrelated error. It took me a while to scroll back and see the carthage: command not found
.
We should fail early if any of the required tools are missing
In Gutenberg-web, there's the "Page Break" block (named next-page
in code) to insert a <!--nextpage-->
page break in the post content.
Let's port that to the mobile GB app as well.
Subtasks:
It seems that there are problems with the way the tap event is intercepted by the main list / block bottom toolbar / RichText component, that does result in weird behavior when you try to move the cursor to another part of the text (into the same RichText item) or when you try to cut&paste content.
https://cloudup.com/cT2GShQAyY8
Above is a video that show how the Cut&Paste acts on the current version on a Nexus 5X.
Edit: I've just noticed that the video does't show the taps. 🤕 So it's hard to follow my interactions.
Once we bring Gutenberg in the apps with #163, we'll need to connect the UI pieces so that the editor:
Task list:
iOS
Native Module
for communication between RN and Native.Android
I'm getting the following error pretty often whenever I try to run the project. This error was also reported by @SergioEstevao in our dev discussions:
While it doesn't always come up, it comes up often enough that a solution to this problem is desirable.
EDIT: this is apparently an external issue that will be solved shortly.
Relevant to WordPress/gutenberg#8774 (comment) and WordPress/gutenberg#8774 (comment).
Even though a commit removed the passing down of those, we should revisit, probably when we start applying proper styling to the components.
When running yarn test
all tests pass but it's logging this error in App.test.js
:
console.warn node_modules/react-native-recyclerview-list/src/DataSource.js:8
RecyclerViewList/DataSource: missing keyExtractor, it's strongly recommended to specify a keyExtractor function in order to use all the features correctly.
console.error node_modules/fbjs/lib/warning.js:33
Warning: Each child in an array or iterator should have a unique "key" prop.
Check the render method of `RecyclerView`. See https://fb.me/react-warning-keys for more information.
in RecyclerViewItem (created by RecyclerView)
in RecyclerView (created by BlockManager)
in View (created by Component)
in Component (created by BlockManager)
in BlockManager (created by MainScreen)
in MainScreen (created by Connect(MainScreen))
in Connect(MainScreen)
in Provider
in Unknown
Flow is a static type checker that helps you write code with fewer bugs. Check out this introduction to using static types in JavaScript if you are new to this concept.
React Native works with Flow out of the box, as long as your Flow version matches the one used in the version of React Native.
I've been playing around with displaying unknown/unsupported blocks from an html source and I made it work. This is no more than a proof of concept and is quite badly coded, so I'm not sending a PR just yet. 😆
All my next statements are based on what I "think" and have learned so far, but of course they can be completely wrong, please help me with that!
Expected behavior
By inspecting the web version, the freeform
block is used for unknown types (setUnknownTypeHandlerName( freeform.name );
), being freeform
the classic editor.
This handle raw html or anything that is not a registered Gutenberg block.
Based on that, we could rethink the expected behavior in this way:
Aztec
based block (our version of "classic editor").To achieve this, we can follow this steps:
Freeform
block from web into mobile, as an Aztec based block (just like the paragraph
block).Freeform
block with setUnknownTypeHandlerName
.
Freeform
block will display content that "seems to be" a Gutenberg block, and show the "unknown" UI instead.In this way we don't need to register a new Unknown
block (at least not yet), and we follow closely how the web version is implemented.
For the first and second steps requite sending a PR to gutenberg
. Since the second step is really simple, I'd send both together.
The last step feels a bit "hacky", but it's quite a simple way to get the expected behavior without loosing the block data, and easily converting from html to blocks and vice versa.
Q: Why not to use the paragraph block instead of declaring a new Aztec based block?
A: Because it mess up the real paragraph
blocks, making the system think that they are unknown
.
Q: How did you declared the Freeform block?
A: It was a copy-paste from paragraph/edit.native.js
to freeform/edit.native.js
. I'm sure there's a better way 😆
This is how it looks when parsing raw html (it is represented as a freeform
block)
This is loading and unknown Gutenberg block, it shows a custom UI.
We’re currently using the serializer code but calling it block by block. I believe this is just because our initial mocks use “fake blocks” that the serializer doesn’t know how to handle, but this might still be problematic with the unsupported block. Let’s use the serialize function with the block list directly and see what needs to be done so it handles unsupported blocks gracefully.
Estimated: 8
Ensure that the RichText component has an interface that is platform agnostic. Ideally this includes the web implementation, but at least start with similar API for iOS and Android.
Estimated: 2
Add an insert button that shows a list of registered blocks, and adds the selected block after the currently focused block.
Requirements for alpha:
Integration with toolbar (2 weeks)
+
adder control placeholder (to be connected to the toolbar)Other (1 week)
When running yarn clean
I'm seeing this error:
/bin/sh: cross-env: command not found
error Command failed with exit code 127.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
It seems the cross-env
package is properly defined as a dev dependency..
[diego@MonsterMac ~/Developer/gutenberg-mobile] cat package.json | grep "cross-env"
"cross-env": "^5.1.4",
...properly resolved by yarn...
[diego@MonsterMac ~/Developer/gutenberg-mobile] cat yarn.lock | grep "cross-env"
cross-env@^5.1.4:
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2"
...and properly installed in node_modules
...
[diego@MonsterMac ~/Developer/gutenberg-mobile] cd node_modules/
[diego@MonsterMac ~/Developer/gutenberg-mobile/node_modules] ls -al | grep "cross-env"
drwxr-xr-x 8 diego staff 256 Jul 26 12:57 cross-env
It would seem like the issue is that whatever alias should be created to be able to execute cross-env
by just using its name is missing.
The web implementation falls back to freeform/classic when it encounters an unrecognized block. Make gutenberg use this new unsupported block that would show the unsupported message on mobile, but would still embed a freeform block on the web. Note: I don’t know if this makes sense for the web, or there are good reasons to keep freeform as the unrecognized block handler.
Estimated: 5
When the user taps into a text block, they should start editing right away with the cursor in the position they tapped, even if it's not the currently selected block.
Add support for the paragraph block.
Most of this is already done, but there are some remaining tasks:
The Jest tests setup is mistakenly picking up iOS platform files (.ios.js
modules) while running in "android" platform mode.
src/app/App.js
module as src/app/App.ios.js
console.log( 'This is an iOS specific module!' );
early on top of the moduleyarn test
. Notice that without any command line parameters like that, the tests are set up to run the Android codepaths (Setting RN platform to: default (android)
printed in the console).This is an iOS specific module!
being printed while it shouldn'tImplement a toolbar component to put the block formatting controls.
API:
UI:
What we're not doing as part of this issue (but good to keep in mind):
Slot/Fill pattern with Toolbar (1 week)
Context (Consumer, Provider) pattern with Toolbar (3 days)
Toolbar Style (2 days)
Keyboard with Toolbar (4 days)
Tests (3 days)
This is a follow up of many UX issues regarding the HTML editor.
As an alternative of using InputView
, we could try to use Aztec component on HTML edit mode. It might save us some troubles (or add more?)
Both platforms:
Android:
iOS
The image placeholder (or editing an image) should let the user pick an existing image from the media library. We're not dealing with uploads in this issue, those will be in #206
Implement a heading block with its toolbar for heading level selection
Estimated: 5
Create a new “unsupported” block. If it’s easy, let’s try to get close to Thomas’ design for it, otherwise a simple “unsupported” label could do the trick.
Estimated: 2
Instead of initializing the gutenberg-mobile store with a block list, parse and load a HTML file. There are some challenges around extracting and validating attributes as the parser relies on the DOM, which is unavailable in React Native.
Estimated: 8
We currently have some packages that we use directly from the Gutenberg submodule source, by taking advantage of Metro's smart ability to find and resolve those packages locally without them being in node_modules
.
To do that we:
react-native
entrypoint, ideally pointing to an extensionless module filenamepackage.json
It would be nice if we had a nicer way to mange this and document which packages we use directly from source.
When a user presses return the block should split in two at the cursor. Similarly, backspace at the beginning of a block should merge it with the previous block (or forward delete at the end of a block)
There are some extra rules for this so double check what Gutenberg does and follow the same patterns. I don't think we have to worry about many of those yet since we only support a few block types, but one that I've identified so far is:
When you press return, the newly created block will be a paragraph, unless it's a multiline block (I think we only have code
in the alpha).
Merge the content (or return false to let Aztec native to handle the backspace)
Merge 2 blocks of different types
Resize after block splitting
Fix problem with content lost on merging
Fix delayed updated from native side (not completely related to this feature, but we need it)
Focus is moved to the wrong block after merging/splitting (We may need to wait until focus problems are resolved)
On blocks merging, should we add a white space character before the content of the 2nd block? (if necessary). Otherwise there is a situation where the last word of the first block, and the first word of the 2nd block, are merged together firing up the spell checker inline suggestions.
Test on RTL languages #380
Block Splitting: If before
content is omitted, treat as intent to delete block and call onReplace( [] );
Check Code
block in regard to enter and backspace
Using backspace while the first word is highlighted should not merge the 2 blocks, only remove the currently selected word. It's working as expected on Android, but iOS does merge the 2 blocks. #325
Add Enter.key handling/detection to PlainText and PlainText powered blocks #324
I noticed that our focus action seems to be off, at least for paragraphs and headings.
It is my understanding that tapping again on a paragraph or heading should not unfocus it.
Here's an example of what I'm seeing (keep an eye on the bottom toolbar, which I believe is what we call the inserter?).
I think we can safely switch this line to always set to true
. I tried that and it works fine (unless there's a scenario I'm missing).
We want to be able to use gutenberg-mobile in the mobile apps (Android and iOS). More specifically we should be able to:
As per #60, when the user enters text into an the RN-wrapped version of AztecText RCTAztecView
currently, each change is saved to the application's state
with each keystroke, and such an event was being reflected back into Aztec as per the binding of text={ this.props.attributes.content }
in RCTAztecView
. This was made apparent in #60 and the performance problems were fixed on Android only by #62, by filtering which events to consider and which not, and provided a variable that counts events is shared and sent back and forth to/from Java/Javascript code.
An approach we could take in order to avoid this, but foremost, avoid changing the app's state on each keystroke is to use the ReactAztecFocusEvent
and ReactAztecEndEditingEvent
events (or, if needed, base it on a different event altogether - just naming the events we already have up to date) to control when to update the state only, instead of making each TextChange event reflect on the RN kept state in this case. This at first is counterintuitive in terms of the React logic, but it rings as something plausible given the performance issues we'll be facing, and is a "pure JS" solution (as opposed to involving platform-specific code like Java and more Js/Java interaction controlling code, and the needed handling code on the iOS counterpart).
I've made tests here just changing onChange
for onEndEditing
in line 84 in this experimental branch and it seems to work pretty well (no more lagging / weird refreshing issues). This, without the code in #62 and wordpress-mobile/react-native-aztec#24
The potential problems that arise from this other approach are around the ability to keep up to date with the changes (that is, do not lose or alter content) in any other case, thinking some here:
Copying here so we're aware only, but not to call immediate attention cc @SergioEstevao @diegoreymendez @daniloercoli @hypest
I noticed that the cut and paste menu does't work fine on iOS when there is a bit of text in the input field.
Actually there are different type of errors with the context menu, the animated GIF at the bottom can show details - some of the errors are briefly listed here:
cut
doesn't always work as expect. Often the menu remains on the screen and no action is taken.Paste
nothing happens.Btw, didn't test in ReacNativeAztec to check if it's a problem of the react native component, or its integration here.
When running yarn run test
on master
all tests pass, however this output can be seen for the core/paragraph
validation:
Pasting the text here for ease of handling:
Test Suites: 4 passed, 4 of 6 total
Tests: 17 passed, 17 total
Snapshots: 0 total
Time: 11s console.error gutenberg/packages/blocks/src/api/validation.js:147
Block validation failed for `core/paragraph` (0).
Expected:
<p class="has-background has-drop-cap has-large-font-size has-vivid-red-background-color custom-class-1 custom-class-2 is-large-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer tempor tincidunt sapien, quis dictum orci sollicitudin quis. Proin sed elit id est pulvinar feugiat vitae eget dolor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
PASS src/parser/block-parser-more.test.js
Parser
✓ parses the more block ok (6ms)
✓ parses the more block attributes ok (11ms)
RUNS src/app/App.test.js
Coming from #105 (review)
If I'm editing a text block and I add another, the "focus" switches to the newly inserted block, but the cursor stays in the previous block. I'm not sure if we're worrying about that at this point, but leaving a note here.
ToDo:
EDIT:
ToDo:
Recreating the ToDo list here after migration to FlatList
Following up this explanation of how Carthage currently works, let's try to hook it up to our iOS build process so that it transparently builds the dependencies.
This is a master issue for implementing the Image Block.
This block has many different features, and the plan is to implement them one by one.
Block settings:
With #66, and especially 8e5ebc8 it seems that master
got broken.
When building and running the app the following (red screen) error appears:
getVendorPrefixedEventName react-dom.development.js:1174:60 react-dom.development.js:1190:85 react-dom.development.js:15:2 loadModuleImplementation require.js:214:12 guardedLoadModule require.js:148:36 _require require.js:132:20 index.js:37:19 loadModuleImplementation require.js:214:12 guardedLoadModule require.js:148:36 _require require.js:132:20 index.js:43:16 loadModuleImplementation require.js:214:12 guardedLoadModule require.js:148:36 _require require.js:132:20 index.js:101:15 loadModuleImplementation require.js:214:12 guardedLoadModule require.js:148:36 _require require.js:132:20 registration.js:12 loadModuleImplementation require.js:214:12 guardedLoadModule require.js:148:36 _require require.js:132:20 factory.js:27 loadModuleImplementation require.js:214:12 guardedLoadModule require.js:148:36 _require require.js:132:20
loadModuleImplementation
require.js:214:12
guardedLoadModule
require.js:148:36
_require
require.js:132:20
loadModuleImplementation
require.js:214:12
guardedLoadModule
require.js:148:36
_require
require.js:132:20
index.native.js:4
loadModuleImplementation
require.js:214:12
guardedLoadModule
require.js:148:36
_require
require.js:132:20
index.js:7
loadModuleImplementation
require.js:214:12
guardedLoadModule
require.js:148:36
_require
require.js:132:20
App.js:6
loadModuleImplementation
require.js:214:12
guardedLoadModule
require.js:148:36
_require
require.js:132:20
index.js:4
loadModuleImplementation
require.js:214:12
guardedLoadModule
require.js:141:45
_require
require.js:132:20
global code
Tested on Nexus 5X, Android 7.1.2
Populate the toolbar with buttons from the focused block, or hide otherwise. Make buttons interactive, reflecting changes in selection and changing style of selected text.
Estimated: 5
Make sure that the block resizes as new lines are added or deleted when editing text.
Estimated: 5
Add support for setting a post as sticky.
Here's a design proposal:
(Migrated from wordpress-mobile/WordPress-Editor-Android#88)
Port the paragraph block so it renders styled text using the Aztec-flavored RichText component. You should be able to edit text, but not styles or any other attributes since we don’t have a toolbar or inspector yet.
Estimated: 5
Turning unrecognized blocks (markup that doesn’t match any of the registered blocks) is the easy part. We also need to identify which blocks are available on the server but don't have a mobile implementation yet.
When the block doesn't exist on the server, we should use a UI similar to the one in WordPress/gutenberg#8274 saying that the site doesn't support that block.
However when it's just not supported on mobile the UI should be different.
To avoid confusion, let's use this terminology unless/until we agree on a new one:
Right now I anticipate we'll need:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.