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 java.util.List; 032 033import ptolemy.kernel.util.IllegalActionException; 034import ptolemy.kernel.util.NameDuplicationException; 035import ptolemy.kernel.util.NamedObj; 036import ptolemy.kernel.util.Settable; 037import ptolemy.util.StringUtilities; 038 039/////////////////////////////////////////////////////////////////// 040//// ParameterDisplayIconScript 041/** 042 * A parameter specifying default JavaScript actions to associate 043 * with icons in model. Putting this into a model causes an action 044 * to be associated with each icon (as specified by the <i>include</i> 045 * and <i>instancesOf</i> parameters) that, on moving the mouse over 046 * the icon, displays in a table the parameters of the corresponding 047 * Ptolemy II object. The table is displayed in a tooltip. 048 * <p> 049 * This parameter is designed to be included in a Configuration file 050 * to specify global default behavior for export to Web. Just put 051 * it in the top level of the Configuration, and this behavior 052 * will be provided by default. 053 * 054 * @author Edward A. Lee 055 * @version $Id$ 056 * @since Ptolemy II 10.0 057 * @Pt.ProposedRating Red (cxh) 058 * @Pt.AcceptedRating Red (cxh) 059 */ 060public class ParameterDisplayIconScript extends DefaultIconScript { 061 062 /** Create an instance of this parameter. 063 * @param container The container. 064 * @param name The name. 065 * @exception IllegalActionException If the superclass throws it. 066 * @exception NameDuplicationException If the superclass throws it. 067 */ 068 public ParameterDisplayIconScript(NamedObj container, String name) 069 throws IllegalActionException, NameDuplicationException { 070 super(container, name); 071 } 072 073 /////////////////////////////////////////////////////////////////// 074 //// public methods //// 075 076 /** Override base class since content here should only be added if 077 * it does not exist already. 078 * 079 * @return False, since default content should only be added if no content 080 * already exists 081 */ 082 @Override 083 public boolean isOverwriteable() { 084 return false; 085 } 086 087 /** Get an HTML table describing the parameters of the object. 088 * @param object The Ptolemy object to return a table for. 089 * @return An HTML table displaying the parameter values for the 090 * specified object, or the string "Has no parameters" if the 091 * object has no parameters. 092 */ 093 public static String getParameterTable(NamedObj object) { 094 StringBuffer table = new StringBuffer(); 095 List<Settable> parameters = object.attributeList(Settable.class); 096 boolean hasParameter = false; 097 for (Settable parameter : parameters) { 098 if (parameter.getVisibility().equals(Settable.FULL)) { 099 hasParameter = true; 100 table.append("<tr><td>"); 101 table.append(parameter.getName()); 102 table.append("</td><td>"); 103 String expression = parameter.getExpression(); 104 expression = StringUtilities.escapeForXML(expression); 105 expression = expression.replaceAll("'", "\\\\'"); 106 // Bizarrely, escaping all characters except newlines work. 107 // Newlines need to be converted to \n. 108 // No idea why so many backslashes are required below. 109 expression = expression.replaceAll(" ", "\\\\\\n"); 110 111 if (expression.length() == 0) { 112 expression = " "; 113 } 114 table.append(expression); 115 table.append("</td><td>"); 116 String value = parameter.getValueAsString(); 117 value = StringUtilities.escapeForXML(value); 118 value = value.replaceAll("'", "\\\\'"); 119 // Bizarrely, escaping all characters except newlines work. 120 // Newlines need to be converted to \n. 121 // No idea why so many backslashes are required below. 122 value = value.replaceAll(" ", "\\\\\\n"); 123 124 if (value.length() == 0) { 125 value = " "; 126 } 127 table.append(value); 128 table.append("</td></tr>"); 129 } 130 } 131 if (hasParameter) { 132 table.insert(0, 133 "<table border=\"1\">" + "<tr><td><b>Parameter</b></td>" 134 + "<td><b>Expression</b></td>" 135 + "<td><b>Value</b></td></tr>"); 136 table.append("</table>"); 137 } else { 138 table.append("Has no parameters."); 139 } 140 return table.toString(); 141 } 142 143 /////////////////////////////////////////////////////////////////// 144 //// protected methods //// 145 146 /** Override the base class to provide the parameter table 147 * for the specified object. 148 * Provide default content to the specified web exporter to be 149 * included in a web page for the container of this object for 150 * objects that do not override onmouseover. 151 * This class provides an area attribute of type 152 * "onmouseover" that displays the parameter values 153 * of the object and one of type "onmouseout" that 154 * clears that display. 155 * 156 * @param exporter The exporter to which to provide the content. 157 * @param object The object which provides the content. 158 * @exception IllegalActionException If there is a problem creating the content 159 * or if there is a name duplication with the created attributes 160 */ 161 @Override 162 protected void _provideDefaultAttributes(NamedObj object, 163 WebExporter exporter) throws IllegalActionException { 164 165 WebAttribute webAttribute; 166 167 String command = "<h2>" + object.getName() + "</h2>" 168 + getParameterTable(object); 169 170 // Create WebAttribute for the class "tooltip". 171 webAttribute = WebAttribute.appendToWebAttribute(object, 172 "classWebAttribute", "class", "tooltip"); 173 exporter.defineAttribute(webAttribute, true); 174 175 // Content of the tooltip. 176 webAttribute = WebAttribute.createWebAttribute(object, 177 "titleWebAttribute", "title"); 178 webAttribute.setExpression(command); 179 exporter.defineAttribute(webAttribute, true); 180 } 181 182 /** Provide default content to the specified web exporter to be 183 * included in a web page for the container of this object for 184 * objects that do not override onmouseover. This class provides 185 * an HTML table containing parameter names and values, plus a 186 * placeholder <div> tag which the script writes 187 * information in upon onmouseover(). 188 * 189 * @param exporter The exporter to which to provide the content. 190 * @exception IllegalActionException If evaluating the value 191 * of this parameter fails. 192 */ 193 @Override 194 protected void _provideElements(WebExporter exporter) 195 throws IllegalActionException { 196 // FIXME: How to do this, from old comments? 197 //* If the <i>eventType</i> parameter is "default", then 198 //* remove all previously defined defaults and use the global 199 //* defaults. 200 201 WebElement webElement; 202 203 // Add content from IconScript (DefaultIconScript does not override 204 // _provideElements) 205 super._provideElements(exporter); 206 207 // Define the JavaScript command writeText. Script with this name 208 // should only be included once (onceOnly -> true) 209 /* Replaced by tooltipster 210 webElement = WebElement.createWebElement(getContainer(), 211 "writeTextScriptWebElement", "writeTextScript"); 212 webElement.setParent(WebElement.HEAD); 213 webElement 214 .setExpression("<script type=\"text/javascript\">\n" 215 + "function writeText(text) {\n" 216 + " document.getElementById(\"afterImage\").innerHTML = text;\n" 217 + "};\n" + "</script>"); 218 exporter.defineElement(webElement, true); 219 */ 220 221 // Define the JavaScript command to initialize tooltipster, 222 // the JQuery library being used to display parameters. Script with this name 223 // should only be included once (onceOnly -> true) 224 webElement = WebElement.createWebElement(getContainer(), 225 "tooltipsterScriptWebElement", "tooltipster"); 226 webElement.setParent(WebElement.HEAD); 227 webElement.setExpression("<script type=\"text/javascript\">\n" 228 + "$(document).ready(function() {\n" 229 + " $('.tooltip').tooltipster({\n" 230 + " contentAsHTML: true\n" + " });\n" + "});\n" 231 + "</script>"); 232 exporter.defineElement(webElement, true); 233 234 // Put a destination paragraph in the end section of the HTML. 235 webElement = WebElement.createWebElement(getContainer(), 236 "afterImageWebElement", "afterImage"); 237 webElement.setParent(WebElement.END); 238 webElement.setExpression("<div id=\"afterImage\">\n" 239 + " <script type=\"text/javascript\">\n" 240 + " writeText('Mouse over the icons to see their parameters. " 241 + "Click on composites and plotters to reveal their contents (if provided).');\n" 242 + " </script>\n" + " <noscript>\n" 243 + " Your browser does not support JavaScript so moving the mouse\n" 244 + " over the actors will not display their parameters. To enable\n" 245 + " JavaScript, consult the security preferences of your browser.\n" 246 + " <br/>See <a href=\"http://support.microsoft.com/gp/howtoscript\"><code>http://support.microsoft.com/gp/howtoscript</code></a> for details.\n" 247 + " </noscript>\n" + "</div>"); 248 exporter.defineElement(webElement, true); 249 } 250}