/* JQueryRenderPatch.java
Purpose:
Description:
History:
Sun Jan 17 11:48:04 TST 2010, Created by tomyeh
Copyright (C) 2010 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.zkplus.liferay;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Used to patch the rendering result of a ZK portlet for Liferay.
* When using ZK portlets with Liferay under Internet Explorer, we have
* to delay the processing at the client a bit. This patch assume
* "/zkau/web/js/zk.wpd" has loaded by Liferay, please refer to
* www.liferay.com document for configuration
*
* <p>To use it, you have to specify a library property called
* ""org.zkoss.zk.portlet.PageRenderPatch.class" with this class's name
* ("org.zkoss.zkplus.liferay.JQueryRenderCachedPatch").
*
* @author tomyeh, sam
* @since 5.0.1
*/
public class JQueryRenderCachedPatch extends JQueryRenderPatch {
private static final Logger log = LoggerFactory.getLogger(JQueryRenderCachedPatch.class);
protected String getBrowserDelay() {
return "zk.ie6_ || zk.ie7_ ? 1300 : 100";
}
/**
* Append CSS link to head, and remove zk.wpd script
*/
protected String[] processHtml(String html) {
boolean isAppendCSS = false;
StringBuffer script = new StringBuffer(
"<script>function _zkCSS(uri){var e=document.createElement(\"LINK\");e.rel=\"stylesheet\";e.type=\"text/css\";e.href=uri;document.getElementsByTagName(\"HEAD\")[0].appendChild(e);};");
Pattern cssPattern = Pattern.compile("<link[^>]+href=[\"']?([^'\"> ]+)[\"']?[^>]*(/>|>\\s*</link>)");
Pattern scriptPattern = Pattern
.compile("<script[^>]+src=[\"']?([^'\"> ]+/zk.wpd)[\"']?[^>]*(/>|>\\s*</script>)");
StringBuffer buffer = new StringBuffer();
int parseStart = 0, scriptStart = 0, scriptEnd = 0;
for (scriptStart = html.indexOf("<script"); scriptStart != -1;) {
isAppendCSS = extractCSS(html, parseStart, scriptStart, cssPattern, script, buffer) ? true : isAppendCSS;
scriptEnd = html.indexOf("</script>", scriptStart);
if (scriptEnd == -1)
break;
scriptEnd += "</script>".length();
removeScript(html, scriptStart, scriptEnd, scriptPattern, script, buffer);
if ((scriptStart = html.indexOf("<script", scriptEnd)) != -1)
parseStart = scriptEnd;
else {
buffer.append(html.substring(scriptEnd, html.length()));
break;
}
}
String[] ret = { "", html };
if (isAppendCSS) {
script.append("</script>");
ret[0] = script.toString();
ret[1] = buffer.toString();
}
return ret;
}
private static boolean extractCSS(String html, int start, int end, Pattern cssPattern, StringBuffer scriptBuffer,
StringBuffer htmlBuffer) {
if (!(start < end))
return false;
boolean isAppendCSS = false;
Matcher m = cssPattern.matcher(html.substring(start, end));
while (m.find()) {
isAppendCSS = true;
scriptBuffer.append("_zkCSS('" + m.group(1) + "');");
m.appendReplacement(htmlBuffer, "");
}
m.appendTail(htmlBuffer);
return isAppendCSS;
}
private static void removeScript(String html, int start, int end, Pattern scriptPattern, StringBuffer scriptBuffer,
StringBuffer htmlBuffer) {
String scriptBlock = html.substring(start, end);
Matcher m = scriptPattern.matcher(scriptBlock);
if (m.find())
m.appendReplacement(scriptBuffer, "");
else
htmlBuffer.append(scriptBlock);
}
}