Permalink
Browse files

Merge branch 'master' of git://github.com/mozilla-b2g/gaia into lastU…

…pdated

Conflicts:
	apps/settings/index.html
	apps/settings/style/settings.css
  • Loading branch information...
2 parents 59d7365 + 8783efc commit e78b0942505f636dcc057a6ecc553e096f6b0b0e @marshall marshall committed Dec 4, 2012
Showing with 18,208 additions and 5,612 deletions.
  1. +12 −5 apps/bluetooth/js/transfer.js
  2. +3 −4 apps/bluetooth/manifest.webapp
  3. +16 −0 apps/bluetooth/style/transfer.css
  4. +10 −8 apps/browser/index.html
  5. +2 −4 apps/browser/js/browser.js
  6. +3 −1 apps/browser/style/browser.css
  7. +14 −33 apps/calendar/index.html
  8. +195 −119 apps/calendar/js/app.js
  9. +1 −1 apps/calendar/js/controllers/alarm.js
  10. +61 −9 apps/calendar/js/db.js
  11. +12 −5 apps/calendar/js/models/account.js
  12. +4 −4 apps/calendar/js/presets.js
  13. +77 −28 apps/calendar/js/router.js
  14. +12 −5 apps/calendar/js/service/caldav.js
  15. +7 −2 apps/calendar/js/store/account.js
  16. +32 −71 apps/calendar/js/template.js
  17. +15 −16 apps/calendar/js/templates/account.js
  18. +13 −13 apps/calendar/js/templates/calendar.js
  19. +27 −25 apps/calendar/js/templates/day.js
  20. +33 −31 apps/calendar/js/templates/month.js
  21. +19 −15 apps/calendar/js/templates/week.js
  22. +2 −2 apps/calendar/js/{ → utils}/input_parser.js
  23. +1 −1 apps/calendar/js/{ → utils}/ordered_map.js
  24. +5 −4 apps/calendar/js/{ → utils}/overlap.js
  25. +0 −1 apps/calendar/js/views/day.js
  26. +6 −2 apps/calendar/js/views/day_based.js
  27. +1 −1 apps/calendar/js/views/day_child.js
  28. +1 −1 apps/calendar/js/views/modify_event.js
  29. +1 −1 apps/calendar/js/views/time_parent.js
  30. +1 −1 apps/calendar/js/views/week_child.js
  31. +4 −0 apps/calendar/style/day_views.css
  32. +1 −0 apps/calendar/style/settings.css
  33. +5 −0 apps/calendar/style/ui.css
  34. +4 −0 apps/calendar/style/week_view.css
  35. +18 −0 apps/calendar/test/integration/atoms/get_pos.js
  36. +30 −0 apps/calendar/test/integration/atoms/view_swipe.js
  37. +101 −2 apps/calendar/test/integration/calendar_integration.js
  38. +14 −0 apps/calendar/test/integration/calendar_view.js
  39. +7 −4 apps/calendar/test/integration/factory/forms.js
  40. +73 −8 apps/calendar/test/integration/modify_events_test.js
  41. +181 −0 apps/calendar/test/integration/navigation_test.js
  42. +80 −0 apps/calendar/test/integration/views/day_view.js
  43. +5 −3 apps/calendar/test/integration/views/modify_event_view.js
  44. +16 −0 apps/calendar/test/integration/views/month_view.js
  45. +3 −1 apps/calendar/test/integration/views/months_day_view.js
  46. +10 −0 apps/calendar/test/integration/views/week_view.js
  47. +26 −56 apps/calendar/test/unit/app_test.js
  48. +100 −0 apps/calendar/test/unit/db_test.js
  49. +70 −0 apps/calendar/test/unit/dependency_loader_test.js
  50. +1 −1 apps/calendar/test/unit/helper.js
  51. +2 −2 apps/calendar/test/unit/input_parser_test.js
  52. +6 −4 apps/calendar/test/unit/models/account_test.js
  53. +2 −2 apps/calendar/test/unit/ordered_map_test.js
  54. +2 −33 apps/calendar/test/unit/router_test.js
  55. +17 −7 apps/calendar/test/unit/service/caldav_test.js
  56. +4 −6 apps/calendar/test/unit/store/account_test.js
  57. +3 −2 apps/calendar/test/unit/support/factories/all.js
  58. +10 −0 apps/calendar/test/unit/support/templates/mock_template.js
  59. +34 −0 apps/calendar/test/unit/support/views/lazy_mock_view.js
  60. +32 −32 apps/calendar/test/unit/template_test.js
  61. +26 −4 apps/calendar/test/unit/{ → utils}/overlap_test.js
  62. +11 −4 apps/calendar/test/unit/views/day_based_test.js
  63. +1 −1 apps/calendar/test/unit/views/day_child_test.js
  64. +1 −3 apps/calendar/test/unit/views/day_test.js
  65. +11 −5 apps/calendar/test/unit/views/modify_event_test.js
  66. +1 −1 apps/calendar/test/unit/views/month_test.js
  67. +1 −1 apps/calendar/test/unit/views/months_day_test.js
  68. +2 −2 apps/calendar/test/unit/views/time_parent_test.js
  69. +1 −1 apps/calendar/test/unit/views/week_child_test.js
  70. +1 −1 apps/calendar/test/unit/views/week_test.js
  71. +13 −8 apps/camera/js/camera.js
  72. +4 −3 apps/camera/manifest.webapp
  73. +2 −1 apps/clock/manifest.webapp
  74. +7 −8 apps/communications/contacts/fb_import.html
  75. +1 −1 apps/communications/contacts/fb_link.html
  76. +15 −10 apps/communications/contacts/index.html
  77. +8 −6 apps/communications/contacts/js/contacts.js
  78. +34 −9 apps/communications/contacts/js/contacts_form.js
  79. +15 −28 apps/communications/contacts/js/contacts_list.js
  80. +33 −1 apps/communications/contacts/js/contacts_settings.js
  81. +7 −11 apps/communications/contacts/js/contacts_shortcuts.js
  82. +2 −0 apps/communications/contacts/js/fb/fb_contact.js
  83. +3 −4 apps/communications/contacts/js/fb/fb_import.js
  84. +1 −1 apps/communications/contacts/js/search.js
  85. +4 −0 apps/communications/{facebook/js/fb_image_loader.js → contacts/js/utilities/image_loader.js}
  86. +11 −112 apps/communications/contacts/style/app.css
  87. +6 −16 apps/communications/contacts/style/contacts.css
  88. +9 −57 apps/communications/contacts/style/fb/facebook.css
  89. BIN apps/communications/contacts/style/gphx/bitmap/default/vw-jumper/fav.png
  90. BIN apps/communications/contacts/style/gphx/bitmap/default/vw-jumper/search.png
  91. +1 −2 apps/communications/contacts/style/search.css
  92. +2 −2 apps/communications/contacts/test/unit/contacts_list_test.js
  93. +70 −19 apps/communications/dialer/js/dialer.js
  94. +1 −6 apps/communications/dialer/js/handled_call.js
  95. +0 −15 apps/communications/dialer/js/keypad.js
  96. +12 −1 apps/communications/dialer/js/oncall.js
  97. +3 −3 apps/communications/dialer/js/recents.js
  98. +35 −27 apps/communications/dialer/js/ussd.js
  99. +3 −1 apps/communications/dialer/locales/dialer.en-US.properties
  100. +0 −3 apps/communications/dialer/style/commslog.css
  101. +11 −13 apps/communications/dialer/test/unit/handled_call_test.js
  102. +11 −0 apps/communications/dialer/test/unit/mock_call_handler.js
  103. +65 −75 apps/communications/ftu/css/style.css
  104. +35 −32 apps/communications/ftu/index.html
  105. +7 −0 apps/communications/ftu/js/navigation.js
  106. +1 −30 apps/communications/ftu/js/time.js
  107. +35 −29 apps/communications/ftu/js/ui.js
  108. +24 −10 apps/communications/ftu/locales/ftu.en-US.properties
  109. +2 −2 apps/communications/manifest.webapp
  110. +12 −18 apps/email/js/compose-cards.js
  111. +96 −38 apps/email/js/ext/gaia-email-opt.js
  112. +166 −373 apps/email/js/iframe-shims.js
  113. +7 −3 apps/email/js/message-cards.js
  114. +23 −19 apps/fm/style/fm.css
  115. +1 −0 apps/gallery/index.html
  116. +7 −29 apps/gallery/js/Frame.js
  117. +81 −0 apps/gallery/js/MP4Parser.js
  118. +121 −14 apps/gallery/js/MetadataParser.js
  119. +51 −11 apps/gallery/js/VideoPlayer.js
  120. +11 −5 apps/gallery/js/gallery.js
  121. +3 −0 apps/gallery/style/VideoPlayer.css
  122. +5 −5 apps/homescreen/index.html
  123. +43 −2 apps/homescreen/js/grid.js
  124. +6 −5 apps/homescreen/js/homescreen.js
  125. +30 −9 apps/homescreen/js/page.js
  126. +16 −6 apps/homescreen/js/request.js
  127. +3 −1 apps/homescreen/js/wallpaper.js
  128. +5 −0 apps/homescreen/locales/homescreen.en-US.properties
  129. +2 −2 apps/homescreen/style/request.css
  130. +2 −22 apps/keyboard/js/keyboard.js
  131. +0 −5 apps/keyboard/style/keyboard.css
  132. +63 −26 apps/music/js/metadata.js
  133. +8 −1 apps/music/js/music.js
  134. +2 −1 apps/music/manifest.webapp
  135. +1,846 −442 apps/pdfjs/content/build/pdf.js
  136. +9 −2 apps/pdfjs/content/web/images/annotation-check.svg
  137. +14 −2 apps/pdfjs/content/web/images/annotation-comment.svg
  138. +25 −0 apps/pdfjs/content/web/images/annotation-help.svg
  139. +9 −0 apps/pdfjs/content/web/images/annotation-insert.svg
  140. +10 −0 apps/pdfjs/content/web/images/annotation-key.svg
  141. +10 −0 apps/pdfjs/content/web/images/annotation-newparagraph.svg
  142. +41 −0 apps/pdfjs/content/web/images/annotation-note.svg
  143. +15 −0 apps/pdfjs/content/web/images/annotation-paragraph.svg
  144. BIN apps/pdfjs/content/web/images/div_line_left.png
  145. BIN apps/pdfjs/content/web/images/div_line_right.png
  146. BIN apps/pdfjs/content/web/images/document_bg.png
  147. BIN apps/pdfjs/content/web/images/findbarButton-next-rtl.png
  148. BIN apps/pdfjs/content/web/images/findbarButton-next.png
  149. BIN apps/pdfjs/content/web/images/findbarButton-previous-rtl.png
  150. BIN apps/pdfjs/content/web/images/findbarButton-previous.png
  151. BIN apps/pdfjs/content/web/images/icon_next_page.png
  152. BIN apps/pdfjs/content/web/images/icon_previous_page.png
  153. BIN apps/pdfjs/content/web/images/icon_zoom_in.png
  154. BIN apps/pdfjs/content/web/images/icon_zoom_out.png
  155. BIN apps/pdfjs/content/web/images/loading-small.png
  156. BIN apps/pdfjs/content/web/images/spinner.png
  157. BIN apps/pdfjs/content/web/images/toolbar_background.png
  158. +794 −194 apps/pdfjs/content/web/l10n.js
  159. +614 −283 apps/pdfjs/content/web/locale.properties
  160. +111 −0 apps/pdfjs/content/web/locale/ar/viewer.properties
  161. +127 −0 apps/pdfjs/content/web/locale/ca/viewer.properties
  162. +59 −0 apps/pdfjs/content/web/locale/cs/viewer.properties
  163. +107 −0 apps/pdfjs/content/web/locale/da/viewer.properties
  164. +45 −0 apps/pdfjs/content/web/locale/de/viewer.properties
  165. +122 −0 apps/pdfjs/content/web/locale/en-US/viewer.properties
  166. +107 −0 apps/pdfjs/content/web/locale/es/viewer.properties
  167. +108 −0 apps/pdfjs/content/web/locale/fi/viewer.properties
  168. +71 −0 apps/pdfjs/content/web/locale/fr/viewer.properties
  169. +60 −0 apps/pdfjs/content/web/locale/he/viewer.properties
  170. +45 −0 apps/pdfjs/content/web/locale/it/viewer.properties
  171. +122 −0 apps/pdfjs/content/web/locale/ja/viewer.properties
  172. +63 −0 apps/pdfjs/content/web/locale/locale.properties
  173. +121 −0 apps/pdfjs/content/web/locale/nl/viewer.properties
  174. +57 −0 apps/pdfjs/content/web/locale/pl/viewer.properties
  175. +45 −0 apps/pdfjs/content/web/locale/pt-BR/viewer.properties
  176. +56 −0 apps/pdfjs/content/web/locale/ro/viewer.properties
  177. +63 −0 apps/pdfjs/content/web/locale/ru/viewer.properties
  178. +56 −0 apps/pdfjs/content/web/locale/sr/viewer.properties
  179. +122 −0 apps/pdfjs/content/web/locale/sv/viewer.properties
  180. +59 −0 apps/pdfjs/content/web/locale/zh-CN/viewer.properties
  181. +112 −0 apps/pdfjs/content/web/locale/zh-TW/viewer.properties
  182. +8 −0 apps/pdfjs/content/web/viewer-b2g.css
  183. +90 −1,112 apps/pdfjs/content/web/viewer.css
  184. +116 −149 apps/pdfjs/content/web/viewer.html
  185. +1,010 −219 apps/pdfjs/content/web/viewer.js
  186. +2 −1 apps/pdfjs/manifest.webapp
  187. +74 −97 apps/settings/index.html
  188. +1 −1 apps/settings/js/apps.js
  189. +9 −0 apps/settings/js/connectivity.js
  190. +14 −117 apps/settings/js/date_time.js
  191. +28 −0 apps/settings/js/hotspot.js
  192. +31 −13 apps/settings/js/icc.js
  193. +18 −1 apps/settings/js/icc_menu.js
  194. +1 −1 apps/settings/js/phone_lock.js
  195. +23 −4 apps/settings/js/settings.js
  196. +6 −9 apps/settings/js/wifi.js
  197. +2 −1 apps/settings/locales/settings.en-US.properties
  198. +0 −2 apps/settings/manifest.webapp
  199. +6,920 −0 apps/settings/open-source-license.html
  200. +2 −2 apps/settings/style/apps.css
  201. +7 −22 apps/settings/style/lists.css
  202. +4 −4 apps/settings/style/onpair.css
  203. +2 −2 apps/settings/style/phone_lock.css
  204. +29 −5 apps/settings/style/settings.css
  205. +2 −2 apps/settings/style/simcard.css
  206. +0 −2 apps/sms/index.html
  207. +7 −33 apps/sms/js/sms.js
  208. +20 −38 apps/sms/style/sms.css
  209. +0 −11 apps/system/emergency-call/js/keypad.js
  210. +101 −47 apps/system/js/app_install_manager.js
  211. +7 −2 apps/system/js/attention_screen.js
  212. +7 −0 apps/system/js/background_service.js
  213. +4 −4 apps/system/js/bluetooth_transfer.js
  214. +23 −0 apps/system/js/icc_cache.js
  215. +29 −10 apps/system/js/keyboard_manager.js
  216. +6 −3 apps/system/js/operator_variant/operator_variant.js
  217. +6 −4 apps/system/js/statusbar.js
  218. +21 −2 apps/system/js/update_manager.js
  219. +19 −10 apps/system/js/window_manager.js
  220. +3 −3 apps/system/manifest.webapp
  221. BIN apps/system/style/bluetooth_transfer/images/icon_bluetooth.png
  222. +5 −1 apps/system/style/statusbar/statusbar.css
  223. +0 −4 apps/system/style/system/keyboard.css
  224. +1 −0 apps/system/style/system/system.css
  225. +26 −11 apps/system/style/update_manager/update_manager.css
  226. +1 −0 apps/system/style/zindex.css
  227. +329 −127 apps/system/test/unit/app_install_manager_test.js
  228. +64 −0 apps/system/test/unit/mock_navigator_settings.js
  229. +69 −79 apps/system/test/unit/update_manager_test.js
  230. +2 −0 apps/video/js/video.js
  231. +2 −1 apps/video/manifest.webapp
  232. +2 −2 apps/wallpaper/js/pick.js
  233. +3 −2 build/multilocale.py
  234. +3 −5 build/settings.py
  235. +3 −0 build/ua-override-prefs.js
  236. +1 −1 external-apps/maps/origin
  237. +11 −1 shared/js/idletimer.js
  238. +3 −1 shared/js/l10n.js
  239. +13 −12 shared/js/l10n_date.js
  240. +127 −0 shared/js/tz_select.js
  241. +81 −51 shared/locales/date/date.en-US.properties
  242. +0 −1 shared/locales/permissions/permissions.en-US.properties
  243. +0 −1 shared/locales/permissions/permissions.fr.properties
  244. +1 −0 shared/locales/tz.ini
  245. +13 −0 shared/locales/tz/tz.en-US.properties
  246. +4 −4 shared/resources/apn.json
  247. +4 −0 shared/resources/apn/operator-variant.xml
  248. +9 −3 shared/resources/apn/query.js
  249. +0 −572 shared/resources/timezones.json
  250. +483 −0 shared/resources/tz.json
  251. +6 −6 shared/style/headers.css
  252. +40 −0 test_apps/test-agent/agent.js
  253. +1 −45 test_apps/test-agent/index.html
  254. +0 −2 test_apps/test-container/manifest.webapp
  255. +8 −32 test_apps/uitest/js/contacts.js
  256. +0 −11 test_apps/uitest/tests/inlineactivities.html
  257. +37 −20 tests/atoms/gaia_apps.js
  258. +161 −0 tests/atoms/gaia_data_layer.js
  259. +58 −0 tests/atoms/gaia_lock_screen.js
  260. +0 −21 tests/atoms/gaia_unlock.js
Sorry, we could not display the entire diff because it was too big.
View
17 apps/bluetooth/js/transfer.js
@@ -16,7 +16,7 @@ window.addEventListener('localized', function showPanel() {
activity = activityRequest;
if (settings && bluetooth &&
(activity.source.name == 'share') &&
- (activity.source.data.filenames != null)) {
+ (activity.source.data.filepaths != null)) {
isBluetoothEnabled();
} else {
var msg = 'Cannot transfer without blobs data!';
@@ -41,6 +41,10 @@ window.addEventListener('localized', function showPanel() {
var deviceCancelButton =
document.getElementById('device-select-button-cancel');
var deviceOkButton = document.getElementById('device-select-button-ok');
+ // Don't let this form accidentally get submitted
+ document.getElementById('select-option-popup').onsubmit =
+ function handleSubmit(e) { e.preventDefault(); };
+
var _debug = false;
function debug(msg) {
@@ -110,7 +114,10 @@ window.addEventListener('localized', function showPanel() {
};
}
- function cancelTransfer() {
+ function cancelTransfer(evt) {
+ if (evt)
+ evt.preventDefault();
+
dialogConfirmBluetooth.hidden = true;
dialogDeviceSelector.hidden = true;
activity.postError('cancelled');
@@ -219,7 +226,7 @@ window.addEventListener('localized', function showPanel() {
evt.target.setAttribute('aria-checked', 'true');
}
- function transferToDevice() {
+ function transferToDevice(evt) {
var selectee =
deviceSelectorContainers.querySelectorAll('[aria-checked="true"]');
deviceSelect.selectedIndex = selectee[0].dataset.optionIndex;
@@ -232,9 +239,9 @@ window.addEventListener('localized', function showPanel() {
// XXX: Bug 811615 - Miss file name when passing file by Web Activity.
// If above issue is fixed,
// we could refine following code to pass blob to API directly.
- var filenames = activity.source.data.filenames;
+ var filepaths = activity.source.data.filepaths;
var storage = navigator.getDeviceStorage('sdcard');
- var getRequest = storage.get(filenames[0]);
+ var getRequest = storage.get(filepaths[0]);
getRequest.onsuccess = function() {
defaultAdapter.sendFile(targetDevice.address, getRequest.result);
View
7 apps/bluetooth/manifest.webapp
@@ -17,17 +17,16 @@
"activities": {
"share": {
"filters": {
+ "number": 1
},
"disposition": "inline",
"returnValue": true,
"href": "/transfer.html"
}
},
"permissions": {
- "settings":{ "access": "readwrite" },
"bluetooth":{},
- "mozBluetooth":{},
- "device-storage:pictures":{ "access": "readwrite" },
- "device-storage:music":{ "access": "readwrite" }
+ "device-storage:sdcard":{ "access": "readonly" },
+ "settings":{ "access": "readwrite" }
}
}
View
16 apps/bluetooth/style/transfer.css
@@ -151,6 +151,22 @@ button.affirmative.active {
height: 100%;
}
+/* The following rules is to override the styles defined in building blocks of value selector */
+#value-selector li {
+ height: auto;
+ padding-bottom: 0px;
+ line-height: 3.9rem;
+}
+
+#value-selector li span {
+ padding: 1rem 2rem 1rem 1.5rem;
+}
+
+#value-selector li input:checked + span,
+#value-selector li[aria-checked="true"] span {
+ background: url("/bb/value_selector/images/icons/checked.png") no-repeat right center border-box transparent;
+}
+
/* 320x480 phones */
@media screen and (width: 320px) {
html {
View
18 apps/browser/index.html
@@ -65,14 +65,16 @@ <h2 data-l10n-id="top-sites">Top Sites</h2>
</li>
</ul>
</nav>
- <section id="top-sites" role="tabpanel" class="selected">
- </section>
- <section id="bookmarks" role="tabpanel">
- </section>
- <section id="history" role="tabpanel">
- </section>
- <section id="results">
- </section>
+ <div id="tab-panels">
+ <section id="top-sites" role="tabpanel" class="selected">
+ </section>
+ <section id="bookmarks" role="tabpanel">
+ </section>
+ <section id="history" role="tabpanel">
+ </section>
+ <section id="results">
+ </section>
+ </div>
</div>
<div id="crashscreen">
View
6 apps/browser/js/browser.js
@@ -63,9 +63,7 @@ var Browser = {
this.urlInput.addEventListener('mouseup', this.urlMouseUp.bind(this));
this.urlInput.addEventListener('keyup',
this.handleUrlInputKeypress.bind(this));
- this.topSites.addEventListener('click', this.followLink.bind(this));
- this.bookmarks.addEventListener('click', this.followLink.bind(this));
- this.history.addEventListener('click', this.followLink.bind(this));
+ this.tabPanels.addEventListener('click', this.followLink.bind(this));
this.urlButton.addEventListener('click',
this.handleUrlFormSubmit.bind(this));
this.tabsBadge.addEventListener('click',
@@ -169,7 +167,7 @@ var Browser = {
'bookmark-entry-sheet-done', 'bookmark-title', 'bookmark-url',
'bookmark-previous-url', 'bookmark-menu-add-home', 'new-tab-button',
'awesomescreen-cancel-button', 'startscreen', 'top-site-thumbnails',
- 'no-top-sites', 'clear-private-data-button', 'results'];
+ 'no-top-sites', 'clear-private-data-button', 'results', 'tab-panels'];
// Loop and add element with camel style name to Modal Dialog attribute.
elementIDs.forEach(function createElementRef(name) {
View
4 apps/browser/style/browser.css
@@ -611,7 +611,6 @@ ul[role="tablist"] {
li[role="tab"] {
display: inline;
-
}
li[role="tab"] a {
@@ -626,6 +625,9 @@ li[role="tab"] a {
font-size: 14px;
outline: none;
margin-left: -30px;
+ text-overflow: ellipsis;
+ max-width: calc(33% - 37px);
+ overflow: hidden;
}
li[role="tab"]:first-child a {
View
47 apps/calendar/index.html
@@ -4,18 +4,13 @@
<meta charset="utf-8">
<meta http-equiv="pragma" content="no-cache">
<title>Calendar</title>
- <link rel="stylesheet" type="text/css" href="/style/fonts.css">
<link rel="stylesheet" type="text/css" href="/style/calendar.css">
<link rel="stylesheet" type="text/css" href="/style/ui.css">
<link rel="stylesheet" type="text/css" href="/style/day_views.css">
- <link rel="stylesheet" type="text/css" href="/style/week_view.css">
- <link rel="stylesheet" type="text/css" href="/style/modify_event_view.css">
<link rel="stylesheet" type="text/css" href="/style/forms.css">
- <link rel="stylesheet" type="text/css" href="/style/settings.css">
<link rel="stylesheet" type="text/css" href="/style/overlay.css">
<link rel="stylesheet" type="text/css" href="/style/building_blocks.css" />
-
<!-- localization -->
<link rel="resource" type="application/l10n" href="/locales/locales.ini">
<link rel="resource" type="application/l10n" href="/shared/locales/date.ini">
@@ -43,7 +38,6 @@
<!--- utils -->
<script defer src="/js/presets.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/ordered_map.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/calc.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/template.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/responder.js" type="text/javascript" charset="utf-8"></script>
@@ -53,22 +47,27 @@
<script defer src="/js/timespan.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/time_observer.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/interval_tree.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/overlap.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/input_parser.js" type="text/javascript" charset="utf-8"></script>
-
- <!--- templates -->
- <script defer src="/js/templates/month.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/templates/day.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/templates/week.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/templates/account.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/templates/calendar.js" type="text/javascript" charset="utf-8"></script>
<!--- providers -->
<script defer src="/js/provider/abstract.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/provider/local.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/provider/caldav.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/provider/caldav_pull_events.js" type="text/javascript" charset="utf-8"></script>
+ <!-- It's possible to lazy load these, but we include them here to reduce flickering -->
+ <script defer src="/js/views/calendar_colors.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/time_header.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/templates/month.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/templates/day.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/month_child.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/utils/ordered_map.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/utils/overlap.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/time_parent.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/day_based.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/month.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/day_child.js" type="text/javascript" charset="utf-8"></script>
+ <script defer src="/js/views/months_day.js" type="text/javascript" charset="utf-8"></script>
+
<!--- store -->
<script defer src="/js/store/abstract.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/store/busytime.js" type="text/javascript" charset="utf-8"></script>
@@ -85,24 +84,6 @@
<script defer src="/js/models/calendar.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/models/event.js" type="text/javascript" charset="utf-8"></script>
- <!--- views -->
- <script defer src="/js/views/calendar_colors.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/time_header.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/day_based.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/month_child.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/day_child.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/week_child.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/months_day.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/time_parent.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/month.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/day.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/week.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/settings.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/advanced_settings.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/create_account.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/modify_account.js" type="text/javascript" charset="utf-8"></script>
- <script defer src="/js/views/modify_event.js" type="text/javascript" charset="utf-8"></script>
-
<!-- workers / main / controller -->
<script defer src="/js/worker/manager.js" type="text/javascript" charset="utf-8"></script>
<script defer src="/js/controllers/service.js" type="text/javascript" charset="utf-8"></script>
View
314 apps/calendar/js/app.js
@@ -9,6 +9,70 @@ Calendar.App = (function(window) {
*/
var App = {
+ // Dependency map for loading
+ cssBase: '/style/',
+ jsBase: '/js/',
+ dependencies: {
+ Store: {},
+ Style: {},
+ Templates: {},
+ Utils: {},
+ Views: {
+ AdvancedSettings: [
+ {type: 'Templates', name: 'Account'}
+ ],
+ CreateAccount: [
+ {type: 'Templates', name: 'Account'}
+ ],
+ Day: [
+ {type: 'Views', name: 'DayChild'},
+ {type: 'Views', name: 'TimeParent'}
+ ],
+ DayBased: [
+ {type: 'Utils', name: 'OrderedMap'}
+ ],
+ DayChild: [
+ {type: 'Templates', name: 'Day'},
+ {type: 'Utils', name: 'OrderedMap'},
+ {type: 'Utils', name: 'Overlap'},
+ {type: 'Views', name: 'DayBased'}
+ ],
+ ModifyEvent: [
+ {type: 'Style', name: 'ModifyEventView'},
+ {type: 'Utils', name: 'InputParser'}
+ ],
+ Month: [
+ {type: 'Templates', name: 'Month'},
+ {type: 'Views', name: 'MonthChild'},
+ {type: 'Views', name: 'TimeParent'}
+ ],
+ MonthChild: [
+ {type: 'Templates', name: 'Month'}
+ ],
+ MonthsDay: [
+ {type: 'Views', name: 'DayChild'}
+ ],
+ Settings: [
+ {type: 'Style', name: 'Settings'},
+ {type: 'Templates', name: 'Calendar'}
+ ],
+ TimeParent: [
+ {type: 'Utils', name: 'OrderedMap'}
+ ],
+ Week: [
+ {type: 'Style', name: 'WeekView'},
+ {type: 'Templates', name: 'Week'},
+ {type: 'Views', name: 'Day'},
+ {type: 'Views', name: 'WeekChild'}
+ ],
+ WeekChild: [
+ {type: 'Templates', name: 'Week'},
+ {type: 'Utils', name: 'OrderedMap'},
+ {type: 'Views', name: 'DayBased'}
+ ]
+ }
+ },
+
/**
* Entry point for application
* must be called at least once before
@@ -37,36 +101,44 @@ Calendar.App = (function(window) {
this.router.show(url);
},
- _routes: function() {
- var self = this;
+ /**
+ * Shortcut for app.router.state
+ */
+ state: function() {
+ this.router.state.apply(this.router, arguments);
+ },
- function tempView(selector) {
- self._views[selector] = new Calendar.View(selector);
- return selector;
- }
+ /**
+ * Shortcut for app.router.modifier
+ */
+ modifier: function() {
+ this.router.modifier.apply(this.router, arguments);
+ },
- function setPath(data, next) {
- document.body.setAttribute('data-path', data.canonicalPath);
- next();
- }
+ /**
+ * Shortcut for app.router.resetState
+ */
+ resetState: function() {
+ this.router.resetState();
+ },
+
+ _routes: function() {
/* routes */
- this.state('/week/', setPath, 'Week');
- this.state('/day/', setPath, 'Day');
- this.state('/month/', setPath, 'Month', 'MonthsDay');
- this.modifier('/settings/', setPath, 'Settings', { clear: false });
- this.modifier(
- '/advanced-settings/', setPath, 'AdvancedSettings'
- );
+ this.state('/week/', 'Week');
+ this.state('/day/', 'Day');
+ this.state('/month/', ['Month', 'MonthsDay']);
+ this.modifier('/settings/', 'Settings', { clear: false });
+ this.modifier('/advanced-settings/', 'AdvancedSettings');
- this.state('/alarm-display/:id', 'ModifyEvent');
+ this.state('/alarm-display/:id', 'ModifyEvent', { path: false });
- this.state('/add/', setPath, 'ModifyEvent');
- this.state('/event/:id', setPath, 'ModifyEvent');
+ this.state('/add/', 'ModifyEvent');
+ this.state('/event/:id', 'ModifyEvent');
- this.modifier('/select-preset/', setPath, 'CreateAccount');
- this.modifier('/create-account/:preset', setPath, 'ModifyAccount');
- this.modifier('/update-account/:id', setPath, 'ModifyAccount');
+ this.modifier('/select-preset/', 'CreateAccount');
+ this.modifier('/create-account/:preset', 'ModifyAccount');
+ this.modifier('/update-account/:id', 'ModifyAccount');
this.router.start();
@@ -104,11 +176,13 @@ Calendar.App = (function(window) {
this.timeController.move(new Date());
- var header = this.view('TimeHeader');
- var colors = this.view('CalendarColors');
+ this.view('TimeHeader', function(header) {
+ header.render();
+ });
- colors.render();
- header.render();
+ this.view('CalendarColors', function(colors) {
+ colors.render();
+ });
document.body.classList.remove('loading');
this._routes();
@@ -155,6 +229,81 @@ Calendar.App = (function(window) {
},
/**
+ * Loads a resource and all of it's dependencies
+ * @param {String} type of resource to load (folder name).
+ * @param {String} name view name.
+ * @param {Function} callback after all resources are loaded.
+ */
+ loadResource: function(type, name, cb) {
+
+ var file, script, classes = [];
+
+ var head = document.getElementsByTagName('head')[0];
+
+ var self = this;
+
+ /**
+ * Appends a script to the dom
+ */
+ var appendScript = function(config, cb) {
+ // lowercase_and_underscore the view to get the filename
+ file = config.name.replace(/([A-Z])/g, '_$1')
+ .replace(/^_/, '').toLowerCase();
+
+ if (config.type == 'Style') {
+ script = document.createElement('link');
+ script.type = 'text/css';
+ script.rel = 'stylesheet';
+ script.href = self.cssBase + file + '.css';
+ head.appendChild(script);
+ return cb();
+ }
+
+ script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.src = self.jsBase + config.type.toLowerCase() +
+ '/' + file + '.js';
+
+ if (cb) script.onload = cb;
+ head.appendChild(script);
+ };
+
+ /**
+ * Process a dependency node
+ * Ensures all sub-dependencies are processed
+ */
+ function processScripts(node, cb) {
+
+ // If there are no dependencies, or we already have this resource loaded, bail out
+ if (!App.dependencies[node.type] || (Calendar[node.type] && Calendar[node.type][node.name])) {
+ return cb();
+ }
+
+ var dependencies = App.dependencies[node.type][node.name];
+ var numDependencies = dependencies ? dependencies.length : 0;
+ var counter = 0;
+
+ if (numDependencies > 0) {
+ !function processRemaining() {
+ var toProcess = dependencies.shift();
+ processScripts(toProcess, function() {
+ counter++;
+ if (counter >= numDependencies) {
+ appendScript(node, cb);
+ } else {
+ processRemaining();
+ }
+ });
+ }();
+
+ } else {
+ appendScript(node, cb);
+ }
+ }
+ processScripts({type: type, name: name}, cb);
+ },
+
+ /**
* Initializes a provider.
*/
provider: function(name) {
@@ -171,43 +320,39 @@ Calendar.App = (function(window) {
* Initializes a view and stores
* a internal reference so when
* view is called a second
- * time the same view is returned.
+ * time the same view is used.
+ *
+ * Makes an asynchronous call to
+ * load the script if we do not
+ * have the view cached.
*
* // for example if you have
* // a calendar view Foo
*
* Calendar.Views.Foo = Klass;
*
- * var view = app.view('Foo');
- * (view instanceof Calendar.Views.Foo) === true
+ * app.view('Foo', function(view) {
+ * (view instanceof Calendar.Views.Foo) === true
+ * });
*
* @param {String} name view name.
+ * @param {Function} view loaded callback.
*/
- view: function(name) {
-
+ view: function(name, cb) {
if (!(name in this._views)) {
- this._views[name] = new Calendar.Views[name]({
- app: this
- });
- }
-
- return this._views[name];
- },
+ this.loadResource('Views', name, function() {
+ this._views[name] = new Calendar.Views[name]({
+ app: this
+ });
+ cb.call(this, this._views[name]);
+ }.bind(this));
- /**
- * Re-usable (via bind) function
- * to create view callbacks.
- */
- _routeCallback: function(object, ctx, next) {
-
- if (typeof(object) === 'string') {
- object = this.view(object);
+ } else {
+ cb.call(this, this._views[name]);
}
-
- this.router.mangeObject(object, ctx);
- next();
},
+
/**
* Pure convenience function for
* referencing a object store.
@@ -217,75 +362,6 @@ Calendar.App = (function(window) {
*/
store: function(name) {
return this.db.getStore(name);
- },
-
- /**
- * Wraps a view object in a function
- * so it can be used with a router.
- *
- * Caches results so to not create
- * duplicate functions.
- */
- _wrapViewObject: function(name) {
- var self = this;
-
- if (!(name in this._routeViewFn)) {
- var routeViewCallback = this._routeCallback.bind(this, name);
- this._routeViewFn[name] = routeViewCallback;
- }
-
- return this._routeViewFn[name];
- },
-
- _mapRoutes: function(args) {
- args = Array.prototype.slice.call(args);
-
- var path = args.shift();
- var self = this;
-
- var list = args.map(function(value) {
- var type = typeof(value);
-
- if (type === 'string') {
- return self._wrapViewObject(value);
- } else if (type === 'object') {
- return self._routeCallback.bind(self, value);
- }
- return value;
- });
-
- list.unshift(path);
-
- return list;
- },
-
- resetState: function() {
- if (!this.currentPath) {
- this.currentPath = '/month/';
- }
-
- this.go(this.currentPath);
- },
-
- state: function() {
- var self = this;
- this.router.state.apply(
- this.router,
- this._mapRoutes(arguments).concat([
- // HACK: Sets current path in app.
- function(ctx, next) {
- self.currentPath = ctx.canonicalPath;
- next();
- }
- ])
- );
- },
-
- modifier: function() {
- this.router.modifier.apply(
- this.router,
- this._mapRoutes(arguments)
- );
}
};
View
2 apps/calendar/js/controllers/alarm.js
@@ -118,7 +118,7 @@ Calendar.ns('Controllers').Alarm = (function() {
if (endDate > now) {
self._sendAlarmNotification(alarm, event, busytime);
}
- }
+ };
alarmStore.get(alarm._id, trans, function(err, record) {
dbAlarm = record;
View
70 apps/calendar/js/db.js
@@ -1,6 +1,6 @@
(function(window) {
var idb = window.indexedDB;
- const VERSION = 11;
+ const VERSION = 12;
var debug = Calendar.debug('database');
var store = {
@@ -165,7 +165,7 @@
req.onblocked = function(error) {
callback(error, null);
self.emit('error', error);
- }
+ };
req.onupgradeneeded = function(event) {
self._handleVersionChange(req.result, event);
@@ -294,6 +294,10 @@
if (this.oldVersion !== 0) {
this._upgradeOperations.push(this._resetCaldavAccounts);
}
+ } else if (curVersion === 11) {
+ if (this.oldVersion !== 0) {
+ this._upgradeOperations.push(this._upgradeAccountUrls);
+ }
}
}
},
@@ -373,15 +377,15 @@
req.onblocked = function(e) {
// improve interface
callback(new Error('blocked'));
- }
+ };
req.onsuccess = function(event) {
callback(null, event);
- }
+ };
req.onerror = function(event) {
callback(event, null);
- }
+ };
},
/** private db upgrade methods **/
@@ -426,7 +430,7 @@
trans.oncomplete = function() {
callback();
- }
+ };
var caldavAccounts = Object.create(null);
@@ -469,6 +473,54 @@
};
},
+ _upgradeAccountUrls: function(callback) {
+ var trans = this.transaction(store.accounts, 'readwrite');
+
+ trans.oncomplete = function() {
+ callback();
+ }
+
+ trans.onerror = function(event) {
+ console.error('Error updating account urls');
+ callback(event.error.name);
+ }
+
+ var accountStore = trans.objectStore(store.accounts);
+ var req = accountStore.openCursor();
+
+ req.onsuccess = function upgradeUrls(e) {
+ var cursor = e.target.result;
+ if (cursor) {
+ var value = cursor.value;
+ var preset = value.preset;
+
+ value.calendarHome = value.url;
+
+ // url is removed we have two urls now so
+ // it would be unnecessarily confusing.
+ delete value.url;
+
+ // when possible we calculate the correct
+ // entrypoint (from our presets) if the preset
+ // is missing then we fallback to the original url.
+ if (preset in Calendar.Presets) {
+ var presetData = Calendar.Presets[preset].options;
+
+ // not using "in" intentionally.
+ if (presetData && presetData.entrypoint) {
+ value.entrypoint = presetData.entrypoint;
+ }
+ }
+
+ if (!value.entrypoint) {
+ value.entrypoint = value.calendarHome;
+ }
+ cursor.update(value);
+ cursor.continue();
+ }
+ };
+ },
+
_upgradeMoveICALComponents: function(callback) {
var trans = this.transaction(
[store.events, store.icalComponents],
@@ -478,11 +530,11 @@
trans.onerror = function() {
console.error('Error while upgrading ical components');
callback();
- }
+ };
trans.oncomplete = function() {
callback();
- }
+ };
var eventStore = trans.objectStore(store.events);
var componentStore = trans.objectStore(store.icalComponents);
@@ -504,7 +556,7 @@
cursor.continue();
}
- }
+ };
}
};
View
17 apps/calendar/js/models/account.js
@@ -40,7 +40,13 @@
/**
* url/path for account
*/
- url: '',
+ entrypoint: '',
+
+ /**
+ * Location where calendars can be found.
+ * May be the same as entrypoint.
+ */
+ calendarHome: '',
/**
* username for authentication
@@ -53,14 +59,14 @@
password: '',
get fullUrl() {
- return this.domain + this.url;
+ return this.domain + this.entrypoint;
},
set fullUrl(value) {
var protocolIdx = value.indexOf('://');
this.domain = value;
- this.url = '/';
+ this.entrypoint = '/';
if (protocolIdx !== -1) {
protocolIdx += 3;
@@ -72,7 +78,7 @@
if (pathIdx !== -1) {
pathIdx = pathIdx + protocolIdx;
- this.url = value.substr(pathIdx);
+ this.entrypoint = value.substr(pathIdx);
this.domain = value.substr(0, pathIdx);
}
@@ -88,7 +94,8 @@
toJSON: function() {
var output = {};
var fields = [
- 'url',
+ 'entrypoint',
+ 'calendarHome',
'domain',
'password',
'user',
View
8 apps/calendar/js/presets.js
@@ -6,7 +6,7 @@
options: {
providerType: 'Caldav',
domain: 'https://calendar.google.com',
- url: '/calendar/dav/',
+ entrypoint: '/calendar/dav/',
user: '@gmail.com'
}
},
@@ -16,7 +16,7 @@
options: {
domain: 'https://caldav.calendar.yahoo.com',
providerType: 'Caldav',
- url: '/',
+ entrypoint: '/',
user: '@yahoo.com'
}
},
@@ -27,7 +27,7 @@
options: {
domain: '',
providerType: 'Caldav',
- url: ''
+ entrypoint: ''
}
},
@@ -46,7 +46,7 @@
options: {
domain: 'https://mail.mozilla.com',
providerType: 'Caldav',
- url: '',
+ entrypoint: '',
user: '@mozilla.com'
}
}
View
105 apps/calendar/js/router.js
@@ -7,7 +7,6 @@
this.page = page;
this._activeObjects = [];
- this._clearObjects = this._clearObjects.bind(this);
for (; i < len; i++) {
this[COPY_METHODS[i]] = this.page[COPY_METHODS[i]].bind(this.page);
@@ -42,15 +41,14 @@
* Clears active objects, calls oninactive
* on object if available.
*/
- _clearObjects: function(ctx, next) {
+ clearObjects: function(ctx) {
var item;
while ((item = this._activeObjects.pop())) {
// intentionally using 'in'
if ('oninactive' in item) {
item.oninactive();
}
}
- next();
},
/**
@@ -65,25 +63,12 @@
this.last = ctx;
},
- _route: function() {
- var args = Array.prototype.slice.call(arguments);
-
- //add noop so next works correctly...
- args.push(this._lastState);
-
- var len = args.length;
- var i = 0;
- var item;
-
- this.page.apply(this.page, args);
- },
+ resetState: function() {
+ if (!this.currentPath) {
+ this.currentPath = '/month/';
+ }
- /**
- * Adds a state modifier
- *
- */
- modifier: function() {
- this._route.apply(this, arguments);
+ this.show(this.currentPath);
},
/**
@@ -96,16 +81,80 @@
* of a given state (without exiting it)
*
* @param {String} path path as defined by page.js.
- * @param {Function|Object...} args unlimited number of objects or function
- * callbacks.
+ * @param {String|Array} one or multiple view identifiers
+ * @param {Object} options: (clear, path)
*/
- state: function() {
- var args = Array.prototype.slice.call(arguments);
- args.splice(1, 0, this._clearObjects);
+ state: function(path, views, options) {
- this._route.apply(this, args);
- }
+ options = options || {};
+ if (!Array.isArray(views)) {
+ views = [views];
+ }
+
+ var self = this;
+ var viewObjs = [];
+
+ function setPath(ctx, next) {
+
+ // Reset our views
+ viewObjs = [];
+
+ if (options.path !== false) {
+ document.body.dataset.path = ctx.canonicalPath;
+ }
+ next();
+ }
+ function loadAllViews(ctx, next) {
+ var len = views.length;
+ var numViews = len;
+ var i;
+
+ for (i = 0; i < numViews; i++) {
+ Calendar.App.view(views[i], function(view) {
+ viewObjs.push(view);
+ len--;
+
+ if (!len) {
+ next();
+ }
+ });
+ }
+ }
+
+ function handleViews(ctx, next) {
+
+ // Clear views if needed
+ if (options.clear !== false) {
+ self.clearObjects();
+ }
+
+ // Activate objects
+ for (var i = 0,view; view = viewObjs[i]; i++) {
+ self.mangeObject(view, ctx);
+ }
+
+ // Set the current path
+ if (options.appPath !== false) {
+ self.currentPath = ctx.canonicalPath;
+ }
+
+ next();
+ }
+
+ this.page(path, setPath, loadAllViews, handleViews, this._lastState);
+ },
+
+ /**
+ * Adds a modifier route
+ * Modifiers are eseentially views, without the currentPath updating
+ */
+ modifier: function(path, view, options) {
+ options = options || {};
+ options.appPath = false;
+ options.clear = false;
+ this.state(path, view, options)
+ }
};
Calendar.Router = Router;
View
17 apps/calendar/js/service/caldav.js
@@ -102,12 +102,19 @@ Calendar.ns('Service').Caldav = (function() {
},
getAccount: function(account, callback) {
- var url = account.url;
+ var url = account.entrypoint;
var connection = new Caldav.Connection(account);
var request = this._requestHome(connection, url);
- return request.send(function() {
- callback.apply(this, arguments);
+ return request.send(function(err, data) {
+ if (err) {
+ callback(err);
+ return;
+ }
+
+ callback(null, {
+ calendarHome: data.url
+ });
});
},
@@ -126,7 +133,7 @@ Calendar.ns('Service').Caldav = (function() {
findCalendars: function(account, callback) {
var self = this;
- var url = account.url;
+ var url = account.calendarHome;
var connection = new Caldav.Connection(
account
);
@@ -755,7 +762,7 @@ Calendar.ns('Service').Caldav = (function() {
target.endDate = self.formatInputTime(event.end);
var vcal = target.component.parent.toString();
- event.icalComponent = target.component.parent.toJSON();
+ event.icalComponent = vcal;
req.put({ etag: etag }, vcal, function(err, data, xhr) {
var token = xhr.getResponseHeader('Etag');
View
9 apps/calendar/js/store/account.js
@@ -21,8 +21,13 @@
return;
}
- if ('url' in data) {
- model.url = data.url;
+ // if this works we always will get a calendar home.
+ // This is used to find calendars.
+ model.calendarHome = data.calendarHome;
+
+ // entrypoint is used to re-authenticate.
+ if ('entrypoint' in data) {
+ model.entrypoint = data.entrypoint;
}
if ('domain' in data) {
View
103 apps/calendar/js/template.js
@@ -1,8 +1,4 @@
(function(window) {
- var FORMAT_REGEX;
- FORMAT_REGEX = new RegExp('\\{([a-zA-Z0-9\\-\\_\\.]+)\\|?' +
- '([a-z0-9A-Z]+)?' +
- '(=([a-z-A-Z0-9\\-_ ]+))?\\}', 'g');
var POSSIBLE_HTML = /[&<>"'`]/;
@@ -20,105 +16,70 @@
return result;
}
- function Template(str) {
- this.template = str;
+ function Template(fn) {
+ this.template = fn;
}
Template.handlers = {
- 'h': function(arg) {
+ arg: function(key) {
+ if (typeof(this.data) === 'undefined') {
+ return '';
+ } else if (typeof(this.data) !== 'object') {
+ return this.data;
+ }
+
+ return this.data[key];
+ },
+
+ 'h': function(a) {
+
+ var arg = this.arg(a);
+
//only escape bad looking stuff saves
//a ton of time
if (POSSIBLE_HTML.test(arg)) {
span.textContent = arg;
return span.innerHTML.replace(/"/g, '&quot;').replace(/'/g, '&#x27;');
} else {
- return arg.toString();
+ return String(arg);
}
},
- bool: function(value, onTrue) {
- if (value) {
+ 's': function(a) {
+ var arg = this.arg(a);
+ return String((arg || ''));
+ },
+
+ bool: function(key, onTrue) {
+ if (this.data[key]) {
return onTrue;
} else {
return '';
}
},
- 'l10n': function(name, prefix) {
+ 'l10n': function(key, prefix) {
+ var value = this.arg(key);
+
if (prefix) {
- name = prefix + name;
+ value = prefix + value;
}
- return navigator.mozL10n.get(name);
+ return navigator.mozL10n.get(value);
}
};
Template.prototype = {
- compile: function(str) {
- // Split the template string with template placeholders
- // the resulting array is a mix of plain text string
- // and placeholder pieces.
- var chunks = str.split(FORMAT_REGEX);
- return this.processTemplate.bind(this, chunks);
- },
-
- processTemplate: function processTemplate(chunks, a) {
- if (typeof(a) === 'undefined') {
- a = {};
- } else if (typeof(a) !== 'object') {
- a = { 'value': a };
- }
- var processPlaceholder = this.processPlaceholder.bind(null,
- Calendar.Template.handlers,
- a);
- var str = [];
- for (var i = 0; i < chunks.length; i++) {
- // Append plain text piece of string
- str.push(chunks[i]);
- // Thanks to `str.split(FORMAT_REGEX)`, `chunks`
- // contains non-placeholder piece of the template
- // followed by the Regexp matching placeholders.
- // FORMAT_REGEX has 4 internal matches.
- // So the next 4 items are FORMAT_REGEX matches.
- if (i < chunks.length-4) {
- var matches = chunks.slice(i+1, i+5);
- var placeholder = processPlaceholder.apply(null,
- matches);
- // Append processed placeholder
- str.push(placeholder);
- i += 4;
- }
- }
- return str.join('');
- },
-
- processPlaceholder: function processPlaceholder(handlers, a, name, type,
- wrap, value) {
- if (!type) {
- type = 'h';
- }
-
- if (type === 's') {
- return String((a[name] || ""));
- } else {
- if (value) {
- return handlers[type](a[name] || "", value || '');
- } else {
- return handlers[type](a[name] || "");
- }
- }
- },
-
/**
* Renders template with given slots.
*
* @param {Object} object key, value pairs for template.
*/
- render: function() {
- this.render = this.compile(this.template);
- return this.render.apply(this, arguments);
+ render: function(data) {
+ Template.handlers.data = data;
+ return this.template.apply(Template.handlers);
},
/**
View
31 apps/calendar/js/templates/account.js
@@ -1,23 +1,22 @@
(function(window) {
var Account = Calendar.Template.create({
- provider: [
- '<li class="{name}">',
- '<a data-provider="{name}" href="/create-account/{name}">',
- '{name|l10n=preset-}',
- '</a>',
- '</li>'
- ].join(''),
-
- account: [
- '<li id="account-{id}">',
- '<a href="/update-account/{id}">',
- '<span class="preset">{preset|l10n=preset-}</span>',
- '<span class="user">{user}</span>',
- '</a>',
- '</li>'
- ].join('')
+ provider: function() {
+ return '<li class="' + this.h('name') + '">' +
+ '<a data-provider="' + this.h('name') + '" href="/create-account/' + this.h('name') + '">' +
+ this.l10n('name', 'preset-') +
+ '</a>' +
+ '</li>';
+ },
+ account: function() {
+ return '<li id="account-' + this.h('id') + '">' +
+ '<a href="/update-account/' + this.h('id') + '">' +
+ '<span class="preset">' + this.l10n('preset', 'preset-') + '</span>' +
+ '<span class="user">' + this.h('user') + '</span>' +
+ '</a>' +
+ '</li>';
+ }
});
Calendar.ns('Templates').Account = Account;
View
26 apps/calendar/js/templates/calendar.js
@@ -1,19 +1,19 @@
(function(window) {
var Cal = Calendar.Template.create({
- item: [
- '<li id="calendar-{_id}">',
- '<div class="calendar-id-{_id} calendar-color"></div>',
- '<label>',
- '<span class="name">{name}</span>',
- '<input ',
- 'value="{_id}" ',
- 'type="checkbox" ',
- '{localDisplayed|bool=checked} />',
- '<span></span>',
- '</label>',
- '</li>'
- ].join('')
+ item: function() {
+ return '<li id="calendar-' + this.h('_id') + '">' +
+ '<div class="calendar-id-' + this.h('_id') + ' calendar-color"></div>' +
+ '<label>' +
+ '<span class="name">' + this.h('name') + '</span>' +
+ '<input ' +
+ 'value="' + this.h('_id') + '" ' +
+ 'type="checkbox" ' +
+ this.bool('localDisplayed', 'checked') + ' />' +
+ '<span></span>' +
+ '</label>' +
+ '</li>';
+ }
});
Calendar.ns('Templates').Calendar = Cal;
View
52 apps/calendar/js/templates/day.js
@@ -1,36 +1,38 @@
(function(window) {
+
var Day = Calendar.Template.create({
- hour: [
- '<section class="hour hour-{hour} {classes} calendar-display">',
- '<h4>',
- '<span class="display-hour {hour}">{displayHour}</span>',
- '</h4>',
- /** has no semantic value - re-evaluate */
- '<div class="events">{items|s}</div>',
- '</section>'
- ].join(''),
+ hour: function() {
+ return '<section class="hour hour-' + this.h('hour') + ' ' + this.h('classes') + ' calendar-display">' +
+ '<h4>' +
+ '<span class="display-hour ' + this.h('hour') + '">' + this.h('displayHour') + '</span>' +
+ '</h4>' +
+ /** has no semantic value - re-evaluate */
+ '<div class="events">' + this.s('items') + '</div>' +
+ '</section>';
+ },
- attendee: '<span class="attendee">{value}</span>',
+ attendee: function() {
+ return '<span class="attendee">' + this.h('value') + '</span>';
+ },
- event: [
- '<section class="event calendar-id-{calendarId} ' +
- 'calendar-display" data-id="{busytimeId}">',
- '<div class="container calendar-id-{calendarId} calendar-color">',
- '<h5>{title}</h5>',
- '<span class="details">',
- '<span class="location">',
- '{location}',
- '</span>',
- '{attendees|s}',
- '</span>',
- '</div>',
- '</section>'
- ].join('')
+ event: function() {
+ return '<section class="event calendar-id-' + this.h('calendarId') + ' ' +
+ 'calendar-display" data-id="' + this.h('busytimeId') + '">' +
+ '<div class="container calendar-id-' + this.h('calendarId') + ' calendar-color">' +
+ '<h5>' + this.h('title') + '</h5>' +
+ '<span class="details">' +
+ '<span class="location">' +
+ this.h('location') +
+ '</span>' +
+ this.s('attendees') +
+ '</span>' +
+ '</div>' +
+ '</section>';
+ }
});
Day.eventSelector = '.event';
Day.hourEventsSelector = '.events';
Calendar.ns('Templates').Day = Day;
}(this));
-
View
64 apps/calendar/js/templates/month.js
@@ -1,41 +1,43 @@
(function(window) {
var Month = Calendar.Template.create({
- busy: '<span class="' +
- 'busytime-{_id} ' +
- 'busy-length-{length} ' +
- 'busy-{start} ' +
- 'calendar-id-{calendarId} calendar-color calendar-display' +
- '">' +
- '&nbsp;' +
- '</span>',
+ busy: function() {
+ return '<span class="' +
+ 'busytime-' + this.h('_id') +
+ ' busy-length-' + this.h('length') +
+ ' busy-' + this.h('start') +
+ ' calendar-id-' + this.h('calendarId') + ' calendar-color calendar-display' +
+ '">' +
+ '&nbsp;' +
+ '</span>';
+ },
- weekDaysHeader: [
- '<header id="month-days">',
- '<ol role="row">',
- '{value|s}',
- '</ol>',
- '</header>'
- ].join(''),
+ weekDaysHeader: function() {
+ return '<header id="month-days">' +
+ '<ol role="row">' +
+ this.s('value') +
+ '</ol>' +
+ '</header>';
+ },
- weekDaysHeaderDay: [
- '<li data-l10n-id="weekday-{day}-short">',
- '{dayName}',
- '</li>'
- ].join(''),
+ weekDaysHeaderDay: function() {
+ return '<li data-l10n-id="weekday-' + this.h('day') + '-short">' +
+ this.h('dayName') +
+ '</li>';
+ },
- week: [
- '<ol role="row">',
- '{value|s}',
- '</ol>'
- ].join(''),
+ week: function() {
+ return '<ol role="row">' +
+ this.s('value') +
+ '</ol>';
+ },
- day: [
- '<li id="{id|s}" data-date="{dateString|s}" class="{state|s}">',
- '<span class="day">{date}</span>',
- '<div class="busy-indicator">{busy|s}</div>',
- '</li>'
- ].join('')
+ day: function() {
+ return '<li id="' + this.s('id') + '" data-date="' + this.s('dateString') + '" class="' + this.s('state') + '">' +
+ '<span class="day">' + this.h('date') + '</span>' +
+ '<div class="busy-indicator">' + this.s('busy') + '</div>' +
+ '</li>';
+ }
});
Calendar.ns('Templates').Month = Month;
View
34 apps/calendar/js/templates/week.js
@@ -1,23 +1,27 @@
(function(window) {
var Week = Calendar.Template.create({
- header: '<h1 class="date">{value}</h1>',
+ header: function() {
+ return '<h1 class="date">' + this.h('value') + '</h1>';