Skip to content

Commit

Permalink
Squashed 'libs/editor/' changes from 4832795..50ddd25
Browse files Browse the repository at this point in the history
50ddd25 Merge pull request #289 from wordpress-mobile/issue/24-js-security
300ffea Added profiling markers for visual editor startup
8747fc5 Merge branch 'issue/24-js-security' of github.com:wordpress-mobile/WordPress-Editor-Android into issue/24-js-security
da37d47 Drop NativeStateJsInterface, loading native localized Strings during ZSSEditor init instead
e6b654e Drop NativeStateJsInterface, loading native localized Strings during ZSSEditor init instead
6914c39 Inject androidApiLevel variable when loading the android-editor HTML file
050de28 Use URL loading through an iframe for JS callbacks on API<17, instead of a JavascriptInterface
39534a2 escape single quotes when calling execJavaScriptFromString
2771c83 fix wordpress-mobile/WordPress-Editor-Android#285: markImage(Video)UploadFailed now called with 2 parameters
b22fd31 Merge branch 'develop' into feature/visual-editor
4a8f94c Upgrade gradle plugin to 2.0.0-beta5
9bab5b7 Update gradle version in wrapper
f358e5e fix MockEditorActivity for tests
e2e4ec2 Merge commit '68c6f4cd95baefe3198dca9e8bd7d1ee3732f576' into issue/3610-media-tracking-fixes
30ffce9 Centralized tracking of added images/videos
2515856 Merge commit '097b51b9618f0fe23146c66b58918651e9c80bbc' into issue/3610-media-tracking-fixes
b46fd23 Merge branch 'develop' into feature/visual-editor
1f0df17 Merge pull request #3742 from wordpress-mobile/issue/update-to-android-gradle-plugin-2.0
c0e7c30 update to android gradle plugin beta4
40fdc2d update to android gradle plugin 2.0.0-beta-2 - Instant Run
5b4eb42 Updating to latest versions of internal dependencies
bd28005 Keeping internal dependencies always pointing to the latest version

git-subtree-dir: libs/editor
git-subtree-split: 50ddd25ce768b2caeae1634deaefe31c23d3a0e0
  • Loading branch information
aforcier committed Feb 23, 2016
1 parent 68c6f4c commit 87b5e7c
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 72 deletions.
4 changes: 2 additions & 2 deletions WordPressEditor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.android.tools.build:gradle:2.0.0-beta5'
}
}

Expand Down Expand Up @@ -48,7 +48,7 @@ android {
dependencies {
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'org.wordpress:utils:1.7.0'
compile 'org.wordpress:utils:1.9.0'

// Test libraries
testCompile 'junit:junit:4.11'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.support.v7.app.AppCompatActivity;
import android.widget.LinearLayout;

import org.wordpress.android.editor.EditorFragmentAbstract.TrackableEvent;
import org.wordpress.android.util.helpers.MediaFile;

public class MockEditorActivity extends AppCompatActivity implements EditorFragmentAbstract.EditorFragmentListener {
Expand Down Expand Up @@ -75,5 +76,10 @@ public String onAuthHeaderRequested(String url) {
public void saveMediaFile(MediaFile mediaFile) {

}

@Override
public void onTrackableEvent(TrackableEvent event) {

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.webkit.JavascriptInterface;
import android.webkit.URLUtil;
import android.webkit.WebView;
import android.widget.ToggleButton;
Expand All @@ -36,6 +35,7 @@
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.JSONUtils;
import org.wordpress.android.util.ProfilingUtils;
import org.wordpress.android.util.StringUtils;
import org.wordpress.android.util.ToastUtils;
import org.wordpress.android.util.UrlUtils;
Expand All @@ -60,7 +60,6 @@ public class EditorFragment extends EditorFragmentAbstract implements View.OnCli
private static final String ARG_PARAM_CONTENT = "param_content";

private static final String JS_CALLBACK_HANDLER = "nativeCallbackHandler";
private static final String JS_STATE_INTERFACE = "nativeState";

private static final String KEY_TITLE = "title";
private static final String KEY_CONTENT = "content";
Expand Down Expand Up @@ -121,6 +120,9 @@ public EditorFragment() {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ProfilingUtils.start("Visual Editor Startup");
ProfilingUtils.split("EditorFragment.onCreate");
}

@Override
Expand Down Expand Up @@ -372,14 +374,26 @@ protected void initJsEditor() {
return;
}

ProfilingUtils.split("EditorFragment.initJsEditor");

String htmlEditor = Utils.getHtmlFromFile(getActivity(), "android-editor.html");
if (htmlEditor != null) {
htmlEditor = htmlEditor.replace("%%TITLE%%", getString(R.string.visual_editor));
htmlEditor = htmlEditor.replace("%%ANDROID_API_LEVEL%%", String.valueOf(Build.VERSION.SDK_INT));
htmlEditor = htmlEditor.replace("%%LOCALIZED_STRING_INIT%%",
"nativeState.localizedStringEdit = '" + getString(R.string.edit) + "';\n" +
"nativeState.localizedStringUploading = '" + getString(R.string.uploading) + "';\n" +
"nativeState.localizedStringUploadingGallery = '" + getString(R.string.uploading_gallery_placeholder) + "';\n");
}

mWebView.addJavascriptInterface(new JsCallbackReceiver(this), JS_CALLBACK_HANDLER);
mWebView.addJavascriptInterface(new NativeStateJsInterface(getActivity().getApplicationContext()),
JS_STATE_INTERFACE);
// To avoid reflection security issues with JavascriptInterface on API<17, we use an iframe to make URL requests
// for callbacks from JS instead. These are received by WebViewClient.shouldOverrideUrlLoading() and then
// passed on to the JsCallbackReceiver
if (Build.VERSION.SDK_INT < 17) {
mWebView.setJsCallbackReceiver(new JsCallbackReceiver(this));
} else {
mWebView.addJavascriptInterface(new JsCallbackReceiver(this), JS_CALLBACK_HANDLER);
}

mWebView.loadDataWithBaseURL("file:///android_asset/", htmlEditor, "text/html", "utf-8", "");

Expand Down Expand Up @@ -745,13 +759,11 @@ public void run() {
if (URLUtil.isNetworkUrl(mediaUrl)) {
String mediaId = mediaFile.getMediaId();
mWebView.execJavaScriptFromString("ZSSEditor.insertImage('" + mediaUrl + "', '" + mediaId + "');");
mEditorFragmentListener.onTrackableEvent(TrackableEvent.NETWORK_IMAGE_ADDED);
} else {
String id = mediaFile.getMediaId();
mWebView.execJavaScriptFromString("ZSSEditor.insertLocalImage(" + id + ", '" + mediaUrl + "');");
mWebView.execJavaScriptFromString("ZSSEditor.setProgressOnImage(" + id + ", " + 0 + ");");
mUploadingMediaIds.add(id);
mEditorFragmentListener.onTrackableEvent(TrackableEvent.LOCAL_IMAGE_ADDED);
}
}
});
Expand Down Expand Up @@ -835,12 +847,12 @@ public void run() {
}

@Override
public void onMediaUploadFailed(final String mediaId) {
public void onMediaUploadFailed(final String mediaId, final String errorMessage) {
mWebView.post(new Runnable() {
@Override
public void run() {
mEditorFragmentListener.onTrackableEvent(TrackableEvent.UPLOAD_IMAGE_FAILED);
mWebView.execJavaScriptFromString("ZSSEditor.markImageUploadFailed(" + mediaId + ");");
mWebView.execJavaScriptFromString("ZSSEditor.markImageUploadFailed(" + mediaId + ", '"
+ errorMessage.replace("'", "\\'").replace("\"", "\\\"") + "');");
mFailedMediaIds.add(mediaId);
mUploadingMediaIds.remove(mediaId);
}
Expand Down Expand Up @@ -869,6 +881,8 @@ public void run() {
}

public void onDomLoaded() {
ProfilingUtils.split("EditorFragment.onDomLoaded");

mWebView.post(new Runnable() {
public void run() {
mDomHasLoaded = true;
Expand All @@ -886,7 +900,8 @@ public void run() {

// If there are images that are still in progress (because the editor exited before they completed),
// set them to failed, so the user can restart them (otherwise they will stay stuck in 'uploading' mode)
mWebView.execJavaScriptFromString("ZSSEditor.markAllUploadingImagesAsFailed();");
mWebView.execJavaScriptFromString("ZSSEditor.markAllUploadingImagesAsFailed('"
+ getString(R.string.tap_to_try_again) + "');");

// Update the list of failed media uploads
mWebView.execJavaScriptFromString("ZSSEditor.getFailedImages();");
Expand Down Expand Up @@ -924,6 +939,10 @@ public void run() {

mWaitingGalleries.clear();
}

ProfilingUtils.split("EditorFragment.onDomLoaded completed");
ProfilingUtils.dump();
ProfilingUtils.stop();
}
});
}
Expand Down Expand Up @@ -998,7 +1017,6 @@ public void onClick(DialogInterface dialog, int id) {
mWebView.post(new Runnable() {
@Override
public void run() {
mEditorFragmentListener.onTrackableEvent(TrackableEvent.UPLOAD_IMAGE_RETRIED);
mWebView.execJavaScriptFromString("ZSSEditor.unmarkImageUploadFailed(" + mediaId + ");");
mWebView.execJavaScriptFromString("ZSSEditor.setProgressOnImage(" + mediaId + ", " + 0 + ");");
mFailedMediaIds.remove(mediaId);
Expand Down Expand Up @@ -1268,37 +1286,4 @@ private void applyFormattingHtmlMode(ToggleButton toggleButton, String tag) {
mSourceViewContent.setSelection(selectionEnd + endTag.length());
}
}

private class NativeStateJsInterface {
Context mContext;

NativeStateJsInterface(Context context) {
mContext = context;
}

@JavascriptInterface
public String getStringEdit() {
return mContext.getString(R.string.edit);
}

@JavascriptInterface
public String getStringTapToRetry() {
return mContext.getString(R.string.tap_to_try_again);
}

@JavascriptInterface
public String getStringUploading() {
return mContext.getString(R.string.uploading);
}

@JavascriptInterface
public String getStringUploadingGallery() {
return mContext.getString(R.string.uploading_gallery_placeholder);
}

@JavascriptInterface
public int getAPILevel() {
return Build.VERSION.SDK_INT;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,6 @@ public enum TrackableEvent {
UNLINK_BUTTON_TAPPED,
LINK_BUTTON_TAPPED,
MEDIA_BUTTON_TAPPED,
NETWORK_IMAGE_ADDED,
LOCAL_IMAGE_ADDED,
UPLOAD_IMAGE_FAILED,
UPLOAD_IMAGE_RETRIED,
IMAGE_EDITED,
BOLD_BUTTON_TAPPED,
ITALIC_BUTTON_TAPPED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public interface EditorMediaUploadListener {
void onMediaUploadSucceeded(String localId, String remoteId, String remoteUrl);
void onMediaUploadProgress(String localId, float progress);
void onMediaUploadFailed(String localId);
void onMediaUploadFailed(String localId, String errorMessage);
void onGalleryMediaUploadSucceeded(long galleryId, String remoteId, int remaining);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public abstract class EditorWebViewAbstract extends WebView {

private OnImeBackListener mOnImeBackListener;
private AuthHeaderRequestListener mAuthHeaderRequestListener;
private JsCallbackReceiver mJsCallbackReceiver;

private Map<String, String> mHeaderMap = new HashMap<>();

Expand All @@ -53,6 +54,12 @@ private void configureWebView() {
this.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null && url.startsWith("callback") && mJsCallbackReceiver != null) {
String[] split = url.split(":", 2);
String callbackId = split[0];
String params = (split.length > 1 ? split[1] : "");
mJsCallbackReceiver.executeCallback(callbackId, params);
}
return true;
}

Expand Down Expand Up @@ -178,6 +185,14 @@ public void setAuthHeaderRequestListener(AuthHeaderRequestListener listener) {
mAuthHeaderRequestListener = listener;
}

/**
* Used on API<17 to handle callbacks as a safe alternative to JavascriptInterface (which has security risks
* at those API levels).
*/
public void setJsCallbackReceiver(JsCallbackReceiver jsCallbackReceiver) {
mJsCallbackReceiver = jsCallbackReceiver;
}

@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
Expand Down
2 changes: 1 addition & 1 deletion example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.android.tools.build:gradle:2.0.0-beta5'
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ public void run() {
count += 0.1;
}

((EditorMediaUploadListener) mEditorFragment).onMediaUploadFailed(mediaId);
((EditorMediaUploadListener) mEditorFragment).onMediaUploadFailed(mediaId,
getString(R.string.tap_to_try_again));

mFailedUploads.put(mediaId, mediaUrl);
} catch (InterruptedException e) {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
Loading

0 comments on commit 87b5e7c

Please sign in to comment.