Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

added mobileinit support in the standalone build

  • Loading branch information...
commit 1f5c16c5627ecf08ace1fd17ada0cf29a61d890b 1 parent 77deb9d
Tobias Bosch authored
View
11 Changelog.md
@@ -0,0 +1,11 @@
+Changelog
+=====================
+
+1.0.1
+-------------
+Added the `mobileinit` support for the standalone build.
+
+
+1.0
+-------------
+Initial stable release
View
8 README.md
@@ -19,6 +19,10 @@ and automatically calls the refresh function.
Finally provides special enhancements useful for mobile applications.
+Changelog
+----------
+See project [Changelog.md](Changelog.md).
+
Sample
------------
@@ -57,6 +61,10 @@ The build is done using maven and requirejs.
- `mvn clean package -Pbuild`: This will create a new version of the adapter and put it into `/compiled`.
+The build also creates a standalone library including jquery, jquery-mobile and angular.
+If you want to do something during the initialization of jquery-mobile, use the following callback:
+`window.mobileinit = function() { ... }`
+
Please install the latest version of the maven plugin `brew`. This project provides a
snapshot release in `/localrepo`.
View
1,286 compiled/jquery-mobile-angular-adapter-1.0.1.js
@@ -0,0 +1,1286 @@
+/**
+ * The MIT License
+ *
+ * Copyright (c) 2011 Tobias Bosch (OPITZ CONSULTING GmbH, www.opitz-consulting.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function() {
+
+// Placeholder for the build process
+
+/**
+ * Simple implementation of require/define assuming all
+ * modules are named, in one file and in the correct order.
+ * This is just what r.js produces.
+ * This implementation is used for creating standalone bundles
+ * that do no more require require.js
+ */
+// This syntax is needed for the namespace function of r.js to work.
+var requirejs, require, define;
+(function (window) {
+
+ if (typeof define !== "undefined") {
+ //If a define is already in play via another AMD loader,
+ //do not overwrite.
+ return;
+ }
+
+
+ var defined = [];
+ var def;
+ define = def = function(name, deps, value) {
+ var dotJs = name.indexOf('.js');
+ if (dotJs!==-1) {
+ name = name.substring(0, dotJs);
+ }
+ if (arguments.length==2) {
+ // No deps...
+ value = deps;
+ deps = [];
+ }
+ if (typeof value === 'function') {
+ var args = [];
+ for (var i=0; i<deps.length; i++) {
+ var dep = deps[i];
+ args.push(defined[dep]);
+ }
+ value = value.apply(this, args);
+ }
+ defined[name] = value;
+ }
+
+ require = function(deps, callback) {
+ if (typeof callback === 'function') {
+ var args = [];
+ for (var i=0; i<deps.length; i++) {
+ var dep = deps[i];
+ args.push(defined[dep]);
+ }
+ callback.apply(this, args);
+ }
+
+ }
+
+ require.ready = $;
+})(window);
+
+/**
+ * Wrapper around window.angular.
+ */
+define('angular', function() {
+ if (typeof angular !== "undefined") {
+ return angular;
+ }
+});
+
+define('jquery', function() {
+ if (typeof $ !== "undefined") {
+ return $;
+ }
+});
+
+/**
+ * Global scope
+ */
+define('jqmng/globalScope',['jquery', 'angular'], function($, angular) {
+ var onCreateListeners = [];
+
+ /**
+ * Widget to stop the page compilation at the body
+ */
+ angular.widget("body", function(element) {
+ this.descend(false);
+ this.directives(true);
+ return function(element) {
+ var scope = this;
+ for (var i=0; i<onCreateListeners.length; i++) {
+ onCreateListeners[i](scope);
+ }
+ }
+ });
+
+ var globalScope;
+
+ /**
+ * Return the global scope.
+ * This equals the scope of the body element.
+ */
+ function getGlobalScope() {
+ if (!globalScope) {
+ globalScope = $("body").scope();
+ if (!globalScope) {
+ angular.compile($(document))();
+ }
+ globalScope = $("body").scope();
+ }
+ return globalScope;
+ }
+
+ function onCreate(listener) {
+ onCreateListeners.push(listener);
+ }
+
+ return {
+ globalScope: getGlobalScope,
+ onCreate: onCreate
+ }
+});
+
+define('jqmng/activePage',['jquery', 'jqmng/globalScope'], function($, globalScope) {
+ /*
+ * Service for page navigation.
+ * A call without parameters returns the current page id.
+ * Parameters (see $.mobile.changePage)
+ * - pageId: Id of page to navigate to. The special page id "back" navigates back.
+ * - transition (optional): Transition to be used.
+ * - reverse (optional): If the transition should be executed in reverse style
+ */
+ function activePage() {
+ if (arguments.length == 0) {
+ var currPage = $.mobile.activePage;
+ if (currPage) {
+ return currPage.attr('id');
+ } else {
+ return null;
+ }
+ } else {
+ // set the page...
+ var pageId = arguments[0];
+ if (pageId == 'back') {
+ window.history.back();
+ } else {
+ $.mobile.changePage.apply($.mobile.changePage, arguments);
+ }
+ }
+ }
+
+ $('div').live('pagebeforehide', function(event, ui) {
+ var currPageScope = $(event.target).scope();
+ if (!currPageScope) {
+ return;
+ }
+ var nextPage = ui.nextPage;
+ var nextPageScope = nextPage && nextPage.scope();
+ if (currPageScope.onPassivate) {
+ currPageScope.onPassivate.call(currPageScope, nextPageScope);
+ }
+ });
+
+ $('div').live('pagebeforeshow', function(event, ui) {
+ var currPageScope = $(event.target).scope();
+ if (!currPageScope) {
+ return;
+ }
+ var prevPage = ui.prevPage;
+ var prevPageScope = prevPage && prevPage.scope();
+ if (currPageScope.onActivate) {
+ currPageScope.onActivate.call(currPageScope, prevPageScope);
+ }
+ });
+
+ return {
+ activePage: activePage
+ }
+
+});
+
+/*
+ * waitdialog service.
+ */
+define('jqmng/waitDialog',['jquery'], function($) {
+ var showCalls = [];
+
+ function onClick(event) {
+ var lastCall = showCalls[showCalls.length - 1];
+ if (lastCall.callback) {
+ lastCall.callback.apply(this, arguments);
+ }
+ // This is required to prevent a second
+ // click event, see
+ // https://github.com/jquery/jquery-mobile/issues/1787
+ event.preventDefault();
+ }
+
+ var loadDialog;
+
+ function initIfNeeded() {
+ if (!loadDialog || loadDialog.length == 0) {
+ loadDialog = $(".ui-loader");
+ loadDialog.bind('vclick', onClick);
+ }
+ }
+
+ if (!$.mobile.loadingMessageWithCancel) {
+ $.mobile.loadingMessageWithCancel = 'Loading. Click to cancel.';
+ }
+
+ function updateUi() {
+ initIfNeeded();
+ if (showCalls.length > 0) {
+ var lastCall = showCalls[showCalls.length - 1];
+ var msg = lastCall.msg;
+ $.mobile.loadingMessage = msg;
+ $.mobile.showPageLoadingMsg();
+ } else {
+ $.mobile.hidePageLoadingMsg();
+ }
+ }
+
+ /**
+ * jquery mobile hides the wait dialog when pages are transitioned.
+ * This immediately closes wait dialogs that are opened in the onActivate
+ * function of controllers.
+ */
+ $('div').live('pageshow', function(event, ui) {
+ updateUi();
+ });
+
+ /**
+ *
+ * @param msg (optional)
+ * @param tapCallback (optional)
+ */
+ function show() {
+ var msg, tapCallback;
+ if (typeof arguments[0] == 'string') {
+ msg = arguments[0];
+ }
+ if (typeof arguments[0] == 'function') {
+ tapCallback = arguments[0];
+ }
+ if (typeof arguments[1] == 'function') {
+ tapCallback = arguments[1];
+ }
+ if (!msg) {
+ msg = $.mobile.loadingMessage;
+ }
+
+ showCalls.push({msg: msg, callback: tapCallback});
+ updateUi();
+ }
+
+ function hide() {
+ showCalls.pop();
+ updateUi();
+ }
+
+ /**
+ *
+ * @param promise
+ * @param msg (optional)
+ */
+ function waitFor(promise, msg) {
+ show();
+ promise.always(function() {
+ hide();
+ });
+ }
+
+ /**
+ *
+ * @param promise
+ * @param cancelData
+ * @param msg (optional)
+ */
+ function waitForWithCancel(promise, cancelData, msg) {
+ if (!msg) {
+ msg = $.mobile.loadingMessageWithCancel;
+ }
+ show(msg, function() {
+ promise.reject(cancelData);
+ });
+ promise.always(function() {
+ hide();
+ });
+ }
+
+ return {
+ show: show,
+ hide: hide,
+ waitFor: waitFor,
+ waitForWithCancel:waitForWithCancel
+ };
+});
+
+define('jqmng/event',['angular'], function(angular) {
+ /* A widget for clicks.
+ * Just as ng:click, but reacts to the jquery mobile vclick event, which
+ * includes taps, mousedowns, ...
+ */
+ angular.directive("ngm:click", function(expression, element) {
+ return angular.directive('ng:event')('vclick:' + expression, element);
+ });
+
+ /* A widget to bind general events like touches, ....
+ */
+ angular.directive("ng:event", function(expression, element) {
+ var eventHandlers = {};
+ var pattern = /(.*?):(.*?)($|,)/g;
+ var match;
+ var hasData = false;
+ while (match = pattern.exec(expression)) {
+ hasData = true;
+ var event = match[1];
+ var handler = match[2];
+ eventHandlers[event] = handler;
+ }
+ if (!hasData) {
+ throw "Expression " + expression + " needs to have the syntax <event>:<handler>,...";
+ }
+
+ var linkFn = function($updateView, element) {
+ var self = this;
+ for (var eventType in eventHandlers) {
+ (function(eventType) {
+ var handler = eventHandlers[eventType];
+ element.bind(eventType, function(event) {
+ var res = self.$tryEval(handler, element);
+ $updateView();
+ if (eventType.charAt(0)=='v') {
+ // This is required to prevent a second
+ // click event, see
+ // https://github.com/jquery/jquery-mobile/issues/1787
+ event.preventDefault();
+ }
+ });
+ })(eventType);
+ }
+ };
+ linkFn.$inject = ['$updateView'];
+ return linkFn;
+ });
+
+ /* A widget that reacts when the user presses the enter key.
+ */
+ angular.directive("ng:enterkey", function(expression, element) {
+ var linkFn = function($updateView, element) {
+ var self = this;
+ element.bind('keypress', function(e) {
+ var key = e.keyCode || e.which;
+ if (key == 13) {
+ var res = self.$tryEval(expression, element);
+ $updateView();
+ }
+ });
+ };
+ linkFn.$inject = ['$updateView'];
+ return linkFn;
+ });
+});
+
+/*
+ * The ng:fadein directive
+ */
+define('jqmng/fadein',['angular'], function(angular) {
+ /*
+ * Directive that fades in an element when angular
+ * uses it. Useful in templating when the underlying template changed.
+ */
+ angular.directive("ng:fadein", function(expression, element) {
+ this.directives(true);
+ this.descend(true);
+ element.css({opacity:0.1});
+ return function(element) {
+ element.animate({opacity:1.0}, parseInt(expression));
+ };
+ });
+
+});
+
+/*
+ * Defines the ng:if tag. This is useful if jquery mobile does not allow
+ * an ng:switch element in the dom, e.g. between ul and li.
+ * Uses ng:repeat and angular.Object.iff under the hood.
+ */
+define('jqmng/if',['angular'], function(angular) {
+ angular.Object.iff = function(self, test, trueCase, falseCase) {
+ if (test) {
+ return trueCase;
+ } else {
+ return falseCase;
+ }
+ }
+
+ angular.widget('@ng:if', function(expression, element) {
+ var newExpr = 'ngif in $iff(' + expression + ",[1],[])";
+ element.removeAttr('ng:if');
+ return angular.widget('@ng:repeat').call(this, newExpr, element);
+ });
+});
+
+/**
+ * Paging Support for lists.
+ * Note that this will cache the result of two calls until the next eval cycle
+ * or a change to the filter or orderBy arguments.
+ * <p>
+ * Operations on the result:
+ * - hasMorePages: returns whether there are more pages that can be loaded via loadNextPage
+ * - loadNextPage: Loads the next page of the list
+ *
+ * Usage:
+ <li ng:repeat="l in list.$paged()">{{l}}</li>
+ <li ng:if="list.$paged().hasMorePages()">
+ <a href="#" ngm:click="list.$paged().loadNextPage()">Load more</a>
+ </li>
+ */
+define('jqmng/paging',['jquery', 'angular', 'jqmng/globalScope'], function($, angular, globalScope) {
+ /**
+ * The default page size for all lists.
+ * Can be overwritten using array.pageSize.
+ */
+ if (!$.mobile.defaultListPageSize) {
+ $.mobile.defaultListPageSize = 10;
+ }
+
+ var globalEvalId = 0;
+ globalScope.onCreate(function(scope) {
+ scope.$onEval(-99999, function() {
+ globalEvalId++;
+ });
+ });
+
+ var enhanceFunctions = {
+ init : init,
+ refresh : refresh,
+ refreshIfNeeded : refreshIfNeeded,
+ setFilter : setFilter,
+ setOrderBy : setOrderBy,
+ loadNextPage : loadNextPage,
+ hasMorePages : hasMorePages,
+ reset : reset
+ };
+
+ var usedProps = {
+ pageSize: true,
+ originalList: true,
+ refreshNeeded: true,
+ filter: true,
+ orderBy: true,
+ loadedCount: true,
+ availableCount: true,
+ evalId: true
+ }
+
+
+ function createPagedList(list) {
+ var res = [];
+ for (var fnName in enhanceFunctions) {
+ res[fnName] = enhanceFunctions[fnName];
+ }
+ res.init(list);
+ var oldHasOwnProperty = res.hasOwnProperty;
+ res.hasOwnProperty = function(propName) {
+ if (propName in enhanceFunctions || propName in usedProps) {
+ return false;
+ }
+ return oldHasOwnProperty.apply(this, arguments);
+ }
+ return res;
+ }
+
+ function init(list) {
+ if (list.pageSize) {
+ this.pageSize = list.pageSize;
+ } else {
+ this.pageSize = $.mobile.defaultListPageSize;
+ }
+ this.originalList = list;
+ this.refreshNeeded = true;
+ this.reset();
+ }
+
+ function refresh() {
+ var list = this.originalList;
+ if (this.filter) {
+ list = angular.Array.filter(list, this.filter);
+ }
+ if (this.orderBy) {
+ list = angular.Array.orderBy(list, this.orderBy);
+ }
+ var loadedCount = this.loadedCount;
+ if (loadedCount<this.pageSize) {
+ loadedCount = this.pageSize;
+ }
+ if (loadedCount>list.length) {
+ loadedCount = list.length;
+ }
+ this.loadedCount = loadedCount;
+ this.availableCount = list.length;
+ var newData = list.slice(0, loadedCount);
+ var spliceArgs = [0, this.length].concat(newData);
+ this.splice.apply(this, spliceArgs);
+ }
+
+ function refreshIfNeeded() {
+ if (this.evalId != globalEvalId) {
+ this.refreshNeeded = true;
+ this.evalId = globalEvalId;
+ }
+ if (this.refreshNeeded) {
+ this.refresh();
+ this.refreshNeeded = false;
+ }
+ return this;
+ }
+
+ function setFilter(filterExpr) {
+ if (!angular.Object.equals(this.filter, filterExpr)) {
+ this.filter = filterExpr;
+ this.refreshNeeded = true;
+ }
+ }
+
+ function setOrderBy(orderBy) {
+ if (!angular.Object.equals(this.orderBy, orderBy)) {
+ this.orderBy = orderBy;
+ this.refreshNeeded = true;
+ }
+ }
+
+ function loadNextPage() {
+ this.loadedCount = this.loadedCount + this.pageSize;
+ this.refreshNeeded = true;
+ }
+
+ function hasMorePages() {
+ this.refreshIfNeeded();
+ return this.loadedCount < this.availableCount;
+ }
+
+ function reset() {
+ this.loadedCount = 0;
+ this.refreshNeeded = true;
+ }
+
+ /**
+ * Returns the already loaded pages.
+ * Also includes filtering (second argument) and ordering (third argument),
+ * as the standard angular way does not work with paging.
+ *
+ * Does caching: Evaluates the filter and order expression only once in an eval cycle.
+ * ATTENTION: There can only be one paged list per original list.
+ */
+ angular.Array.paged = function(list, filter, orderBy) {
+ var pagedList = list.pagedList;
+ if (!pagedList) {
+ pagedList = createPagedList(list);
+ list.pagedList = pagedList;
+ }
+ pagedList.setFilter(filter);
+ pagedList.setOrderBy(orderBy);
+ pagedList.refreshIfNeeded();
+ return pagedList;
+
+ };
+});
+
+/**
+ * Integration of the page widget.
+ */
+define('jqmng/widgets/pageCompile',['jquery', 'angular', 'jqmng/globalScope'], function($, angular, globalScope) {
+ // redirect all events from the page widget,
+ // so we can intercept them.
+ $.mobile.page.prototype.widgetEventPrefix = 'jqmngpage';
+
+ var afterCompileQueue = [];
+
+ function executeAfterCompileQueue() {
+ while (afterCompileQueue.length>0) {
+ var callback = afterCompileQueue.shift();
+ callback();
+ }
+ }
+
+ function addAfterCompileCallback(callback) {
+ if (afterCompileQueue.length==0) {
+ setTimeout(executeAfterCompileQueue, 0);
+ }
+ afterCompileQueue.push(callback);
+ }
+
+ $('div').live('jqmngpagecreate', function(event) {
+ var page = $(event.target);
+ var parentScope = globalScope.globalScope();
+ var childScope = angular.scope(parentScope);
+ angular.compile(page)(childScope);
+ addAfterCompileCallback(function() {
+ // The second pagecreate does only initialize
+ // the widgets that we did not already create by angular.
+ page.trigger("pagecreate");
+ });
+ executeAfterCompileQueue();
+ });
+
+ $('div').live('jqmngpagebeforeshow', function(event, data) {
+ var currPageScope = $(event.target).scope();
+ if (currPageScope) {
+ currScope = currPageScope;
+ currScope.$service("$updateView")();
+ }
+ var page = $(event.target);
+ page.trigger("pagebeforeshow", data);
+ });
+
+ $('div').live('jqmngpagebeforehide', function(event, data) {
+ var page = $(event.target);
+ page.trigger("pagebeforehide", data);
+ });
+
+ $('div').live('jqmngpagehide', function(event, data) {
+ var page = $(event.target);
+ page.trigger("pagehide", data);
+ });
+
+ $('div').live('jqmngpageshow', function(event, data) {
+ var page = $(event.target);
+ page.trigger("pageshow", data);
+ });
+
+ var currScope = null;
+ // The eval function of the global scope should eval
+ // the active scope only.
+ globalScope.onCreate(function(scope) {
+ scope.$onEval(function() {
+ // Note that wen cannot use $.mobile.activePage here,
+ // as this is not set until the pageshow event, but
+ // our pages are created before this!
+ if (currScope) {
+ currScope.$eval();
+ }
+ });
+ });
+
+ /**
+ * Deactivate the url changing capabilities
+ * of angular, so we do not get into trouble with
+ * jquery mobile: angular saves the current url before a $eval
+ * and updates the url after the $eval.
+ * <p>
+ * This also replaces the hashListen implementation
+ * of angular by the jquery mobile impementation,
+ * so we do not have two polling functions, ...
+ * <p>
+ * Attention: By this, urls can no more be changed via angular's $location service!
+ */
+ (function(angular) {
+ var oldBrowser = angular.service("$browser");
+ angular.service("$browser", function() {
+ var res = oldBrowser.apply(this, arguments);
+ res.onHashChange = function(handler) {
+ $(window).bind('hashchange', handler);
+ return handler;
+ };
+ res.setUrl = function() {
+ };
+ return res;
+ }, {$inject:['$log']});
+ })(angular);
+
+ return {
+ afterCompile: addAfterCompileCallback
+ }
+});
+
+/**
+ * Helper functions for proxying jquery widgets and angular widgets.
+ */
+define('jqmng/widgets/widgetProxyUtil',['jquery', 'angular', 'jqmng/globalScope'], function($, angular, globalScope) {
+ /**
+ * Creates a proxy around an existing angular widget.
+ * Needed to use the angular functionalities like disabled handling,
+ * invalidWidgets marking, formatting and validation.
+ * @param tagname
+ * @param compileFn
+ */
+ function createAngularWidgetProxy(tagname, compileFn) {
+
+ var oldWidget = angular.widget(tagname);
+ angular.widget(tagname, function() {
+ var oldBinder;
+ var bindFn = compileFn.apply(this, arguments);
+ var newBinder = function() {
+ var elementArgumentPos = (oldBinder && oldBinder.$inject && oldBinder.$inject.length) || 0;
+ var element = arguments[elementArgumentPos];
+ var self = this;
+ var myargs = arguments;
+ var oldBinderCalled = false;
+ var res;
+ if (bindFn) {
+ res = bindFn.call(this, element, function() {
+ oldBinderCalled = true;
+ return oldBinder && oldBinder.apply(self, myargs);
+ });
+ }
+ if (!oldBinderCalled) {
+ return oldBinder && oldBinder.apply(self, myargs);
+ }
+ return res;
+ }
+ // execute the angular compiler after our compiler!
+ oldBinder = oldWidget && oldWidget.apply(this, arguments);
+ if (!oldWidget) {
+ this.descend(true);
+ this.directives(true);
+ }
+
+ newBinder.$inject = oldBinder && oldBinder.$inject;
+ return newBinder;
+ });
+ }
+
+ /**
+ * Creates a proxy around an existing angular directive.
+ * Needed e.g. to intercept the disabled handling, ...
+ * @param directiveName
+ * @param compileFn
+ */
+ function createAngularDirectiveProxy(directiveName, compileFn) {
+ var oldDirective = angular.directive(directiveName);
+ angular.directive(directiveName, function(expression) {
+ var oldBinder = oldDirective.apply(this, arguments);
+ var bindFn = compileFn(expression);
+ var newBinder = function() {
+ var elementArgumentPos = (oldBinder.$inject && oldBinder.$inject.length) || 0;
+ var element = arguments[elementArgumentPos];
+ var scope = this;
+ var res = oldBinder.apply(this, arguments);
+ bindFn.call(this, element);
+ return res;
+ }
+ newBinder.$inject = oldBinder.$inject;
+ return newBinder;
+ });
+ }
+
+ /**
+ * Removes all elements from list1 that are contained in list2
+ * and returns a new list.
+ * @param list1
+ * @param list2
+ */
+ function minusArray(list1, list2) {
+ var res = [];
+ // temporarily add marker...
+ for (var i=0; i<list2.length; i++) {
+ list2[i].diffMarker = true;
+ }
+ for (var i=0; i<list1.length; i++) {
+ if (!list1[i].diffMarker) {
+ res.push(list1[i]);
+ }
+ }
+ for (var i=0; i<list2.length; i++) {
+ delete list2[i].diffMarker;
+ }
+ return res;
+ }
+
+ function recordDomAdditions(selector, callback) {
+ var oldState = $(selector);
+ callback();
+ var newState = $(selector);
+ return minusArray(newState, oldState);
+ }
+
+ var garbageCollector = [];
+
+ function isConnectedToDocument(element) {
+ var rootElement = document.documentElement;
+ while (element!==null && element!==rootElement) {
+ element = element.parentNode;
+ }
+ return element===rootElement;
+ }
+
+ function removeSlaveElements() {
+ var rootElement = document.documentElement;
+ for (var i=0; i<garbageCollector.length; i++) {
+ var entry = garbageCollector[i];
+ if (!isConnectedToDocument(entry.master[0])) {
+ entry.slaves.remove();
+ garbageCollector.splice(i, 1);
+ i--;
+ }
+ }
+ }
+
+ function removeSlavesWhenMasterIsRemoved(master, slaves) {
+ garbageCollector.push({master: master, slaves:slaves});
+ }
+
+ globalScope.onCreate(function(scope) {
+ scope.$onEval(99999, function() {
+ removeSlaveElements();
+ });
+ });
+
+
+ return {
+ recordDomAdditions: recordDomAdditions,
+ createAngularDirectiveProxy: createAngularDirectiveProxy,
+ createAngularWidgetProxy: createAngularWidgetProxy,
+ removeSlavesWhenMasterIsRemoved: removeSlavesWhenMasterIsRemoved
+ }
+});
+
+define('jqmng/widgets/disabledHandling',[
+ 'jqmng/widgets/widgetProxyUtil'
+], function(widgetProxyUtil) {
+ /**
+ * Binds the enabled/disabled handler of angular and jquery mobile together,
+ * for the jqm widgets that are in jqmWidgetDisabledHandling.
+ */
+ var jqmWidgetDisabledHandling = {};
+
+ widgetProxyUtil.createAngularDirectiveProxy('ng:bind-attr', function(expression) {
+ var regex = /([^:{'"]+)/;
+ var attr = regex.exec(expression)[1];
+ if (attr !== 'disabled') {
+ return function() {
+
+ };
+ } else {
+ return function(element) {
+ var scope = this;
+ var oldValue;
+ // Note: We cannot use scope.$watch here:
+ // We want to be called after the proxied angular implementation, and
+ // that uses $onEval. $watch always gets evaluated before $onEval.
+ scope.$onEval(function() {
+ var value = element.attr(attr);
+ if (value != oldValue) {
+ oldValue = value;
+ var jqmOperation = value?"disable":"enable";
+ var data = element.data();
+ for (var key in data) {
+ if (typeof key === 'string' && jqmWidgetDisabledHandling[key]) {
+ element[key](jqmOperation);
+ }
+ }
+ }
+ });
+ }
+ }
+ });
+
+ return jqmWidgetDisabledHandling;
+});
+
+define('jqmng/widgets/jqmButton',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling'
+], function(proxyUtil, disabledHandling) {
+ disabledHandling.button = true;
+
+ function compileButton(element, name) {
+ var scope = this;
+ element.button();
+ // the input button widget creates a new parent element.
+ // remove that element when the input element is removed
+ proxyUtil.removeSlavesWhenMasterIsRemoved(element, element.parent());
+ }
+
+ function isButton(element) {
+ return element.filter($.mobile.button.prototype.options.initSelector)
+ .not(":jqmData(role='none'), :jqmData(role='nojs')").length > 0;
+
+ }
+
+ return {
+ compileButton: compileButton,
+ isButton: isButton
+ }
+
+});
+
+define('jqmng/widgets/angularButton',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/jqmButton'
+], function(proxyUtil, jqmButton) {
+
+ proxyUtil.createAngularWidgetProxy('button', function(element) {
+ var isButton = jqmButton.isButton(element);
+ var name = element.attr('name');
+ return function(element, origBinder) {
+ var res = origBinder();
+ if (isButton) {
+ jqmButton.compileButton.call(this, element, name);
+ }
+ return res;
+ }
+ });
+});
+
+define('jqmng/widgets/jqmCollapsible',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling'
+], function(proxyUtil, disabledHandling) {
+
+ function compileCollapsible(element, name) {
+ var scope = this;
+ element.collapsible();
+ }
+
+ function isCollapsible(element) {
+ return element.filter($.mobile.collapsible.prototype.options.initSelector).length > 0;
+ }
+
+ return {
+ compileCollapsible: compileCollapsible,
+ isCollapsible: isCollapsible
+ }
+});
+
+define('jqmng/widgets/angularDiv',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/jqmCollapsible'
+], function(proxyUtil, jqmCollapsible) {
+ proxyUtil.createAngularWidgetProxy('div', function(element) {
+ var isCollapsible = jqmCollapsible.isCollapsible(element);
+ var name = element.attr('name');
+ return function(element, origBinder) {
+ var res = origBinder();
+ if (isCollapsible) {
+ jqmCollapsible.compileCollapsible.call(this, element, name);
+ }
+ return res;
+ };
+ });
+
+
+});
+
+define('jqmng/widgets/jqmSelectMenu',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling',
+ 'jqmng/widgets/pageCompile'
+], function(proxyUtil, disabledHandling, pageCompile) {
+ disabledHandling.selectmenu = true;
+
+ function compileSelectMenu(element, name) {
+ var scope = this;
+ // The selectmenu needs access to the page,
+ // so we can not create it until after the eval cycle!
+ pageCompile.afterCompile(function() {
+ // The selectmenu widget creates a parent tag. This needs
+ // to be deleted when the select tag is deleted from the dom.
+ // Furthermore, it creates ui-selectmenu and ui-selectmenu-screen divs, as well as new dialogs
+ var removeSlaves;
+ var newElements = proxyUtil.recordDomAdditions(".ui-selectmenu,.ui-selectmenu-screen,:jqmData(role='dialog')", function() {
+ element.selectmenu();
+ removeSlaves = element.parent();
+ });
+ removeSlaves = removeSlaves.add(newElements);
+ proxyUtil.removeSlavesWhenMasterIsRemoved(element, removeSlaves);
+
+ scope.$watch(name, function(value) {
+ element.selectmenu('refresh', true);
+ });
+ // update the value when the number of options change.
+ // needed if the default values changes.
+ var oldCount;
+ scope.$onEval(999999, function() {
+ var newCount = element[0].childNodes.length;
+ if (oldCount !== newCount) {
+ oldCount = newCount;
+ element.trigger('change');
+ }
+ });
+ });
+ }
+
+ function isSelectMenu(element) {
+ return element.filter($.mobile.selectmenu.prototype.options.initSelector)
+ .not(":jqmData(role='none'), :jqmData(role='nojs')").length > 0;
+ }
+
+ return {
+ compileSelectMenu: compileSelectMenu,
+ isSelectMenu: isSelectMenu
+ }
+});
+
+define('jqmng/widgets/jqmSlider',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling',
+ 'jqmng/widgets/pageCompile'
+], function(proxyUtil, disabledHandling, pageCompile) {
+ disabledHandling.slider = true;
+
+ function compileSlider(element, name) {
+ var scope = this;
+ pageCompile.afterCompile(function() {
+ // The slider widget creates an element of class ui-slider
+ // after the slider.
+ var newElements = proxyUtil.recordDomAdditions(".ui-slider", function() {
+ element.slider();
+ });
+ proxyUtil.removeSlavesWhenMasterIsRemoved(element, $(newElements));
+
+ scope.$watch(name, function(value) {
+ element.slider('refresh');
+ });
+ });
+ }
+
+ function isSlider(element) {
+ return element.filter($.mobile.slider.prototype.options.initSelector)
+ .not(":jqmData(role='none'), :jqmData(role='nojs')").length > 0;
+
+ }
+
+ return {
+ compileSlider: compileSlider,
+ isSlider: isSlider
+ }
+
+});
+
+define('jqmng/widgets/jqmCheckboxRadio',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling',
+ 'jqmng/widgets/pageCompile'
+], function(proxyUtil, disabledHandling, pageCompile) {
+ disabledHandling.checkboxradio = true;
+
+ function compileCheckboxRadio(element, name) {
+ var scope = this;
+ // The checkboxradio widget looks for a label
+ // within the page. So we need to defer the creation.
+ pageCompile.afterCompile(function() {
+ element.checkboxradio();
+ scope.$watch(name, function(value) {
+ element.checkboxradio('refresh');
+ });
+ });
+ }
+
+ function isCheckboxRadio(element) {
+ return element.filter($.mobile.checkboxradio.prototype.options.initSelector)
+ .not(":jqmData(role='none'), :jqmData(role='nojs')").length > 0;
+
+ }
+
+ return {
+ compileCheckboxRadio: compileCheckboxRadio,
+ isCheckboxRadio: isCheckboxRadio
+ }
+
+
+});
+
+define('jqmng/widgets/jqmTextInput',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling'
+], function(proxyUtil, disabledHandling) {
+ disabledHandling.textinput = true;
+
+ function compileTextInput(element, name) {
+ var scope = this;
+ element.textinput();
+ }
+
+ function isTextInput(element) {
+ return element.filter($.mobile.textinput.prototype.options.initSelector)
+ .not(":jqmData(role='none'), :jqmData(role='nojs')").length > 0;
+ }
+
+ return {
+ compileTextInput: compileTextInput,
+ isTextInput: isTextInput
+ }
+
+
+});
+
+define('jqmng/widgets/angularInput',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/jqmSelectMenu',
+ 'jqmng/widgets/jqmSlider',
+ 'jqmng/widgets/jqmCheckboxRadio',
+ 'jqmng/widgets/jqmTextInput',
+ 'jqmng/widgets/jqmButton'
+],
+ function(proxyUtil, jqmSelectMenu, jqmSlider, jqmCheckboxRadio, jqmTextInput, jqmButton) {
+ proxyUtil.createAngularWidgetProxy('input', function(element) {
+ var isTextinput = jqmTextInput.isTextInput(element);
+ var isCheckboxRadio = jqmCheckboxRadio.isCheckboxRadio(element);
+ var isSlider = jqmSlider.isSlider(element);
+ var isButton = jqmButton.isButton(element);
+
+ var name = element.attr('name');
+ var oldType = element[0].type;
+ // Need to set the type temporarily always to 'text' so that
+ // the original angular widget is used.
+ if (isTextinput) {
+ element[0].type = 'text';
+ element[0]['data-type'] = oldType;
+ }
+ return function(element, origBinder) {
+ element[0].type = oldType;
+ if (isCheckboxRadio) {
+ // Angular only binds to the click event for radio and check boxes,
+ // but jquery mobile fires a change event. So be sure that angular also listens to the change event.
+ var origBind = element.bind;
+ element.bind = function(events, callback) {
+ if (events.indexOf('click') != -1) {
+ events += " change";
+ }
+ return origBind.call(this, events, callback);
+ };
+ }
+ var res = origBinder();
+ if (isSlider) {
+ jqmSlider.compileSlider.call(this, element, name);
+ }
+ if (isCheckboxRadio) {
+ jqmCheckboxRadio.compileCheckboxRadio.call(this, element, name);
+ }
+ if (isButton) {
+ jqmButton.compileButton.call(this, element, name);
+ }
+ if (isTextinput) {
+ jqmTextInput.compileTextInput.call(this, element, name);
+ }
+ return res;
+ };
+ });
+
+ });
+
+define('jqmng/widgets/angularSelect',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/jqmSelectMenu',
+ 'jqmng/widgets/jqmSlider'
+], function(proxyUtil, jqmSelectMenu, jqmSlider) {
+ proxyUtil.createAngularWidgetProxy('select', function(element) {
+ var isSelectMenu = jqmSelectMenu.isSelectMenu(element);
+ var isSlider = jqmSlider.isSlider(element);
+ var name = element.attr('name');
+ return function(element, origBinder) {
+ var res = origBinder();
+ if (isSelectMenu) {
+ jqmSelectMenu.compileSelectMenu.call(this, element, name);
+ }
+ if (isSlider) {
+ jqmSlider.compileSlider.call(this, element, name);
+ }
+ return res;
+ }
+ });
+
+});
+
+define('jqmng/widgets/jqmListView',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/disabledHandling',
+ 'jquery',
+ 'jqmng/widgets/pageCompile'
+], function(proxyUtil, disabledHandling, $, pageCompile) {
+
+ function compileListView(element) {
+ var scope = this;
+ // The listview widget looks for the persistent footer,
+ // so we need to defer the creation.
+ pageCompile.afterCompile(function() {
+ // listviews may create subpages for nested lists.
+ // Be sure that they get removed from the dom when the list is removed.
+ var newElemens = proxyUtil.recordDomAdditions(":jqmData(role='page')", function() {
+ element.listview();
+ });
+ proxyUtil.removeSlavesWhenMasterIsRemoved(element, $(newElemens));
+ // refresh the listview when the number of children changes.
+ // This does not need to check for changes to the
+ // ordering of children, for the following reason:
+ // The only changes to elements is done by ng:repeat.
+ // And ng:repeat reuses the same element for the same index position,
+ // independent of the value of that index position.
+ var oldCount;
+ scope.$onEval(999999, function() {
+ var newCount = element[0].childNodes.length;
+ if (oldCount !== newCount) {
+ oldCount = newCount;
+ element.listview("refresh");
+ }
+ });
+ });
+ }
+
+ function isListView(element) {
+ return element.filter($.mobile.listview.prototype.options.initSelector).length > 0;
+ }
+
+ return {
+ compileListView: compileListView,
+ isListView: isListView
+ }
+});
+
+define('jqmng/widgets/angularUl',[
+ 'jqmng/widgets/widgetProxyUtil',
+ 'jqmng/widgets/jqmListView'
+], function(proxyUtil, jqmListView) {
+ proxyUtil.createAngularWidgetProxy('ul', function(element) {
+ var isListView = jqmListView.isListView(element);
+ return function(element, origBinder) {
+ var res = origBinder();
+ if (isListView) {
+ jqmListView.compileListView.call(this, element);
+ }
+ return res;
+ };
+ });
+});
+
+// Wrapper module as facade for the internal modules.
+define('jqm-angular',[
+ 'angular',
+ 'jquery',
+ 'jqmng/globalScope',
+ 'jqmng/activePage',
+ 'jqmng/waitDialog',
+ 'jqmng/event',
+ 'jqmng/fadein',
+ 'jqmng/if',
+ 'jqmng/paging',
+ 'jqmng/widgets/pageCompile',
+ 'jqmng/widgets/angularButton',
+ 'jqmng/widgets/angularDiv',
+ 'jqmng/widgets/angularInput',
+ 'jqmng/widgets/angularSelect',
+ 'jqmng/widgets/angularUl',
+], function(angular, $, globalScope, activePage, waitDialog) {
+ // create global variables
+ $.mobile.globalScope = globalScope.globalScope;
+
+ // export waitDialog as angular Service
+ angular.service('waitdialog', function() {
+ return waitDialog;
+ });
+ angular.service('$activePage', function() {
+ return activePage.activePage;
+ });
+ return {
+ globalScope: globalScope.globalScope,
+ activePage: activePage.activePage,
+ waitDialog: waitDialog
+ }
+});
+})();
View
1  compiled/jquery-mobile-angular-adapter-1.0.1.min.js
@@ -0,0 +1 @@
+(function(){var a,b,c;(function(a){if(typeof c=="undefined"){var d=[],e;c=e=function(a,b,c){var e=a.indexOf(".js");e!==-1&&(a=a.substring(0,e)),arguments.length==2&&(c=b,b=[]);if(typeof c=="function"){var f=[];for(var g=0;g<b.length;g++){var h=b[g];f.push(d[h])}c=c.apply(this,f)}d[a]=c},b=function(a,b){if(typeof b=="function"){var c=[];for(var e=0;e<a.length;e++){var f=a[e];c.push(d[f])}b.apply(this,c)}},b.ready=$}})(window),c("angular",function(){if(typeof angular!="undefined")return angular}),c("jquery",function(){if(typeof $!="undefined")return $}),c("jqmng/globalScope",["jquery","angular"],function(a,b){function f(a){c.push(a)}function e(){d||(d=a("body").scope(),d||b.compile(a(document))(),d=a("body").scope());return d}var c=[];b.widget("body",function(a){this.descend(!1),this.directives(!0);return function(a){var b=this;for(var d=0;d<c.length;d++)c[d](b)}});var d;return{globalScope:e,onCreate:f}}),c("jqmng/activePage",["jquery","jqmng/globalScope"],function(a,b){function c(){if(arguments.length==0){var b=a.mobile.activePage;return b?b.attr("id"):null}var c=arguments[0];c=="back"?window.history.back():a.mobile.changePage.apply(a.mobile.changePage,arguments)}a("div").live("pagebeforehide",function(b,c){var d=a(b.target).scope();if(!!d){var e=c.nextPage,f=e&&e.scope();d.onPassivate&&d.onPassivate.call(d,f)}}),a("div").live("pagebeforeshow",function(b,c){var d=a(b.target).scope();if(!!d){var e=c.prevPage,f=e&&e.scope();d.onActivate&&d.onActivate.call(d,f)}});return{activePage:c}}),c("jqmng/waitDialog",["jquery"],function(a){function j(b,c,d){d||(d=a.mobile.loadingMessageWithCancel),g(d,function(){b.reject(c)}),b.always(function(){h()})}function i(a,b){g(),a.always(function(){h()})}function h(){b.pop(),f()}function g(){var c,d;typeof arguments[0]=="string"&&(c=arguments[0]),typeof arguments[0]=="function"&&(d=arguments[0]),typeof arguments[1]=="function"&&(d=arguments[1]),c||(c=a.mobile.loadingMessage),b.push({msg:c,callback:d}),f()}function f(){e();if(b.length>0){var c=b[b.length-1],d=c.msg;a.mobile.loadingMessage=d,a.mobile.showPageLoadingMsg()}else a.mobile.hidePageLoadingMsg()}function e(){if(!d||d.length==0)d=a(".ui-loader"),d.bind("vclick",c)}function c(a){var c=b[b.length-1];c.callback&&c.callback.apply(this,arguments),a.preventDefault()}var b=[],d;a.mobile.loadingMessageWithCancel||(a.mobile.loadingMessageWithCancel="Loading. Click to cancel."),a("div").live("pageshow",function(a,b){f()});return{show:g,hide:h,waitFor:i,waitForWithCancel:j}}),c("jqmng/event",["angular"],function(a){a.directive("ngm:click",function(b,c){return a.directive("ng:event")("vclick:"+b,c)}),a.directive("ng:event",function(a,b){var c={},d=/(.*?):(.*?)($|,)/g,e,f=!1;while(e=d.exec(a)){f=!0;var g=e[1],h=e[2];c[g]=h}if(!f)throw"Expression "+a+" needs to have the syntax <event>:<handler>,...";var i=function(a,b){var d=this;for(var e in c)(function(e){var f=c[e];b.bind(e,function(c){var g=d.$tryEval(f,b);a(),e.charAt(0)=="v"&&c.preventDefault()})})(e)};i.$inject=["$updateView"];return i}),a.directive("ng:enterkey",function(a,b){var c=function(b,c){var d=this;c.bind("keypress",function(e){var f=e.keyCode||e.which;if(f==13){var g=d.$tryEval(a,c);b()}})};c.$inject=["$updateView"];return c})}),c("jqmng/fadein",["angular"],function(a){a.directive("ng:fadein",function(a,b){this.directives(!0),this.descend(!0),b.css({opacity:.1});return function(b){b.animate({opacity:1},parseInt(a))}})}),c("jqmng/if",["angular"],function(a){a.Object.iff=function(a,b,c,d){return b?c:d},a.widget("@ng:if",function(b,c){var d="ngif in $iff("+b+",[1],[])";c.removeAttr("ng:if");return a.widget("@ng:repeat").call(this,d,c)})}),c("jqmng/paging",["jquery","angular","jqmng/globalScope"],function(a,b,c){function o(){this.loadedCount=0,this.refreshNeeded=!0}function n(){this.refreshIfNeeded();return this.loadedCount<this.availableCount}function m(){this.loadedCount=this.loadedCount+this.pageSize,this.refreshNeeded=!0}function l(a){b.Object.equals(this.orderBy,a)||(this.orderBy=a,this.refreshNeeded=!0)}function k(a){b.Object.equals(this.filter,a)||(this.filter=a,this.refreshNeeded=!0)}function j(){this.evalId!=d&&(this.refreshNeeded=!0,this.evalId=d),this.refreshNeeded&&(this.refresh(),this.refreshNeeded=!1);return this}function i(){var a=this.originalList;this.filter&&(a=b.Array.filter(a,this.filter)),this.orderBy&&(a=b.Array.orderBy(a,this.orderBy));var c=this.loadedCount;c<this.pageSize&&(c=this.pageSize),c>a.length&&(c=a.length),this.loadedCount=c,this.availableCount=a.length;var d=a.slice(0,c),e=[0,this.length].concat(d);this.splice.apply(this,e)}function h(b){b.pageSize?this.pageSize=b.pageSize:this.pageSize=a.mobile.defaultListPageSize,this.originalList=b,this.refreshNeeded=!0,this.reset()}function g(a){var b=[];for(var c in e)b[c]=e[c];b.init(a);var d=b.hasOwnProperty;b.hasOwnProperty=function(a){return a in e||a in f?!1:d.apply(this,arguments)};return b}a.mobile.defaultListPageSize||(a.mobile.defaultListPageSize=10);var d=0;c.onCreate(function(a){a.$onEval(-99999,function(){d++})});var e={init:h,refresh:i,refreshIfNeeded:j,setFilter:k,setOrderBy:l,loadNextPage:m,hasMorePages:n,reset:o},f={pageSize:!0,originalList:!0,refreshNeeded:!0,filter:!0,orderBy:!0,loadedCount:!0,availableCount:!0,evalId:!0};b.Array.paged=function(a,b,c){var d=a.pagedList;d||(d=g(a),a.pagedList=d),d.setFilter(b),d.setOrderBy(c),d.refreshIfNeeded();return d}}),c("jqmng/widgets/pageCompile",["jquery","angular","jqmng/globalScope"],function(a,b,c){function f(a){d.length==0&&setTimeout(e,0),d.push(a)}function e(){while(d.length>0){var a=d.shift();a()}}a.mobile.page.prototype.widgetEventPrefix="jqmngpage";var d=[];a("div").live("jqmngpagecreate",function(d){var g=a(d.target),h=c.globalScope(),i=b.scope(h);b.compile(g)(i),f(function(){g.trigger("pagecreate")}),e()}),a("div").live("jqmngpagebeforeshow",function(b,c){var d=a(b.target).scope();d&&(g=d,g.$service("$updateView")());var e=a(b.target);e.trigger("pagebeforeshow",c)}),a("div").live("jqmngpagebeforehide",function(b,c){var d=a(b.target);d.trigger("pagebeforehide",c)}),a("div").live("jqmngpagehide",function(b,c){var d=a(b.target);d.trigger("pagehide",c)}),a("div").live("jqmngpageshow",function(b,c){var d=a(b.target);d.trigger("pageshow",c)});var g=null;c.onCreate(function(a){a.$onEval(function(){g&&g.$eval()})}),function(b){var c=b.service("$browser");b.service("$browser",function(){var b=c.apply(this,arguments);b.onHashChange=function(b){a(window).bind("hashchange",b);return b},b.setUrl=function(){};return b},{$inject:["$log"]})}(b);return{afterCompile:f}}),c("jqmng/widgets/widgetProxyUtil",["jquery","angular","jqmng/globalScope"],function(a,b,c){function k(a,b){h.push({master:a,slaves:b})}function j(){var a=document.documentElement;for(var b=0;b<h.length;b++){var c=h[b];i(c.master[0])||(c.slaves.remove(),h.splice(b,1),b--)}}function i(a){var b=document.documentElement;while(a!==null&&a!==b)a=a.parentNode;return a===b}function g(b,c){var d=a(b);c();var e=a(b);return f(e,d)}function f(a,b){var c=[];for(var d=0;d<b.length;d++)b[d].diffMarker=!0;for(var d=0;d<a.length;d++)a[d].diffMarker||c.push(a[d]);for(var d=0;d<b.length;d++)delete b[d].diffMarker;return c}function e(a,c){var d=b.directive(a);b.directive(a,function(a){var b=d.apply(this,arguments),e=c(a),f=function(){var a=b.$inject&&b.$inject.length||0,c=arguments[a],d=this,f=b.apply(this,arguments);e.call(this,c);return f};f.$inject=b.$inject;return f})}function d(a,c){var d=b.widget(a);b.widget(a,function(){var a,b=c.apply(this,arguments),e=function(){var c=a&&a.$inject&&a.$inject.length||0,d=arguments[c],e=this,f=arguments,g=!1,h;b&&(h=b.call(this,d,function(){g=!0;return a&&a.apply(e,f)}));return g?h:a&&a.apply(e,f)};a=d&&d.apply(this,arguments),d||(this.descend(!0),this.directives(!0)),e.$inject=a&&a.$inject;return e})}var h=[];c.onCreate(function(a){a.$onEval(99999,function(){j()})});return{recordDomAdditions:g,createAngularDirectiveProxy:e,createAngularWidgetProxy:d,removeSlavesWhenMasterIsRemoved:k}}),c("jqmng/widgets/disabledHandling",["jqmng/widgets/widgetProxyUtil"],function(a){var b={};a.createAngularDirectiveProxy("ng:bind-attr",function(a){var c=/([^:{'"]+)/,d=c.exec(a)[1];return d!=="disabled"?function(){}:function(a){var c=this,e;c.$onEval(function(){var c=a.attr(d);if(c!=e){e=c;var f=c?"disable":"enable",g=a.data();for(var h in g)typeof h=="string"&&b[h]&&a[h](f)}})}});return b}),c("jqmng/widgets/jqmButton",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling"],function(a,b){function d(a){return a.filter($.mobile.button.prototype.options.initSelector).not(":jqmData(role='none'), :jqmData(role='nojs')").length>0}function c(b,c){var d=this;b.button(),a.removeSlavesWhenMasterIsRemoved(b,b.parent())}b.button=!0;return{compileButton:c,isButton:d}}),c("jqmng/widgets/angularButton",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/jqmButton"],function(a,b){a.createAngularWidgetProxy("button",function(a){var c=b.isButton(a),d=a.attr("name");return function(a,e){var f=e();c&&b.compileButton.call(this,a,d);return f}})}),c("jqmng/widgets/jqmCollapsible",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling"],function(a,b){function d(a){return a.filter($.mobile.collapsible.prototype.options.initSelector).length>0}function c(a,b){var c=this;a.collapsible()}return{compileCollapsible:c,isCollapsible:d}}),c("jqmng/widgets/angularDiv",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/jqmCollapsible"],function(a,b){a.createAngularWidgetProxy("div",function(a){var c=b.isCollapsible(a),d=a.attr("name");return function(a,e){var f=e();c&&b.compileCollapsible.call(this,a,d);return f}})}),c("jqmng/widgets/jqmSelectMenu",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling","jqmng/widgets/pageCompile"],function(a,b,c){function e(a){return a.filter($.mobile.selectmenu.prototype.options.initSelector).not(":jqmData(role='none'), :jqmData(role='nojs')").length>0}function d(b,d){var e=this;c.afterCompile(function(){var c,f=a.recordDomAdditions(".ui-selectmenu,.ui-selectmenu-screen,:jqmData(role='dialog')",function(){b.selectmenu(),c=b.parent()});c=c.add(f),a.removeSlavesWhenMasterIsRemoved(b,c),e.$watch(d,function(a){b.selectmenu("refresh",!0)});var g;e.$onEval(999999,function(){var a=b[0].childNodes.length;g!==a&&(g=a,b.trigger("change"))})})}b.selectmenu=!0;return{compileSelectMenu:d,isSelectMenu:e}}),c("jqmng/widgets/jqmSlider",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling","jqmng/widgets/pageCompile"],function(a,b,c){function e(a){return a.filter($.mobile.slider.prototype.options.initSelector).not(":jqmData(role='none'), :jqmData(role='nojs')").length>0}function d(b,d){var e=this;c.afterCompile(function(){var c=a.recordDomAdditions(".ui-slider",function(){b.slider()});a.removeSlavesWhenMasterIsRemoved(b,$(c)),e.$watch(d,function(a){b.slider("refresh")})})}b.slider=!0;return{compileSlider:d,isSlider:e}}),c("jqmng/widgets/jqmCheckboxRadio",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling","jqmng/widgets/pageCompile"],function(a,b,c){function e(a){return a.filter($.mobile.checkboxradio.prototype.options.initSelector).not(":jqmData(role='none'), :jqmData(role='nojs')").length>0}function d(a,b){var d=this;c.afterCompile(function(){a.checkboxradio(),d.$watch(b,function(b){a.checkboxradio("refresh")})})}b.checkboxradio=!0;return{compileCheckboxRadio:d,isCheckboxRadio:e}}),c("jqmng/widgets/jqmTextInput",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling"],function(a,b){function d(a){return a.filter($.mobile.textinput.prototype.options.initSelector).not(":jqmData(role='none'), :jqmData(role='nojs')").length>0}function c(a,b){var c=this;a.textinput()}b.textinput=!0;return{compileTextInput:c,isTextInput:d}}),c("jqmng/widgets/angularInput",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/jqmSelectMenu","jqmng/widgets/jqmSlider","jqmng/widgets/jqmCheckboxRadio","jqmng/widgets/jqmTextInput","jqmng/widgets/jqmButton"],function(a,b,c,d,e,f){a.createAngularWidgetProxy("input",function(a){var b=e.isTextInput(a),g=d.isCheckboxRadio(a),h=c.isSlider(a),i=f.isButton(a),j=a.attr("name"),k=a[0].type;b&&(a[0].type="text",a[0]["data-type"]=k);return function(a,l){a[0].type=k;if(g){var m=a.bind;a.bind=function(a,b){a.indexOf("click")!=-1&&(a+=" change");return m.call(this,a,b)}}var n=l();h&&c.compileSlider.call(this,a,j),g&&d.compileCheckboxRadio.call(this,a,j),i&&f.compileButton.call(this,a,j),b&&e.compileTextInput.call(this,a,j);return n}})}),c("jqmng/widgets/angularSelect",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/jqmSelectMenu","jqmng/widgets/jqmSlider"],function(a,b,c){a.createAngularWidgetProxy("select",function(a){var d=b.isSelectMenu(a),e=c.isSlider(a),f=a.attr("name");return function(a,g){var h=g();d&&b.compileSelectMenu.call(this,a,f),e&&c.compileSlider.call(this,a,f);return h}})}),c("jqmng/widgets/jqmListView",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/disabledHandling","jquery","jqmng/widgets/pageCompile"],function(a,b,c,d){function f(a){return a.filter(c.mobile.listview.prototype.options.initSelector).length>0}function e(b){var e=this;d.afterCompile(function(){var d=a.recordDomAdditions(":jqmData(role='page')",function(){b.listview()});a.removeSlavesWhenMasterIsRemoved(b,c(d));var f;e.$onEval(999999,function(){var a=b[0].childNodes.length;f!==a&&(f=a,b.listview("refresh"))})})}return{compileListView:e,isListView:f}}),c("jqmng/widgets/angularUl",["jqmng/widgets/widgetProxyUtil","jqmng/widgets/jqmListView"],function(a,b){a.createAngularWidgetProxy("ul",function(a){var c=b.isListView(a);return function(a,d){var e=d();c&&b.compileListView.call(this,a);return e}})}),c("jqm-angular",["angular","jquery","jqmng/globalScope","jqmng/activePage","jqmng/waitDialog","jqmng/event","jqmng/fadein","jqmng/if","jqmng/paging","jqmng/widgets/pageCompile","jqmng/widgets/angularButton","jqmng/widgets/angularDiv","jqmng/widgets/angularInput","jqmng/widgets/angularSelect","jqmng/widgets/angularUl"],function(a,b,c,d,e){b.mobile.globalScope=c.globalScope,a.service("waitdialog",function(){return e}),a.service("$activePage",function(){return d.activePage});return{globalScope:c.globalScope,activePage:d.activePage,waitDialog:e}})})()
View
27,800 compiled/jquery-mobile-angular-adapter-standalone-1.0.1.js
27,800 additions, 0 deletions not shown
View
1  compiled/jquery-mobile-angular-adapter-standalone-1.0.1.min.js
1 addition, 0 deletions not shown
View
3  pom.xml
@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.opitzconsulting.html5</groupId>
<artifactId>jquery-mobile-angular-adapter</artifactId>
- <version>1.0</version>
+ <version>1.0.1</version>
<name>JQuery Mobile Angular Adapter</name>
<packaging>war</packaging>
<description>Adapter for using jquery mobile with angular</description>
@@ -115,6 +115,7 @@
<name>jquery-mobile-angular-adapter-standalone</name>
<include>
<entry>lib/jquery-1.6.2</entry>
+ <entry>lib/mobileinit</entry>
<entry>lib/angular-0.9.19</entry>
<entry>lib/jquery.mobile-1.0b2-oc1</entry>
<entry>../../../compiled/jquery-mobile-angular-adapter-${version}</entry>
View
12 src/main/webapp/lib/mobileinit.js
@@ -0,0 +1,12 @@
+/**
+ * Helper function to be able to use the jquery mobile mobileinit event
+ * in the standalone build, that already includes jquery and jquery mobile.
+ */
+(function(window) {
+ if (window.mobileinit) {
+ $(window.document).bind("mobileinit", function() {
+ window.mobileinit.apply(this, arguments);
+ });
+ }
+
+})(window);
Please sign in to comment.
Something went wrong with that request. Please try again.