001 /*
002 * Apache License
003 * Version 2.0, January 2004
004 * http://www.apache.org/licenses/
005 *
006 * Copyright 2008-2010 by chenillekit.org
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 */
014
015 package org.chenillekit.tapestry.core.mixins.yui;
016
017 import org.apache.tapestry5.BindingConstants;
018 import org.apache.tapestry5.ComponentEventCallback;
019 import org.apache.tapestry5.ComponentResources;
020 import org.apache.tapestry5.Field;
021 import org.apache.tapestry5.Link;
022 import org.apache.tapestry5.MarkupWriter;
023 import org.apache.tapestry5.StreamResponse;
024 import org.apache.tapestry5.annotations.Environmental;
025 import org.apache.tapestry5.annotations.Import;
026 import org.apache.tapestry5.annotations.InjectContainer;
027 import org.apache.tapestry5.annotations.Parameter;
028 import org.apache.tapestry5.corelib.components.TextArea;
029 import org.apache.tapestry5.internal.util.Holder;
030 import org.apache.tapestry5.ioc.annotations.Inject;
031 import org.apache.tapestry5.json.JSONObject;
032 import org.apache.tapestry5.services.javascript.JavaScriptSupport;
033 import org.apache.tapestry5.upload.services.MultipartDecoder;
034 import org.apache.tapestry5.upload.services.UploadedFile;
035 import org.apache.tapestry5.util.TextStreamResponse;
036 import org.chenillekit.tapestry.core.base.AbstractYahooComponent;
037
038 /**
039 * @version $Id: Editor.java 675 2010-07-30 14:49:17Z homburgs $
040 */
041 @Import(stack = {"yahoo"}, stylesheet = {"${yahoo.yui}/assets/skins/sam/skin.css"},
042 library = {"../../Chenillekit.js",
043 "${yahoo.yui}/container/container_core${yahoo.yui.mode}.js",
044 "${yahoo.yui}/menu/menu${yahoo.yui.mode}.js",
045 "${yahoo.yui}/button/button${yahoo.yui.mode}.js",
046 "${yahoo.yui}/connection/connection${yahoo.yui.mode}.js",
047 "${yahoo.yui}/editor/editor${yahoo.yui.mode}.js",
048 "yui-image-uploader26.js",
049 "Editor.js"})
050 public class Editor extends AbstractYahooComponent
051 {
052 private static String INTERNAL_EVENT = "internalUploaded";
053 private static String UPLOAD_EVENT = "uploaded";
054
055 /**
056 * Allow image uploads.
057 */
058 @Parameter(required = false, defaultPrefix = BindingConstants.PROP, value = "false")
059 private boolean allowUploads;
060
061 /**
062 * RenderSupport to get unique client side id.
063 */
064 @Environmental
065 private JavaScriptSupport javascriptSupport;
066
067 /**
068 * For blocks, messages, crete actionlink, trigger event.
069 */
070 @Inject
071 private ComponentResources resources;
072
073 @Inject
074 private MultipartDecoder decoder;
075
076 @InjectContainer
077 private Field clientElement;
078
079 /**
080 * Tapestry render phase method.
081 * Start a tag here, end it in afterRender
082 *
083 * @param writer the markup writer
084 */
085 void beginRender(MarkupWriter writer)
086 {
087 if (!(clientElement instanceof TextArea))
088 throw new RuntimeException("Mixin 'yui/Editor' must have a TextArea as parent component");
089 }
090
091
092 /**
093 * Tapestry render phase method. End a tag here.
094 *
095 * @param writer the markup writer
096 */
097 void afterRender(MarkupWriter writer)
098 {
099 JSONObject options = new JSONObject();
100
101 configure(options);
102
103 options.put("disabled", clientElement.isDisabled());
104 options.put("handleSubmit", true);
105
106 Link uploadEventLink = null;
107 if (allowUploads)
108 uploadEventLink = resources.createEventLink(INTERNAL_EVENT);
109
110 javascriptSupport.addScript("new Ck.YuiEditor('%s', '%s', %s);", clientElement.getClientId(), uploadEventLink, options);
111 }
112
113 StreamResponse onInternalUploaded()
114 {
115 UploadedFile uploaded = decoder.getFileUpload("fileElement");
116
117 final Holder<JSONObject> valueHolder = Holder.create();
118
119 ComponentEventCallback callback = new ComponentEventCallback<JSONObject>()
120 {
121 public boolean handleResult(JSONObject result)
122 {
123 valueHolder.put(result);
124 return true;
125 }
126 };
127
128 resources.triggerEvent(UPLOAD_EVENT, new Object[]{uploaded}, callback);
129
130 return new TextStreamResponse("text/html", valueHolder.get().toString());
131 }
132
133 /**
134 * Invoked to allow subclasses to further configure the parameters passed to this mixin's javascript
135 * options. Subclasses may override this method to configure additional features of this mixin.
136 * <p/>
137 * This implementation does nothing.
138 *
139 * @param options option object
140 */
141 protected void configure(JSONObject options)
142 {
143 }
144 }