Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use format-library for the formatting bar #275

Merged
merged 51 commits into from
Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
fdf14d7
Import format library on app launch
koke Nov 23, 2018
8debbec
Add format-library to symlinked packages
koke Nov 23, 2018
28d6d29
Update gutenberg
Tug Dec 19, 2018
5360a62
Update gutenberg
Tug Dec 27, 2018
ee92fef
Merge remote-tracking branch 'origin/develop' into feature/rich-text-…
Tug Jan 6, 2019
84b5f38
Fix react-native-aztec submodule ref
Tug Jan 7, 2019
09e2d6c
Merge remote-tracking branch 'origin/develop' into feature/rich-text-…
Tug Jan 21, 2019
8c38497
Use last version of react-native-aztec
Tug Jan 21, 2019
bb9ec04
Changes from react-native-aztec PR #105
Tug Jan 21, 2019
74b0ae9
Use FORMAT_ITALIC for italic formatting
Tug Jan 22, 2019
02c27dc
Make new aztec format emphasis the default italic format
Tug Jan 23, 2019
0391415
Update gutenberg
Tug Jan 23, 2019
3538a30
Update gutenberg
Tug Jan 23, 2019
baba8fe
Update gutenberg
Tug Jan 24, 2019
2b9ad3f
Disable triggering extra selection change events when updating the html
Tug Jan 24, 2019
4f86d4f
Disable emitting selection change events when resetting the HTML and …
Tug Jan 28, 2019
ed85258
Update gutenberg
Tug Jan 28, 2019
4ec319e
Remove reset last active formats
Tug Jan 28, 2019
64cdded
Update gutenberg
Tug Jan 28, 2019
b6f35f5
Update gutenberg
Tug Jan 29, 2019
0e3599a
Revert aztec version change
Tug Jan 29, 2019
22c2ceb
Merge remote-tracking branch 'origin/develop' into feature/rich-text-…
Tug Jan 31, 2019
d02c1e6
Update gutenberg
Tug Jan 31, 2019
2933c7d
Update gutenberg
Tug Jan 31, 2019
dd533e3
Update Gutenberg ref
hypest Feb 1, 2019
0b15193
Update Gutenberg ref
hypest Feb 1, 2019
b9e19da
Merge remote-tracking branch 'origin/develop' into feature/rich-text-…
hypest Feb 4, 2019
5d38c3e
Point to updated Aztec branch
hypest Feb 6, 2019
0d97cdf
Update the gutenberg ref
hypest Feb 6, 2019
9676c56
Update gutenberg ref
hypest Feb 6, 2019
9c1e493
Merge branch 'develop' into feature/rich-text-formats
hypest Feb 6, 2019
874ffa4
Update gutenberg ref
hypest Feb 6, 2019
46c086e
Update gutenberg ref
hypest Feb 6, 2019
5c8b96b
Update Aztec ref
hypest Feb 6, 2019
e151053
Update Aztec ref
hypest Feb 6, 2019
41f1708
Merge branch 'develop' into feature/rich-text-formats
hypest Feb 8, 2019
5a8ea3a
Update Aztec ref
hypest Feb 12, 2019
00bb954
Update Gutenberg ref
hypest Feb 12, 2019
a4fd193
Merge branch 'develop' into feature/rich-text-formats
hypest Feb 12, 2019
1c5d4e4
Added missing format-library import
koke Feb 15, 2019
5e54361
Increment eventCount for enter and selection changes
koke Feb 15, 2019
03f6037
Update the Gutenberg ref
hypest Feb 15, 2019
f91ab4e
Update Gutenberg with modal fixes for iOS
koke Feb 15, 2019
1916b83
Update Gutenberg (lint fixes)
koke Feb 15, 2019
5756ed1
Update bundles to help with testing the PR
koke Feb 15, 2019
1949629
Merge branch 'develop' into feature/rich-text-formats
koke Feb 15, 2019
9a25e7f
Update bundles
koke Feb 15, 2019
157b944
Update GB ref
hypest Feb 18, 2019
9938ec8
Update to Aztec merged commit
hypest Feb 18, 2019
ff33379
Merge branch 'develop' into feature/rich-text-formats
hypest Feb 18, 2019
558c2ff
Update the GB ref to the merged commit
hypest Feb 18, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,844 changes: 923 additions & 921 deletions bundle/android/App.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bundle/android/App.js.map

Large diffs are not rendered by default.

1,856 changes: 929 additions & 927 deletions bundle/ios/App.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bundle/ios/App.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion react-native-aztec/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ buildscript {
wordpressUtilsVersion = '1.22'
espressoVersion = '3.0.1'

aztecVersion = 'v1.3.19'
aztecVersion = 'e02ec1387c739d73645e498a2e5ed1b3916b2587'
}

repositories {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ class ReactAztecEnterEvent extends Event<ReactAztecEnterEvent> {
private String mText;
private int mSelectionStart;
private int mSelectionEnd;
private int mEventCount;

public ReactAztecEnterEvent(int viewId, String text, int selectionStart, int selectionEnd) {
public ReactAztecEnterEvent(int viewId, String text, int selectionStart, int selectionEnd, int eventCount) {
super(viewId);
mText = text;
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mEventCount = eventCount;
}

@Override
Expand All @@ -44,6 +46,7 @@ private WritableMap serializeEventData() {
eventData.putString("text", mText);
eventData.putInt("selectionStart", mSelectionStart);
eventData.putInt("selectionEnd", mSelectionEnd);
eventData.putInt("eventCount", mEventCount);
return eventData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@
import org.wordpress.aztec.plugins.wpcomments.toolbar.MoreToolbarButton;

import java.util.Map;
import java.util.ArrayList;
import java.util.Arrays;

public class ReactAztecManager extends SimpleViewManager<ReactAztecText> {

public static final String REACT_CLASS = "RCTAztecView";

private static final int FOCUS_TEXT_INPUT = 1;
private static final int BLUR_TEXT_INPUT = 2;
private static final int COMMAND_NOTIFY_APPLY_FORMAT = 100;
private static final int UNSET = -1;

// we define the same codes in ReactAztecText as they have for ReactNative's TextInput, so
Expand Down Expand Up @@ -165,6 +166,7 @@ public void setText(ReactAztecText view, ReadableMap inputMap) {
// Don't think there is necessity of this branch, but justin case we want to
// force a 2nd setText from JS side to Native, just set a high eventCount
int eventCount = inputMap.getInt("eventCount");

if (view.mNativeEventCount < eventCount) {
setTextfromJS(view, inputMap.getString("text"));
}
Expand All @@ -173,10 +175,24 @@ public void setText(ReactAztecText view, ReadableMap inputMap) {

private void setTextfromJS(ReactAztecText view, String text) {
view.setIsSettingTextFromJS(true);
view.disableOnSelectionListener();
view.fromHtml(text, true);
view.enableOnSelectionListener();
view.setIsSettingTextFromJS(false);
}

@ReactProp(name = "activeFormats", defaultBoolean = false)
public void setActiveFormats(final ReactAztecText view, @Nullable ReadableArray activeFormats) {
if (activeFormats != null) {
String[] activeFormatsArray = new String[activeFormats.size()];
for (int i = 0; i < activeFormats.size(); i++) {
activeFormatsArray[i] = activeFormats.getString(i);
}
view.setActiveFormats(Arrays.asList(activeFormatsArray));
} else {
view.setActiveFormats(new ArrayList<String>());
}
}

/*
The code below was taken from the class ReactTextInputManager
Expand Down Expand Up @@ -346,11 +362,6 @@ public void setOnContentSizeChange(final ReactAztecText view, boolean onContentS
}
}

@ReactProp(name = "onActiveFormatsChange", defaultBoolean = false)
public void setOnActiveFormatsChange(final ReactAztecText view, boolean onActiveFormatsChange) {
view.shouldHandleActiveFormatsChange = onActiveFormatsChange;
}

@ReactProp(name = "onSelectionChange", defaultBoolean = false)
public void setOnSelectionChange(final ReactAztecText view, boolean onSelectionChange) {
view.shouldHandleOnSelectionChange = onSelectionChange;
Expand Down Expand Up @@ -378,7 +389,6 @@ public void setOnBackspaceHandling(final ReactAztecText view, boolean onBackspac
@Override
public Map<String, Integer> getCommandsMap() {
return MapBuilder.<String, Integer>builder()
.put("applyFormat", COMMAND_NOTIFY_APPLY_FORMAT)
.put("focusTextInput", mFocusTextInputCommandCode)
.put("blurTextInput", mBlurTextInputCommandCode)
.build();
Expand All @@ -387,12 +397,7 @@ public Map<String, Integer> getCommandsMap() {
@Override
public void receiveCommand(final ReactAztecText parent, int commandType, @Nullable ReadableArray args) {
Assertions.assertNotNull(parent);
if (commandType == COMMAND_NOTIFY_APPLY_FORMAT) {
final String format = args.getString(0);
Log.d(TAG, String.format("Apply format: %s", format));
parent.applyFormat(format);
return;
} else if (commandType == mFocusTextInputCommandCode) {
if (commandType == mFocusTextInputCommandCode) {
parent.requestFocusFromJS();
return;
} else if (commandType == mBlurTextInputCommandCode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ class ReactAztecSelectionChangeEvent extends Event<ReactAztecSelectionChangeEven
private String mText;
private int mSelectionStart;
private int mSelectionEnd;
private int mEventCount;

public ReactAztecSelectionChangeEvent(int viewId, String text, int selectionStart, int selectionEnd) {
public ReactAztecSelectionChangeEvent(int viewId, String text, int selectionStart, int selectionEnd, int eventCount) {
super(viewId);
mText = text;
mSelectionStart = selectionStart;
mSelectionEnd = selectionEnd;
mEventCount = eventCount;
}

@Override
Expand All @@ -45,6 +47,7 @@ private WritableMap serializeEventData() {
eventData.putString("text", mText);
eventData.putInt("selectionStart", mSelectionStart);
eventData.putInt("selectionEnd", mSelectionEnd);
eventData.putInt("eventCount", mEventCount);
return eventData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;

public class ReactAztecText extends AztecText {

Expand All @@ -52,6 +56,17 @@ public class ReactAztecText extends AztecText {
boolean shouldHandleOnSelectionChange = false;
boolean shouldHandleActiveFormatsChange = false;

private static final HashMap<ITextFormat, String> typingFormatsMap = new HashMap<ITextFormat, String>() {
{
put(AztecTextFormat.FORMAT_BOLD, "bold");
put(AztecTextFormat.FORMAT_STRONG, "bold");
put(AztecTextFormat.FORMAT_EMPHASIS, "italic");
put(AztecTextFormat.FORMAT_ITALIC, "italic");
put(AztecTextFormat.FORMAT_CITE, "italic");
put(AztecTextFormat.FORMAT_STRIKETHROUGH, "strikethrough");
}
};

public ReactAztecText(ThemedReactContext reactContext) {
super(reactContext);

Expand Down Expand Up @@ -232,7 +247,7 @@ private void propagateSelectionChanges(int selStart, int selEnd) {
ReactContext reactContext = (ReactContext) getContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(
new ReactAztecSelectionChangeEvent(getId(), content, selStart, selEnd)
new ReactAztecSelectionChangeEvent(getId(), content, selStart, selEnd, incrementAndGetEventCounter())
);
}

Expand Down Expand Up @@ -296,7 +311,7 @@ private boolean onEnter() {
ReactContext reactContext = (ReactContext) getContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(
new ReactAztecEnterEvent(getId(), content, cursorPositionStart, cursorPositionEnd)
new ReactAztecEnterEvent(getId(), content, cursorPositionStart, cursorPositionEnd, incrementAndGetEventCounter())
);
return true;
}
Expand All @@ -321,66 +336,27 @@ private boolean onBackspace() {
return true;
}

public void applyFormat(String format) {
ArrayList<ITextFormat> newFormats = new ArrayList<>();
switch (format) {
case ("bold"):
case ("strong"):
newFormats.add(AztecTextFormat.FORMAT_STRONG);
newFormats.add(AztecTextFormat.FORMAT_BOLD);
break;
case ("italic"):
newFormats.add(AztecTextFormat.FORMAT_ITALIC);
newFormats.add(AztecTextFormat.FORMAT_CITE);
break;
case ("strikethrough"):
newFormats.add(AztecTextFormat.FORMAT_STRIKETHROUGH);
break;
}

if (newFormats.size() == 0) {
return;
}

if (!isTextSelected()) {
final ArrayList<ITextFormat> newStylesList = getNewStylesList(newFormats);
setSelectedStyles(newStylesList);
// Update the toolbar state
updateToolbarButtons(newStylesList);
} else {
toggleFormatting(newFormats.get(0));
// Update the toolbar state
updateToolbarButtons(getSelectionStart(), getSelectionEnd());
}

// emit onChange because the underlying HTML has changed applying the style
ReactContext reactContext = (ReactContext) getContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
eventDispatcher.dispatchEvent(
new ReactTextChangedEvent(
getId(),
toHtml(false),
incrementAndGetEventCounter())
);
}

// Removes all formats in the list but if none found, applies the first one
private ArrayList<ITextFormat> getNewStylesList(ArrayList<ITextFormat> newFormats) {
ArrayList<ITextFormat> textFormats = new ArrayList<>();
textFormats.addAll(getSelectedStyles());
boolean wasRemoved = false;
for (ITextFormat newFormat : newFormats) {
if (textFormats.contains(newFormat)) {
wasRemoved = true;
textFormats.remove(newFormat);
public void setActiveFormats(Iterable<String> newFormats) {
Set<ITextFormat> selectedStylesSet = new HashSet<>(getSelectedStyles());
Set<ITextFormat> newFormatsSet = new HashSet<>();
for (String newFormat : newFormats) {
switch (newFormat) {
case "bold":
newFormatsSet.add(AztecTextFormat.FORMAT_STRONG);
break;
case "italic":
newFormatsSet.add(AztecTextFormat.FORMAT_EMPHASIS);
break;
case "strikethrough":
newFormatsSet.add(AztecTextFormat.FORMAT_STRIKETHROUGH);
break;
}
}

if (!wasRemoved) {
textFormats.add(newFormats.get(0));
}

return textFormats;
selectedStylesSet.removeAll(typingFormatsMap.keySet());
selectedStylesSet.addAll(newFormatsSet);
ArrayList<ITextFormat> newStylesList = new ArrayList<>(selectedStylesSet);
setSelectedStyles(newStylesList);
updateToolbarButtons(newStylesList);
}

/**
Expand Down
72 changes: 13 additions & 59 deletions react-native-aztec/ios/RNTAztecView/RCTAztecView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class RCTAztecView: Aztec.TextView {
@objc var onBlur: RCTBubblingEventBlock? = nil
@objc var onContentSizeChange: RCTBubblingEventBlock? = nil
@objc var onSelectionChange: RCTBubblingEventBlock? = nil
@objc var onActiveFormatsChange: RCTBubblingEventBlock? = nil
@objc var onActiveFormatAttributesChange: RCTBubblingEventBlock? = nil
@objc var blockType: NSDictionary? = nil {
didSet {
guard let block = blockType, let tag = block["tag"] as? String else {
Expand All @@ -20,6 +18,14 @@ class RCTAztecView: Aztec.TextView {
blockModel = BlockModel(tag: tag)
}
}
@objc var activeFormats: NSSet? = nil {
didSet {
let currentTypingAttributes = formattingIdentifiersForTypingAttributes()
for (key, value) in formatStringMap where currentTypingAttributes.contains(key) != activeFormats?.contains(value) {
toggleFormat(format: value)
}
}
}

var blockModel = BlockModel(tag: "") {
didSet {
Expand Down Expand Up @@ -353,44 +359,16 @@ class RCTAztecView: Aztec.TextView {

// MARK: - Formatting interface

@objc func apply(format: String) {
@objc func toggleFormat(format: String) {
let emptyRange = NSRange(location: selectedRange.location, length: 0)
switch format {
case "bold": toggleBold(range: selectedRange)
case "italic": toggleItalic(range: selectedRange)
case "strikethrough": toggleStrikethrough(range: selectedRange)
case "bold": toggleBold(range: emptyRange)
case "italic": toggleItalic(range: emptyRange)
case "strikethrough": toggleStrikethrough(range: emptyRange)
default: print("Format not recognized")
}
}

@objc
func setLink(with url: String, and title: String?) {
guard let url = URL(string: url) else {
return
}
if let title = title {
setLink(url, title: title, inRange: selectedRange)
} else {
setLink(url, inRange: selectedRange)
}
}

@objc
func removeLink() {
guard let expandedRange = linkFullRange(forRange: selectedRange) else {
return
}
removeLink(inRange: expandedRange)
}

func linkAttributes() -> [String: Any] {
var attributes: [String: Any] = ["isActive": false]
if let expandedRange = linkFullRange(forRange: selectedRange) {
attributes["url"] = linkURL(forRange: expandedRange)?.absoluteString ?? ""
attributes["isActive"] = true
}
return attributes
}

func forceTypingAttributesIfNeeded() {
if let formatHandler = HeadingBlockFormatHandler(block: blockModel) {
formatHandler.forceTypingFormat(on: self)
Expand All @@ -406,27 +384,6 @@ class RCTAztecView: Aztec.TextView {
}
}

func propagateFormatChanges() {
guard let onActiveFormatsChange = onActiveFormatsChange else {
return
}
let identifiers: Set<FormattingIdentifier>
if selectedRange.length > 0 {
identifiers = formattingIdentifiersSpanningRange(selectedRange)
} else {
identifiers = formattingIdentifiersForTypingAttributes()
}
let formats = identifiers.compactMap { formatStringMap[$0] }
onActiveFormatsChange(["formats": formats])
}

func propagateAttributesChanges() {
let attributes: [String: [String: Any]] = [
"link": linkAttributes()
]
onActiveFormatAttributesChange?(["attributes": attributes])
}

func propagateSelectionChanges() {
guard let onSelectionChange = onSelectionChange else {
return
Expand All @@ -440,14 +397,11 @@ class RCTAztecView: Aztec.TextView {
extension RCTAztecView: UITextViewDelegate {

func textViewDidChangeSelection(_ textView: UITextView) {
propagateAttributesChanges()
propagateFormatChanges()
propagateSelectionChanges()
}

func textViewDidChange(_ textView: UITextView) {
forceTypingAttributesIfNeeded()
propagateFormatChanges()
propagateContentChanges()
//Necessary to send height information to JS after pasting text.
textView.setNeedsLayout()
Expand Down
Loading