You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2017/03/21 22:23:38 UTC

[3/7] wicket git commit: WICKET-6286 ajax download

WICKET-6286 ajax download


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/5578e698
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/5578e698
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/5578e698

Branch: refs/heads/master
Commit: 5578e6982b93f81be23c56c8ece90b6f68440eb7
Parents: fd6befd
Author: Sven Meier <sv...@apache.org>
Authored: Wed Jan 4 00:00:01 2017 +0100
Committer: Sven Meier <sv...@apache.org>
Committed: Tue Mar 21 23:23:16 2017 +0100

----------------------------------------------------------------------
 .../examples/ajax/builtin/AjaxApplication.java  |   2 +-
 .../examples/ajax/builtin/AjaxDownloadPage.html |  41 +++
 .../examples/ajax/builtin/AjaxDownloadPage.java | 244 +++++++++++++++
 .../wicket/examples/ajax/builtin/Index.html     |   2 +
 .../wicket/extensions/ajax/AjaxDownload.java    | 295 +++++++++++++++++++
 .../extensions/ajax/wicket-ajaxdownload.js      |  60 ++++
 6 files changed, 643 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/5578e698/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
index 871fdbf..dd44b56 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
@@ -57,7 +57,7 @@ public class AjaxApplication extends WicketExampleApplication
 		mountPage("todo-list", TodoList.class);
 		mountPage("world-clock", WorldClockPage.class);
 		mountPage("upload", FileUploadPage.class);
-
+		mountPage("download", AjaxDownloadPage.class);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/wicket/blob/5578e698/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.html
new file mode 100644
index 0000000..2764b25
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<html xmlns:wicket="http://wicket.apache.org">
+<head>
+<wicket:head>
+    <style>
+    	.download-veil {
+    		position: absolute;
+    		left: 20%;
+    		right: 20%;
+    		color: white;
+    		background-color: darkorange;
+    		font-size: 40px;
+    		text-align: center;
+    	}
+
+    	.download-veil span {
+    		line-height: 128px;
+    	}
+    </style>
+</wicket:head>
+</head>
+<body>
+<wicket:extend>
+
+<p>
+This example demonstrates a <a wicket:id="download">download</a> initiated via Ajax.
+</p>
+
+<p>
+This download <a wicket:id="downloadFailure">fails</a>.
+</p>
+
+<p>
+A resource reference can be <a wicket:id="downloadReference">used too</a>.
+</p>
+
+<div wicket:id="downloading" class="download-veil"><span>Preparing download ...</span></div>
+
+</wicket:extend>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/wicket/blob/5578e698/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.java
new file mode 100644
index 0000000..a23368c
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxDownloadPage.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-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.apache.wicket.examples.ajax.builtin;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.extensions.ajax.AjaxDownload;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.request.http.flow.AbortWithHttpErrorCodeException;
+import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.request.resource.ResourceStreamResource;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.apache.wicket.util.resource.StringResourceStream;
+import org.apache.wicket.util.time.Duration;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Ajax download.
+ * 
+ * @author svenmeier
+ */
+public class AjaxDownloadPage extends BasePage
+{
+	private WebMarkupContainer downloadingContainer;
+
+	/**
+	 * Constructor
+	 */
+	public AjaxDownloadPage()
+	{
+		downloadingContainer = new WebMarkupContainer("downloading");
+		downloadingContainer.setOutputMarkupPlaceholderTag(true);
+		downloadingContainer.setVisible(false);
+		add(downloadingContainer);
+		
+		initDownload();
+		
+		initDownloadFailure();
+		
+		initDownloadReference();
+	}
+
+	private void initDownload()
+	{
+		IResource resource = new ResourceStreamResource() {
+			protected IResourceStream getResourceStream() {
+				// simulate delay
+				try
+				{
+					TimeUnit.MILLISECONDS.sleep(5000);
+				}
+				catch (InterruptedException e)
+				{
+				}
+				
+				return new StringResourceStream("downloaded via ajax");
+			};
+			
+		}.setFileName("File-from-IResource.txt").setContentDisposition(ContentDisposition.ATTACHMENT).setCacheDuration(Duration.NONE);
+		
+		final AjaxDownload download = new AjaxDownload(resource) {
+			
+			@Override
+			protected void onBeforeDownload(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(true);
+				target.add(downloadingContainer);
+			}
+
+			@Override
+			protected void onDownloadSuccess(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(false);
+				target.add(downloadingContainer);
+			}
+			
+			@Override
+			protected void onDownloadFailed(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(false);
+				target.add(downloadingContainer);
+			}
+		};
+		add(download);
+		
+		add(new AjaxLink<Void>("download")
+		{
+			@Override
+			public void onClick(AjaxRequestTarget target)
+			{
+				download.initiate(target);
+			}
+		});
+	}
+	
+	private void initDownloadFailure()
+	{
+		IResource resource = new ResourceStreamResource() {
+			protected IResourceStream getResourceStream() {
+				// simulate delay
+				try
+				{
+					TimeUnit.MILLISECONDS.sleep(2000);
+				}
+				catch (InterruptedException e)
+				{
+				}
+				
+				throw new AbortWithHttpErrorCodeException(500);
+			};
+			
+		}.setFileName("file").setContentDisposition(ContentDisposition.ATTACHMENT).setCacheDuration(Duration.NONE);
+		
+		final AjaxDownload download = new AjaxDownload(resource) {
+			
+			@Override
+			protected void onBeforeDownload(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(true);
+				target.add(downloadingContainer);
+			}
+
+			@Override
+			protected void onDownloadSuccess(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(false);
+				target.add(downloadingContainer);
+			}
+			
+			@Override
+			protected void onDownloadFailed(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(false);
+				target.add(downloadingContainer);
+				
+				target.appendJavaScript("alert('Download failed');");
+			}
+		};
+		add(download);
+		
+		add(new AjaxLink<Void>("downloadFailure")
+		{
+			@Override
+			public void onClick(AjaxRequestTarget target)
+			{
+				download.initiate(target);
+			}
+		});
+	}
+	
+	private void initDownloadReference()
+	{
+		ResourceReference reference = new ResourceReference("referenceToResource") {
+			@Override
+			public IResource getResource()
+			{
+				return new StaticResource();
+			}
+		};
+		
+		final AjaxDownload download = new AjaxDownload(reference) {
+			
+			@Override
+			protected void onBeforeDownload(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(true);
+				target.add(downloadingContainer);
+			}
+
+			@Override
+			protected void onDownloadSuccess(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(false);
+				target.add(downloadingContainer);
+			}
+			
+			@Override
+			protected void onDownloadFailed(AjaxRequestTarget target)
+			{
+				downloadingContainer.setVisible(false);
+				target.add(downloadingContainer);
+			}
+		};
+		add(download);
+		
+		add(new AjaxLink<Void>("downloadReference")
+		{
+			@Override
+			public void onClick(AjaxRequestTarget target)
+			{
+				download.initiate(target);
+			}
+		});
+	}
+	
+	public static class StaticResource extends ResourceStreamResource {
+
+		StaticResource() {
+			setFileName("File-from-ResourceReference");
+			setContentDisposition(ContentDisposition.ATTACHMENT);
+			setCacheDuration(Duration.NONE);
+		}
+		
+		@Override
+		public void respond(Attributes attributes)
+		{
+			AjaxDownload.markCompleted(attributes);
+			
+			super.respond(attributes);
+		}
+		
+		@Override
+		protected IResourceStream getResourceStream()
+		{
+			// simulate delay
+			try
+			{
+				TimeUnit.MILLISECONDS.sleep(5000);
+			}
+			catch (InterruptedException e)
+			{
+			}
+			
+			return new StringResourceStream("downloaded via ajax with resource reference");
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/5578e698/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
index 4813972..2da2160 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
@@ -35,6 +35,8 @@
 <a href="TodoList.html">Todo list Example</a>: shows ajax todo list page without writing any JavaScript
 <br/><br/>
 <a href="WorldClockPage.html">World Clock Example</a>: demonstrates a single component with AjaxTimerBehavior updating multiple components
+<br/><br/>
+<a href="AjaxDownloadPage.html">Ajax Download</a>: download initiated via Ajax
 </wicket:link>
 
 </wicket:extend>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/5578e698/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/AjaxDownload.java
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/AjaxDownload.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/AjaxDownload.java
new file mode 100644
index 0000000..a879d5b
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/AjaxDownload.java
@@ -0,0 +1,295 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-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.apache.wicket.extensions.ajax;
+
+import javax.annotation.Resource;
+import javax.servlet.http.Cookie;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.IResourceListener;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.json.JSONObject;
+import org.apache.wicket.ajax.json.JsonFunction;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
+import org.apache.wicket.request.Response;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.http.WebResponse;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+import org.apache.wicket.request.resource.IResource;
+import org.apache.wicket.request.resource.IResource.Attributes;
+import org.apache.wicket.request.resource.ResourceReference;
+import org.apache.wicket.resource.JQueryPluginResourceReference;
+import org.apache.wicket.util.lang.Args;
+
+/**
+ * Download resources via Ajax.
+ * <p>
+ * Usage:
+ * 
+ * <pre>
+ * final AjaxDownload download = new AjaxDownload(resource);
+ * add(download);
+ * 
+ * add(new AjaxButton("download")
+ * {
+ * 	&#64;Override
+ * 	protected void onSubmit(AjaxRequestTarget target, Form&lt;?> form)
+ * 	{
+ * 		download.initiate(target);
+ * 	}
+ * });
+ * </pre>
+ * 
+ * @author svenmeier
+ */
+public class AjaxDownload extends AbstractDefaultAjaxBehavior
+{
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * Name of parameter used to transfer the download identifier to the resource.
+	 *
+	 * @see #markCompleted(Attributes)
+	 */
+	private static final String RESOURCE_PARAMETER_NAME = "wicket-ajaxdownload";
+
+	private static final ResourceReference JS = new JQueryPluginResourceReference(
+		AjaxDownload.class, "wicket-ajaxdownload.js");
+
+	private final ResourceReference resourceReference;
+
+	private final ResourceBehavior resourceBehavior;
+
+	private PageParameters resourceParameters;
+
+	/**
+	 * Download of a {@link Resource}.
+	 * 
+	 * @param resource
+	 *            resource to download
+	 */
+	public AjaxDownload(IResource resource)
+	{
+		Args.notNull(resource, "resource");
+		this.resourceBehavior = new ResourceBehavior(resource);
+		this.resourceReference = null;
+	}
+
+	/**
+	 * Download of a {@link ResourceReference}.
+	 * <p>
+	 * The {@link IResource} returned by {@link ResourceReference#getResource()} must call
+	 * {@link #markCompleted(Attributes)} when responding, otherwise the callback
+	 * {@link #onDownloadSuccess(AjaxRequestTarget)} will not work.
+	 * 
+	 * @param reference
+	 *            reference to resource to download
+	 */
+	public AjaxDownload(ResourceReference reference)
+	{
+		this(reference, null);
+	}
+
+	/**
+	 * Download of a {@link ResourceReference}.
+	 * <p>
+	 * The {@link IResource} returned by {@link ResourceReference#getResource()} must call
+	 * {@link #markCompleted(Attributes)} when responding, otherwise the callback
+	 * {@link #onDownloadSuccess(AjaxRequestTarget)} will not work.
+	 * 
+	 * @param reference
+	 *            reference to resource to download
+	 * @param resourceParameters
+	 *            parameters for the resource
+	 */
+	public AjaxDownload(ResourceReference reference, PageParameters resourceParameters)
+	{
+		this.resourceBehavior = null;
+
+		this.resourceReference = Args.notNull(reference, "reference");
+		this.resourceParameters = resourceParameters;
+	}
+
+	@Override
+	protected void onBind()
+	{
+		super.onBind();
+
+		if (resourceBehavior != null)
+		{
+			getComponent().add(resourceBehavior);
+		}
+	}
+
+	@Override
+	protected void onUnbind()
+	{
+		super.onUnbind();
+
+		if (resourceBehavior != null)
+		{
+			getComponent().remove(resourceBehavior);
+		}
+	}
+
+	/**
+	 * Call this method to initiate the download.
+	 * 
+	 * @param target
+	 *            the initiating Ajax target
+	 */
+	public void initiate(AjaxRequestTarget target)
+	{
+		if (getComponent() == null)
+		{
+			throw new WicketRuntimeException("not bound to a component");
+		}
+
+		((WebResponse)RequestCycle.get().getResponse()).clearCookie(cookie(getName()));
+
+		CharSequence url;
+		if (resourceBehavior == null)
+		{
+			if (resourceReference.canBeRegistered())
+			{
+				getComponent().getApplication().getResourceReferenceRegistry()
+					.registerResourceReference(resourceReference);
+			}
+
+			PageParameters parameters = new PageParameters();
+			if (resourceParameters != null)
+			{
+				parameters.mergeWith(resourceParameters);
+			}
+			parameters.set(RESOURCE_PARAMETER_NAME, getName());
+
+			url = getComponent().getRequestCycle()
+				.urlFor(new ResourceReferenceRequestHandler(resourceReference, parameters));
+		}
+		else
+		{
+			url = resourceBehavior.getUrl();
+		}
+
+		JSONObject settings = new JSONObject();
+		settings.put("attributes", new JsonFunction(renderAjaxAttributes(getComponent())));
+		settings.put("name", getName());
+		settings.put("url", url);
+
+		target.appendJavaScript(String.format("Wicket.AjaxDownload.initiate(%s);", settings));
+
+		onBeforeDownload(target);
+	}
+
+	protected void onBeforeDownload(AjaxRequestTarget target)
+	{
+	}
+
+	protected void onDownloadSuccess(AjaxRequestTarget target)
+	{
+	}
+
+	protected void onDownloadFailed(AjaxRequestTarget target)
+	{
+	}
+
+	@Override
+	public void renderHead(Component component, IHeaderResponse response)
+	{
+		super.renderHead(component, response);
+
+		response.render(JavaScriptHeaderItem.forReference(JS));
+	}
+
+	@Override
+	protected void respond(AjaxRequestTarget target)
+	{
+		String result = getComponent().getRequest().getRequestParameters().getParameterValue("result").toOptionalString();
+		if ("success".equals(result)) {
+			onDownloadSuccess(target);
+		} else if ("failed".equals(result)) {
+			onDownloadFailed(target);
+		}
+	}
+
+	/**
+	 * Identifying name of this behavior.
+	 */
+	private String getName()
+	{
+		return String.format("wicket-ajaxdownload-%s-%s", getComponent().getMarkupId(),
+			getComponent().getBehaviorId(this));
+	}
+
+	/**
+	 * The behavior responding with the actual resource.
+	 */
+	private class ResourceBehavior extends Behavior implements IResourceListener
+	{
+		private final IResource resource;
+
+		private ResourceBehavior(IResource resource)
+		{
+			this.resource = Args.notNull(resource, "resource");
+		}
+
+		@Override
+		public void onResourceRequested()
+		{
+			final RequestCycle requestCycle = RequestCycle.get();
+			final Response response = requestCycle.getResponse();
+			((WebResponse) response).addCookie(cookie(getName()));
+
+			Attributes a = new Attributes(requestCycle.getRequest(), response, null);
+
+			resource.respond(a);
+		}
+
+		public CharSequence getUrl()
+		{
+			return getComponent().urlFor(this, IResourceListener.INTERFACE, null);
+		}
+	}
+
+	/**
+	 * Mark a resource as complete.
+	 * <p>
+	 * Has to be called from {@link IResource#respond(Attributes)} when downloaded via
+	 * {@link #AjaxDownload(IResource)}.
+	 * 
+	 * @param attributes
+	 *            resource attributes
+	 */
+	public static void markCompleted(IResource.Attributes attributes)
+	{
+		String cookieName = attributes.getParameters().get(RESOURCE_PARAMETER_NAME).toString();
+
+		((WebResponse)attributes.getResponse()).addCookie(cookie(cookieName));
+	}
+
+	private static Cookie cookie(String name)
+	{
+		Cookie cookie = new Cookie(name, "complete");
+		cookie.setPath("/");
+		return cookie;
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/5578e698/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/wicket-ajaxdownload.js
----------------------------------------------------------------------
diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/wicket-ajaxdownload.js b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/wicket-ajaxdownload.js
new file mode 100644
index 0000000..52471df
--- /dev/null
+++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/wicket-ajaxdownload.js
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-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.
+ */
+;(function (undefined) {
+	'use strict';
+
+	if (!window.Wicket) {
+		window.Wicket = {};
+	}
+
+	if (Wicket.AjaxDownload) {
+		return;
+	}
+
+	Wicket.AjaxDownload = {
+		initiate : function(settings) {
+			
+			var frame = jQuery("<iframe>").hide().prop("src", settings.url).appendTo("body");
+			
+			var checkComplete = function() {
+				var result;
+				
+				if (document.cookie.indexOf(settings.name + '=') > -1) {
+					result = "success";
+				} else {
+					var html = frame.contents().find('body').html();
+					if (html && html.length) {
+						result = "failed";
+					}
+				}
+
+				if (result) {
+					setTimeout(function() { frame.remove(); }, 0);
+					
+					settings.attributes.ep = settings.attributes.ep || {};
+					settings.attributes.ep['result'] = result;
+					Wicket.Ajax.ajax(settings.attributes);
+				} else {
+					setTimeout(checkComplete, 100);
+				}
+			}; 
+			
+			checkComplete();
+		}
+	}; 
+	
+})();
\ No newline at end of file