Package chrriis.dj.nativeswing.swtimpl.components

Source Code of chrriis.dj.nativeswing.swtimpl.components.JHTMLEditorTinyMCE

/*
* Christopher Deckers (chrriis@nextencia.net)
* http://www.nextencia.net
*
* See the file "readme.txt" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
package chrriis.dj.nativeswing.swtimpl.components;

import java.io.InputStream;
import java.util.Map;

import javax.swing.SwingUtilities;

import chrriis.common.Utils;
import chrriis.common.WebServer;
import chrriis.common.WebServer.HTTPRequest;
import chrriis.common.WebServer.WebServerContent;
import chrriis.dj.nativeswing.swtimpl.EventDispatchUtils;
import chrriis.dj.nativeswing.swtimpl.Message;
import chrriis.dj.nativeswing.swtimpl.NSSystemPropertySWT;
import chrriis.dj.nativeswing.swtimpl.NativeComponent;
import chrriis.dj.nativeswing.swtimpl.components.JHTMLEditor.JHTMLEditorImplementation;

/**
* @author Jörn Heid
* @author Christopher Deckers
*/
class JHTMLEditorTinyMCE implements JHTMLEditorImplementation {

  private static final String PACKAGE_PREFIX = "/tiny_mce/";
  private static final String EDITOR_INSTANCE = "HTMLeditor1";

  private final JHTMLEditor htmlEditor;
  private final String customOptions;
  private final String customHTMLHeaders;

  private static final String LS = Utils.LINE_SEPARATOR;

  @SuppressWarnings("unchecked")
  public JHTMLEditorTinyMCE(JHTMLEditor htmlEditor, Map<Object, Object> optionMap) {
    if(getClass().getResource(PACKAGE_PREFIX + "tiny_mce.js") == null) {
      throw new IllegalStateException("The TinyMCE distribution is missing from the classpath!");
    }
    this.htmlEditor = htmlEditor;
    Map<String, String> customOptionsMap = (Map<String, String>)optionMap.get(JHTMLEditor.TinyMCEOptions.SET_OPTIONS_OPTION_KEY);
    if(customOptionsMap != null) {
      StringBuilder sb = new StringBuilder();
      for(String key: customOptionsMap.keySet()) {
        String value = customOptionsMap.get(key);
        if(value != null && value.length() > 0) {
          if(sb.length() > 0) {
            sb.append(',' + LS);
          }
          sb.append("        " + key + ": " + value);
        }
      }
      customOptions = sb.length() > 0? sb.toString(): null;
    } else {
      customOptions = null;
    }
    customHTMLHeaders = (String)optionMap.get(JHTMLEditor.TinyMCEOptions.SET_CUSTOM_HTML_HEADERS_OPTION_KEY);
    // We want potential dialogs to actually be dialogs.
    htmlEditor.getWebBrowser().addWebBrowserListener(new WebBrowserAdapter() {
      @Override
      public void windowWillOpen(WebBrowserWindowWillOpenEvent e) {
        e.setDialogWindow(true);
      }
    });
  }

  public WebServerContent getWebServerContent(final HTTPRequest httpRequest, final String resourcePath, final int instanceID) {
    if ("index.html".equals (resourcePath)) {
      return new WebServerContent() {
        @Override
        public String getContentType() {
          int index = resourcePath.lastIndexOf('.');
          return getDefaultMimeType(index == -1? null: resourcePath.substring(index));
        }
        @Override
        public InputStream getInputStream () {
          String content =
            "<html xmlns=\"http://www.w3.org/1999/xhtml\">" + LS +
            "  <head>" + LS +
            "    <title></title>" + LS +
            (customHTMLHeaders != null? customHTMLHeaders + LS: "") +
            "    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>" + LS +
            "    <style type=\"text/css\">" + LS +
            "      body, form {margin: 0; padding: 0; overflow: auto;}" + LS +
            "    </style>" + LS +
            "    <script type=\"text/javascript\" src=\"tiny_mce.js\"></script>" + LS +
            "    <script type=\"text/javascript\">" + LS +
            "      function debug (text) {" + LS +
            "        document.getElementById ('debug').innerHTML = text;" + LS +
            "      }" + LS +
//            "      window.onerror = function (e) {" + LS +
//            "        var text = '';" + LS +
//            "        if (typeof e == 'string') {" + LS +
//            "          text = e;" + LS +
//            "        } else {" +
//            "          for (var x in e) {" + LS +
//            "            text += x+': '+e[x]+'\\n';" + LS +
//            "          }" + LS +
//            "        }" + LS +
//            "        debug (text);" + LS +
//            "      };" + LS +
            "      var sendCommand = " + JWebBrowser.COMMAND_FUNCTION + ";" + LS +
            "      var htmlContent;" + LS +
            "      var htmlDirtyTracker;" + LS +
            "      var isDirtyTrackingActive = true;" + LS +
            "      function JH_checkDirty() {" + LS +
            "        var inst = tinyMCE.get ('" + EDITOR_INSTANCE + "');" + LS +
            "        if(htmlContent == null) {" + LS +
            "          try {" + LS +
            "            htmlContent = inst.getContent();" + LS +
            "          } catch(e) {" + LS +
            "          }" + LS +
            "          htmlDirtyTracker = setTimeout('JH_checkDirty()', 1000);" + LS +
            "        } else {" + LS +
            "          try {" + LS +
            "            var newHtmlContent = inst.getContent();" + LS +
            "            if(newHtmlContent != htmlContent) {" + LS +
            "              htmlContent = null;" + LS +
            "              htmlDirtyTracker = null;" + LS +
            "              sendCommand('[Chrriis]JH_setDirty');" + LS +
            "            } else {" + LS +
            "              htmlContent = newHtmlContent;" + LS +
            "              htmlDirtyTracker = setTimeout('JH_checkDirty()', 1000);" + LS +
            "            }" + LS +
            "          } catch(e) {" + LS +
            "            htmlDirtyTracker = setTimeout('JH_checkDirty()', 1000);" + LS +
            "          }" + LS +
            "        }" + LS +
            "      }" + LS +
            "      function JH_clearDirtyIndicator() {" + LS +
            "        if(htmlDirtyTracker) {" + LS +
            "          clearTimeout(htmlDirtyTracker);" + LS +
            "        }" + LS +
            "        htmlContent = null;" + LS +
            "        if(isDirtyTrackingActive) {" + LS +
            "          htmlDirtyTracker = setTimeout('JH_checkDirty()', 1000);" + LS +
            "        }" + LS +
            "      }" + LS +
            "      function JH_setDirtyTrackingActive(isActive) {" + LS +
            "        isDirtyTrackingActive = isActive;" + LS +
            "        JH_clearDirtyIndicator();" + LS +
            "      }" + LS +
            "      function JH_setData (html) {" + LS +
            "        tinyMCE.get ('" + EDITOR_INSTANCE + "').setContent (decodeURIComponent (html));" + LS +
            "        JH_clearDirtyIndicator();" + LS +
            "      }" + LS +
            "      function JH_sendData () {" + LS +
            "        tinyMCE.get ('" + EDITOR_INSTANCE + "').save ();" + LS +
            "        document.jhtml_form.action = 'jhtml_sendData';" + LS +
            "        document.jhtml_form.submit ();" + LS +
            "      }" + LS +
            "      function JH_doSave () {" + LS +
            "        tinyMCE.get ('" + EDITOR_INSTANCE + "').save ();" + LS +
            "        document.jhtml_form.action = 'jhtml_save';" + LS +
            "        document.jhtml_form.submit ();" + LS +
            "        return false;" + LS +
            "      }" + LS +
            "      var opts = {" + LS +
            "        mode: 'exact'," + LS +
            "        elements: '" + EDITOR_INSTANCE + "'," + LS +
            "        theme: 'advanced'," + LS +
            "        save_onsavecallback : 'JH_doSave'," + LS +
            "        setup: function (ed) {" + LS +
            "          ed.onInit.add (function (ed) {" + LS +
            "            sendCommand ('[Chrriis]JH_setLoaded');" + LS +
            "          });" + LS +
            "        }" + LS +
            "      };" + LS +
            (customOptions != null? "      var addOpts = {" + LS + customOptions + LS + "      };" + LS + "      for (var x in addOpts) {" + LS + "        opts[x] = addOpts[x];" + LS + "      }" + LS: "") +
            "      tinyMCE.init (opts);" + LS +
            "      JH_clearDirtyIndicator();" + LS +
            "    </script>" + LS +
            "  </head>" + LS +
            "  <body>" + LS +
            "    <div id=\"debug\"></div>" + LS +
            "    <iframe style=\"display:none;\" name=\"j_iframe\"></iframe>" + LS +
            "    <form name=\"jhtml_form\" method=\"POST\" target=\"j_iframe\">" + LS +
            "      <textarea name=\"" + EDITOR_INSTANCE + "\" id=\"" + EDITOR_INSTANCE + "\" style=\"width:100%;height:100%\"></textarea>" + LS +
            "    </form>" + LS +
            "  </body>" + LS +
            "</html>" + LS;
          return getInputStream(content);
        }
      };
    }
    if("jhtml_save".equals(resourcePath)) {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          String html = JHTMLEditor.convertLinksToLocal(httpRequest.getHTTPPostDataArray()[0].getHeaderMap().get(EDITOR_INSTANCE));
          HTMLEditorSaveEvent e = null;
          for(HTMLEditorListener listener: htmlEditor.getHTMLEditorListeners()) {
            if(e == null) {
              e = new HTMLEditorSaveEvent(htmlEditor, html);
            }
            listener.saveHTML(e);
          }
        }
      });
      return new WebServerContent() {
        @Override
        public InputStream getInputStream() {
          String content =
            "<html>" + LS +
            "  <body>" + LS +
            "    Save successful." + LS +
            "  </body>" + LS +
            "</html>" + LS;
          return getInputStream(content);
        }
      };
    }
    if("jhtml_sendData".equals(resourcePath)) {
      String data = httpRequest.getHTTPPostDataArray()[0].getHeaderMap().get(EDITOR_INSTANCE);
      tempResult = data;
      return new WebServerContent() {
        @Override
        public InputStream getInputStream() {
          String content =
            "<html>" + LS +
            "  <body>" + LS +
            "    Send data successful." + LS +
            "  </body>" + LS +
            "</html>" + LS;
          return getInputStream(content);
        }
      };
    }
    return WebServer.getDefaultWebServer ().getURLContent(WebServer.getDefaultWebServer ().getClassPathResourceURL (JHTMLEditor.class.getName(), PACKAGE_PREFIX + resourcePath));
  }

  public void clearDirtyIndicator() {
    htmlEditor.getWebBrowser().executeJavascript("JH_clearDirtyIndicator();");
  }

  public void setDirtyTrackingActive(boolean isDirtyTrackingActive) {
    htmlEditor.getWebBrowser().executeJavascript("JH_setDirtyTrackingActive(" + isDirtyTrackingActive + ");");
  }

  private volatile Object tempResult;

  /**
   * Get the HTML content.
   * @return the HTML content.
   */
  public String getHTMLContent() {
    JWebBrowser webBrowser = htmlEditor.getWebBrowser();
    if(!webBrowser.isNativePeerInitialized()) {
      return "";
    }
    tempResult = this;
    webBrowser.executeJavascript("JH_sendData();");
    int timeout = Integer.parseInt(NSSystemPropertySWT.HTMLEDITOR_GETHTMLCONTENT_TIMEOUT.get("1500"));
    long start = System.currentTimeMillis();
    while(true) {
      EventDispatchUtils.sleepWithEventDispatch(new EventDispatchUtils.Condition() {
        public boolean getValue() {
          return tempResult != JHTMLEditorTinyMCE.this;
        }
      }, 50);
      if(tempResult != this) {
        return (String)tempResult;
      }
      if(System.currentTimeMillis() - start > timeout) {
        break;
      }
    }
    return null;
  }

  public void setHTMLContent(String html) {
//    webBrowser.executeJavascript("JH_setData('" + Utils.encodeURL(html) + "');");
    // There is a problem: IE crashes when it has the focus and is flooded with this message.
    // While waiting for an SWT fix, we use the workaround to disable the component which loses the focus.
    JWebBrowser webBrowser = htmlEditor.getWebBrowser();
    NativeComponent nativeComponent = webBrowser.getNativeComponent();
    boolean isEnabled = nativeComponent.isEnabled();
    nativeComponent.setEnabled(false);
    new Message().syncSend(true);
    webBrowser.executeJavascript("JH_setData('" + Utils.encodeURL(html) + "');");
    new Message().syncSend(true);
    nativeComponent.setEnabled(isEnabled);
  }

}
TOP

Related Classes of chrriis.dj.nativeswing.swtimpl.components.JHTMLEditorTinyMCE

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.