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    }