package org.vaadin.touchkit.settings;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.DocumentType;
import org.jsoup.nodes.Element;
import com.vaadin.server.BootstrapFragmentResponse;
import com.vaadin.server.BootstrapListener;
import com.vaadin.server.BootstrapPageResponse;
/**
* The ViewPortSettings class is responsible for configuring the viewport in the
* application bootstrap page.
*
* See the <a href=
* "http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html%23//apple_ref/doc/uid/TP40008193-SW6"
* >Apple developer documentation</a> for details.
*/
public class ViewPortSettings implements BootstrapListener {
private Boolean viewPortUserScalable = false;
private Float viewPortInitialScale = 1f;
private Float viewPortMinimumScale = null;
private Float viewPortMaximumScale = null;
private String viewPortWidth = null;
/**
* Sets whether the user should be allowed to zoom the content. The default
* value for TouchKit apps is false, as we expect that applications are
* designed for smaller/all devices.
* <p>
*
* @param viewPortUserScalable
* true to allow pinch-to-zoom
*/
public void setViewPortUserScalable(Boolean viewPortUserScalable) {
this.viewPortUserScalable = viewPortUserScalable;
}
/**
* @see #setViewPortUserScalable(Boolean)
*
* @return true if the view port is user scalable (pinch-to-zoom)
*/
public Boolean isViewPortUserScalable() {
return viewPortUserScalable;
}
/**
* Sets the initial scale of the viewport.
*
* @param viewPortInitialScale
* The initial scale of the viewport as a multiplier.
*/
public void setViewPortInitialScale(Float viewPortInitialScale) {
this.viewPortInitialScale = viewPortInitialScale;
}
/**
* @return the initial scale of the viewport as a multiplier or null if none
* set.
*/
public Float getViewPortInitialScale() {
return viewPortInitialScale;
}
/**
* Sets the maximum scale allowed for the user.
*
* @param viewPortMaximumScale
* the maximum scale allowed when zooming
*/
public void setViewPortMaximumScale(Float viewPortMaximumScale) {
this.viewPortMaximumScale = viewPortMaximumScale;
}
/**
* @return the maximum scale allowed for the user when zooming or null if
* none set.
*/
public Float getViewPortMaximumScale() {
return viewPortMaximumScale;
}
/**
* Sets the viewport width into which the client browsers should render the
* page. The value can be pixels or "device-width". The device width
* constant is used as a default as we expect TouchKit Applications to be
* designed for small devices. If the value is null, browsers try to figure
* out a proper viewport width by themselves.
*
* @param viewPortWidth
* the requested viewport width.
*/
public void setViewPortWidth(String viewPortWidth) {
this.viewPortWidth = viewPortWidth;
}
/**
* @return the requested viewport width or null if none set.
* @see #setViewPortWidth(String)
*/
public String getViewPortWidth() {
return viewPortWidth;
}
/**
* Sets the minimum scale allowed by the user.
*
* @param viewPortMinimumScale
* the minimum scale allowed when zooming.
*/
public void setViewPortMinimumScale(Float viewPortMinimumScale) {
this.viewPortMinimumScale = viewPortMinimumScale;
}
/**
* @return the minimum scale allowed when zooming.
* @see #setViewPortMinimumScale(Float)
*/
public Float getViewPortMinimumScale() {
return viewPortMinimumScale;
}
@Override
public void modifyBootstrapFragment(BootstrapFragmentResponse response) {
// NOP
}
@Override
public void modifyBootstrapPage(BootstrapPageResponse response) {
Document document = response.getDocument();
Element html = document.getElementsByTag("html").get(0);
Element head = document.getElementsByTag("head").get(0);
DocumentType doctype = (DocumentType) html.previousSibling();
DocumentType html5doc = new DocumentType("html", "", "", "");
doctype.replaceWith(html5doc);
Element element = document.createElement("meta");
element.attr("name", "viewport");
StringBuilder content = new StringBuilder();
boolean open = false;
open = addViewPortRule(content, open, "width", getViewPortWidth());
if (!isViewPortUserScalable()) {
open = addViewPortRule(content, open, "user-scalable", "no");
}
open = addViewPortRule(content, open, "initial-scale",
getViewPortInitialScale());
open = addViewPortRule(content, open, "maximum-scale",
getViewPortMaximumScale());
open = addViewPortRule(content, open, "minimum-scale",
getViewPortMaximumScale());
element.attr("content", content.toString());
head.appendChild(element);
// meta tag to disable gray tap highlights in WP8 (note, for some reason
// these do not appear in W8, not even RT)
// <meta name="msapplication-tap-highlight" content="no" />
element = document.createElement("meta");
element.attr("name", "msapplication-tap-highlight");
element.attr("content", "no");
head.appendChild(element);
}
private boolean addViewPortRule(StringBuilder content, boolean open,
String name, Object value) {
if (value == null) {
return open;
}
if (open) {
content.append(",");
}
content.append(name);
content.append("=");
content.append(value);
return true;
}
}