Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
$URL: https://source.sakaiproject.org/svn/jsf/tags/sakai-10.0/jsf-widgets/src/java/org/sakaiproject/jsf/renderer/InputRichTextRenderer.java $ $Id: InputRichTextRenderer.java 120900 2013-03-07 20:21:44Z ottenhoff@longsight.com $ Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 The Sakai Foundation Licensed under the Educational Community License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.opensource.org/licenses/ECL-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /
 
 
 package org.sakaiproject.jsf.renderer;
 
 
 
 import java.util.*;

Formerly RichTextEditArea.java

Renders a rich text editor and toolbar within an HTML "textarea" element.

The textarea is decorated using the HTMLArea JavaScript library.

HTMLArea is a free, customizable online editor. It works inside your browser. It uses a non-standard feature implemented in Internet Explorer 5.5 or better for Windows and Mozilla 1.3 or better (any platform), therefore it will only work in one of these browsers.

HTMLArea is copyright InteractiveTools.com and released under a BSD-style license. HTMLArea is created and developed upto version 2.03 by InteractiveTools.com. Version 3.0 developed by Mihai Bazon for InteractiveTools. It contains code sponsored by other companies as well.

Copyright: Copyright (c) 2004 Sakai

Author(s):
cwen@iu.edu
Ed Smiley esmiley@stanford.edu (modifications)
Version:
$Id: InputRichTextRenderer.java 120900 2013-03-07 20:21:44Z ottenhoff@longsight.com $
 
 public class InputRichTextRenderer extends Renderer
 {
   private static final String SCRIPT_PATH;
   private static final String HTMLAREA_SCRIPT_PATH;
   private static final String RESOURCE_PATH;
   private static final String TOOLBAR_SCRIPT_NONE;
   private static final String TOOLBAR_SCRIPT_SMALL;
   private static final String TOOLBAR_SCRIPT_MEDIUM;
   
   private static final String TOOLBAR_SCRIPT_LARGE;
   private static final int DEFAULT_WIDTH_PX;
   private static final int DEFAULT_HEIGHT_PX;
   private static final int DEFAULT_COLUMNS;
   private static final int DEFAULT_ROWS;
   private static final String INSERT_IMAGE_LOC;
   private static final MessageFormat LIST_ITEM_FORMAT_HTML =
      new MessageFormat("\"{0}\" : \"<a href=''{1}''>{0}</a>\"");
   private static final MessageFormat LIST_ITEM_FORMAT_FCK =
      new MessageFormat("[\"{0}\", \"{1}\"]");
 
   private static final Log log = LogFactory.getLog(InputRichTextRenderer.class);
 
   // we have static resources for our script path and built-in toolbars etc.
   static {
     = cr.get("inputRichTextScript");
     = cr.get("inputRichTextHTMLArea");
     = cr.get("resources");
     = makeToolbarScript(cr.get("inputRichText_none"));
     = makeToolbarScript(cr.get("inputRichText_small"));
     = makeToolbarScript(cr.get("inputRichText_medium"));
     = makeToolbarScript(cr.get("inputRichText_large"));
     = Integer.parseInt(cr.get("inputRichTextDefaultWidthPx").trim());
    /*SAK-20809 if an erant white space is left after the value this could throw a
     * number format exception so we trim it
    */
     = Integer.parseInt(cr.get("inputRichTextDefaultHeightPx").trim());
     = Integer.parseInt(cr.get("inputRichTextDefaultTextareaColumns").trim());
     = Integer.parseInt(cr.get("inputRichTextDefaultTextareaRows").trim());
     = "/" +  + "/" + cr.get("inputRichTextFileInsertImage");
  }
  public boolean supportsComponentType(UIComponent component)
  {
    return (component instanceof org.sakaiproject.jsf.component.InputRichTextComponent);
  }
  public void encodeBegin(FacesContext contextUIComponent component)
      throws IOException
  {
    if (!component.isRendered())
    {
      return;
    }
    String contextPath =
    String clientId = component.getClientId(context);
    ResponseWriter writer = context.getResponseWriter();
    String value = null;
    if (component instanceof UIInput)
        value = (String) ((UIInputcomponent).getSubmittedValue();
    if (value == null && component instanceof ValueHolder)
        value = (String) ((ValueHoldercomponent).getValue();
    // SAK-23313
    // The rich-text editor will interpret a string like &lt;tag&gt; as a real tag
    // So we double-escape the ampersand to create &amp;lt; so CKEditor displays this as text
    if (value!=null) {
    	java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("&([^\\s])");
    	value = pattern.matcher(value).replaceAll("&amp;$1");
    }
    ///////////////////////////////////////////////////////////////////////////
    // attributes
    ///////////////////////////////////////////////////////////////////////////
//  If true, only the textarea will be rendered.  Defaults to false.
//  If true, the rich text toolbar  and external HTMLArea JavaScript will NOT.
    String textareaOnly = (String) RendererUtil.getAttribute(contextcomponent"textareaOnly");
//    Specify toolbar from among a number precanned lists of command buttons.
//    Allowed values are: "none", "small", "medium", "large".
     String buttonSet = (String) RendererUtil.getAttribute(contextcomponent"buttonSet");
//  Comma delimited list of toolbar command buttons registered with component.
    String buttonList = (String) RendererUtil.getAttribute(contextcomponent"buttonList");
    

Todo:
need to do something with extensions.
//  URL to an external JavaScript file with additional JavaScript
    String javascriptLibraryExtensionURL =
        (String) RendererUtil.getAttribute(contextcomponent"javascriptLibraryExtensionURL");
//   The URL to the directory of the HTMLArea JavaScript library.
    String javascriptLibraryURL =
        (String) RendererUtil.getAttribute(contextcomponent"javascriptLibraryURL");
//  If true show XPath at bottom of editor.  Default is true.
    String showXPath = (String) RendererUtil.getAttribute(contextcomponent"showXPath");
    showXPath = RendererUtil.makeSwitchString(showXPathtruetruetruefalsefalsetrue);
    ///////////////////////////////////////////////////////////////////////////
    // set up dimensions
    int widthPx = ;
    int heightPx = ;
    int textareaColumns = ;
    int textareaRows = ;
    try
    {
      Integer cols = Integer.parseInt("" + RendererUtil.getAttribute(contextcomponent"cols"));
      Integer rows = Integer.parseInt("" + RendererUtil.getAttribute(contextcomponent"rows"));
      if (cols != nulltextareaColumns = cols.intValue();
      if (rows != nulltextareaRows = rows.intValue();
      
      // Width of the widget (in pixel units).
      // If this attribute is not specified, the width is controlled by the 'cols' attribute.
      Integer width = (Integer) RendererUtil.getAttribute(contextcomponent"width");
      if (width != nullwidthPx = width.intValue();
      // Height of the widget (in pixel units).
      // If this attribute is not specified, the width is controlled by the 'rows' attribute.
      Integer height = (Integer) RendererUtil.getAttribute(contextcomponent"height");
      if (height != nullheightPx = height.intValue();
    }
    catch (Exception ex)
    {
      //default, whatever goes awry
      if (.isDebugEnabled()) .debug(ex);  
    }
    if (widthPx ==  && textareaColumns != )
       widthPx = (*textareaColumns)/;
    if (heightPx ==  && textareaRows != )
       heightPx = (*textareaRows)/;
    Locale locale = Locale.getDefault();
	ServerConfigurationService serverConfigurationService = (ServerConfigurationService)ComponentManager.get(ServerConfigurationService.class.getName());
    String editor = serverConfigurationService.getString("wysiwyg.editor");
    
    String collectionBase = (String) RendererUtil.getAttribute(contextcomponent"collectionBase");
    String collectionId = "";
    if (collectionBase != null) {
        collectionId="collectionId: '"+collectionBase.replaceAll("\"","\\\"")+"'";
    }
    
    writer.write("<table border=\"0\"><tr><td>");
    writer.write("<textarea name=\"" + clientId + "_inputRichText\" id=\"" + clientId + "_inputRichText\"");
    if (textareaColumns > 0) writer.write(" cols=\""+textareaColumns+"\"");
    if (textareaRows > 0) writer.write(" rows=\""+textareaRows+"\"");
    writer.write(">");
    if (value != null)
       writer.write((Stringvalue);
    writer.write("</textarea>");
    
    if (!"true".equals(textareaOnly))
    {
    writer.write("<script type=\"text/javascript\">sakai.editor.launch('" + clientId + "_inputRichText', {"+collectionId+"}, '" + widthPx + "','" + heightPx + "');</script>");
    }
    writer.write("</td></tr></table>\n");
    /*
    if(editor != null && !editor.equalsIgnoreCase("FCKeditor"))
    {
      // Render JavaScripts.
      writeExternalScripts(locale, writer);
      // Render base textarea.
      writeTextArea(clientId, value, textareaRows, textareaColumns, writer);
      // Make textarea rich text (unless textareaOnly is true).
      if (!"true".equals(textareaOnly))
      {
        String toolbarScript;
        if (buttonList != null)
        {
          toolbarScript = makeToolbarScript(buttonList);
        }
        else
        {
          toolbarScript = getStandardToolbarScript(buttonSet);
        }
        // hook up configuration object
        writeConfigurationScript(context, component, clientId, toolbarScript, widthPx, heightPx, showXPath, locale, writer);
      }
    }
    else
    {
    	ToolManager toolManager = (ToolManager)ComponentManager.get(ToolManager.class.getName());
    	ContentHostingService contentHostingService = (ContentHostingService)ComponentManager.get(ContentHostingService.class.getName());
       //not as slick as the way htmlarea is rendered, but the difference in functionality doesn't all
       //make sense for FCK at this time since it's already got the ability to insert files and such.
       String collectionBase = (String) RendererUtil.getAttribute(context, component, "collectionBase");
       String collectionId = null;
       String connector = "/sakai-fck-connector/filemanager/connector";
       if (collectionBase != null) 
       {
         collectionId = collectionBase;
         connector += collectionBase;
       }
       else
       {
         collectionId = contentHostingService.getSiteCollection(toolManager.getCurrentPlacement().getContext());
       }
       writer.write("<table border=\"0\"><tr><td>");
       writer.write("<textarea name=\"" + clientId + "_inputRichText\" id=\"" + clientId + "_inputRichText\"");
       if (textareaColumns > 0) writer.write(" cols=\""+textareaColumns+"\"");
       if (textareaRows > 0) writer.write(" rows=\""+textareaRows+"\"");
       writer.write(">");
       if (value != null)
          writer.write((String) value);
       writer.write("</textarea>");
       RendererUtil.writeExternalJSDependencies(context, writer, "inputrichtext.jsf.fckeditor.js", "/library/editor/FCKeditor/fckeditor.js");
       //writer.write("<script type=\"text/javascript\" src=\"/library/editor/FCKeditor/fckeditor.js\"></script>\n");
       writer.write("<script type=\"text/javascript\" language=\"JavaScript\">\n");
       String attachmentVar = "attachment" + createSafeRandomNumber();
       boolean hasAttachments = false;
       Object attchedFiles = RendererUtil.getAttribute(context,  component, "attachedFiles");
       if (attchedFiles != null && getSize(attchedFiles) > 0) {
          writeFilesArray(writer, attachmentVar, attchedFiles, LIST_ITEM_FORMAT_FCK, false);
          writer.write("\n");
          hasAttachments = true;
       }
       writer.write("function chef_setupformattedtextarea(textarea_id){\n");
       writer.write("var oFCKeditor = new FCKeditor(textarea_id);\n");
       writer.write("oFCKeditor.BasePath = \"/library/editor/FCKeditor/\";\n");
       if (widthPx < 0)
         widthPx = 600;
       if (heightPx < 0)
         heightPx = 400;
       //FCK's toolset is larger then htmlarea and this prevents tools from ending up with all toolbar
       //and no actual editing area.
       if (heightPx < 200)
         heightPx = 200;
       writer.write("oFCKeditor.Width  = \"" + widthPx + "\" ;\n");
       writer.write("oFCKeditor.Height = \"" + heightPx + "\" ;\n");
       writer.write("\n\t\tvar collectionId = \"" + collectionId  + "\";");
       writer.write("\n\toFCKeditor.Config['ImageBrowserURL'] = oFCKeditor.BasePath + " +
             "\"editor/filemanager/browser/default/browser.html?Connector=" + connector + "&Type=Image&CurrentFolder=\" + collectionId;");
       writer.write("\n\toFCKeditor.Config['LinkBrowserURL'] = oFCKeditor.BasePath + " +
             "\"editor/filemanager/browser/default/browser.html?Connector=" + connector + "&Type=Link&CurrentFolder=\" + collectionId;");
       writer.write("\n\toFCKeditor.Config['FlashBrowserURL'] = oFCKeditor.BasePath + " +
             "\"editor/filemanager/browser/default/browser.html?Connector=" + connector + "&Type=Flash&CurrentFolder=\" + collectionId;");
       writer.write("\n\toFCKeditor.Config['ImageUploadURL'] = oFCKeditor.BasePath + " +
             "\"" + connector + "?Type=Image&Command=QuickUpload&Type=Image&CurrentFolder=\" + collectionId;");
       writer.write("\n\toFCKeditor.Config['FlashUploadURL'] = oFCKeditor.BasePath + " +
             "\"" + connector + "?Type=Flash&Command=QuickUpload&Type=Flash&CurrentFolder=\" + collectionId;");
       writer.write("\n\toFCKeditor.Config['LinkUploadURL'] = oFCKeditor.BasePath + " +
             "\"" + connector + "?Type=File&Command=QuickUpload&Type=Link&CurrentFolder=\" + collectionId;");
       writer.write("\n\n\toFCKeditor.Config['CurrentFolder'] = collectionId;");
       boolean resourceSearch = EditorConfiguration.enableResourceSearch();
       if(resourceSearch)
       {
       	// need to set document.__pid to placementId
       	String placementId = toolManager.getCurrentPlacement().getId();
       	writer.write("\t\tdocument.__pid=\"" + placementId + "\";\n");
       	
       	// need to set document.__baseUrl to baseUrl
       	String baseUrl = serverConfigurationService.getToolUrl() + "/" + Web.escapeUrl(placementId);
       	writer.write("\t\tdocument.__baseUrl=\"" + baseUrl + "\";\n");
      	writer.write("\n\toFCKeditor.Config['CustomConfigurationsPath'] = \"/library/editor/FCKeditor/config_rs.js\";\n");
       }
       else
       {
      	 writer.write("\n\toFCKeditor.Config['CustomConfigurationsPath'] = \"/library/editor/FCKeditor/config.js\";\n");
       }
       if (hasAttachments) {
          writer.write("\n\n\toFCKeditor.Config['AttachmentsVariable'] = \"" + attachmentVar  + "\";");
          writer.write("\n\n\toFCKeditor.ToolbarSet = \"Attachments\";");
       }
       writer.write("oFCKeditor.ReplaceTextarea();\n");
       writer.write("} \n");
       writer.write("</script>\n");
       writer.write("<script type=\"text/javascript\" defer=\"1\">chef_setupformattedtextarea('"+clientId+"_inputRichText');</script>");
       writer.write("</td></tr></table>\n");
    }
    */
  }

  
Return the config script portion for a standard button set.

Parameters:
buttonSet
Returns:
  private String  getStandardToolbarScript(String buttonSet) {
    String toolbarScript;
    if ("none".equals(buttonSet))
    {
      toolbarScript = ;
    }
    else if ("small".equals(buttonSet))
    {
      toolbarScript = ;
    }
    else if ("medium".equals(buttonSet))
    {
      toolbarScript = ;
    }
    else if ("large".equals(buttonSet))
    {
      toolbarScript = ;
    }
    else
    {
      toolbarScript = ;
    }
    return toolbarScript;
  }

  
Write out HTML rextarea

Parameters:
clientId
value the textarrea value
writer
Throws:
java.io.IOException
  private void writeTextArea(String clientIdString valueint rowsint cols,
    ResponseWriter writerthrows IOException {
  	// wrap the textarea in a table, so that the HTMLArea toolbar doesn't bleed to the
  	// edge of the screen.
  	writer.write("<table border=\"0\"><tr><td>\n");
    writer.write("<textarea name=\"");
    writer.write(clientId);
    writer.write("_inputRichText\" id=\"");
    writer.write(clientId);
    writer.write("_inputRichText\"");
    writer.write(" rows=\"" + rows + "\"");
    writer.write(" cols=\"" + cols + "\"");
    writer.write(">" + value + "</textarea>\n");
    writer.write("</td></tr></table>\n");
  }

  

Parameters:
contextPath
writer
Throws:
java.io.IOException
Todo:
do these as a document.write after testing if done
  protected void writeExternalScripts(Locale localeResponseWriter writer)
      throws IOException {
    writer.write("<script type=\"text/javascript\">var _editor_url = \"" +
                 "/" +  + "/" +  + "/" +
                 "\";</script>\n");
    writer.write("<script type=\"text/javascript\" src=\"" + "/" +
                  + "/" +  + "/" +
                 "htmlarea.js\"></script>\n");
    writer.write("<script type=\"text/javascript\" src=\"" + "/" +
                  + "/" +  + "/" +
                 "dialog.js\"></script>\n");
    writer.write("<script type=\"text/javascript\" src=\"" + "/" +
                  + "/" +  + "/" +
                 "popupwin.js\"></script>\n");
    writer.write("<script type=\"text/javascript\" src=\"" + "/" +
                  + "/" +  + "/" +
                 "lang/en.js\"></script>\n");
    String language = locale.getLanguage();
    if (!..getLanguage().equals(language))
    {
      writer.write("<script type=\"text/javascript\" src=\"" + "/" +
         + "/"     +  + "/" +
        "lang/" + language + ".js\"></script>\n");
    }
    writer.write("<script type=\"text/javascript\" src=\"" + "/" +
       + "/" +  + "\"></script>\n");
  }

  
Standard decode method.

Parameters:
context
component
  public void decode(FacesContext contextUIComponent component)
  {
    if( RendererUtil.isDisabledOrReadonly(contextcomponent)) return;
    if (null == context || null == component
        || !(component instanceof org.sakaiproject.jsf.component.InputRichTextComponent))
    {
      throw new IllegalArgumentException();
    }
    String clientId = component.getClientId(context);
    Map requestParameterMap = context.getExternalContext()
        .getRequestParameterMap();
    String newValue = (StringrequestParameterMap.get(clientId + "_inputRichText");
    comp.setSubmittedValue(newValue);
  }

  
Write configuration script

Parameters:
clientId the client id
toolbar the toolbar configuration string (i.e from makeToolbarScript())
widthPx columns
heightPx rows
  protected void writeConfigurationScript(FacesContext contextUIComponent componentString clientId,
    String toolbarint widthPxint heightPxString showXPathLocale localeResponseWriter writer)
    throws IOException
  {
    // script creates unique Config object
    String configVar = "config" + createSafeRandomNumber();
    writer.write("<script type=\"text/javascript\">\n");
    writer.write("  sakaiSetLanguage(\"" + locale.getDisplayLanguage() + "\");");
    writer.write("  var " + configVar + "=new HTMLArea.Config();\n");
    writer.write("  sakaiRegisterButtons(" + configVar + ");\n");
    writer.write("  " + configVar + ".toolbar = " + toolbar + ";\n");
    writer.write("  " + configVar + ".width=\"" + widthPx + "px\";\n");
    writer.write("  " + configVar + ".height=\"" + heightPx + "px\";\n");
    writer.write("  " + configVar + ".statusBar=" + showXPath + ";\n");
    writeAdditionalConfig(contextcomponentconfigVarclientId,
          toolbarwidthPxheightPxlocale,  writer);
    writer.write(  "sakaiSetupRichTextarea(\"");
    writer.write(clientId);
    writer.write("_inputRichText\"," + configVar + ");\n");
    writer.write("</script>\n");
  }

   
subclasses can override to provide additonal configuration such as add buttons, etc

Parameters:
context
component
configVar
clientId
toolbar
widthPx
heightPx
locale
writer
   protected void writeAdditionalConfig(FacesContext contextUIComponent componentString configVar,
      String clientIdString toolbarint widthPxint heightPxLocale localeResponseWriter writer)
      throws IOException{
      writeAttachedFiles(contextcomponentconfigVarwritertoolbar);
      registerWithParent(componentconfigVarclientId);
   }
   protected void writeAttachedFiles(FacesContext contextUIComponent component,
                                     String configVarResponseWriter writerString toolbarthrows IOException {
      Object attchedFiles = RendererUtil.getAttribute(context,  component"attachedFiles");
      if (attchedFiles != null && getSize(attchedFiles) > 0) {
         String arrayVar = configVar + "_Resources";
         writeFilesArray(writerarrayVarattchedFilestrue);
         writer.write(  "sakaiRegisterResourceList(");
         writer.write(configVar + ",'" +  + "'," + arrayVar);
         writer.write(");\n");
         writer.write("  " + configVar + ".toolbar = " + addToolbar(toolbar) + ";\n");
      }
   }
   protected void writeFilesArray(ResponseWriter writerString arrayVar,
                                  Object attchedFilesMessageFormat format,
                                  boolean includeLabelthrows IOException {
      StringWriter buffer = new StringWriter();
      char startChar = '[';
      char endChar = ']';
      if (format == ) {
         startChar = '{';
         endChar = '}';
      }
      buffer.write("  var " + arrayVar + " = "+startChar+"\n");
      if (includeLabel) {
         buffer.write("\"select a file url to insert\" : \"\"");
      }
      if (attchedFiles instanceof Map) {
         buffer.write(outputFiles((Map)attchedFilesformat, !includeLabel));
      }
      else {
         buffer.write(outputFiles((List)attchedFilesformat, !includeLabel));
      }
      buffer.write(endChar + ";\n");
      String result = buffer.toString();
      writer.write(result);
   }
   protected void registerWithParent(UIComponent componentString configVarString clientId) {
      InitObjectContainer parentContainer = null;
      UIComponent testContainer = component.getParent();
      while (testContainer != null) {
         if (testContainer instanceof InitObjectContainer) {
            parentContainer = (InitObjectContainer)testContainer;
            String script = " resetRichTextEditor(\"" + clientId +
               "_inputRichText\"," + configVar + ");\n";
            parentContainer.addInitScript(script);
         }
         testContainer = testContainer.getParent();
      }
   }
   protected String outputFiles(Map mapMessageFormat formatboolean first) {
	   StringBuffer sb = new StringBuffer();
      for (Iterator i=map.entrySet().iterator();i.hasNext();) {
         Map.Entry entry = (Map.Entry)i.next();
         if (!first) {
            sb.append(',');
         }
         else {
            first = false;
         }
         format.format(new Object[]{entry.getValue(), entry.getKey()}, sbnull);
      }
      return sb.toString();
   }
   protected String outputFiles(List listMessageFormat formatboolean first) {
	   StringBuffer sb = new StringBuffer();
      for (Iterator i=list.iterator();i.hasNext();) {
         Object value = i.next();
         String url;
         String label;
         if (value instanceof SelectItem) {
            SelectItem item = (SelectItem)value;
            url = item.getValue().toString();
            label = item.getLabel();
         }
         else {
            url = value.toString();
            label = value.toString();
         }
         if (!first) {
            sb.append(',');
         }
         else {
            first = false;
         }
         format.format(new Object[]{labelurl}, sbnull);
      }
      return sb.toString();
   }
   protected int getSize(Object attchedFiles) {
      if (attchedFiles instanceof Map) {
         return ((Map)attchedFiles).size();
      }
      else {
         return ((List)attchedFiles).size();
      }
   }
   protected String addToolbar(String toolbar) {
      int pos = toolbar.lastIndexOf("]");
      toolbar = toolbar.substring(0, pos) +
         ",[\"filedropdown\", \"insertfile\", ]" +
         toolbar.substring(pos);
      return toolbar;
   }

   
Built toolbar part of configuration script for a list of button commands.

Parameters:
buttonList csv list of buttons
Returns:
String, e.g.
    [["fontname", "space",... ]] etc.
 
  private static String makeToolbarScript(String buttonList) {
    StringBuilder script = new StringBuilder();
    String q = "\"";
    script.append("[[");
    StringTokenizer st = new StringTokenizer(buttonList","false);
    while (st.hasMoreTokens())
    {
      String command = st.nextToken();
      if (!"linebreak".equals(command))
      {
        script.append(q + command + q + ", ");
      }
      else
      {
        script.append("],[");
      }
    }
    script.append("]]");
    return script.toString();
  }
  
     return "" + (long)(Math.floor(Math.random() * 1000000000));
  }
New to GrepCode? Check out our FAQ X