Modified: tuscany/sca-cpp/trunk/hosting/server/htdocs/store/index.html URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/htdocs/store/index.html?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/htdocs/store/index.html (original) +++ tuscany/sca-cpp/trunk/hosting/server/htdocs/store/index.html Mon Feb 11 05:48:20 2013 @@ -50,8 +50,7 @@ var categories = [ ['Featured', 'featured', 1], ['Top', 'top', 2], - //['New', 'new', 3], - //['Search', 'all', 4], + ['New', 'new', 3], ['My Apps', 'myapps', 5] ]; @@ -83,7 +82,7 @@ $('viewhead').innerHTML = (function catm var m = ''; map(function(c) { m += catmenuitem(car(c), cadr(c), caddr(c)); }, categories); - m += '<span class="rmenu"><input type="button" class="bluebutton" id="createApp" title="Create a new app" Value="Create"/></span>'; + m += '<input type="button" class="bluebutton" id="createApp" style="position: absolute; top: 4px; right: 2px;" title="Create a new app" Value="Create"/>'; return m; })(); @@ -113,9 +112,9 @@ function viewapp(appname) { /** * Create an app. */ -$('createApp').onclick = function() { +ui.onclick($('createApp'), function(e) { return ui.navigate('/#view=create', '_view'); -}; +}); /** * Get and display an app icon.
Modified: tuscany/sca-cpp/trunk/hosting/server/icons.py URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/icons.py?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/icons.py (original) +++ tuscany/sca-cpp/trunk/hosting/server/icons.py Mon Feb 11 05:48:20 2013 @@ -105,12 +105,22 @@ def put(id, icon, user, cache, apps): debug('icons.py::put::img', img) iconentry = mkentry(title(app), car(id), author(app), now(), ("'icon", ("'image", img))) debug('icons.py::put::iconentry', iconentry) - return cache.put(iconid(id), iconentry) + rc = cache.put(iconid(id), iconentry) + if rc == False: + return False + + # Update the app's updated date + return apps.put(id, app) # Put default empty icon iconentry = mkentry(title(app), car(id), author(app), now(), ()) debug('icons.py::put::iconentry', iconentry) - return cache.put(iconid(id), iconentry) + rc = cache.put(iconid(id), iconentry) + if rc == False: + return False + + # Update the app's updated date + return apps.put(id, app) # Get an icon def get(id, user, cache, apps): @@ -171,5 +181,10 @@ def delete(id, user, cache, apps): return False # Delete the icon - return cache.delete(iconid(id)) + rc = cache.delete(iconid(id)) + if rc == False: + return False + + # Update the app's updated date + return apps.put(id, app) Modified: tuscany/sca-cpp/trunk/hosting/server/pages.py URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/pages.py?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/pages.py (original) +++ tuscany/sca-cpp/trunk/hosting/server/pages.py Mon Feb 11 05:48:20 2013 @@ -43,7 +43,12 @@ def put(id, page, user, cache, apps): # Update the page in the page db pageentry = mkentry(title(app), car(id), user.get(()), now(), content(page)) debug('pages.py::put::pageentry', pageentry) - return cache.put(pageid(id), pageentry) + rc = cache.put(pageid(id), pageentry) + if rc == False: + return False + + # Update the app's updated date + return apps.put(id, app) # Get a page from the page db def get(id, user, cache, apps): @@ -90,5 +95,10 @@ def delete(id, user, cache, apps): return False # Delete the page - return cache.delete(pageid(id)) + rc = cache.delete(pageid(id)) + if rc == False: + return False + + # Update the app's updated date + return apps.put(id, app) Modified: tuscany/sca-cpp/trunk/hosting/server/ratings.py URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/ratings.py?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/ratings.py (original) +++ tuscany/sca-cpp/trunk/hosting/server/ratings.py Mon Feb 11 05:48:20 2013 @@ -110,9 +110,9 @@ def get(id, user, cache, db, apps): if isNull(id): topentries = db.get((("'regex", '("ratings" .* "app.ratings")'), ("'rank", "(regexp_matches(value, '(.*\(rating )([^\)]+)(\).*)'))[2]::float"), ("'limit", 25))) flatentries = tuple(map(lambda v: car(v), () if isNull(topentries) else topentries)) - def rating(e): + def sortkey(e): return cadr(assoc("'rating", assoc("'ratings", assoc("'content", e)))) - sortedentries = tuple(sorted(flatentries, key = rating, reverse = True)) + sortedentries = tuple(sorted(flatentries, key = sortkey, reverse = True))[0:25] topratings = ((("'feed", ("'title", "Ratings"), ("'id", 'ratings')) + sortedentries),) debug('ratings.py::get::topratings', topratings) return topratings Modified: tuscany/sca-cpp/trunk/hosting/server/server.composite URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/server.composite?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/server.composite (original) +++ tuscany/sca-cpp/trunk/hosting/server/server.composite Mon Feb 11 05:48:20 2013 @@ -105,6 +105,7 @@ <implementation.python script="apps.py"/> <reference name="user" target="User"/> <reference name="cache" target="Cache"/> + <reference name="db" target="Database"/> <reference name="dashboard" target="Dashboards"/> <reference name="store" target="AppStore"/> <reference name="composites" target="Composites"/> Modified: tuscany/sca-cpp/trunk/hosting/server/store.py URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/store.py?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/store.py (original) +++ tuscany/sca-cpp/trunk/hosting/server/store.py Mon Feb 11 05:48:20 2013 @@ -102,6 +102,14 @@ def get(id, user, cache, apps, ratings): debug('store.py::get::store', topstore) return topstore + # Collect the newest apps + if tag == 'new': + newapps = apps.get(()) + newapps = mergeapps(cdddr(car(newapps)), apps, ratings) + newstore = ((("'feed", ("'title", 'App Store'), ("'id", tag)) + newapps),) + debug('store.py::get::store', newstore) + return newstore + # Collect the featured apps appid = cdr(id) def findapp(appid, store): Modified: tuscany/sca-cpp/trunk/hosting/server/test.py URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/test.py?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/hosting/server/test.py (original) +++ tuscany/sca-cpp/trunk/hosting/server/test.py Mon Feb 11 05:48:20 2013 @@ -98,7 +98,7 @@ def testPages(): # Put and get a page cache1 = mkcache('cache', {}) page1updated = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", '[email protected]'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content",)),) - assert pages.put(('app1',), page1, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert pages.put(('app1',), page1, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert pages.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == page1updated # Reject put from user other than the author @@ -113,7 +113,7 @@ def testPages(): assert pages.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == page1updated # Delete a page - assert pages.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert pages.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert pages.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == defpagefromapp return True @@ -137,7 +137,7 @@ def testIcons(): # Put and get a icon cache1 = mkcache('cache', {}) icon1updated = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", '[email protected]'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'icon", ("'image", img50)))),) - assert icons.put(('app1',), icon1, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert icons.put(('app1',), icon1, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert icons.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == icon1updated # Reject put from user other than the author @@ -164,11 +164,11 @@ def testIcons(): # Upload with valid token icon1oktoken = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", '[email protected]'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'icon", ("'image", img50), ("'token", '1234')))),) - assert icons.put(('app1',), icon1oktoken, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert icons.put(('app1',), icon1oktoken, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert icons.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == icon1updated # Delete a icon - assert icons.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert icons.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert icons.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == deficonfromapp return True @@ -187,7 +187,7 @@ def testComposites(): # Put and get a composite cache1 = mkcache('cache', {}) composite1updated = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", '[email protected]'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content",)),) - assert composites.put(('app1',), composite1, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert composites.put(('app1',), composite1, mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert composites.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == composite1updated # Reject put from user other than the author @@ -202,36 +202,36 @@ def testComposites(): assert composites.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == composite1updated # Delete a composite - assert composites.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == True + assert composites.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True assert composites.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('apps', lambda id: app1)) == defcompositefromapp return True def testApps(): # Get default app - assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), mkcache('cache', {}), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) is None + assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), mkcache('cache', {}), mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) is None # Get an app app1 = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", '[email protected]'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'info", ("'description", '')))),) - assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), mkcache('cache', {('apps', 'app1', 'app.info') : app1}), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 + assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), mkcache('cache', {('apps', 'app1', 'app.info') : app1}), mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 # Put and get an app cache1 = mkcache('cache', {}) - assert apps.put(('app1',), app1, mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id, app: True), mkref('store', lambda id, app: True), mkref('composites', lambda id, app: True), mkref('pages', lambda id, app: True), mkref('icons', lambda id, app: True)) == True - assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 + assert apps.put(('app1',), app1, mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id, app: True), mkref('store', lambda id, app: True), mkref('composites', lambda id, app: True), mkref('pages', lambda id, app: True), mkref('icons', lambda id, app: True)) == True + assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 return True # Reject put from user other than the author app1otherauthor = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", '[email protected]'), ("'updated", '2012-01-03T00:00:00+00:00'), ("'content",)),) - assert apps.put(('app1',), app1, mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id, app: True), mkref('store', lambda id, app: True), mkref('composites', lambda id, app: True), mkref('pages', lambda id, app: True), mkref('icons', lambda id, app: True)) == false - assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 + assert apps.put(('app1',), app1, mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id, app: True), mkref('store', lambda id, app: True), mkref('composites', lambda id, app: True), mkref('pages', lambda id, app: True), mkref('icons', lambda id, app: True)) == false + assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 # Reject delete from user other than the author - assert apps.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == False - assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 + assert apps.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == False + assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == app1 # Delete an app - assert apps.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == True - assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), mkcache('cache', {}), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) is None + assert apps.delete(('app1',), mkref('user', lambda id: '[email protected]'), cache1, mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) == True + assert apps.get(('app1',), mkref('user', lambda id: '[email protected]'), mkcache('cache', {}), mkref('db', lambda id: None), mkref('dashboard', lambda id: None), mkref('store', lambda id: None), mkref('composites', lambda id: None), mkref('pages', lambda id: None), mkref('icons', lambda id: None)) is None return True def testStore(): Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/component.js URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/component.js?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/modules/js/htdocs/component.js (original) +++ tuscany/sca-cpp/trunk/modules/js/htdocs/component.js Mon Feb 11 05:48:20 2013 @@ -184,43 +184,113 @@ HTTPBindingClient.jsonResult = function( }; /** - * Schedule async requests, and limit to 4 concurrent running requests. + * Schedule async requests, limiting the number of concurrent running requests. */ HTTPBindingClient.queuedRequests = new Array(); -HTTPBindingClient.runningRequests = 0; -HTTPBindingClient.scheduleAsyncRequest = function(f) { +HTTPBindingClient.runningRequests = new Array(); +HTTPBindingClient.concurrentRequests = 2; + +HTTPBindingClient.scheduleAsyncRequest = function(f, cancelable) { + //debug('schedule async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + // Queue the request function - HTTPBindingClient.queuedRequests.push(f); + var req = new Object(); + req.f = f; + req.cancelable = cancelable; + req.canceled = false; + HTTPBindingClient.queuedRequests.push(req); + + // Execute any requests in the queue + setTimeout(function() { + HTTPBindingClient.runAsyncRequests(true); + }, 0); + return true; +}; - // Execute requests in the queue - (function runAsyncRequests() { - // Stop now if we already have enough requests running or there's no request in the queue - //debug('runAsyncRequests', 'running', HTTPBindingClient.runningRequests, 'queued', HTTPBindingClient.queuedRequests.length); - if(HTTPBindingClient.runningRequests >= 4 || HTTPBindingClient.queuedRequests.length == 0) +HTTPBindingClient.forgetRequest = function(req) { + req.http = null; + + // Remove a request from the list of running requests + for (i in HTTPBindingClient.runningRequests) { + if (HTTPBindingClient.runningRequests[i] == req) { + HTTPBindingClient.runningRequests.splice(i, 1); + //debug('forget async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); return true; + } + } + return false; +}; + +HTTPBindingClient.cancelRequests = function() { + //debug('cancel async requests, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); - // Run the first request in the queue - var req = HTTPBindingClient.queuedRequests.shift(); - HTTPBindingClient.runningRequests++; - setTimeout(function runAsyncRequest() { + // Cancel any cancelable in flight HTTP requests + for (i in HTTPBindingClient.queuedRequests) { + var req = HTTPBindingClient.queuedRequests[i]; + if (req.cancelable) + req.canceled = true; + } + for (i in HTTPBindingClient.runningRequests) { + var req = HTTPBindingClient.runningRequests[i]; + if (req.cancelable) { + req.canceled = true; + if (req.http) { + req.http.abort(); + req.http = null; + //debug('abort async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + } + } + } + + // Flush the queue + setTimeout(function() { + HTTPBindingClient.runAsyncRequests(true); + }, 0); +} + +HTTPBindingClient.runAsyncRequests = function(fromui) { + // Stop now if we already have enough requests running or there's no request in the queue + if(HTTPBindingClient.runningRequests.length >= HTTPBindingClient.concurrentRequests || HTTPBindingClient.queuedRequests.length == 0) + return true; + + // Run the first request in the queue + var req = HTTPBindingClient.queuedRequests.shift(); + if (!req.canceled) { + HTTPBindingClient.runningRequests.push(req); + //debug('run async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + var runAsyncRequest = function() { + if (req.canceled) { + HTTPBindingClient.forgetRequest(req); + //debug('canceled timed async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + return false; + } try { - return req(function asyncRequestDone() { + req.http = new XMLHttpRequest(); + return req.f(req.http, function asyncRequestDone() { // Execute any requests left in the queue - HTTPBindingClient.runningRequests--; - runAsyncRequests(); + HTTPBindingClient.forgetRequest(req); + //debug('done async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + HTTPBindingClient.runAsyncRequests(false); return true; }); } catch(e) { // Execute any requests left in the queue - HTTPBindingClient.runningRequests--; - runAsyncRequests(); + HTTPBindingClient.forgetRequest(req); + //debug('err async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + HTTPBindingClient.runAsyncRequests(false); } - }, 0); + return false; + }; + if (false) + setTimeout(runAsyncRequest, 0); + else + runAsyncRequest(); + } else { + //debug('canceled queued async request, running ' + HTTPBindingClient.runningRequests.length + ' queued ' + HTTPBindingClient.queuedRequests.length); + } - // Execute any requests left in the queue - runAsyncRequests(); - })(); - return true; + // Execute any requests left in the queue + HTTPBindingClient.runAsyncRequests(fromui); }; /** @@ -339,8 +409,7 @@ HTTPBindingClient.prototype.jsonApply = // Call asynchronously with a callback if(hascb) { var u = this.uri; - return HTTPBindingClient.scheduleAsyncRequest(function jsonApplyRequest(done) { - var http = new XMLHttpRequest(); + return HTTPBindingClient.scheduleAsyncRequest(function jsonApplyRequest(http, done) { http.open("POST", u, true); http.setRequestHeader("Accept", "*/*"); http.setRequestHeader("Content-Type", "application/json-rpc"); @@ -371,7 +440,7 @@ HTTPBindingClient.prototype.jsonApply = // Send the request http.send(req.data); return req.id; - }); + }, false); } // Call synchronously and return the result or exception @@ -402,16 +471,15 @@ HTTPBindingClient.prototype.get = functi return item; // Pass local result to callback - try { + setTimeout(function() { cb(item); - } catch (cbe) {} + }, 0); } } // Call asynchronously with a callback if(hascb) { - return HTTPBindingClient.scheduleAsyncRequest(function getRequest(done) { - var http = new XMLHttpRequest(); + return HTTPBindingClient.scheduleAsyncRequest(function getRequest(http, done) { http.open("GET", u, true); http.setRequestHeader("Accept", "*/*"); http.onreadystatechange = function() { @@ -420,7 +488,8 @@ HTTPBindingClient.prototype.get = functi // Pass result if different from local result if(http.status == 200) { var xl = http.getResponseHeader("X-Login"); - if(xl != null && xl != '') { + var ct = http.getResponseHeader("Content-Type"); + if(xl != null && xl != '' && ct != null && ct.indexOf('text/html') == 0) { // Detect redirect to a login page try { var le = new HTTPBindingClient.Exception(403, 'X-Login'); @@ -431,7 +500,6 @@ HTTPBindingClient.prototype.get = functi } catch(cbe) {} } - var ct = http.getResponseHeader("Content-Type"); if(http.responseText == '' || ct == null || ct == '') { // Report empty response try { @@ -467,7 +535,7 @@ HTTPBindingClient.prototype.get = functi // Send the request http.send(null); return true; - }); + }, true); } // Call synchronously and return the result or exception @@ -477,7 +545,8 @@ HTTPBindingClient.prototype.get = functi http.send(null); if(http.status == 200) { var xl = http.getResponseHeader("X-Login"); - if(xl != null && xl != '') { + var ct = http.getResponseHeader("Content-Type"); + if(xl != null && xl != '' && ct != null && ct.indexOf('text/html') == 0) { // Detect redirect to a login page var le = new HTTPBindingClient.Exception(403, 'X-Login'); if(window.onloginredirect) @@ -504,8 +573,7 @@ HTTPBindingClient.prototype.post = funct // Call asynchronously with a callback if(hascb) { var u = this.uri; - return HTTPBindingClient.scheduleAsyncRequest(function postRequest(done) { - var http = new XMLHttpRequest(); + return HTTPBindingClient.scheduleAsyncRequest(function postRequest(http, done) { http.open("POST", u, true); http.setRequestHeader("Accept", "*/*"); http.setRequestHeader("Content-Type", "application/atom+xml"); @@ -529,7 +597,7 @@ HTTPBindingClient.prototype.post = funct // Send the request http.send(entry); return true; - }); + }, false); } // Call synchronously @@ -562,8 +630,7 @@ HTTPBindingClient.prototype.put = functi // Call asynchronously with a callback if(hascb) { - return HTTPBindingClient.scheduleAsyncRequest(function putRequest(done) { - var http = new XMLHttpRequest(); + return HTTPBindingClient.scheduleAsyncRequest(function putRequest(http, done) { http.open("PUT", u, true); http.setRequestHeader("Accept", "*/*"); http.setRequestHeader("Content-Type", "application/atom+xml"); @@ -599,7 +666,7 @@ HTTPBindingClient.prototype.put = functi // Send the request http.send(entry); return true; - }); + }, false); } // Call synchronously @@ -640,8 +707,7 @@ HTTPBindingClient.prototype.del = functi // Call asynchronously with a callback if(hascb) { - return HTTPBindingClient.scheduleAsyncRequest(function delRequest(done) { - var http = new XMLHttpRequest(); + return HTTPBindingClient.scheduleAsyncRequest(function delRequest(http, done) { http.open("DELETE", u, true); http.setRequestHeader("Accept", "*/*"); http.onreadystatechange = function() { @@ -665,7 +731,7 @@ HTTPBindingClient.prototype.del = functi // Send the request http.send(null); return true; - }); + }, false); } // Call synchronously Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js?rev=1444660&r1=1444659&r2=1444660&view=diff ============================================================================== --- tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js (original) +++ tuscany/sca-cpp/trunk/modules/js/htdocs/ui.js Mon Feb 11 05:48:20 2013 @@ -29,6 +29,8 @@ var ui = {}; ui.elementByID = function(node, id) { if (node.skipNode == true) return null; + if (node == document) + return document.getElementById(id); for (var i in node.childNodes) { var child = node.childNodes[i]; if (isNull(child)) @@ -43,6 +45,21 @@ ui.elementByID = function(node, id) { }; /** + * Remove ids in a tree of elements. + */ +ui.removeElementIDs = function(node) { + if (!isNull(node.id)) + node.id = null; + for (var i in node.childNodes) { + var child = node.childNodes[i]; + if (isNull(child)) + continue; + ui.removeElementIDs(child); + } + return true; +}; + +/** * Return the current document, or a child element with the given id. */ function $(id) { @@ -229,6 +246,20 @@ ui.webkitVersion = function() { }; /** + * Return the Safari version. + */ +ui.browserVersion = function() { + return Number(navigator.userAgent.replace(/.*Version\/(\d+\.\d+).*/, '$1')); +}; + +/** + * Return true if the client is Android based. + */ +ui.isAndroid = function() { + return navigator.userAgent.match(/Android/i); +}; + +/** * Return true if the client is Firefox. */ ui.isFirefox = function() { @@ -273,16 +304,11 @@ ui.msieVersion = function() { /** * Run a UI rendering function asynchronously. */ -ui.asyncFrame = null; -ui.async = function(f) { - if (isNull(ui.asyncFrame)) - // Use requestAnimationFrame when available, fallback to setTimeout - ui.asyncFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || - function(f) { - return window.setTimeout(f, 16); - }; - return ui.asyncFrame.call(window, f); +ui.async = function(f, t) { + window.setTimeout(function() { + return f(); + }, isNull(t)? 0 : t); + return true; }; /** @@ -290,10 +316,10 @@ ui.async = function(f) { */ ui.delayed = {} ui.delay = function(f, t) { - var id = window.setTimeout(function() { + var id = window.setTimeout(function() { delete ui.delayed[id]; return f(); - }, isNull(t)? 16 : t); + }, isNull(t)? 0 : t); ui.delayed[id] = id; return id; }; @@ -443,6 +469,9 @@ ui.navigate = function(url, win) { window.ontouchmove = null; } + // Cancel any cancelable HTTP requests + HTTPBindingClient.cancelRequests(); + // Cleanup memoized element lookups ui.unmemo$(); @@ -460,12 +489,65 @@ ui.navigate = function(url, win) { } /** + * Bind a click handler to a widget. + */ +ui.ontouchstart = function(widget, e) { + //debug('ontouchstart'); + widget.down = true; + widget.moved = false; + var t = e.touches[0]; + widget.moveX = t.clientX; + widget.moveY = t.clientY; +}; + +ui.ontouchmove = function(widget, e) { + //debug('ontouchmove'); + var t = e.touches[0]; + if (t.clientX != widget.moveX) { + widget.moveX = t.clientX; + widget.moved = true; + } + if (t.clientY != widget.moveY) { + widget.moveY = t.clientY; + widget.moved = true; + } +}; + +ui.ontouchend = function(widget, e) { + //debug('ontouchend'); + widget.down = false; + if (!widget.moved) { + e.preventDefault(); + return widget.onclick(e); + } +}; + +ui.onclick = function(widget, handler) { + if (ui.isMobile()) { + widget.ontouchstart = function(e) { + return ui.ontouchstart(widget, e); + }; + widget.ontouchmove = function(e) { + return ui.ontouchmove(widget, e); + }; + widget.ontouchend = function(e) { + return ui.ontouchend(widget, e); + }; + } + widget.onclick = function(e) { + //debug('onclick'); + return handler(e); + }; + return widget; +}; + +/** * Build a portable <a href> tag. */ ui.href = function(id, loc, target, html) { if (target == '_blank') return '<a id="' + id + '" href="' + loc + '" target="_blank">' + html + '</a>'; - return '<a id="' + id + '" href="' + loc + '" onclick="return ui.navigate(\'' + loc + '\', \'' + target + '\');">' + html + '</a>'; + return '<a id="' + id + '" href="' + loc + '" ' + (ui.isMobile()? 'ontouchstart="return ui.ontouchstart(this, event);" ontouchmove="return ui.ontouchmove(this, event);" ontouchend="return ui.ontouchend(this, event);" ' : '') + 'onclick="return ui.navigate(\'' + loc + '\', \'' + target + '\');">' + html + '</a>'; }; /** @@ -489,7 +571,7 @@ ui.menufunc = function(id, name, fun, hi function Menu() { this.content = function() { function href(id, fun, html) { - return '<a id="' + id + '" href="/" onclick="' + fun + '">' + html + '</a>'; + return '<a id="' + id + '" href="/" ' + (ui.isMobile()? 'ontouchstart="return ui.ontouchstart(this, event);" ontouchmove="return ui.ontouchmove(this, event);" ontouchend="return ui.ontouchend(this, event);" ' : '') + 'onclick="' + fun + '">' + html + '</a>'; } if (hilight == true)
