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: SimpleEditor.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", "${yahoo.yui}/container/container_core${yahoo.yui.mode}.js",
043 "${yahoo.yui}/menu/menu${yahoo.yui.mode}.js",
044 "${yahoo.yui}/button/button${yahoo.yui.mode}.js",
045 "${yahoo.yui}/editor/simpleeditor${yahoo.yui.mode}.js",
046 "yui-image-uploader26.js",
047 "SimpleEditor.js"})
048 public class SimpleEditor extends AbstractYahooComponent
049 {
050 private static String INTERNAL_EVENT = "internalUploaded";
051 private static String UPLOAD_EVENT = "uploaded";
052
053 /**
054 * Allow image uploads.
055 */
056 @Parameter(required = false, defaultPrefix = BindingConstants.PROP, value = "false")
057 private boolean allowUploads;
058
059 /**
060 * RenderSupport to get unique client side id.
061 */
062 @Environmental
063 private JavaScriptSupport javascriptSupport;
064
065 /**
066 * For blocks, messages, crete actionlink, trigger event.
067 */
068 @Inject
069 private ComponentResources resources;
070
071 @Inject
072 private MultipartDecoder decoder;
073
074 @InjectContainer
075 private Field clientElement;
076
077 /**
078 * Tapestry render phase method.
079 * Start a tag here, end it in afterRender
080 *
081 * @param writer the markup writer
082 */
083 void beginRender(MarkupWriter writer)
084 {
085 if (!(clientElement instanceof TextArea))
086 throw new RuntimeException("Mixin 'yui/SimpleEditor' must have a TextArea as parent component");
087 }
088
089
090 /**
091 * Tapestry render phase method. End a tag here.
092 *
093 * @param writer the markup writer
094 */
095 void afterRender(MarkupWriter writer)
096 {
097 JSONObject options = new JSONObject();
098
099 configure(options);
100
101 options.put("disabled", clientElement.isDisabled());
102 options.put("handleSubmit", true);
103
104 Link uploadEventLink = null;
105 if (allowUploads)
106 uploadEventLink = resources.createEventLink(INTERNAL_EVENT);
107
108 javascriptSupport.addScript("new Ck.YuiSimpleEditor('%s', '%s', %s);", clientElement.getClientId(), uploadEventLink, options);
109 }
110
111 StreamResponse onInternalUploaded()
112 {
113 UploadedFile uploaded = decoder.getFileUpload("fileElement");
114
115 final Holder<JSONObject> valueHolder = Holder.create();
116
117 ComponentEventCallback callback = new ComponentEventCallback<JSONObject>()
118 {
119 public boolean handleResult(JSONObject result)
120 {
121 valueHolder.put(result);
122 return true;
123 }
124 };
125
126 resources.triggerEvent(UPLOAD_EVENT, new Object[]{uploaded}, callback);
127
128 return new TextStreamResponse("text/html", valueHolder.get().toString());
129 }
130
131 /**
132 * Invoked to allow subclasses to further configure the parameters passed to this mixin's javascript
133 * options. Subclasses may override this method to configure additional features of this mixin.
134 * <p/>
135 * This implementation does nothing.
136 *
137 * @param options option object
138 */
139 protected void configure(JSONObject options)
140 {
141 }
142 }