diff --git a/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/EditorInitializePromiseHolder.java b/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/EditorInitializePromiseHolder.java index dde743a42e9..3e8cb05a34b 100644 --- a/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/EditorInitializePromiseHolder.java +++ b/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/EditorInitializePromiseHolder.java @@ -10,9 +10,35 @@ *******************************************************************************/ package org.eclipse.che.ide.editor.orion.client; +import com.google.gwt.core.client.Callback; +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.JavaScriptException; +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArrayString; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.LinkElement; +import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Singleton; import org.eclipse.che.api.promises.client.Promise; +import org.eclipse.che.api.promises.client.callback.AsyncPromiseHelper; +import org.eclipse.che.ide.api.editor.EditorLocalizationConstants; +import org.eclipse.che.ide.api.notification.NotificationManager; +import org.eclipse.che.ide.api.notification.StatusNotification; +import org.eclipse.che.ide.editor.orion.client.jso.OrionTextThemeOverlay; +import org.eclipse.che.ide.editor.orion.client.signature.SignatureHelpResources; +import org.eclipse.che.ide.ui.loaders.request.LoaderFactory; +import org.eclipse.che.ide.ui.loaders.request.MessageLoader; +import org.eclipse.che.ide.util.loging.Log; +import org.eclipse.che.plugin.requirejs.ide.RequireJsLoader; +import org.eclipse.che.plugin.requirejs.ide.RequirejsErrorHandler.RequireError; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE; + +import javax.inject.Inject; /** * Holds promise that resolve when all editor js scripts are loaded ad initialized @@ -20,16 +46,141 @@ @Singleton public class EditorInitializePromiseHolder { - private Promise initializerPromise; + /** The logger. */ + private static final Logger LOG = Logger.getLogger(EditorInitializePromiseHolder.class.getSimpleName()); - public void setInitializerPromise(Promise initializerPromise) { - this.initializerPromise = initializerPromise; + private final NotificationManager notificationManager; + private final RequireJsLoader requireJsLoader; + private final OrionResource orionResource; + private final MessageLoader loader; + private final String waitEditorMessage; + + private boolean initFailedWarnedOnce = false; + private boolean cssLinkInjected = false; + + @Inject + public EditorInitializePromiseHolder(final NotificationManager notificationManager, + final RequireJsLoader requireJsLoader, + final OrionResource orionResource, + final LoaderFactory loaderFactory, + final EditorLocalizationConstants constants, + final SignatureHelpResources signatureHelpResources) { + this.notificationManager = notificationManager; + this.requireJsLoader = requireJsLoader; + this.orionResource = orionResource; + this.loader = loaderFactory.newLoader(); + this.waitEditorMessage = constants.waitEditorInitMessage(); + signatureHelpResources.css().ensureInjected(); } public Promise getInitializerPromise() { - if (initializerPromise == null) { - throw new RuntimeException("Editor initializer not set"); + return AsyncPromiseHelper.createFromAsyncRequest(new AsyncPromiseHelper.RequestCall() { + @Override + public void makeCall(AsyncCallback callback) { + injectOrion(callback); + } + }); + } + + private void injectOrion(final AsyncCallback callback) { + loader.setMessage(waitEditorMessage); + final String[] scripts = new String[]{ + "built-codeEdit/code_edit/built-codeEdit-amd", + "orion/CheContentAssistMode" + }; + + requireJsLoader.require(new Callback() { + @Override + public void onSuccess(final JavaScriptObject[] result) { + requireOrion(callback); + } + + @Override + public void onFailure(final Throwable e) { + if (e instanceof JavaScriptException) { + final JavaScriptException jsException = (JavaScriptException)e; + final Object nativeException = jsException.getThrown(); + if (nativeException instanceof RequireError) { + final RequireError requireError = (RequireError)nativeException; + final String errorType = requireError.getRequireType(); + String message = "Orion injection failed: " + errorType; + final JsArrayString modules = requireError.getRequireModules(); + if (modules != null) { + message += modules.join(","); + } + Log.debug(OrionEditorExtension.class, message); + } + } + initializationFailed(callback, "Failed to inject Orion editor", e); + } + }, scripts, new String[0]); + + injectCssLink(GWT.getModuleBaseForStaticFiles() + "built-codeEdit/code_edit/built-codeEdit.css"); + } + + private void injectCssLink(final String url) { + // Avoid injecting built-codeEdit.css more than once as it may override + // orion-codenvy-theme.css + if (!cssLinkInjected) { + final LinkElement link = Document.get().createLinkElement(); + link.setRel("stylesheet"); + link.setHref(url); + Document.get().getHead().appendChild(link); + cssLinkInjected = true; + } + } + + private void requireOrion(final AsyncCallback callback) { + requireJsLoader.require(new Callback() { + + @Override + public void onFailure(final Throwable reason) { + LOG.log(Level.SEVERE, "Unable to initialize Orion ", reason); + initializationFailed(callback, "Failed to initialize Orion editor", reason); + } + + @Override + public void onSuccess(final JavaScriptObject[] result) { + endConfiguration(callback); + } + }, + new String[]{"orion/codeEdit", + "orion/editor/emacs", + "orion/editor/vi", + "orion/keyBinding", + "che/editor/contentAssist", + "orion/editor/eventTarget", + "orion/uiUtils"}, + new String[]{"CodeEditWidget", + "OrionEmacs", + "OrionVi", + "OrionKeyBinding", + "CheContentAssistMode", + "OrionEventTarget", + "UiUtils"}); + } + + private void endConfiguration(final AsyncCallback callback) { + defineDefaultTheme(); + loader.hide(); + callback.onSuccess(null); + } + + private void defineDefaultTheme() { + // The codenvy theme uses both an orion css file and a CssResource + orionResource.editorStyle().ensureInjected(); + orionResource.getIncrementalFindStyle().ensureInjected(); + OrionTextThemeOverlay.setDefaultTheme("orionCodenvy", "orion-codenvy-theme.css"); + } + + private void initializationFailed(final AsyncCallback callback, final String errorMessage, Throwable e) { + if (initFailedWarnedOnce) { + return; } - return initializerPromise; + loader.hide(); + initFailedWarnedOnce = true; + notificationManager.notify(errorMessage, StatusNotification.Status.FAIL, FLOAT_MODE); + LOG.log(Level.SEVERE, errorMessage + " - ", e); + callback.onFailure(e); } } diff --git a/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionEditorExtension.java b/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionEditorExtension.java index 3466061901d..efe365d13d0 100644 --- a/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionEditorExtension.java +++ b/plugins/plugin-orion/che-plugin-orion-editor/src/main/java/org/eclipse/che/ide/editor/orion/client/OrionEditorExtension.java @@ -10,171 +10,18 @@ *******************************************************************************/ package org.eclipse.che.ide.editor.orion.client; -import com.google.gwt.core.client.Callback; -import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.JavaScriptException; -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.core.client.JsArrayString; -import com.google.gwt.dom.client.Document; -import com.google.gwt.dom.client.LinkElement; -import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.inject.Singleton; -import org.eclipse.che.api.promises.client.Promise; -import org.eclipse.che.api.promises.client.callback.AsyncPromiseHelper; -import org.eclipse.che.ide.api.editor.EditorLocalizationConstants; import org.eclipse.che.ide.api.extension.Extension; -import org.eclipse.che.ide.api.notification.NotificationManager; -import org.eclipse.che.ide.api.notification.StatusNotification; -import org.eclipse.che.ide.editor.orion.client.jso.OrionTextThemeOverlay; -import org.eclipse.che.ide.editor.orion.client.signature.SignatureHelpResources; -import org.eclipse.che.plugin.requirejs.ide.RequireJsLoader; -import org.eclipse.che.plugin.requirejs.ide.RequirejsErrorHandler.RequireError; -import org.eclipse.che.ide.ui.loaders.request.LoaderFactory; -import org.eclipse.che.ide.ui.loaders.request.MessageLoader; -import org.eclipse.che.ide.util.loging.Log; import javax.inject.Inject; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static org.eclipse.che.ide.api.notification.StatusNotification.DisplayMode.FLOAT_MODE; @Extension(title = "Orion Editor", version = "1.1.0") @Singleton public class OrionEditorExtension { - /** The logger. */ - private static final Logger LOG = Logger.getLogger(OrionEditorExtension.class.getSimpleName()); - - private final NotificationManager notificationManager; - private final RequireJsLoader requireJsLoader; - private final OrionResource orionResource; - private final MessageLoader loader; - private final String waitEditorMessage; - - private boolean initFailedWarnedOnce = false; - @Inject - public OrionEditorExtension(final NotificationManager notificationManager, - final RequireJsLoader requireJsLoader, - final EditorInitializePromiseHolder editorModule, - final OrionResource orionResource, - final LoaderFactory loaderFactory, - final EditorLocalizationConstants constants, - final SignatureHelpResources signatureHelpResources) { - this.notificationManager = notificationManager; - this.requireJsLoader = requireJsLoader; - this.orionResource = orionResource; - this.loader = loaderFactory.newLoader(); - this.waitEditorMessage = constants.waitEditorInitMessage(); - signatureHelpResources.css().ensureInjected(); - - Promise promise = AsyncPromiseHelper.createFromAsyncRequest(new AsyncPromiseHelper.RequestCall() { - @Override - public void makeCall(AsyncCallback callback) { - injectOrion(callback); - } - }); - editorModule.setInitializerPromise(promise); - + public OrionEditorExtension() { KeyMode.init(); } - - private void injectOrion(final AsyncCallback callback) { - loader.setMessage(waitEditorMessage); - final String[] scripts = new String[]{ - "built-codeEdit/code_edit/built-codeEdit-amd", - "orion/CheContentAssistMode" - }; - - requireJsLoader.require(new Callback() { - @Override - public void onSuccess(final JavaScriptObject[] result) { - requireOrion(callback); - } - - @Override - public void onFailure(final Throwable e) { - if (e instanceof JavaScriptException) { - final JavaScriptException jsException = (JavaScriptException)e; - final Object nativeException = jsException.getThrown(); - if (nativeException instanceof RequireError) { - final RequireError requireError = (RequireError)nativeException; - final String errorType = requireError.getRequireType(); - String message = "Orion injection failed: " + errorType; - final JsArrayString modules = requireError.getRequireModules(); - if (modules != null) { - message += modules.join(","); - } - Log.debug(OrionEditorExtension.class, message); - } - } - initializationFailed(callback, "Failed to inject Orion editor", e); - } - }, scripts, new String[0]); - - injectCssLink(GWT.getModuleBaseForStaticFiles() + "built-codeEdit/code_edit/built-codeEdit.css"); - } - - private static void injectCssLink(final String url) { - final LinkElement link = Document.get().createLinkElement(); - link.setRel("stylesheet"); - link.setHref(url); - Document.get().getHead().appendChild(link); - } - - private void requireOrion(final AsyncCallback callback) { - requireJsLoader.require(new Callback() { - - @Override - public void onFailure(final Throwable reason) { - LOG.log(Level.SEVERE, "Unable to initialize Orion ", reason); - initializationFailed(callback, "Failed to initialize Orion editor", reason); - } - - @Override - public void onSuccess(final JavaScriptObject[] result) { - endConfiguration(callback); - } - }, - new String[]{"orion/codeEdit", - "orion/editor/emacs", - "orion/editor/vi", - "orion/keyBinding", - "che/editor/contentAssist", - "orion/editor/eventTarget", - "orion/uiUtils"}, - new String[]{"CodeEditWidget", - "OrionEmacs", - "OrionVi", - "OrionKeyBinding", - "CheContentAssistMode", - "OrionEventTarget", - "UiUtils"}); - } - - private void endConfiguration(final AsyncCallback callback) { - defineDefaultTheme(); - loader.hide(); - callback.onSuccess(null); - } - - private void defineDefaultTheme() { - // The codenvy theme uses both an orion css file and a CssResource - orionResource.editorStyle().ensureInjected(); - orionResource.getIncrementalFindStyle().ensureInjected(); - OrionTextThemeOverlay.setDefaultTheme("orionCodenvy", "orion-codenvy-theme.css"); - } - - private void initializationFailed(final AsyncCallback callback, final String errorMessage, Throwable e) { - if (initFailedWarnedOnce) { - return; - } - loader.hide(); - initFailedWarnedOnce = true; - notificationManager.notify(errorMessage, StatusNotification.Status.FAIL, FLOAT_MODE); - LOG.log(Level.SEVERE, errorMessage + " - ", e); - callback.onFailure(e); - } }