001/* Interface for parameters that provide web export content.
002
003 Copyright (c) 2011-2014 The Regents of the University of California.
004 All rights reserved.
005 Permission is hereby granted, without written agreement and without
006 license or royalty fees, to use, copy, modify, and distribute this
007 software and its documentation for any purpose, provided that the above
008 copyright notice and the following two paragraphs appear in all copies
009 of this software.
010
011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015 SUCH DAMAGE.
016
017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022 ENHANCEMENTS, OR MODIFICATIONS.
023
024 PT_COPYRIGHT_VERSION_2
025 COPYRIGHTENDKEY
026
027 */
028
029package ptolemy.vergil.basic.export.web;
030
031import ptolemy.actor.gui.style.TextStyle;
032import ptolemy.data.BooleanToken;
033import ptolemy.data.expr.StringParameter;
034import ptolemy.kernel.util.IllegalActionException;
035import ptolemy.kernel.util.NameDuplicationException;
036import ptolemy.kernel.util.NamedObj;
037
038///////////////////////////////////////////////////////////////////
039//// IconScript
040/**
041 * A parameter associating a JavaScript with an icon in model.
042 * This class assumes that the icon becomes an area in an image map
043 * on an HTML page. This parameter provides a way to specify a
044 * script to execute when that area in the image map is the target
045 * of some UI event, such as mouse movement or clicking or keyboard
046 * action. A typical use of this would be to set its string value
047 * to something like "foo(args)" where foo is a JavaScript function
048 * defined in the <i>script</i> parameter.
049 * You can also provide HTML text to insert into the start or
050 * end sections of the container's container's web page.
051 *
052 * @author Edward A. Lee
053 * @version $Id$
054 * @since Ptolemy II 10.0
055 * @Pt.ProposedRating Red (cxh)
056 * @Pt.AcceptedRating Red (cxh)
057 */
058public class IconScript extends Script implements WebExportable {
059
060    /** Create an instance of this parameter.
061     *  @param container The container.
062     *  @param name The name.
063     *  @exception IllegalActionException If the superclass throws it.
064     *  @exception NameDuplicationException If the superclass throws it.
065     */
066    public IconScript(NamedObj container, String name)
067            throws IllegalActionException, NameDuplicationException {
068        super(container, name);
069
070        startText = new StringParameter(this, "startText");
071        TextStyle style = new TextStyle(startText, "style");
072        style.height.setExpression("5");
073
074        endText = new StringParameter(this, "endText");
075        style = new TextStyle(endText, "style");
076        style.height.setExpression("5");
077
078        jQueryLibraries = new StringParameter(this, "jQueryLibraries");
079        style = new TextStyle(jQueryLibraries, "style");
080        style.height.setExpression("5");
081    }
082
083    ///////////////////////////////////////////////////////////////////
084    ////                         parameters                        ////
085
086    /** Text to insert in the end section of the
087     *  web page. This text will be inserted exactly once.
088     */
089    public StringParameter endText;
090
091    /** Text to insert in the start section of the
092     *  web page. This text will be inserted exactly once.
093     */
094    public StringParameter startText;
095
096    /** jQuery libraries to be included in the HEAD section of the html file
097     * The path to the libraries will be copied in the same order as given.
098     */
099    public StringParameter jQueryLibraries;
100
101    ///////////////////////////////////////////////////////////////////
102    ////                         public methods                    ////
103
104    /** Provide content to the specified web exporter to be
105     *  included in a web page.
106     *  This class provides an area attribute, and also
107     *  the value of <i>script</i>, <i>startText</i>,
108     *  and <i>endText</i>, if any has been provided.
109     *  These value get inserted into the container's container's
110     *  corresponding HTML sections, where the <i>script</i>
111     *  is inserted inside a JavaScript HTML element.
112     *
113     *  @param exporter The web exporter to add content to
114     *  @exception IllegalActionException If evaluating the value
115     *   of this parameter fails.
116     */
117
118    //FIXME:  From DefaultIconScript - what did previous file do?
119    //*  If the <i>eventType</i> parameter is "default", then
120    //*  remove all previously defined defaults and use the global
121    //*  defaults.
122    @Override
123    protected void _provideElements(WebExporter exporter)
124            throws IllegalActionException {
125
126        // All content covered?
127        // 1) the script itself, and
128        // 2) the method call to invoke the script
129        // 3) data, and
130        // 4) <divs> that the script will change the content of -> target <div>
131
132        WebElement webElement;
133        String jQueryImports = jQueryLibraries.stringValue();
134        if (!jQueryImports.trim().equals("")) {
135            //Create WebElement for jQueryLibraries and add the exporter.
136            //content should only be added once(<onceOnly->true)
137            webElement = WebElement.createWebElement(getContainer(),
138                    "jQueryLibraries", "jQueryLibraries");
139            webElement.setParent(WebElement.HEAD);
140            webElement.setExpression(jQueryImports);
141            exporter.defineElement(webElement, true);
142        }
143
144        String scriptValue;
145        // Check whether the user wants to insert the evaluated expression
146        // or the exact text for the script
147        if (evaluateScript.getToken().isEqualTo(BooleanToken.TRUE)
148                .booleanValue()) {
149            scriptValue = script.stringValue();
150        } else {
151            scriptValue = script.getExpression();
152        }
153
154        if (!scriptValue.trim().equals("")) {
155            // Create WebElement for script and add to exporter.
156            // Content should only be added once (onceOnly -> true).
157            webElement = WebElement.createWebElement(getContainer(), "script",
158                    "script");
159            webElement.setParent(WebElement.HEAD);
160            webElement.setExpression("<script type=\"" + getMimeType() + "\">\n"
161                    + scriptValue + "\n</script>\n");
162            exporter.defineElement(webElement, true);
163        }
164
165        String startTextValue = startText.stringValue();
166        if (!startTextValue.trim().equals("")) {
167            // Create WebElement for start text and add to exporter.
168            // Content should only be added once (onceOnly -> true).
169            webElement = WebElement.createWebElement(getContainer(),
170                    "startText", "startText");
171            webElement.setParent(WebElement.START);
172            webElement.setExpression(startTextValue);
173            exporter.defineElement(webElement, true);
174        }
175
176        String endTextValue = endText.stringValue();
177        if (!endTextValue.trim().equals("")) {
178            // Create WebElement for end text and add to exporter.
179            // Content should only be added once (onceOnly -> true).
180            webElement = WebElement.createWebElement(getContainer(), "endText",
181                    "endText");
182            webElement.setParent(WebElement.END);
183            webElement.setExpression(endTextValue);
184            exporter.defineElement(webElement, true);
185        }
186    }
187
188    /** Provide method call to invoke script that can be included as an
189     *  attribute of an HTML tag, e.g. onclick="runFunction()" in
190     *  &lt;button onclick="runFunction()"/&gt;
191     *
192     *  @param exporter  The web exporter to which to write content.
193     *  @exception IllegalActionException If the eventType cannot be obtained,
194     *  the web attribute cannot be created or set.
195     */
196    @Override
197    protected void _provideAttributes(WebExporter exporter)
198            throws IllegalActionException {
199
200        // FIXME:  Support multiple events in the future.  E.g. onclick() and
201        // ontap() might call the same Javascript method.
202        WebAttribute webAttribute;
203
204        NamedObj container = getContainer();
205        if (container != null) {
206            String eventTypeValue = eventType.stringValue();
207            if (!eventTypeValue.trim().equals("")) {
208                // Create WebAttribute for event and add to exporter.
209                // Content should only be added once (onceOnly -> true).
210                webAttribute = WebAttribute.createWebAttribute(getContainer(),
211                        eventTypeValue + "WebAttribute", eventTypeValue);
212                webAttribute.setExpression(stringValue());
213                exporter.defineAttribute(webAttribute, true);
214            }
215        }
216    }
217}