/* 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); } }