com.sksamuel.jqm4gwt.JQMContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jqm4gwt-standalone Show documentation
Show all versions of jqm4gwt-standalone Show documentation
jqm4gwt bundled with all of its dependencies
The newest version!
package com.sksamuel.jqm4gwt;
import java.util.Date;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.core.client.JsDate;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
/**
* @author Stephen K Samuel [email protected] 9 Jul 2011 12:57:43
*
*
The {@link JQMContext} provides methods that facilitate interaction
* between GWT, JQM and the DOM.
*
*/
public class JQMContext {
public static interface WidgetDefaults {
/**
* Called after a widget becomes attached to the browser's document.
*/
void loaded(Widget w);
}
private static WidgetDefaults widgetDefaults;
private static TransitionIntf> defaultTransition = Transition.FADE;
private static TransitionIntf> defaultDialogTransition = Transition.POP;
private static boolean defaultTransistionDirection = false;
private static boolean defaultChangeHash = true;
// FIXME: it can work only if called from mobileinit event handler (i.e. before jqm is loaded)
/*
*/
public static native void disableHashListening() /*-{
$wnd.$.mobile.hashListeningEnabled = false;
}-*/;
// FIXME: it can work only if called from mobileinit event handler (i.e. before jqm is loaded)
public static native void disablePushStateEnabled() /*-{
$wnd.$.mobile.pushStateEnabled = false;
}-*/;
/**
* Appends the given {@link JQMPage} to the DOM so that JQueryMobile is
* able to manipulate it and render it. This should only be done once per
* page, otherwise duplicate HTML would be added to the DOM and this would
* result in elements with overlapping IDs.
*
*/
public static void attachAndEnhance(JQMContainer container) {
if (container == null) return;
RootPanel p = RootPanel.get();
if (p == null) return;
p.add(container);
enhance(container);
container.setEnhanced(true);
}
/**
* Programatically change the displayed page to the given {@link JQMPage}
* instance. This uses the default transition which is Transition.FADE
*/
public static void changePage(JQMContainer container) {
changePage(container, false/*dialog*/);
}
public static void changePage(JQMContainer container, boolean dialog) {
TransitionIntf> t = container.getTransition();
if (t == null) {
t = dialog || JQMCommon.isDataDialog(container.getElement())
? getDefaultDialogTransition() : getDefaultTransition();
}
changePage(container, dialog, t);
}
/**
* Change the displayed page to the given {@link JQMPage} instance using
* the supplied transition.
*/
public static void changePage(JQMContainer container, TransitionIntf> transition) {
changePage(container, false/*dialog*/, transition);
}
public static void changePage(JQMContainer container, boolean dialog, TransitionIntf> transition) {
changePage(container, dialog, transition, defaultTransistionDirection);
}
/**
* Change the displayed page to the given {@link JQMPage} instance using
* the supplied transition and reverse setting.
*/
public static void changePage(JQMContainer container, TransitionIntf> transition, boolean reverse) {
changePage(container, false/*dialog*/, transition, reverse);
}
public static void changePage(JQMContainer container, boolean dialog, TransitionIntf> transition,
boolean reverse) {
Mobile.changePage("#" + container.getId(), transition, reverse, defaultChangeHash, dialog);
}
private static void enhance(JQMContainer c) {
render(c.getElement());
}
public static TransitionIntf> getDefaultTransition() {
String val = getDefaultTransitionImpl();
TransitionIntf> t = defaultTransition.parseJqmValue(val);
return t != null ? t : Transition.FADE;
}
private static native String getDefaultTransitionImpl() /*-{
return $wnd.$.mobile.defaultPageTransition;
}-*/;
public static TransitionIntf> getDefaultDialogTransition() {
String val = getDefaultDialogTransitionImpl();
TransitionIntf> t = defaultDialogTransition.parseJqmValue(val);
return t != null ? t : Transition.POP;
}
private static native String getDefaultDialogTransitionImpl() /*-{
return $wnd.$.mobile.defaultDialogTransition;
}-*/;
/**
* Return the pixel offset of an element from the left of the document.
* This can also be thought of as the y coordinate of the top of the
* elements bounding box.
*
* @param id
* the id of the element to find the offset
*/
public static native int getLeft(String id) /*-{
return $wnd.$("#" + id).offset().left;
}-*/;
/**
* Return the pixel offset of an element from the top of the document.
* This can also be thought of as the x coordinate of the left of the
* elements bounding box.
*
* @param id
* the id of the element to find the offset
*/
public static native int getTop(String id) /*-{
return $wnd.$("#" + id).offset().top;
}-*/;
public static native int getTop(Element elt) /*-{
return $wnd.$(elt).offset().top;
}-*/;
public static native void initializePage() /*-{
$wnd.$.mobile.initializePage();
}-*/;
/**
* Ask JQuery Mobile to "render" the child elements of the element with the given id.
*/
public static void render(String id) {
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException("render() for empty id is not possible");
}
renderImpl(id);
}
public static void render(Element elt) {
if (elt == null) {
throw new IllegalArgumentException("render() for null element is not possible");
}
renderImpl(elt);
}
// page() was replaced by trigger("create"), see http://stackoverflow.com/a/6848969
// trigger("create") was replaced by enhanceWithin(), see http://jquerymobile.com/upgrade-guide/1.4/#enhancewithin
private static native void renderImpl(String id) /*-{
if ($wnd.$ === undefined || $wnd.$ === null) return; // jQuery is not loaded
$wnd.$("#" + id).enhanceWithin();
}-*/;
private static native void renderImpl(Element elt) /*-{
if ($wnd.$ === undefined || $wnd.$ === null) return; // jQuery is not loaded
$wnd.$(elt).enhanceWithin();
}-*/;
public static void setDefaultTransition(TransitionIntf> dfltTransition) {
defaultTransition = dfltTransition;
setDefaultTransitionImpl(defaultTransition.getJqmValue());
}
/**
* @param direction - if true then "reverse" effect will be used,
* see Pagecontainer.change()
*/
public static void setDefaultTransition(TransitionIntf> dfltTransition, boolean direction) {
setDefaultTransition(dfltTransition);
defaultTransistionDirection = direction;
}
private static native void setDefaultTransitionImpl(String transition) /*-{
$wnd.$.mobile.defaultPageTransition = transition;
}-*/;
public static void setDefaultDialogTransition(TransitionIntf> dfltDlgTransition) {
defaultDialogTransition = dfltDlgTransition;
setDefaultDialogTransitionImpl(defaultDialogTransition.getJqmValue());
}
private static native void setDefaultDialogTransitionImpl(String transition) /*-{
$wnd.$.mobile.defaultDialogTransition = transition;
}-*/;
/**
* @param maxWidth - Transitions can be disabled (set to "none") when the window
* width is greater than a certain pixel width. This feature is useful because transitions
* can be distracting or perform poorly on larger screens. This value is configurable via
* the global option $.mobile.maxTransitionWidth, which defaults to false. The option accepts
* any number representing a pixel width or false value. If it's not false, the handler will
* use a "none" transition when the window is wider than the specified value.
*
See
* Page transitions
*/
private static native void setMaxTransitionWidthImpl(String maxWidth) /*-{
$wnd.$.mobile.maxTransitionWidth = maxWidth;
}-*/;
/**
* @param maxWidth - (null or <= 0) means transitions will be used regardless of current
* window width, otherwise they will be disabled when window width > maxWidth.
*/
public static void setMaxTransitionWidth(Integer maxWidth) {
if (maxWidth == null || maxWidth.intValue() <= 0) setMaxTransitionWidthImpl("false");
else setMaxTransitionWidthImpl(maxWidth.toString());
}
public static void setDefaultChangeHash(boolean defaultChangeHash) {
JQMContext.defaultChangeHash = defaultChangeHash;
}
/**
* Scroll the page to the y-position of the given element. The element must
* be attached to the DOM (obviously!).
*
* This method will not fire jquery mobile scroll events.
*/
public static void silentScroll(Element e) {
if (e.getId() != null)
Mobile.silentScroll(getTop(e.getId()));
}
/**
* Scroll the page to the y-position of the given widget. The widget must be
* attached to the DOM (obviously!)
*
* This method will not fire jquery mobile scroll events.
*/
public static void silentScroll(Widget widget) {
silentScroll(widget.getElement());
}
public static final double MSEC_IN_MINUTE = 60d * 1000d;
public static Date jsDateToDate(JsDate jsDate) {
if (jsDate == null) return null;
double msec = jsDate.getTime();
Date d = new Date((long) msec);
int o1 = jsDate.getTimezoneOffset();
@SuppressWarnings("deprecation")
int o2 = d.getTimezoneOffset();
// For 1951 PST -> PDT was changed on Sun, Apr 29, 2:00 AM
// But 04/04/1951 is PDT in JsDate (which is wrong) and PST in Java Date (which is right)
if (o1 != o2) {
msec += MSEC_IN_MINUTE * (o2 - o1);
d = new Date((long) msec);
}
return d;
}
public static JsArrayString getJsArrayString(String... strings) {
JsArrayString jsStrs = (JsArrayString) JavaScriptObject.createArray();
for (String s : strings) {
jsStrs.push(s);
}
return jsStrs;
}
/**
* See Read :hover pseudo class with javascript
*
* @param rule - substring for css rule search
* @param props - requested property names
* @param regexProps - regular expressions for requested properties, see the following links:
*
*
JavaScript RegExp Object
*
Regex Tester
*
Start of String and End of String Anchors
*
*
* @return - property/value javascript object
*/
public static native JavaScriptObject getCssForRule(String rule, JsArrayString props, JsArrayString regexProps) /*-{
var sheets = $wnd.document.styleSheets;
var slen = sheets.length;
for (var i = 0; i < slen; i++) {
var rules = $wnd.document.styleSheets[i].cssRules;
if (rules === undefined || rules === null) { continue; }
var rlen = rules.length;
for (var j = 0; j < rlen; j++) {
var selectorText = rules[j].selectorText;
if (selectorText === undefined || selectorText === null) { continue; }
if (selectorText.indexOf(rule) >= 0) {
var ret = {};
var styleDefs = rules[j].style;
for (var k = 0, dlen = styleDefs.length; k < dlen; k++) {
var def = styleDefs[k];
var found = props === null && regexProps === null;
if (props !== null) {
for (n = 0, plen = props.length; n < plen; n++) {
if (def === props[n]) {
found = true;
break;
}
}
}
if (!found && regexProps !== null) {
for (n = 0, plen = regexProps.length; n < plen; n++) {
if (def.match(regexProps[n])) {
found = true;
break;
}
}
}
if (!found) { continue; }
ret[def] = styleDefs.getPropertyValue(def);
}
return ret;
}
}
}
return null;
}-*/;
public static double round(double valueToRound, int numberOfDecimalPlaces) {
double multipicationFactor = Math.pow(10, numberOfDecimalPlaces);
double interestedInZeroDPs = valueToRound * multipicationFactor;
return Math.round(interestedInZeroDPs) / multipicationFactor;
}
public static WidgetDefaults getWidgetDefaults() {
return widgetDefaults;
}
public static void setWidgetDefaults(WidgetDefaults widgetDefaults) {
JQMContext.widgetDefaults = widgetDefaults;
}
public static void widgetDefaultsNotifyLoaded(Widget w) {
if (w != null && widgetDefaults != null) widgetDefaults.loaded(w);
}
}