/*
* [JavaScript.java]
*
* Summary: Expands a reference to JavaScript inline. Included JavaScript text lives in embellishment directory.
*
* Copyright: (c) 2011-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
*
* Licence: This software may be copied and used freely for any purpose but military.
* http://mindprod.com/contact/nonmil.html
*
* Requires: JDK 1.8+
*
* Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
*
* Version History:
* 1.0 2011-12-01 initial version
*/
package com.mindprod.htmlmacros.macro;
import com.mindprod.fastcat.FastCat;
import com.mindprod.htmlmacros.support.Tools;
import com.mindprod.hunkio.HunkIO;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import static java.lang.System.*;
/**
* Expands a reference to JavaScript inline. Included JavaScript text lives in embellishment directory.
*
* The included JavaScript would normally include an HTML sandwich.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.0 2011-12-01 initial version
* @since 2011-12-01
*/
public final class JavaScript extends Macro
{
// JavaScript use includes:
// ClustrMaps link via ID, load file
// GoogleAdjustableSearch inline
// GoogleSiteSearch inline
// Google PlusOne links via ID
// Google AdSense inline + load
// Webrings inline + load
// If possible, loading should be moved from header to body to end of body.
/**
* how to use the macro
* include = expand contents of script inline.
* link = build a link to the script file inline.
* bottom = build a link to the script file at the very bottom of the page.
*/
private static final String USAGE = "\nJavaScript macro needs {include|link|bottom} {script.js} to include.";
/**
* cache previously read scripts
*/
private static final HashMap cachedScripts = new HashMap<>( 50 );
/**
* get the contents of the give script store in embellishments directory.
*
* @param scriptName name of file without directory but with trailing .js
*
* @return contents of the script
*/
static String getJavaScriptContents( final String scriptName )
{
String scriptContents = cachedScripts.get( scriptName );
if ( scriptContents != null )
{
return scriptContents;
}
else
{
final File scriptFile = Tools.toFileFromUPath( "embellishment/" + scriptName );
try
{
scriptContents = HunkIO.readEntireFile( scriptFile, HunkIO.UTF8 ).trim();
}
catch ( IOException e )
{
throw new IllegalArgumentException( e.getMessage() + " problem reading JavaScript file " + scriptName );
}
cachedScripts.put( scriptName, scriptContents );
return scriptContents;
}
}
/**
* get html markup for a Link to an given script in embellishments directory.
* The result can be placed inline or at the bottom.
*
* @param scriptName name of file without directory but with trailing .js
* or full http:/https: url.
* @param fileBeingDistributed target file where expanded macros go. May be null if scriptname is absolute URL.
*
* @return contents of the script
*/
static String getJavaScriptLink( final String scriptName, final boolean async, final boolean defer, File fileBeingDistributed )
{
final String url;
if ( scriptName.startsWith( "http" ) )
{
// script is on on the web somewhere
url = scriptName;
}
else
{
// script lives in mindprod/embellishment
url = Tools.relativeURL( "embellishment/" + scriptName, fileBeingDistributed );
}
final FastCat sb = new FastCat( 6 );
sb.append( "\n" );
return sb.toString();
}
/**
* expands a javascript inline.
*
* @param parms parsed params for the macro: async, bottom, defer, include, link the script name
* @param quiet true if want output suppressed.
* @param verbose @return expanded macro HTML
*
* @return text included from some file as result of this macro.
*/
public final String expandMacro( final String[] parms, final boolean quiet, final boolean verbose )
{
if ( !quiet )
{
// indicate we handled an JavaScript macro on the console
out.print( "S" );
}
if ( 2 <= parms.length && parms.length <= 4 )
{
throw new IllegalArgumentException( USAGE );
}
boolean async = false;
boolean bottom = false;
boolean defer = false;
boolean include = false;
boolean link = false;
for ( int i = 0; i < parms.length - 1; i++ )
{
String option = parms[ i ];
switch ( option )
{
case "async":
async = true;
break;
case "bottom":
bottom = true;
break;
case "defer":
defer = true;
break;
case "include":
include = true;
break;
case "link":
link = true;
break;
default:
throw new IllegalArgumentException( USAGE );
}
}
final String scriptName = parms[ parms.length - 1 ];
if ( include )
{
return getJavaScriptContents( scriptName );
}
if ( link )
{
return getJavaScriptLink( scriptName, async, defer, fileBeingDistributed );
}
if ( bottom )
{
Global.forBottom.append( getJavaScriptLink( scriptName, async, defer, fileBeingDistributed ) );
return new FastCat( "\n" ).toString();
}
throw new IllegalArgumentException( USAGE );
}
}