From f6ac2e0d949024343e54dc080d8ad6aea87ab21e Mon Sep 17 00:00:00 2001 From: "Jiten Rangwala (OpenERP)" Date: Wed, 8 Jun 2011 11:21:39 +0530 Subject: [PATCH] [ADD] Add web_mobile in to this new branch for mobile project. bzr revid: jra@tinyerp.com-20110608055139-j5p8fnrwm0ju3ial --- addons/web_mobile/__init__.py | 1 + addons/web_mobile/__openerp__.py | 6 + addons/web_mobile/controllers/__init__.py | 1 + addons/web_mobile/controllers/main.py | 649 ++ .../static/openerp/dynamics/OpenERPmobile.css | 1662 ++++ .../openerp/dynamics/images/ajax-loader.png | Bin 0 -> 503 bytes .../dynamics/images/form-check-off.png | Bin 0 -> 364 bytes .../openerp/dynamics/images/form-check-on.png | Bin 0 -> 460 bytes .../dynamics/images/form-radio-off.png | Bin 0 -> 453 bytes .../openerp/dynamics/images/form-radio-on.png | Bin 0 -> 519 bytes .../dynamics/images/icon-search-black.png | Bin 0 -> 1245 bytes .../openerp/dynamics/images/icone-folder.png | Bin 0 -> 796 bytes .../openerp/dynamics/images/icone-save.png | Bin 0 -> 416 bytes .../dynamics/images/icons-18-black.png | Bin 0 -> 935 bytes .../dynamics/images/icons-18-white.png | Bin 0 -> 940 bytes .../dynamics/images/icons-36-black.png | Bin 0 -> 1331 bytes .../dynamics/images/icons-36-white.png | Bin 0 -> 1331 bytes .../openerp/dynamics/jquer.mobile-1.0a3.js | 4492 +++++++++ .../static/openerp/dynamics/jquery-1.5.1.js | 8316 +++++++++++++++++ .../openerp/dynamics/test/LoginPage.html | 48 + .../static/openerp/dynamics/testConnect.js | 21 + .../static/openerp/mockup/OpenERPmobile.css | 1662 ++++ .../openerp/mockup/formview/AdressesForm.html | 130 + .../openerp/mockup/formview/BankAccount.html | 61 + .../mockup/formview/CustomersForm.html | 117 + .../mockup/formview/CustomersFormClear.html | 114 + .../mockup/formview/CustomersInvoices.html | 106 + .../mockup/formview/CustomersRefunds.html | 106 + .../mockup/formview/DeliverProductsForm.html | 67 + .../openerp/mockup/formview/EMailForm.html | 46 + .../openerp/mockup/formview/EMailForm2.html | 46 + .../openerp/mockup/formview/InboundCall.html | 82 + .../formview/InvitationDetailsForm.html | 44 + .../openerp/mockup/formview/InvoiceLine.html | 56 + .../openerp/mockup/formview/MeetingsForm.html | 82 + .../openerp/mockup/formview/Opportunity.html | 70 + .../openerp/mockup/formview/OutboundCall.html | 81 + .../mockup/formview/PaymentCustomerForm.html | 31 + .../mockup/formview/PaymentSupplierForm.html | 31 + .../formview/PhysicalInventoryForm.html | 46 + .../PhysicalInventoryProductsForm.html | 48 + .../openerp/mockup/formview/Preferences.html | 60 + .../formview/ProcurmentExceptionsForm.html | 157 + .../openerp/mockup/formview/ProductsForm.html | 327 + .../mockup/formview/ReceiveProductsForm.html | 67 + .../mockup/formview/SaleOrderLines.html | 95 + .../openerp/mockup/formview/SalesOrders.html | 104 + .../mockup/formview/SalesOrdersCanceled.html | 104 + .../mockup/formview/SalesOrdersConfirm.html | 105 + .../mockup/formview/StockMovesForm.html | 67 + .../mockup/formview/SuppliersForm.html | 115 + .../mockup/formview/SuppliersInvoices.html | 138 + .../mockup/formview/SuppliersRefunds.html | 138 + .../mockup/formview/WHProductsForm.html | 329 + .../openerp/mockup/formview/password.html | 39 + .../openerp/mockup/images/ajax-loader.png | Bin 0 -> 503 bytes .../openerp/mockup/images/form-check-off.png | Bin 0 -> 364 bytes .../openerp/mockup/images/form-check-on.png | Bin 0 -> 460 bytes .../openerp/mockup/images/form-radio-off.png | Bin 0 -> 453 bytes .../openerp/mockup/images/form-radio-on.png | Bin 0 -> 519 bytes .../mockup/images/icon-search-black.png | Bin 0 -> 1245 bytes .../openerp/mockup/images/icone-folder.png | Bin 0 -> 796 bytes .../openerp/mockup/images/icone-save.png | Bin 0 -> 416 bytes .../openerp/mockup/images/icons-18-black.png | Bin 0 -> 935 bytes .../openerp/mockup/images/icons-18-white.png | Bin 0 -> 940 bytes .../openerp/mockup/images/icons-36-black.png | Bin 0 -> 1331 bytes .../openerp/mockup/images/icons-36-white.png | Bin 0 -> 1331 bytes .../openerp/mockup/jquer.mobile-1.0a3.js | 4492 +++++++++ .../static/openerp/mockup/jquery-1.5.1.js | 8316 +++++++++++++++++ .../openerp/mockup/listview/AdressesList.html | 37 + .../mockup/listview/AdressesList2.html | 37 + .../mockup/listview/AdressesList3.html | 37 + .../mockup/listview/AttachmentList.html | 37 + .../openerp/mockup/listview/BankDetails.html | 37 + .../listview/BankDetailsCustomised.html | 39 + .../openerp/mockup/listview/CountryList.html | 43 + .../mockup/listview/CustomersDelList1.html | 49 + .../mockup/listview/CustomersDelList2.html | 48 + .../listview/CustomersInvoicesList.html | 44 + .../listview/CustomersInvoicesList2.html | 44 + .../mockup/listview/CustomersList.html | 37 + .../listview/CustomersListCustomized.html | 42 + .../listview/CustomersListCustomized2.html | 42 + .../mockup/listview/CustomersRefundsList.html | 44 + .../listview/CustomersRefundsList2.html | 44 + .../mockup/listview/DeliverProductsList.html | 44 + .../mockup/listview/InboundCallsList.html | 44 + .../listview/InvitationsDetailsList.html | 44 + .../mockup/listview/InvoiceLinesList.html | 44 + .../openerp/mockup/listview/MeetingsList.html | 42 + .../mockup/listview/OpportunityList.html | 44 + .../openerp/mockup/listview/OptionsList.html | 41 + .../openerp/mockup/listview/OptionsList2.html | 41 + .../openerp/mockup/listview/OptionsList3.html | 41 + .../mockup/listview/OutboundCallsList.html | 44 + .../openerp/mockup/listview/PartnerList.html | 44 + .../mockup/listview/PaymentsCustomerList.html | 34 + .../mockup/listview/PaymentsSupplierList.html | 34 + .../listview/PhysicalInventoryList.html | 44 + .../PhysicalInventoryProductsList.html | 41 + .../listview/ProcurmentExceptionsList.html | 41 + .../openerp/mockup/listview/ProductsList.html | 43 + .../mockup/listview/ReceiveProductsList.html | 44 + .../openerp/mockup/listview/SalesManList.html | 42 + .../mockup/listview/SalesOrdersDelList2.html | 51 + .../mockup/listview/SalesOrdersLinesList.html | 44 + .../mockup/listview/SalesOrdersList.html | 44 + .../mockup/listview/StockMovesList.html | 44 + .../listview/SuppliersInvoicesList.html | 44 + .../listview/SuppliersInvoicesList2.html | 44 + .../listview/SuppliersListCustomized.html | 42 + .../listview/SuppliersListCustomized2.html | 42 + .../mockup/listview/SuppliersRefundsList.html | 44 + .../listview/SuppliersRefundsList2.html | 44 + .../mockup/listview/WHProductsList.html | 43 + .../static/openerp/mockup/listview/test.html | 54 + .../openerp/mockup/menu/AccountingMenu.html | 31 + .../openerp/mockup/menu/AdressBookMenu.html | 32 + .../openerp/mockup/menu/CustomersMenu.html | 32 + .../openerp/mockup/menu/CustomersOptions.html | 41 + .../mockup/menu/CustomersOptionsForm.html | 38 + .../static/openerp/mockup/menu/HomePage.html | 44 + .../mockup/menu/InventoryControlSubMenu.html | 30 + .../static/openerp/mockup/menu/LoginPage.html | 47 + .../openerp/mockup/menu/PhoneCallMenu.html | 31 + .../mockup/menu/ProductsMovesSubMenu.html | 31 + .../openerp/mockup/menu/ProductsSubMenu.html | 32 + .../static/openerp/mockup/menu/SalesMenu.html | 34 + .../openerp/mockup/menu/SalesSubMenu.html | 32 + .../mockup/menu/SchedulersSubMenu.html | 31 + .../openerp/mockup/menu/SuppliersMenu.html | 32 + .../mockup/menu/TraceabilitySubMenu.html | 30 + .../openerp/mockup/menu/WarehouseMenu.html | 35 + .../formview/InvitationDetailsForm.html | 55 + .../prototype/formview/MeetingsForm.html | 83 + .../listview/InvitationsDetailsList.html | 44 + .../prototype/listview/MeetingsList.html | 42 + .../mockup/prototype/menu/SalesMenu.html | 36 + .../mockup/searchview/CustomerSearch.html | 58 + addons/web_mobile/static/src/css/OpenERP.css | 1608 ++++ .../static/src/images/ajax-loader.png | Bin 0 -> 503 bytes .../static/src/images/icon-search-black.png | Bin 0 -> 1245 bytes .../static/src/images/icons-18-black.png | Bin 0 -> 2138 bytes .../static/src/images/icons-18-white.png | Bin 0 -> 2207 bytes .../static/src/images/icons-36-black.png | Bin 0 -> 4011 bytes .../static/src/images/icons-36-white.png | Bin 0 -> 4343 bytes addons/web_mobile/static/src/js/web_mobile.js | 299 + addons/web_mobile/static/src/web_mobile.html | 43 + addons/web_mobile/static/src/xml/mobile.xml | 167 + openerpweb/openerpweb.py | 3 + 150 files changed, 37893 insertions(+) create mode 100644 addons/web_mobile/__init__.py create mode 100644 addons/web_mobile/__openerp__.py create mode 100644 addons/web_mobile/controllers/__init__.py create mode 100644 addons/web_mobile/controllers/main.py create mode 100755 addons/web_mobile/static/openerp/dynamics/OpenERPmobile.css create mode 100755 addons/web_mobile/static/openerp/dynamics/images/ajax-loader.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/form-check-off.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/form-check-on.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/form-radio-off.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/form-radio-on.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icon-search-black.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icone-folder.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icone-save.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icons-18-black.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icons-18-white.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icons-36-black.png create mode 100755 addons/web_mobile/static/openerp/dynamics/images/icons-36-white.png create mode 100755 addons/web_mobile/static/openerp/dynamics/jquer.mobile-1.0a3.js create mode 100755 addons/web_mobile/static/openerp/dynamics/jquery-1.5.1.js create mode 100755 addons/web_mobile/static/openerp/dynamics/test/LoginPage.html create mode 100644 addons/web_mobile/static/openerp/dynamics/testConnect.js create mode 100755 addons/web_mobile/static/openerp/mockup/OpenERPmobile.css create mode 100755 addons/web_mobile/static/openerp/mockup/formview/AdressesForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/BankAccount.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/CustomersForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/CustomersFormClear.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/CustomersInvoices.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/CustomersRefunds.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/DeliverProductsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/EMailForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/EMailForm2.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/InboundCall.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/InvitationDetailsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/InvoiceLine.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/MeetingsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/Opportunity.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/OutboundCall.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/PaymentCustomerForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/PaymentSupplierForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/PhysicalInventoryForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/PhysicalInventoryProductsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/Preferences.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/ProcurmentExceptionsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/ProductsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/ReceiveProductsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SaleOrderLines.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SalesOrders.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SalesOrdersCanceled.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SalesOrdersConfirm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/StockMovesForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SuppliersForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SuppliersInvoices.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/SuppliersRefunds.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/WHProductsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/formview/password.html create mode 100755 addons/web_mobile/static/openerp/mockup/images/ajax-loader.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/form-check-off.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/form-check-on.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/form-radio-off.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/form-radio-on.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icon-search-black.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icone-folder.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icone-save.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icons-18-black.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icons-18-white.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icons-36-black.png create mode 100755 addons/web_mobile/static/openerp/mockup/images/icons-36-white.png create mode 100755 addons/web_mobile/static/openerp/mockup/jquer.mobile-1.0a3.js create mode 100755 addons/web_mobile/static/openerp/mockup/jquery-1.5.1.js create mode 100755 addons/web_mobile/static/openerp/mockup/listview/AdressesList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/AdressesList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/AdressesList3.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/AttachmentList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/BankDetails.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/BankDetailsCustomised.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CountryList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersDelList1.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersDelList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersInvoicesList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersInvoicesList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersListCustomized.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersListCustomized2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersRefundsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/CustomersRefundsList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/DeliverProductsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/InboundCallsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/InvitationsDetailsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/InvoiceLinesList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/MeetingsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/OpportunityList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/OptionsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/OptionsList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/OptionsList3.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/OutboundCallsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/PartnerList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/PaymentsCustomerList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/PaymentsSupplierList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/PhysicalInventoryList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/PhysicalInventoryProductsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/ProcurmentExceptionsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/ProductsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/ReceiveProductsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SalesManList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SalesOrdersDelList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SalesOrdersLinesList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SalesOrdersList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/StockMovesList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SuppliersInvoicesList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SuppliersInvoicesList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SuppliersListCustomized.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SuppliersListCustomized2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SuppliersRefundsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/SuppliersRefundsList2.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/WHProductsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/listview/test.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/AccountingMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/AdressBookMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/CustomersMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/CustomersOptions.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/CustomersOptionsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/HomePage.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/InventoryControlSubMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/LoginPage.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/PhoneCallMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/ProductsMovesSubMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/ProductsSubMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/SalesMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/SalesSubMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/SchedulersSubMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/SuppliersMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/TraceabilitySubMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/menu/WarehouseMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/prototype/formview/InvitationDetailsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/prototype/formview/MeetingsForm.html create mode 100755 addons/web_mobile/static/openerp/mockup/prototype/listview/InvitationsDetailsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/prototype/listview/MeetingsList.html create mode 100755 addons/web_mobile/static/openerp/mockup/prototype/menu/SalesMenu.html create mode 100755 addons/web_mobile/static/openerp/mockup/searchview/CustomerSearch.html create mode 100644 addons/web_mobile/static/src/css/OpenERP.css create mode 100644 addons/web_mobile/static/src/images/ajax-loader.png create mode 100644 addons/web_mobile/static/src/images/icon-search-black.png create mode 100644 addons/web_mobile/static/src/images/icons-18-black.png create mode 100644 addons/web_mobile/static/src/images/icons-18-white.png create mode 100644 addons/web_mobile/static/src/images/icons-36-black.png create mode 100644 addons/web_mobile/static/src/images/icons-36-white.png create mode 100644 addons/web_mobile/static/src/js/web_mobile.js create mode 100755 addons/web_mobile/static/src/web_mobile.html create mode 100644 addons/web_mobile/static/src/xml/mobile.xml diff --git a/addons/web_mobile/__init__.py b/addons/web_mobile/__init__.py new file mode 100644 index 00000000000..ee5959455ad --- /dev/null +++ b/addons/web_mobile/__init__.py @@ -0,0 +1 @@ +import controllers diff --git a/addons/web_mobile/__openerp__.py b/addons/web_mobile/__openerp__.py new file mode 100644 index 00000000000..da2b345d217 --- /dev/null +++ b/addons/web_mobile/__openerp__.py @@ -0,0 +1,6 @@ +{ + "name" : "OpenERP Web base", + "version" : "2.0", + "depends" : [], + 'active': True, +} diff --git a/addons/web_mobile/controllers/__init__.py b/addons/web_mobile/controllers/__init__.py new file mode 100644 index 00000000000..8ee9bae18d9 --- /dev/null +++ b/addons/web_mobile/controllers/__init__.py @@ -0,0 +1 @@ +import main diff --git a/addons/web_mobile/controllers/main.py b/addons/web_mobile/controllers/main.py new file mode 100644 index 00000000000..058d5c547a2 --- /dev/null +++ b/addons/web_mobile/controllers/main.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +import glob, os +import pprint +from xml.etree import ElementTree +from cStringIO import StringIO + +import simplejson + +import openerpweb +import openerpweb.ast +import openerpweb.nonliterals + +import cherrypy + +# Should move to openerpweb.Xml2Json +class Xml2Json: + # xml2json-direct + # Simple and straightforward XML-to-JSON converter in Python + # New BSD Licensed + # + # URL: http://code.google.com/p/xml2json-direct/ + @staticmethod + def convert_to_json(s): + return simplejson.dumps( + Xml2Json.convert_to_structure(s), sort_keys=True, indent=4) + + @staticmethod + def convert_to_structure(s): + root = ElementTree.fromstring(s) + return Xml2Json.convert_element(root) + + @staticmethod + def convert_element(el, skip_whitespaces=True): + res = {} + if el.tag[0] == "{": + ns, name = el.tag.rsplit("}", 1) + res["tag"] = name + res["namespace"] = ns[1:] + else: + res["tag"] = el.tag + res["attrs"] = {} + for k, v in el.items(): + res["attrs"][k] = v + kids = [] + if el.text and (not skip_whitespaces or el.text.strip() != ''): + kids.append(el.text) + for kid in el: + kids.append(Xml2Json.convert_element(kid)) + if kid.tail and (not skip_whitespaces or kid.tail.strip() != ''): + kids.append(kid.tail) + res["children"] = kids + return res + +#---------------------------------------------------------- +# OpenERP Web mobile Controllers +#---------------------------------------------------------- + +class MOBILE(openerpweb.Controller): + _cp_path = "/web_mobile/mobile" + + def manifest_glob(self, addons, key): + files = [] + for addon in addons: + globlist = openerpweb.addons_manifest.get(addon, {}).get(key, []) + + files.extend([ + resource_path[len(openerpweb.path_addons):] + for pattern in globlist + for resource_path in glob.glob(os.path.join( + openerpweb.path_addons, addon, pattern)) + ]) + return files + + def concat_files(self, file_list): + """ Concatenate file content + return (concat,timestamp) + concat: concatenation of file content + timestamp: max(os.path.getmtime of file_list) + """ + root = openerpweb.path_root + files_content = [] + files_timestamp = 0 + for i in file_list: + fname = os.path.join(root, i) + ftime = os.path.getmtime(fname) + if ftime > files_timestamp: + files_timestamp = ftime + files_content = open(fname).read() + files_concat = "".join(files_content) + return files_concat + + @openerpweb.jsonrequest + def db_list(self, req): + return req.session.proxy('db').list() + + @openerpweb.jsonrequest + def sc_list(self, req): + return req.session.model('ir.ui.view_sc').get_sc(req.session._uid, "ir.ui.menu", {}) + + @openerpweb.jsonrequest + def logout(self,req): + req.session._uid =False + + @openerpweb.jsonrequest + def login(self, req, db, login, password): + req.session.login(db, login, password) + + return { + "session_id": req.session_id, + "uid": req.session._uid, + } + + @openerpweb.jsonrequest + def modules(self, req): + return {"modules": [name + for name, manifest in openerpweb.addons_manifest.iteritems() + if manifest.get('active', True)]} + + @openerpweb.jsonrequest + def csslist(self, req, mods='base'): + return {'files': self.manifest_glob(mods.split(','), 'css')} + + @openerpweb.jsonrequest + def jslist(self, req, mods='base'): + return {'files': self.manifest_glob(mods.split(','), 'js')} + + def css(self, req, mods='base,base_hello'): + files = self.manifest_glob(mods.split(','), 'css') + concat = self.concat_files(files)[0] + # TODO request set the Date of last modif and Etag + return concat + css.exposed = True + + def js(self, req, mods='base,base_hello'): + files = self.manifest_glob(mods.split(','), 'js') + concat = self.concat_files(files)[0] + # TODO request set the Date of last modif and Etag + return concat + js.exposed = True + + @openerpweb.jsonrequest + def eval_domain_and_context(self, req, contexts, domains, + group_by_seq=None): + """ Evaluates sequences of domains and contexts, composing them into + a single context, domain or group_by sequence. + + :param list contexts: list of contexts to merge together. Contexts are + evaluated in sequence, all previous contexts + are part of their own evaluation context + (starting at the session context). + :param list domains: list of domains to merge together. Domains are + evaluated in sequence and appended to one another + (implicit AND), their evaluation domain is the + result of merging all contexts. + :param list group_by_seq: list of domains (which may be in a different + order than the ``contexts`` parameter), + evaluated in sequence, their ``'group_by'`` + key is extracted if they have one. + :returns: + a 3-dict of: + + context (``dict``) + the global context created by merging all of + ``contexts`` + + domain (``list``) + the concatenation of all domains + + group_by (``list``) + a list of fields to group by, potentially empty (in which case + no group by should be performed) + """ + context = req.session.eval_contexts(contexts) + domain = req.session.eval_domains(domains, context) + + group_by_sequence = [] + for candidate in (group_by_seq or []): + ctx = req.session.eval_context(candidate, context) + group_by = ctx.get('group_by') + if not group_by: + continue + elif isinstance(group_by, basestring): + group_by_sequence.append(group_by) + else: + group_by_sequence.extend(group_by) + + return { + 'context': context, + 'domain': domain, + 'group_by': group_by_sequence + } + + @openerpweb.jsonrequest + def save_session_action(self, req, the_action): + """ + This method store an action object in the session object and returns an integer + identifying that action. The method get_session_action() can be used to get + back the action. + + :param the_action: The action to save in the session. + :type the_action: anything + :return: A key identifying the saved action. + :rtype: integer + """ + saved_actions = cherrypy.session.get('saved_actions') + if not saved_actions: + saved_actions = {"next":0, "actions":{}} + cherrypy.session['saved_actions'] = saved_actions + # we don't allow more than 10 stored actions + if len(saved_actions["actions"]) >= 10: + del saved_actions["actions"][min(saved_actions["actions"].keys())] + key = saved_actions["next"] + saved_actions["actions"][key] = the_action + saved_actions["next"] = key + 1 + return key + + @openerpweb.jsonrequest + def get_session_action(self, req, key): + """ + Gets back a previously saved action. This method can return None if the action + was saved since too much time (this case should be handled in a smart way). + + :param key: The key given by save_session_action() + :type key: integer + :return: The saved action or None. + :rtype: anything + """ + saved_actions = cherrypy.session.get('saved_actions') + if not saved_actions: + return None + return saved_actions["actions"].get(key) + + +def load_actions_from_ir_values(req, key, key2, models, meta, context): + Values = req.session.model('ir.values') + actions = Values.get(key, key2, models, meta, context) + + for _, _, action in actions: + clean_action(action, req.session) + + return actions + +def clean_action(action, session): + # values come from the server, we can just eval them + if isinstance(action['context'], basestring): + action['context'] = eval( + action['context'], + session.evaluation_context()) or {} + + if isinstance(action['domain'], basestring): + action['domain'] = eval( + action['domain'], + session.evaluation_context( + action['context'])) or [] + fix_view_modes(action) + +def fix_view_modes(action): + """ For historical reasons, OpenERP has weird dealings in relation to + view_mode and the view_type attribute (on window actions): + + * one of the view modes is ``tree``, which stands for both list views + and tree views + * the choice is made by checking ``view_type``, which is either + ``form`` for a list view or ``tree`` for an actual tree view + + This methods simply folds the view_type into view_mode by adding a + new view mode ``list`` which is the result of the ``tree`` view_mode + in conjunction with the ``form`` view_type. + + TODO: this should go into the doc, some kind of "peculiarities" section + + :param dict action: an action descriptor + :returns: nothing, the action is modified in place + """ + if action.pop('view_type') != 'form': + return + + action['view_mode'] = ','.join( + mode if mode != 'tree' else 'list' + for mode in action['view_mode'].split(',')) + action['views'] = [ + [id, mode if mode != 'tree' else 'list'] + for id, mode in action['views'] + ] + +class Menu(openerpweb.Controller): + _cp_path = "/web_mobile/menu" + + @openerpweb.jsonrequest + def load(self, req): + return {'data': self.do_load(req)} + + def do_load(self, req): + """ Loads all menu items (all applications and their sub-menus). + + :param req: A request object, with an OpenERP session attribute + :type req: < session -> OpenERPSession > + :return: the menu root + :rtype: dict('children': menu_nodes) + """ + Menus = req.session.model('ir.ui.menu') + # menus are loaded fully unlike a regular tree view, cause there are + # less than 512 items + menu_ids = Menus.search([]) + menu_items = Menus.read(menu_ids, ['name', 'sequence', 'parent_id']) + menu_root = {'id': False, 'name': 'root', 'parent_id': [-1, '']} + menu_items.append(menu_root) + + # make a tree using parent_id + menu_items_map = dict((menu_item["id"], menu_item) for menu_item in menu_items) + for menu_item in menu_items: + if menu_item['parent_id']: + parent = menu_item['parent_id'][0] + else: + parent = False + if parent in menu_items_map: + menu_items_map[parent].setdefault( + 'children', []).append(menu_item) + + # sort by sequence a tree using parent_id + for menu_item in menu_items: + menu_item.setdefault('children', []).sort( + key=lambda x:x["sequence"]) + + return menu_root + + @openerpweb.jsonrequest + def action(self, req, menu_id): + actions = load_actions_from_ir_values(req,'action', 'tree_but_open', + [('ir.ui.menu', menu_id)], False, {}) + + return {"action": actions} + +class DataSet(openerpweb.Controller): + _cp_path = "/web_mobile/dataset" + + @openerpweb.jsonrequest + def fields(self, req, model): + return {'fields': req.session.model(model).fields_get()} + + @openerpweb.jsonrequest + def search_read(self, request, model, fields=False, offset=0, limit=False, domain=None, context=None, sort=None): + return self.do_search_read(request, model, fields, offset, limit, domain, context, sort) + def do_search_read(self, request, model, fields=False, offset=0, limit=False, domain=None, context=None, sort=None): + """ Performs a search() followed by a read() (if needed) using the + provided search criteria + + :param request: a JSON-RPC request object + :type request: openerpweb.JsonRequest + :param str model: the name of the model to search on + :param fields: a list of the fields to return in the result records + :type fields: [str] + :param int offset: from which index should the results start being returned + :param int limit: the maximum number of records to return + :param list domain: the search domain for the query + :param list sort: sorting directives + :returns: a list of result records + :rtype: list + """ + Model = request.session.model(model) + ids = Model.search(domain or [], offset or 0, limit or False, + sort or False, request.context) + if fields and fields == ['id']: + # shortcut read if we only want the ids + return map(lambda id: {'id': id}, ids) + return Model.read(ids, fields or False, request.context) + + @openerpweb.jsonrequest + def get(self, request, model, ids, fields=False): + return self.do_get(request, model, ids, fields) + def do_get(self, request, model, ids, fields=False): + """ Fetches and returns the records of the model ``model`` whose ids + are in ``ids``. + + The results are in the same order as the inputs, but elements may be + missing (if there is no record left for the id) + + :param request: the JSON-RPC2 request object + :type request: openerpweb.JsonRequest + :param model: the model to read from + :type model: str + :param ids: a list of identifiers + :type ids: list + :param fields: a list of fields to fetch, ``False`` or empty to fetch + all fields in the model + :type fields: list | False + :returns: a list of records, in the same order as the list of ids + :rtype: list + """ + Model = request.session.model(model) + records = Model.read(ids, fields) + + record_map = dict((record['id'], record) for record in records) + + return [record_map[id] for id in ids if record_map.get(id)] + @openerpweb.jsonrequest + + def load(self, req, model, id, fields): + m = req.session.model(model) + value = {} + r = m.read([id]) + if r: + value = r[0] + return {'value': value} + + @openerpweb.jsonrequest + def create(self, req, model, data, context={}): + m = req.session.model(model) + r = m.create(data, context) + return {'result': r} + + @openerpweb.jsonrequest + def save(self, req, model, id, data, context={}): + m = req.session.model(model) + r = m.write([id], data, context) + return {'result': r} + + @openerpweb.jsonrequest + def call(self, req, model, method, ids, args): + m = req.session.model(model) + r = getattr(m, method)(ids, *args) + return {'result': r} + + @openerpweb.jsonrequest + def exec_workflow(self, req, model, id, signal): + r = req.session.exec_workflow(model, id, signal) + return {'result': r} + + @openerpweb.jsonrequest + def default_get(self, req, model, fields, context={}): + m = req.session.model(model) + r = m.default_get(fields, context) + return {'result': r} + +class View(openerpweb.Controller): + def fields_view_get(self, request, model, view_id, view_type, + transform=True, toolbar=False, submenu=False): + Model = request.session.model(model) + fvg = Model.fields_view_get(view_id, view_type, request.context, + toolbar, submenu) + if transform: + evaluation_context = request.session.evaluation_context( + request.context or {}) + xml = self.transform_view( + fvg['arch'], request.session, evaluation_context) + else: + xml = ElementTree.fromstring(fvg['arch']) + fvg['arch'] = Xml2Json.convert_element(xml) + return fvg + + def normalize_attrs(self, elem, context): + """ Normalize @attrs, @invisible, @required, @readonly and @states, so + the client only has to deal with @attrs. + + See `the discoveries pad `_ for + the rationale. + + :param elem: the current view node (Python object) + :type elem: xml.etree.ElementTree.Element + :param dict context: evaluation context + """ + # If @attrs is normalized in json by server, the eval should be replaced by simplejson.loads + attrs = openerpweb.ast.literal_eval(elem.get('attrs', '{}')) + if 'states' in elem.attrib: + attrs.setdefault('invisible', [])\ + .append(('state', 'not in', elem.attrib.pop('states').split(','))) + if attrs: + elem.set('attrs', simplejson.dumps(attrs)) + for a in ['invisible', 'readonly', 'required']: + if a in elem.attrib: + # In the XML we trust + avalue = bool(eval(elem.get(a, 'False'), + {'context': context or {}})) + if not avalue: + del elem.attrib[a] + else: + elem.attrib[a] = '1' + if a == 'invisible' and 'attrs' in elem.attrib: + del elem.attrib['attrs'] + + def transform_view(self, view_string, session, context=None): + # transform nodes on the fly via iterparse, instead of + # doing it statically on the parsing result + parser = ElementTree.iterparse(StringIO(view_string), events=("start",)) + root = None + for event, elem in parser: + if event == "start": + if root is None: + root = elem + self.normalize_attrs(elem, context) + self.parse_domains_and_contexts(elem, session) + return root + + def parse_domain(self, elem, attr_name, session): + """ Parses an attribute of the provided name as a domain, transforms it + to either a literal domain or a :class:`openerpweb.nonliterals.Domain` + + :param elem: the node being parsed + :type param: xml.etree.ElementTree.Element + :param str attr_name: the name of the attribute which should be parsed + :param session: Current OpenERP session + :type session: openerpweb.openerpweb.OpenERPSession + """ + domain = elem.get(attr_name, '').strip() + if domain: + try: + elem.set( + attr_name, + openerpweb.ast.literal_eval( + domain)) + except ValueError: + # not a literal + elem.set(attr_name, + openerpweb.nonliterals.Domain(session, domain)) + + def parse_domains_and_contexts(self, elem, session): + """ Converts domains and contexts from the view into Python objects, + either literals if they can be parsed by literal_eval or a special + placeholder object if the domain or context refers to free variables. + + :param elem: the current node being parsed + :type param: xml.etree.ElementTree.Element + :param session: OpenERP session object, used to store and retrieve + non-literal objects + :type session: openerpweb.openerpweb.OpenERPSession + """ + self.parse_domain(elem, 'domain', session) + self.parse_domain(elem, 'filter_domain', session) + context_string = elem.get('context', '').strip() + if context_string: + try: + elem.set('context', + openerpweb.ast.literal_eval(context_string)) + except ValueError: + elem.set('context', + openerpweb.nonliterals.Context( + session, context_string)) + +class FormView(View): + _cp_path = "/web_mobile/formview" + + @openerpweb.jsonrequest + def load(self, req, model, view_id, toolbar=False): + fields_view = self.fields_view_get(req, model, view_id, 'form', toolbar=toolbar) + return {'fields_view': fields_view} + +class ListView(View): + _cp_path = "/web_mobile/listview" + + @openerpweb.jsonrequest + def load(self, req, model, view_id, toolbar=False): + fields_view = self.fields_view_get(req, model, view_id, 'tree', toolbar=toolbar) + return {'fields_view': fields_view} + + def fields_view_get(self, request, model, view_id, view_type="tree", + transform=True, toolbar=False, submenu=False): + """ Sets @editable on the view's arch if it isn't already set and + ``set_editable`` is present in the request context + """ + view = super(ListView, self).fields_view_get( + request, model, view_id, view_type, transform, toolbar, submenu) + + view_attributes = view['arch']['attrs'] + if request.context.get('set_editable')\ + and 'editable' not in view_attributes: + view_attributes['editable'] = 'bottom' + return view + + @openerpweb.jsonrequest + def fill(self, request, model, id, domain, + offset=0, limit=False): + return self.do_fill(request, model, id, domain, offset, limit) + + def do_fill(self, request, model, id, domain, + offset=0, limit=False): + """ Returns all information needed to fill a table: + + * view with processed ``editable`` flag + * fields (columns) with processed ``invisible`` flag + * rows with processed ``attrs`` and ``colors`` + + .. note:: context is passed through ``request`` parameter + + :param request: OpenERP request + :type request: openerpweb.openerpweb.JsonRequest + :type str model: OpenERP model for this list view + :type int id: view_id, or False if none provided + :param list domain: the search domain to search for + :param int offset: search offset, for pagination + :param int limit: search limit, for pagination + :returns: hell if I have any idea yet + """ + view = self.fields_view_get(request, model, id, toolbar=True) + + rows = DataSet().do_search_read(request, model, + offset=offset, limit=limit, + domain=domain) + eval_context = request.session.evaluation_context( + request.context) + return { + 'view': view, + 'records': [ + {'data': dict((key, {'value': value}) + for key, value in row.iteritems()), + 'color': self.process_colors(view, row, eval_context)} + for row in rows + ] + } + + def process_colors(self, view, row, context): + colors = view['arch']['attrs'].get('colors') + + if not colors: + return None + + color = [ + pair.split(':')[0] + for pair in colors.split(';') + if eval(pair.split(':')[1], dict(context, **row)) + ] + + if not color: + return None + elif len(color) == 1: + return color[0] + return 'maroon' + + +class SearchView(View): + _cp_path = "/web_mobile/searchview" + + @openerpweb.jsonrequest + def load(self, req, model, view_id): + fields_view = self.fields_view_get(req, model, view_id, 'search') + return {'fields_view': fields_view} + +class Action(openerpweb.Controller): + _cp_path = "/web_mobile/action" + + @openerpweb.jsonrequest + def load(self, req, action_id, context={}): + Actions = req.session.model('ir.actions.actions') + value = False + action_type = Actions.read([action_id], ['type'], context) + if action_type: + action = req.session.model(action_type[0]['type']).read([action_id], False, context) + if action: + value = action[0] + return {'result': value} diff --git a/addons/web_mobile/static/openerp/dynamics/OpenERPmobile.css b/addons/web_mobile/static/openerp/dynamics/OpenERPmobile.css new file mode 100755 index 00000000000..b0a8b6f4e9b --- /dev/null +++ b/addons/web_mobile/static/openerp/dynamics/OpenERPmobile.css @@ -0,0 +1,1662 @@ +/*! + * jQuery Mobile v1.0a3 + * http://jquerymobile.com/ + * + * Copyright 2010, jQuery Project + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* Note: Code is in draft form and is subject to change +*/ + + +/* A +-----------------------------------------------------------------------------------------------------------*/ + +.ui-bar-a { + border: 1px solid #2A2A2A; + background: #111111; + color: #ffffff; + font-weight: bold; + text-shadow: 0 -1px 1px #000000; + background-image: -moz-linear-gradient(top, + #3c3c3c, + #111111); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #3c3c3c), + color-stop(1, #111111)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#3c3c3c', EndColorStr='#111111')"; +} +.ui-bar-a, +.ui-bar-a input, +.ui-bar-a select, +.ui-bar-a textarea, +.ui-bar-a button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-bar-a .ui-link-inherit { + color: #fff; +} +.ui-bar-a .ui-link { + color: #7cc4e7; + font-weight: bold; +} +.ui-body-a { + border: 1px solid #2A2A2A; + background: #222222; + color: #fff; + text-shadow: 0 1px 0 #000; + font-weight: normal; + background-image: -moz-linear-gradient(top, + #666666, + #222222); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #666666), + color-stop(1, #222222)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#666666', EndColorStr='#222222)')"; +} +.ui-body-a, +.ui-body-a input, +.ui-body-a select, +.ui-body-a textarea, +.ui-body-a button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-body-a .ui-link-inherit { + color: #fff; +} +.ui-body-a .ui-link { + color: #2489CE; + font-weight: bold; +} +.ui-br { + border-bottom: 1px solid rgba(130,130,130,.3); +} +.ui-btn-up-a { + border: 1px solid #222; + background: #333333; + font-weight: bold; + color: #fff; + cursor: pointer; + text-shadow: 0 -1px 1px #000; + text-decoration: none; + background-image: -moz-linear-gradient(top, + #555555, + #333333); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #555555), + color-stop(1, #333333)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#555555', EndColorStr='#333333')"; +} +.ui-btn-up-a a.ui-link-inherit { + color: #fff; +} +.ui-btn-hover-a { + border: 1px solid #000; + background: #444444; + font-weight: bold; + color: #fff; + text-shadow: 0 -1px 1px #000; + text-decoration: none; + background-image: -moz-linear-gradient(top, + #666666, + #444444); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #666666), + color-stop(1, #444444)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#666666', EndColorStr='#444444')"; +} +.ui-btn-hover-a a.ui-link-inherit { + color: #fff; +} +.ui-btn-down-a { + border: 1px solid #000; + background: #3d3d3d; + font-weight: bold; + color: #fff; + text-shadow: 0 -1px 1px #000; + background-image: -moz-linear-gradient(top, + #333333, + #5a5a5a); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #333333), + color-stop(1, #5a5a5a)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#333333', EndColorStr='#5a5a5a')"; +} +.ui-btn-down-a a.ui-link-inherit { + color: #fff; +} +.ui-btn-up-a, +.ui-btn-hover-a, +.ui-btn-down-a { + font-family: Helvetica, Arial, sans-serif; +} + + +/* B +-----------------------------------------------------------------------------------------------------------*/ + +.ui-bar-b { + border: 1px solid #456f9a; + background: #5e87b0; + color: #fff; + font-weight: bold; + text-shadow: 0 -1px 1px #254f7a; + background-image: -moz-linear-gradient(top, + #81a8ce, + #5e87b0); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #81a8ce), + color-stop(1, #5e87b0)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#81a8ce', EndColorStr='#5e87b0')"; +} +.ui-bar-b, +.ui-bar-b input, +.ui-bar-b select, +.ui-bar-b textarea, +.ui-bar-b button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-bar-b .ui-link-inherit { + color: #fff; +} +.ui-bar-b .ui-link { + color: #7cc4e7; + font-weight: bold; +} + +.ui-body-b { + border: 1px solid #C6C6C6; + background: #cccccc; + color: #333333; + text-shadow: 0 1px 0 #fff; + font-weight: normal; + background-image: -moz-linear-gradient(top, + #e6e6e6, + #cccccc); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #e6e6e6), + color-stop(1, #cccccc)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#e6e6e6', EndColorStr='#cccccc')"; +} +.ui-body-b, +.ui-body-b input, +.ui-body-b select, +.ui-body-b textarea, +.ui-body-b button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-body-b .ui-link-inherit { + color: #333333; +} +.ui-body-b .ui-link { + color: #2489CE; + font-weight: bold; +} +.ui-btn-up-b { + border: 1px solid #145072; + background: #2567ab; + font-weight: bold; + color: #fff; + cursor: pointer; + text-shadow: 0 -1px 1px #145072; + text-decoration: none; + background-image: -moz-linear-gradient(top, + #4e89c5, + #2567ab); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #5f9cc5), + color-stop(1, #396b9e)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#4e89c5', EndColorStr='#2567ab')"; +} +.ui-btn-up-b a.ui-link-inherit { + color: #fff; +} +.ui-btn-hover-b { + border: 1px solid #00516e; + background: #4b88b6; + font-weight: bold; + color: #fff; + text-shadow: 0 -1px 1px #014D68; + background-image: -moz-linear-gradient(top, + #72b0d4, + #4b88b6); + text-decoration: none; + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #72b0d4), + color-stop(1, #4b88b6)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#72b0d4', EndColorStr='#4b88b6')"; +} +.ui-btn-hover-b a.ui-link-inherit { + color: #fff; +} +.ui-btn-down-b { + border: 1px solid #225377; + background: #4e89c5; + font-weight: bold; + color: #fff; + text-shadow: 0 -1px 1px #225377; + background-image: -moz-linear-gradient(top, + #396b9e, + #4e89c5); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #396b9e), + color-stop(1, #4e89c5)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#396b9e', EndColorStr='#4e89c5')"; +} +.ui-btn-down-b a.ui-link-inherit { + color: #fff; +} +.ui-btn-up-b, +.ui-btn-hover-b, +.ui-btn-down-b { + font-family: Helvetica, Arial, sans-serif; +} + + +/* C +-----------------------------------------------------------------------------------------------------------*/ + +.ui-bar-c { + border: 1px solid #B3B3B3; + background: #e9eaeb; + color: #3E3E3E; + font-weight: bold; + text-shadow: 0 1px 1px #fff; + background-image: -moz-linear-gradient(top, + #f0f0f0, + #e9eaeb); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #f0f0f0), + color-stop(1, #e9eaeb)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#f0f0f0', EndColorStr='#e9eaeb')"; +} +.ui-bar-c, +.ui-bar-c input, +.ui-bar-c select, +.ui-bar-c textarea, +.ui-bar-c button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-body-c { + border: 1px solid #B3B3B3; + color: #333333; + text-shadow: 0 1px 0 #fff; + background: #f0f0f0; + background-image: -moz-linear-gradient(top, + #eeeeee, + #dddddd); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #eeeeee), + color-stop(1, #dddddd)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#dddddd')"; +} +.ui-body-c, +.ui-body-c input, +.ui-body-c select, +.ui-body-c textarea, +.ui-body-c button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-body-c .ui-link-inherit { + color: #333333; +} +.ui-body-c .ui-link { + color: #2489CE; + font-weight: bold; +} + +.ui-btn-up-c { + border: 1px solid #ccc; + background: #eee; + font-weight: bold; + color: #444; + cursor: pointer; + text-shadow: 0 1px 1px #f6f6f6; + text-decoration: none; + background-image: -moz-linear-gradient(top, + #fefefe, + #eeeeee); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fdfdfd), + color-stop(1, #eeeeee)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fdfdfd', EndColorStr='#eeeeee')"; +} +.ui-btn-up-c a.ui-link-inherit { + color: #2F3E46; +} + +.ui-btn-hover-c { + border: 1px solid #bbb; + background: #dadada; + font-weight: bold; + color: #101010; + text-decoration: none; + text-shadow: 0 1px 1px #fff; + background-image: -moz-linear-gradient(top, + #ededed, + #dadada); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #ededed), + color-stop(1, #dadada)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ededed', EndColorStr='#dadada')"; +} +.ui-btn-hover-c a.ui-link-inherit { + color: #2F3E46; +} +.ui-btn-down-c { + border: 1px solid #808080; + background: #fdfdfd; + font-weight: bold; + color: #111111; + text-shadow: 0 1px 1px #ffffff; + background-image: -moz-linear-gradient(top, + #eeeeee, + #fdfdfd); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #eeeeee), + color-stop(1, #fdfdfd)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#fdfdfd')"; +} +.ui-btn-down-c a.ui-link-inherit { + color: #2F3E46; +} +.ui-btn-up-c, +.ui-btn-hover-c, +.ui-btn-down-c { + font-family: Helvetica, Arial, sans-serif; +} + + +/* D +-----------------------------------------------------------------------------------------------------------*/ + +.ui-bar-d { + border: 1px solid #ccc; + background: #bbb; + color: #333; + text-shadow: 0 1px 0 #eee; + background-image: -moz-linear-gradient(top, + #ddd, + #bbb); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #ddd), + color-stop(1, #bbb)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#dddddd', EndColorStr='#bbbbbb')"; +} +.ui-bar-d, +.ui-bar-d input, +.ui-bar-d select, +.ui-bar-d textarea, +.ui-bar-d button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-bar-d .ui-link-inherit { + color: #333; +} +.ui-bar-d .ui-link { + color: #2489CE; + font-weight: bold; +} +.ui-body-d { + border: 1px solid #ccc; + color: #333333; + text-shadow: 0 1px 0 #fff; + background: #ffffff; +} +.ui-body-d, +.ui-body-d input, +.ui-body-d select, +.ui-body-d textarea, +.ui-body-d button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-body-d .ui-link-inherit { + color: #333333; +} +.ui-body-d .ui-link { + color: #2489CE; + font-weight: bold; +} +.ui-btn-up-d { + border: 1px solid #ccc; + background: #fff; + font-weight: bold; + color: #444; + text-decoration: none; + text-shadow: 0 1px 1px #fff; +} +.ui-btn-up-d a.ui-link-inherit { + color: #333; +} +.ui-btn-hover-d { + border: 1px solid #aaa; + background: #eeeeee; + font-weight: bold; + color: #222; + cursor: pointer; + text-shadow: 0 1px 1px #fff; + text-decoration: none; + background-image: -moz-linear-gradient(top, + #fdfdfd, + #eeeeee); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fdfdfd), + color-stop(1, #eeeeee)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fdfdfd', EndColorStr='#eeeeee')"; +} +.ui-btn-hover-d a.ui-link-inherit { + color: #222; +} +.ui-btn-down-d { + border: 1px solid #aaaaaa; + background: #ffffff; + font-weight: bold; + color: #111; + text-shadow: 0 1px 1px #ffffff; + background-image: -moz-linear-gradient(top, + #eeeeee, + #ffffff); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #eeeeee), + color-stop(1, #ffffff)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#eeeeee', EndColorStr='#ffffff')"; +} +.ui-btn-down-d a.ui-link-inherit { + border: 1px solid #808080; + background: #ced0d2; + font-weight: bold; + color: #111; + text-shadow: none; + background-image: -moz-linear-gradient(top, + #cccccc, + #eeeeee); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #cccccc), + color-stop(1, #eeeeee)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#cccccc', EndColorStr='#eeeeee')"; +} +.ui-btn-up-d, +.ui-btn-hover-d, +.ui-btn-down-d { + font-family: Helvetica, Arial, sans-serif; +} + + +/* E +-----------------------------------------------------------------------------------------------------------*/ + +.ui-bar-e { + border: 1px solid #F7C942; + background: #fadb4e; + color: white; + text-shadow: 0 1px 0 black; + background-image: -moz-linear-gradient(top, + #990000, + #cccccc); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fceda7), + color-stop(1, #fadb4e)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fceda7', EndColorStr='#fadb4e')"; +} +.ui-bar-e, +.ui-bar-e input, +.ui-bar-e select, +.ui-bar-e textarea, +.ui-bar-d button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-bar-e .ui-link-inherit { + color: #333; +} +.ui-bar-e .ui-link { + color: #2489CE; + font-weight: bold; +} +.ui-body-e { + border: 1px solid #F7C942; + color: #333333; + text-shadow: 0 1px 0 #fff; + background: #faeb9e; + background-image: -moz-linear-gradient(top, + #fff, + #faeb9e); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fff), + color-stop(1, #faeb9e)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#ffffff', EndColorStr='#faeb9e')"; +} +.ui-body-e, +.ui-body-e input, +.ui-body-e select, +.ui-body-e textarea, +.ui-body-e button { + font-family: Helvetica, Arial, sans-serif; +} +.ui-body-e .ui-link-inherit { + color: #333333; +} +.ui-body-e .ui-link { + color: #2489CE; + font-weight: bold; +} +.ui-btn-up-e { + border: 1px solid #F7C942; + background: #fadb4e; + font-weight: bold; + color: #333; + cursor: pointer; + text-shadow: 0 1px 1px #fe3; + text-decoration: none; + text-shadow: 0 1px 0 #fff; + background-image: -moz-linear-gradient(top, + #fceda7, + #fadb4e); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fceda7), + color-stop(1, #fadb4e)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fceda7', EndColorStr='#fadb4e')"; +} +.ui-btn-up-e a.ui-link-inherit { + color: #333; +} +.ui-btn-hover-e { + border: 1px solid #e79952; + background: #fbe26f; + font-weight: bold; + color: #111; + text-decoration: none; + text-shadow: 0 1px 1px #fff; + background-image: -moz-linear-gradient(top, + #fcf0b5, + #fbe26f); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fcf0b5), + color-stop(1, #fbe26f)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fcf0b5', EndColorStr='#fbe26f')"; +} + +.ui-btn-hover-e a.ui-link-inherit { + color: #333; +} +.ui-btn-down-e { + border: 1px solid #F7C942; + background: #fceda7; + font-weight: bold; + color: #111; + text-shadow: 0 1px 1px #ffffff; + background-image: -moz-linear-gradient(top, + #fadb4e, + #fceda7); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #fadb4e), + color-stop(1, #fceda7)); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fadb4e', EndColorStr='#fceda7')"; +} +.ui-btn-down-e a.ui-link-inherit { + color: #333; +} +.ui-btn-up-e, +.ui-btn-hover-e, +.ui-btn-down-e { + font-family: Helvetica, Arial, sans-serif; +} + + +/* links within "buttons" +-----------------------------------------------------------------------------------------------------------*/ + +a.ui-link-inherit { + text-decoration: none !important; +} + + +/* Active class used as the "on" state across all themes +-----------------------------------------------------------------------------------------------------------*/ + +.ui-btn-active { + border: 1px solid #155678; + background: #4596ce; + font-weight: bold; + color: #fff; + cursor: pointer; + text-shadow: 0 -1px 1px #145072; + text-decoration: none; + background-image: -moz-linear-gradient(top, + #85bae4, + #5393c5); + background-image: -webkit-gradient(linear,left top,left bottom, + color-stop(0, #85bae4), + color-stop(1, #5393c5)); + -msfilter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#85bae4', EndColorStr='#5393c5')"; + outline: none; +} +.ui-btn-active a.ui-link-inherit { + color: #fff; +} + + +/* button inner top highlight +-----------------------------------------------------------------------------------------------------------*/ + +.ui-btn-inner { + border-top: 1px solid #fff; + border-color: rgba(255,255,255,.3); +} + + +/* corner rounding classes +-----------------------------------------------------------------------------------------------------------*/ + +.ui-corner-tl { + -moz-border-radius-topleft: .6em; + -webkit-border-top-left-radius: .6em; + border-top-left-radius: .6em; +} +.ui-corner-tr { + -moz-border-radius-topright: .6em; + -webkit-border-top-right-radius: .6em; + border-top-right-radius: .6em; +} +.ui-corner-bl { + -moz-border-radius-bottomleft: .6em; + -webkit-border-bottom-left-radius: .6em; + border-bottom-left-radius: .6em; +} +.ui-corner-br { + -moz-border-radius-bottomright: .6em; + -webkit-border-bottom-right-radius: .6em; + border-bottom-right-radius: .6em; +} +.ui-corner-top { + -moz-border-radius-topleft: .6em; + -webkit-border-top-left-radius: .6em; + border-top-left-radius: .6em; + -moz-border-radius-topright: .6em; + -webkit-border-top-right-radius: .6em; + border-top-right-radius: .6em; +} +.ui-corner-bottom { + -moz-border-radius-bottomleft: .6em; + -webkit-border-bottom-left-radius: .6em; + border-bottom-left-radius: .6em; + -moz-border-radius-bottomright: .6em; + -webkit-border-bottom-right-radius: .6em; + border-bottom-right-radius: .6em; + } +.ui-corner-right { + -moz-border-radius-topright: .6em; + -webkit-border-top-right-radius: .6em; + border-top-right-radius: .6em; + -moz-border-radius-bottomright: .6em; + -webkit-border-bottom-right-radius: .6em; + border-bottom-right-radius: .6em; +} +.ui-corner-left { + -moz-border-radius-topleft: .6em; + -webkit-border-top-left-radius: .6em; + border-top-left-radius: .6em; + -moz-border-radius-bottomleft: .6em; + -webkit-border-bottom-left-radius: .6em; + border-bottom-left-radius: .6em; +} +.ui-corner-all { + -moz-border-radius: .6em; + -webkit-border-radius: .6em; + border-radius: .6em; +} + + + +/* Interaction cues +-----------------------------------------------------------------------------------------------------------*/ +.ui-disabled { + opacity: .3; +} +.ui-disabled, +.ui-disabled a { + cursor: default !important; +} + +/* Icons +-----------------------------------------------------------------------------------------------------------*/ + +.ui-icon { + background-image: url(images/icons-18-white.png); + background-repeat: no-repeat; + background-color: #666; + background-color: rgba(0,0,0,.4); + -moz-border-radius: 9px; + -webkit-border-radius: 9px; + border-radius: 9px; +} +.ui-icon-disc { + background-color: #666; + background-color: rgba(0,0,0,.3); + -moz-border-radius: 9px; + -webkit-border-radius: 9px; + border-radius: 9px; +} + +/* Alt icon color +-----------------------------------------------------------------------------------------------------------*/ + +.ui-icon-black { + background-image: url(images/icons-18-black.png); +} +.ui-icon-black-disc { + background-color: #fff; + background-color: rgba(255,255,255,.3); + -moz-border-radius: 9px; + -webkit-border-radius: 9px; + border-radius: 9px; +} + +/* HD/"retina" sprite +-----------------------------------------------------------------------------------------------------------*/ + +@media screen and (-webkit-min-device-pixel-ratio: 2), screen and (max--moz-device-pixel-ratio: 2) { + .ui-icon { + background-image: url(images/icons-36-white.png); + background-size: 630px 18px; +} + .ui-icon-black { + background-image: url(images/icons-36-black.png); +} +} + +/* plus minus */ +.ui-icon-plus { + background-position: -0 0; +} +.ui-icon-minus { + background-position: -36px 0; +} + +/* delete/close */ +.ui-icon-delete { + background-position: -72px 0; +} + +/* arrows */ +.ui-icon-arrow-r { + background-position: -108px 0; +} +.ui-icon-arrow-l { + background-position: -144px 0; +} +.ui-icon-arrow-u { + background-position: -180px 0; +} +.ui-icon-arrow-d { + background-position: -216px 0; +} + +/* misc */ +.ui-icon-check { + background-position: -252px 0; +} +.ui-icon-gear { + background-position: -288px 0; +} +.ui-icon-refresh { + background-position: -324px 0; +} +.ui-icon-forward { + background-position: -360px 0; +} +.ui-icon-back { + background-position: -396px 0; +} +.ui-icon-grid { + background-position: -432px 0; +} +.ui-icon-star { + background-position: -468px 0; +} +.ui-icon-alert { + background-position: -504px 0; +} +.ui-icon-info { + background-position: -540px 0; +} +.ui-icon-home { + background-position: -576px 0; +} +.ui-icon-search { + background-position: -612px 0; +} + + +/* checks,radios */ +.ui-icon-checkbox-off, +.ui-icon-checkbox-on, +.ui-icon-radio-off, +.ui-icon-radio-on { + background-color: transparent; + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; + background-size: 20px 20px; +} +.ui-icon-checkbox-off { + background-image: url(images/form-check-off.png); +} +.ui-icon-checkbox-on { + background-image: url(images/form-check-on.png); +} +.ui-icon-radio-off { + background-image: url(images/form-radio-off.png);} +.ui-icon-radio-on { + background-image: url(images/form-radio-on.png); +} +.ui-icon-searchfield { + background-image: url(images/icon-search-black.png); + background-size: 16px 16px; +} +.ui-icon-save { + background-image: url(images/icone-save.png); + background-size: 16px 16px; +} +.ui-icon-folder { + background-image: url(images/icone-folder.png); + background-size: 16px 16px; +} + +/* loading icon */ +.ui-icon-loading { + background-image: url(images/ajax-loader.png); + width: 40px; + height: 40px; + -moz-border-radius: 20px; + -webkit-border-radius: 20px; + border-radius: 20px; + background-size: 35px 35px; +} + + +/* Button corner classes +-----------------------------------------------------------------------------------------------------------*/ + +.ui-btn-corner-tl { + -moz-border-radius-topleft: 1em; + -webkit-border-top-left-radius: 1em; + border-top-left-radius: 1em; +} +.ui-btn-corner-tr { + -moz-border-radius-topright: 1em; + -webkit-border-top-right-radius: 1em; + border-top-right-radius: 1em; +} +.ui-btn-corner-bl { + -moz-border-radius-bottomleft: 1em; + -webkit-border-bottom-left-radius: 1em; + border-bottom-left-radius: 1em; +} +.ui-btn-corner-br { + -moz-border-radius-bottomright: 1em; + -webkit-border-bottom-right-radius: 1em; + border-bottom-right-radius: 1em; +} +.ui-btn-corner-top { + -moz-border-radius-topleft: 1em; + -webkit-border-top-left-radius: 1em; + border-top-left-radius: 1em; + -moz-border-radius-topright: 1em; + -webkit-border-top-right-radius: 1em; + border-top-right-radius: 1em; +} +.ui-btn-corner-bottom { + -moz-border-radius-bottomleft: 1em; + -webkit-border-bottom-left-radius: 1em; + border-bottom-left-radius: 1em; + -moz-border-radius-bottomright: 1em; + -webkit-border-bottom-right-radius: 1em; + border-bottom-right-radius: 1em; +} +.ui-btn-corner-right { + -moz-border-radius-topright: 1em; + -webkit-border-top-right-radius: 1em; + border-top-right-radius: 1em; + -moz-border-radius-bottomright: 1em; + -webkit-border-bottom-right-radius: 1em; + border-bottom-right-radius: 1em; +} +.ui-btn-corner-left { + -moz-border-radius-topleft: 1em; + -webkit-border-top-left-radius: 1em; + border-top-left-radius: 1em; + -moz-border-radius-bottomleft: 1em; + -webkit-border-bottom-left-radius: 1em; + border-bottom-left-radius: 1em; +} +.ui-btn-corner-all { + -moz-border-radius: 1em; + -webkit-border-radius: 1em; + border-radius: 1em; +} + +/* radius clip workaround for cleaning up corner trapping */ +.ui-corner-tl, +.ui-corner-tr, +.ui-corner-bl, +.ui-corner-br, +.ui-corner-top, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-left, +.ui-corner-all, +.ui-btn-corner-tl, +.ui-btn-corner-tr, +.ui-btn-corner-bl, +.ui-btn-corner-br, +.ui-btn-corner-top, +.ui-btn-corner-bottom, +.ui-btn-corner-right, +.ui-btn-corner-left, +.ui-btn-corner-all { + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +/* Overlay / modal +-----------------------------------------------------------------------------------------------------------*/ + +.ui-overlay { + background: #666; + opacity: .5; + filter: Alpha(Opacity=50); + position: absolute; + width: 100%; + height: 100%; +} +.ui-overlay-shadow { + -moz-box-shadow: 0px 0px 12px rgba(0,0,0,.6); + -webkit-box-shadow: 0px 0px 12px rgba(0,0,0,.6); + box-shadow: 0px 0px 12px rgba(0,0,0,.6); +} +.ui-shadow { + -moz-box-shadow: 0px 1px 4px rgba(0,0,0,.3); + -webkit-box-shadow: 0px 1px 4px rgba(0,0,0,.3); + box-shadow: 0px 1px 4px rgba(0,0,0,.3); +} +.ui-bar-a .ui-shadow, +.ui-bar-b .ui-shadow , +.ui-bar-c .ui-shadow { + -moz-box-shadow: 0px 1px 0 rgba(255,255,255,.3); + -webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.3); + box-shadow: 0px 1px 0 rgba(255,255,255,.3); +} +.ui-shadow-inset { + -moz-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); + -webkit-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); + box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); +} +.ui-icon-shadow { + -moz-box-shadow: 0px 1px 0 rgba(255,255,255,.4); + -webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.4); + box-shadow: 0px 1px 0 rgba(255,255,255,.4); +} + + +/* Focus state - set here for specificity +-----------------------------------------------------------------------------------------------------------*/ + +.ui-focus { + -moz-box-shadow: 0px 0px 12px #387bbe; + -webkit-box-shadow: 0px 0px 12px #387bbe; + box-shadow: 0px 0px 12px #387bbe; +} + +/* unset box shadow in browsers that don't do it right +-----------------------------------------------------------------------------------------------------------*/ + +.ui-mobile-nosupport-boxshadow * { + -moz-box-shadow: none !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + +/* ...and bring back focus */ +.ui-mobile-nosupport-boxshadow .ui-focus { + outline-width: 2px; +}/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* Note: Code is in draft form and is subject to change +*/ + +/* some unsets - more probably needed */ +.ui-mobile fieldset, .ui-page { padding: 0; margin: 0; } +.ui-mobile a img, .ui-mobile fieldset { border: 0; } + +/* responsive page widths */ +.ui-mobile-viewport { margin: 0; overflow-x: hidden; -webkit-text-size-adjust: none; -ms-text-size-adjust:none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } + +/* "page" containers - full-screen views, one should always be in view post-pageload */ +.ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page { top: 0; left: 0; width: 100%; min-height: 100%; position: absolute; display: none; border: 0; } +.ui-mobile .ui-page-active { display: block; overflow: visible; } + +/*orientations from js are available */ +.portrait, +.portrait .ui-page { min-height: 480px; } +.landscape, +.landscape .ui-page { min-height: 320px; } + +/* loading screen */ +.ui-loading .ui-mobile-viewport { overflow: hidden !important; } +.ui-loading .ui-loader { display: block; } +.ui-loading .ui-page { overflow: hidden; } +.ui-loader { display: none; position: absolute; opacity: .85; z-index: 10; left: 50%; width: 200px; margin-left: -130px; margin-top: -35px; padding: 10px 30px; } +.ui-loader h1 { font-size: 15px; text-align: center; } +.ui-loader .ui-icon { position: static; display: block; opacity: .9; margin: 0 auto; width: 35px; height: 35px; background-color: transparent; } + +/*fouc*/ +.ui-mobile-rendering > * { visibility: hidden; } + +/*headers, content panels*/ +.ui-bar, .ui-body { position: relative; padding: .4em 15px; overflow: hidden; display: block; clear:both; } +.ui-bar { font-size: 16px; margin: 0; } +.ui-bar h1, .ui-bar h2, .ui-bar h3, .ui-bar h4, .ui-bar h5, .ui-bar h6 { margin: 0; padding: 0; font-size: 16px; display: inline-block; } + +.ui-header, .ui-footer { display: block; } +.ui-page .ui-header, .ui-page .ui-footer { position: relative; } +.ui-header .ui-btn-left { position: absolute; left: 10px; top: .4em; } +.ui-header .ui-title, .ui-footer .ui-title { text-align: center; font-size: 16px; display: block; margin: .6em 90px .8em; padding: 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; outline: 0 !important; } +.ui-header .ui-btn-right { position: absolute; right: 10px; top: .4em; } +.ui-header .ui-btn-right-bis { position: absolute; right: 50px; top: .4em; } +.ui-header .ui-btn-right-bis2 { position: absolute; left: 50px; top: .4em} + +/*content area*/ +.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; } +.ui-page-fullscreen .ui-content { padding:0; } + +/* icons sizing */ +.ui-icon { width: 18px; height: 18px; } + +/* fullscreen class on ui-content div */ +.ui-fullscreen { } +.ui-fullscreen img { max-width: 100%; } + +/* non-js content hiding */ +.ui-nojs { position: absolute; left: -9999px; } +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.spin { + -webkit-transform: rotate(360deg); + -webkit-animation-name: spin; + -webkit-animation-duration: 1s; + -webkit-animation-iteration-count: infinite; +} +@-webkit-keyframes spin { + from {-webkit-transform: rotate(0deg);} + to {-webkit-transform: rotate(360deg);} +} + +/* Transitions from jQtouch (with small modifications): http://www.jqtouch.com/ +Built by David Kaneda and maintained by Jonathan Stark. +*/ +.in, .out { + -webkit-animation-timing-function: ease-in-out; + -webkit-animation-duration: 350ms; +} + +.slide.in { + -webkit-transform: translateX(0); + -webkit-animation-name: slideinfromright; +} + +.slide.out { + -webkit-transform: translateX(-100%); + -webkit-animation-name: slideouttoleft; +} + +.slide.in.reverse { + -webkit-transform: translateX(0); + -webkit-animation-name: slideinfromleft; +} + +.slide.out.reverse { + -webkit-transform: translateX(100%); + -webkit-animation-name: slideouttoright; +} + +.slideup.in { + -webkit-transform: translateY(0); + -webkit-animation-name: slideinfrombottom; + z-index: 10; +} + +.slideup.out { + -webkit-animation-name: dontmove; + z-index: 0; +} + +.slideup.out.reverse { + -webkit-transform: translateY(100%); + z-index: 10; + -webkit-animation-name: slideouttobottom; +} + +.slideup.in.reverse { + z-index: 0; + -webkit-animation-name: dontmove; +} +.slidedown.in { + -webkit-transform: translateY(0); + -webkit-animation-name: slideinfromtop; + z-index: 10; +} + +.slidedown.out { + -webkit-animation-name: dontmove; + z-index: 0; +} + +.slidedown.out.reverse { + -webkit-transform: translateY(-100%); + z-index: 10; + -webkit-animation-name: slideouttotop; +} + +.slidedown.in.reverse { + z-index: 0; + -webkit-animation-name: dontmove; +} + +@-webkit-keyframes slideinfromright { + from { -webkit-transform: translateX(100%); } + to { -webkit-transform: translateX(0); } +} + +@-webkit-keyframes slideinfromleft { + from { -webkit-transform: translateX(-100%); } + to { -webkit-transform: translateX(0); } +} + +@-webkit-keyframes slideouttoleft { + from { -webkit-transform: translateX(0); } + to { -webkit-transform: translateX(-100%); } +} + +@-webkit-keyframes slideouttoright { + from { -webkit-transform: translateX(0); } + to { -webkit-transform: translateX(100%); } +} + + +@-webkit-keyframes slideinfromtop { + from { -webkit-transform: translateY(-100%); } + to { -webkit-transform: translateY(0); } +} + +@-webkit-keyframes slideinfrombottom { + from { -webkit-transform: translateY(100%); } + to { -webkit-transform: translateY(0); } +} + +@-webkit-keyframes slideouttobottom { + from { -webkit-transform: translateY(0); } + to { -webkit-transform: translateY(100%); } +} + +@-webkit-keyframes slideouttotop { + from { -webkit-transform: translateY(0); } + to { -webkit-transform: translateY(-100%); } +} +@-webkit-keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + +@-webkit-keyframes fadeout { + from { opacity: 1; } + to { opacity: 0; } +} + +.fade.in { + opacity: 1; + z-index: 10; + -webkit-animation-name: fadein; +} +.fade.out { + z-index: 0; + -webkit-animation-name: fadeout; +} + +/* The properties in this body rule are only necessary for the 'flip' transition. + * We need specify the perspective to create a projection matrix. This will add + * some depth as the element flips. The depth number represents the distance of + * the viewer from the z-plane. According to the CSS3 spec, 1000 is a moderate + * value. + */ +.ui-mobile-viewport-perspective { + -webkit-perspective: 1000; + position: absolute; +} + +.ui-mobile-viewport-transitioning, +.ui-mobile-viewport-transitioning .ui-page { + width: 100%; + height: 100%; + overflow: hidden; +} + +.flip { + -webkit-animation-duration: .65s; + -webkit-backface-visibility:hidden; + -webkit-transform:translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ +} + +.flip.in { + -webkit-transform: rotateY(0) scale(1); + -webkit-animation-name: flipinfromleft; +} + +.flip.out { + -webkit-transform: rotateY(-180deg) scale(.8); + -webkit-animation-name: flipouttoleft; +} + +/* Shake it all about */ + +.flip.in.reverse { + -webkit-transform: rotateY(0) scale(1); + -webkit-animation-name: flipinfromright; +} + +.flip.out.reverse { + -webkit-transform: rotateY(180deg) scale(.8); + -webkit-animation-name: flipouttoright; +} + +@-webkit-keyframes flipinfromright { + from { -webkit-transform: rotateY(-180deg) scale(.8); } + to { -webkit-transform: rotateY(0) scale(1); } +} + +@-webkit-keyframes flipinfromleft { + from { -webkit-transform: rotateY(180deg) scale(.8); } + to { -webkit-transform: rotateY(0) scale(1); } +} + +@-webkit-keyframes flipouttoleft { + from { -webkit-transform: rotateY(0) scale(1); } + to { -webkit-transform: rotateY(-180deg) scale(.8); } +} + +@-webkit-keyframes flipouttoright { + from { -webkit-transform: rotateY(0) scale(1); } + to { -webkit-transform: rotateY(180deg) scale(.8); } +} + + +/* Hackish, but reliable. */ + +@-webkit-keyframes dontmove { + from { opacity: 1; } + to { opacity: 1; } +} + +.pop { + -webkit-transform-origin: 50% 50%; +} + +.pop.in { + -webkit-transform: scale(1); + opacity: 1; + -webkit-animation-name: popin; + z-index: 10; +} + +.pop.out.reverse { + -webkit-transform: scale(.2); + opacity: 0; + -webkit-animation-name: popout; + z-index: 10; +} + +.pop.in.reverse { + z-index: 0; + -webkit-animation-name: dontmove; +} + +@-webkit-keyframes popin { + from { + -webkit-transform: scale(.2); + opacity: 0; + } + to { + -webkit-transform: scale(1); + opacity: 1; + } +} + +@-webkit-keyframes popout { + from { + -webkit-transform: scale(1); + opacity: 1; + } + to { + -webkit-transform: scale(.2); + opacity: 0; + } +}/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ + +/* content configurations. */ +.ui-grid-a, .ui-grid-b, .ui-grid-c, .ui-grid-d { overflow: hidden; } +.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e { margin: 0; padding: 0; border: 0; float: left; } + +/* grid a: 50/50 */ +.ui-grid-a .ui-block-a, .ui-grid-a .ui-block-b { width: 50%; } +.ui-grid-a .ui-block-a { clear: left; } + +/* grid b: 33/33/33 */ +.ui-grid-b .ui-block-a, .ui-grid-b .ui-block-b, .ui-grid-b .ui-block-c { width: 33.333%; } +.ui-grid-b .ui-block-a { clear: left; } + +/* grid c: 25/25/25/25 */ +.ui-grid-c .ui-block-a, .ui-grid-c .ui-block-b, .ui-grid-c .ui-block-c, .ui-grid-c .ui-block-d { width: 25%; } +.ui-grid-c .ui-block-a { clear: left; } + +/* grid d: 20/20/20/20/20 */ +.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 20%; } +.ui-grid-d .ui-block-a { clear: left; }/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +/* fixed page header & footer configuration */ +.ui-header, .ui-footer, .ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { position: absolute; overflow: hidden; width: 100%; border-left-width: 0; border-right-width: 0; } +.ui-header-fixed, .ui-footer-fixed { + z-index: 1000; + -webkit-transform: translateZ(0); /* Force header/footer rendering to go through the same rendering pipeline as native page scrolling. */ +} +.ui-footer-duplicate, .ui-page-fullscreen .ui-fixed-inline { display: none; } +.ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { opacity: .9; } +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-navbar { overflow: hidden; } +.ui-navbar ul, .ui-navbar-expanded ul { list-style:none; padding: 0; margin: 0; position: relative; display: block; border: 0;} +.ui-navbar-collapsed ul { float: left; width: 75%; margin-right: -2px; } +.ui-navbar-collapsed .ui-navbar-toggle { float: left; width: 25%; } +.ui-navbar li.ui-navbar-truncate { position: absolute; left: -9999px; top: -9999px; } +.ui-navbar li .ui-btn, .ui-navbar .ui-navbar-toggle .ui-btn { display: block; font-size: 12px; text-align: center; margin: 0; border-right-width: 0; } +.ui-navbar li .ui-btn { margin-right: -1px; } +.ui-navbar li .ui-btn:last-child { margin-right: 0; } +.ui-header .ui-navbar li .ui-btn, .ui-header .ui-navbar .ui-navbar-toggle .ui-btn, +.ui-footer .ui-navbar li .ui-btn, .ui-footer .ui-navbar .ui-navbar-toggle .ui-btn { border-top-width: 0; border-bottom-width: 0; } +.ui-navbar .ui-btn-inner { padding-left: 2px; padding-right: 2px; } +.ui-navbar-noicons li .ui-btn .ui-btn-inner, .ui-navbar-noicons .ui-navbar-toggle .ui-btn-inner { padding-top: .8em; padding-bottom: .9em; } +/*expanded page styles*/ +.ui-navbar-expanded .ui-btn { margin: 0; font-size: 14px; } +.ui-navbar-expanded .ui-btn-inner { padding-left: 5px; padding-right: 5px; } +.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner { padding: 45px 5px 15px; text-align: center; } +.ui-navbar-expanded .ui-btn-icon-top .ui-icon { top: 15px; } +.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner { padding: 15px 5px 45px; text-align: center; } +.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon { bottom: 15px; } +.ui-navbar-expanded li .ui-btn .ui-btn-inner { min-height: 2.5em; } +.ui-navbar-expanded .ui-navbar-noicons .ui-btn .ui-btn-inner { padding-top: 1.8em; padding-bottom: 1.9em; } +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-btn { display: block; text-align: center; cursor:pointer; position: relative; margin: .5em 5px; padding: 0; } +.ui-btn:focus, .ui-btn:active { outline: none; } +.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; } +.ui-btn-inline { display: inline-block; } +.ui-btn-inner { padding: .6em 25px; display: block; height: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; } +.ui-header .ui-btn-inner, .ui-footer .ui-btn-inner, .ui-bar .ui-btn-inner { padding: .4em 8px .5em; } +.ui-btn-icon-notext { display: inline-block; width: 20px; height: 20px; padding: 2px 1px 2px 3px; text-indent: -9999px; } +.ui-btn-icon-notext .ui-btn-inner { padding: 0; } +.ui-btn-icon-notext .ui-btn-text { position: absolute; left: -999px; } +.ui-btn-icon-left .ui-btn-inner { padding-left: 33px; } +.ui-header .ui-btn-icon-left .ui-btn-inner, +.ui-footer .ui-btn-icon-left .ui-btn-inner, +.ui-bar .ui-btn-icon-left .ui-btn-inner { padding-left: 27px; } +.ui-btn-icon-right .ui-btn-inner { padding-right: 33px; } +.ui-header .ui-btn-icon-right .ui-btn-inner, +.ui-footer .ui-btn-icon-right .ui-btn-inner, +.ui-bar .ui-btn-icon-right .ui-btn-inner { padding-right: 27px; } +.ui-btn-icon-top .ui-btn-inner { padding-top: 33px; } +.ui-header .ui-btn-icon-top .ui-btn-inner, +.ui-footer .ui-btn-icon-top .ui-btn-inner, +.ui-bar .ui-btn-icon-top .ui-btn-inner { padding-top: 27px; } +.ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 33px; } +.ui-header .ui-btn-icon-bottom .ui-btn-inner, +.ui-footer .ui-btn-icon-bottom .ui-btn-inner, +.ui-bar .ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 27px; } + +/*btn icon positioning*/ +.ui-btn-icon-notext .ui-icon { display: block; } +.ui-btn-icon-left .ui-icon, .ui-btn-icon-right .ui-icon { position: absolute; top: 50%; margin-top: -9px; } +.ui-btn-icon-top .ui-icon, .ui-btn-icon-bottom .ui-icon { position: absolute; left: 50%; margin-left: -9px; } +.ui-btn-icon-left .ui-icon { left: 10px; } +.ui-btn-icon-right .ui-icon {right: 10px; } +.ui-header .ui-btn-icon-left .ui-icon, +.ui-footer .ui-btn-icon-left .ui-icon, +.ui-bar .ui-btn-icon-left .ui-icon { left: 4px; } +.ui-header .ui-btn-icon-right .ui-icon, +.ui-footer .ui-btn-icon-right .ui-icon, +.ui-bar .ui-btn-icon-right .ui-icon { right: 4px; } +.ui-header .ui-btn-icon-top .ui-icon, +.ui-footer .ui-btn-icon-top .ui-icon, +.ui-bar .ui-btn-icon-top .ui-icon { top: 4px; } +.ui-header .ui-btn-icon-bottom .ui-icon, +.ui-footer .ui-btn-icon-bottom .ui-icon, +.ui-bar .ui-btn-icon-bottom .ui-icon { bottom: 4px; } +.ui-btn-icon-top .ui-icon { top: 5px; } +.ui-btn-icon-bottom .ui-icon { bottom: 5px; } +/*hiding native button,inputs */ +.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: 0; cursor: pointer; } +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-collapsible-contain { margin: .5em 0; } +.ui-collapsible-heading { font-size: 16px; display: block; margin: 0 -8px; padding: 0; border-width: 0 0 1px 0; position: relative; } +.ui-collapsible-heading a { text-align: left; margin: 0; } +.ui-collapsible-heading a .ui-btn-inner { padding-left: 40px; } +.ui-collapsible-heading a span.ui-btn { position: absolute; left: 6px; top: 50%; margin: -12px 0 0 0; width: 20px; height: 20px; padding: 1px 0px 1px 2px; text-indent: -9999px; } +.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 0; } +.ui-collapsible-heading a span.ui-btn .ui-icon { left: 0; margin-top: -10px; } +.ui-collapsible-heading-status { position:absolute; left:-9999px; } +.ui-collapsible-content { display: block; padding: 10px 0 10px 8px; } +.ui-collapsible-content-collapsed { display: none; } + +.ui-collapsible-set { margin: .5em 0; } +.ui-collapsible-set .ui-collapsible-contain { margin: -1px 0 0; } +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-controlgroup, fieldset.ui-controlgroup { padding: 0; margin: .5em 0 1em; } +.ui-bar .ui-controlgroup { margin: 0 .3em; } +.ui-controlgroup-label { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; } +.ui-controlgroup-controls { display: block; width: 95%;} +.ui-controlgroup li { list-style: none; } +.ui-controlgroup-vertical .ui-btn, +.ui-controlgroup-vertical .ui-checkbox, .ui-controlgroup-vertical .ui-radio { margin: 0; border-bottom-width: 0; } +.ui-controlgroup-vertical .ui-controlgroup-last { border-bottom-width: 1px; } +.ui-controlgroup-horizontal { padding: 0; } +.ui-controlgroup-horizontal .ui-btn, +.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { margin: 0 -5px 0 0; display: inline-block; } +.ui-controlgroup-horizontal .ui-checkbox .ui-btn, .ui-controlgroup-horizontal .ui-radio .ui-btn, +.ui-controlgroup-horizontal .ui-checkbox:last-child, .ui-controlgroup-horizontal .ui-radio:last-child { margin-right: 0; } +.ui-controlgroup-horizontal .ui-controlgroup-last { margin-right: 0; } +.ui-controlgroup .ui-checkbox label, .ui-controlgroup .ui-radio label { font-size: 16px; } +/* conflicts with listview.. +.ui-controlgroup .ui-btn-icon-notext { width: 30px; height: 30px; text-indent: -9999px; } +.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner { padding: 5px 6px 5px 5px; } +*/ + +.min-width-480px .ui-controlgroup-label { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } +.min-width-480px .ui-controlgroup-controls { width: 60%; display: inline-block; } /* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-dialog { min-height: 480px; } +.ui-dialog .ui-header, .ui-dialog .ui-content, .ui-dialog .ui-footer { margin: 15px; position: relative; } +.ui-dialog .ui-header, .ui-dialog .ui-footer { z-index: 10; width: auto; } +.ui-dialog .ui-content, .ui-dialog .ui-footer { margin-top: -15px; }/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-checkbox, .ui-radio { position:relative; margin: .2em 0 .5em; z-index: 1; } +.ui-checkbox .ui-btn, .ui-radio .ui-btn { margin: 0; text-align: left; z-index: 2; } +.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner { padding-left: 45px; } +.ui-checkbox .ui-btn-icon-right .ui-btn-inner, .ui-radio .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } +.ui-checkbox .ui-btn-icon-left .ui-icon, .ui-radio .ui-btn-icon-left .ui-icon {left: 15px; } +.ui-checkbox .ui-btn-icon-right .ui-icon, .ui-radio .ui-btn-icon-right .ui-icon {right: 15px; } +/* input, label positioning */ +.ui-checkbox input,.ui-radio input { position:absolute; left:20px; top:50%; width: 10px; height: 10px; margin:-5px 0 0 0; outline: 0 !important; z-index: 1; }/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-field-contain { background: none; padding: 1.5em 0; margin: 0; border-bottom-width: 1px; overflow: visible; } +.ui-field-contain:first-child { border-top-width: 0; } +.min-width-480px .ui-field-contain { border-width: 0; padding: 0; margin: 1em 0; }/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-select { display: block; position: relative; } +.ui-select select { position: absolute; left: -9999px; top: -9999px; } +.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0.001; } +.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; } + +.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } +.ui-select .ui-btn-icon-right .ui-icon { right: 15px; } + +/* labels */ +label.ui-select { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; display: block; } + +/*listbox*/ +.ui-select .ui-btn-text, .ui-selectmenu .ui-btn-text { display: inline-block; min-height: 1em; } +.ui-select .ui-btn-text { text-overflow: ellipsis; overflow: hidden; width: 85% } + +.ui-selectmenu { position: absolute; padding: 0; z-index: 100 !important; width: 80%; max-width: 350px; padding: 6px; } +.ui-selectmenu .ui-listview { margin: 0; } +.ui-selectmenu .ui-btn.ui-li-divider { cursor: default; } +.ui-selectmenu-hidden { top: -9999px; left: -9999px; } +.ui-selectmenu-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 99; } +.ui-screen-hidden, .ui-selectmenu-list .ui-li .ui-icon { display: none; } +.ui-selectmenu-list .ui-li .ui-icon { display: block; } +.ui-li.ui-selectmenu-placeholder { display: none; } + +.min-width-480px label.ui-select { display: inline-block; width: 20%; margin: 0 2% 0 0; } +.min-width-480px .ui-select { width: 60%; display: inline-block; } + +/* when no placeholder is defined in a multiple select, the header height doesn't even extend past the close button. this shim's content in there */ +.ui-selectmenu .ui-header h1:after { content: '.'; visibility: hidden; } +/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +label.ui-input-text { font-size: 16px; line-height: 1.4; display: block; font-weight: normal; margin: 0 0 .3em; } +input.ui-input-text, textarea.ui-input-text { background-image: none; padding: .4em; line-height: 1.4; font-size: 16px; display: block; width: 95%; } +input.ui-input-text { -webkit-appearance: none; } +textarea.ui-input-text { height: 50px; -webkit-transition: height 200ms linear; -moz-transition: height 200ms linear; -o-transition: height 200ms linear; transition: height 200ms linear; } +.ui-input-search { padding: 0 30px; width: 77%; background-position: 8px 50%; background-repeat: no-repeat; position: relative; } +.ui-input-search input.ui-input-text { border: none; width: 98%; padding: .4em 0; margin: 0; display: block; background: transparent none; outline: 0 !important; } +.ui-input-search .ui-input-clear { position: absolute; right: 0; top: 50%; margin-top: -14px; } +.ui-input-search .ui-input-clear-hidden { display: none; } + +/* orientation adjustments - incomplete!*/ +.min-width-480px label.ui-input-text { vertical-align: top; } +.min-width-480px label.ui-input-text { display: inline-block; width: 20%; margin: 0 2% 0 0; } +.min-width-480px input.ui-input-text, +.min-width-480px textarea.ui-input-text, +.min-width-480px .ui-input-search { width: 60%; display: inline-block; } +.min-width-480px .ui-input-search { width: 50%; }/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +.ui-listview { margin: 0; counter-reset: listnumbering; } +.ui-content .ui-listview { margin: -15px; } +.ui-content .ui-listview-inset { margin: 1em 0; } +.ui-listview, .ui-li { list-style:none; padding:0; zoom: 1; } +.ui-li { display: block; margin:0; position: relative; overflow: hidden; text-align: left; border-width: 0; border-top-width: 1px; } +.ui-li .ui-btn-text { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } +.ui-li-divider, .ui-li-static { padding: .5em 15px; font-size: 14px; font-weight: bold; counter-reset: listnumbering; } +ol.ui-listview .ui-link-inherit:before, .ui-li-dec { font-size: .8em; display: inline-block; padding-right: .3em; font-weight: normal;counter-increment: listnumbering; content: counter(listnumbering) ". "; } +ol.ui-listview .ui-li-jsnumbering:before { content: "" !important; } /* to avoid chance of duplication */ +.ui-listview-inset .ui-li { border-right-width: 1px; border-left-width: 1px; } +.ui-li:last-child { border-bottom-width: 1px; } +.ui-li .ui-btn-inner { display: block; position: relative; padding: .7em 75px .7em 15px; } +.ui-li-has-thumb .ui-btn-inner { min-height: 60px; padding-left: 100px; } +.ui-li-has-icon .ui-btn-inner { min-height: 20px; padding-left: 40px; } +.ui-li-heading { font-size: 16px; font-weight: bold; display: block; margin: .6em 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } +.ui-li-desc { font-size: 12px; font-weight: normal; display: block; margin: -.5em 0 .6em; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } +.ui-li-thumb, .ui-li-icon { position: absolute; left: 1px; top: 0; max-height: 80px; max-width: 80px; } +.ui-li-icon { max-height: 40px; max-width: 40px; left: 10px; top: .9em; } +.ui-li-thumb, .ui-li-icon, .ui-li-content { float: left; margin-right: 10px; } + +.ui-li-aside { float: right; width: 50%; text-align: right; margin: .3em 0; } +.min-width-480px .ui-li-aside { width: 45%; } +.ui-li-has-alt .ui-btn-inner { padding-right: 95px; } +.ui-li-count { position: absolute; font-size: 11px; font-weight: bold; padding: .2em .5em; top: 50%; margin-top: -.9em; right: 38px; } +.ui-li-divider .ui-li-count { right: 10px; } +.ui-li-has-alt .ui-li-count { right: 55px; } +.ui-li-link-alt { position: absolute; width: 40px; height: 100%; border-width: 0; border-left-width: 1px; top: 0; right: 0; margin: 0; padding: 0; } +.ui-li-link-alt .ui-btn { overflow: hidden; position: absolute; right: 8px; top: 50%; margin: -11px 0 0 0; border-bottom-width: 1px; } +.ui-li-link-alt .ui-btn-inner { padding: 0; position: static; } +.ui-li-link-alt .ui-btn .ui-icon { right: 50%; margin-right: -9px; } + +.ui-listview-filter { border-width: 0; overflow: hidden; margin: -15px -15px 15px -15px } +.ui-listview-filter .ui-input-search { margin: 5px; width: auto; display: block; } + +/* Odd iPad positioning issue. */ +@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { + .ui-li .ui-btn-text { overflow: visible; } +}/* +* jQuery Mobile Framework +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. +*/ +label.ui-slider { display: block; } +input.ui-slider-input, .min-width-480px input.ui-slider-input { display: inline-block; width: 50px; } +select.ui-slider-switch { display: none; } +div.ui-slider { position: relative; display: inline-block; overflow: visible; height: 15px; padding: 0; margin: 0 2% 0 20px; top: 4px; width: 66%; } +a.ui-slider-handle { position: absolute; z-index: 10; top: 50%; width: 28px; height: 28px; margin-top: -15px; margin-left: -15px; } +a.ui-slider-handle .ui-btn-inner { padding-left: 0; padding-right: 0; } +.min-width-480px label.ui-slider { display: inline-block; width: 20%; margin: 0 2% 0 0; } +.min-width-480px div.ui-slider { width: 45%; } + +div.ui-slider-switch { height: 32px; overflow: hidden; margin-left: 0; } +div.ui-slider-inneroffset { margin-left: 50%; position: absolute; top: 1px; height: 100%; width: 50%; } +div.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; } +div.ui-slider-labelbg { position: absolute; top:0; margin: 0; border-width: 0; } +div.ui-slider-switch div.ui-slider-labelbg-a { width: 60%; height: 100%; left: 0; } +div.ui-slider-switch div.ui-slider-labelbg-b { width: 60%; height: 100%; right: 0; } +.ui-slider-switch-a div.ui-slider-labelbg-a, .ui-slider-switch-b div.ui-slider-labelbg-b { z-index: 1; } +.ui-slider-switch-a div.ui-slider-labelbg-b, .ui-slider-switch-b div.ui-slider-labelbg-a { z-index: 10; } + +div.ui-slider-switch a.ui-slider-handle { z-index: 20; width: 101%; height: 32px; margin-top: -18px; margin-left: -101%; } +span.ui-slider-label { width: 100%; position: absolute;height: 32px; font-size: 16px; text-align: center; line-height: 2; background: none; border-color: transparent; } +span.ui-slider-label-a { left: -100%; margin-right: -1px } +span.ui-slider-label-b { right: -100%; margin-left: -1px } diff --git a/addons/web_mobile/static/openerp/dynamics/images/ajax-loader.png b/addons/web_mobile/static/openerp/dynamics/images/ajax-loader.png new file mode 100755 index 0000000000000000000000000000000000000000..811a2cdd1b492c47faf85c1206ad6606521eb6e4 GIT binary patch literal 503 zcmeAS@N?(olHy`uVBq!ia0vp^${@_b3?$!tUzY`>n2Vh}LpV4%Za?&Y0OT43_=LFr z|Ns9ZDd7Dck0hX8fs!DgJ6C3d)qYMwA5Sr=f?F`h}-_x&BOOZ@XQnE}c<_xEZu zoIX1zlA-v_?sD-1ZfECkmVe(>o?xwNmGDbK;?2MR41rRzXA2bX{on66#ob*wrsMPf z`i=nRm=4)s4z4?=xi7SyIo*As^~h=O3#~U!U4D?`wnG2XC7uMQrY5F@nOn9v%usT4 zIQ+eo=O@f^)EG;nv4yKy{)Zban#Mw;QTQ|w3l1fm1G7ixyoePnc0 W<<+r~s8k2qz~JfX=d#Wzp$Py*TXTc} literal 0 HcmV?d00001 diff --git a/addons/web_mobile/static/openerp/dynamics/images/form-check-on.png b/addons/web_mobile/static/openerp/dynamics/images/form-check-on.png new file mode 100755 index 0000000000000000000000000000000000000000..e6daaaf8b10684cc6bcdb58f038616800182bbee GIT binary patch literal 460 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dH0CE!od_r9R zgTeCU%hfg16%`dFB_-FcT`MFcG;`+6o}L~nD=SAQ$L8kdnwpxDk`iNMV?90Hw6ruJ zJ1Q#5-{0@dnKM8we*XRt1=-ozKv|#^Q03txM}S7{?Z0{wXqQ4skY6yvf1of5IAd&F zKGWC*2tw1!XMQ%wKMhpNS>O>_%)r1c1j3A$?$-SQ3d)qYMwA5SrEak7F}3vKO`$^yJgtcv*14*3Y_+cZzx|D3>>SN+`x7SR7qtid-~HCB>?G5?%?++% z7oxmVJnya8slYUC|DtQNRzq$nXS!NNh`q{qe+_xo?{-f4rhDj!)1)di$jC9c}_fJEuIm|vwqP6 zj=!5%u^;>xXv(##qWAOPW5(wKmkIAN;k>l7Q{wE(lP47G*LYsGDG%dLC| u-W7?3r7X?u+Nai)c3ARHWR%H;Z;V&91T)uhc)bETiNVv=&t;ucLK6Vp3!QKP literal 0 HcmV?d00001 diff --git a/addons/web_mobile/static/openerp/dynamics/images/form-radio-on.png b/addons/web_mobile/static/openerp/dynamics/images/form-radio-on.png new file mode 100755 index 0000000000000000000000000000000000000000..ddc40497055e1e4dc24b4cb2397923b9ae3061f9 GIT binary patch literal 519 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQa%*9TgAsieWw;%dH0CE!od_r9R zg8`5S6o3Ez{ne{i&zw24X3ZJ_et|7pwmg6S{MfN$4CnrTk#gdYepReNg_0n@V21ypp@K?E zN}+cJ1(iZWm6VK)LxCU-2+GSlX08glzdIPHmb1VkvY3H^TL^?1FWs&C0~C}gag8Vm z&QB{TPb^Aha7@WhN>y;nEJ`iUFUl@fa1J&t-1^uIs7@55&bcTxu_QA;Paz~TH z&OKalKC$AO@{^t>{r9zE!e{?{5>olJk8kfQ+ldPlwbFNQnA>`SLuu;X*xR?`I9Ov{ zo-F;O7}p^&cfrjKZ_*#1+xsAmWvcgTgX3G&uD2&OmfrSyczV`>IQ#t4sB8BoZTTxV pximrST*Gc(zOY%r`_uj`_t#Y7|G7@rs~+en22WQ%mvv4FO#lm@&w~H} literal 0 HcmV?d00001 diff --git a/addons/web_mobile/static/openerp/dynamics/images/icon-search-black.png b/addons/web_mobile/static/openerp/dynamics/images/icon-search-black.png new file mode 100755 index 0000000000000000000000000000000000000000..5721120f8df590d9b745fe96342590600580954b GIT binary patch literal 1245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+n3Xa^B1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPAEg{v+u2}(t{7puX=A(aKG z`a!A1`K3k4z=%sz23b{L-^Aq1JP;qO z-q+X4Gq1QLF)umQ)5TT^Xo6m5W{Q=$frY8Dg{g^?frWvgp^KZNxsipFqp^##k(sHh zxvLpWuSMv>2~2MaLa!-Ky`ZF!TL84#CABECEH%ZgC_h&L>}9J=+-@<#X&zK> z3U0R;~ffC;SG&XwqMVf^ch~>^Yvx!tm1jqY457ni}SVjYVq%taI-#D(4G9|(WxaX8>%?0 zEnMtZ3AiXPE9g4;pNVTjo8X=Vv9Bv!*uMofb@+W(Ul1LCXEFch9S5!T3|b`D#=Epi z8!X$`Q#^T}SV3DB&kn}5KMpmXj4}KwX0EWLVYv=t|Er^U4l+M8P6%CCB3I7rXTtng z(ro%`J;}32*E3kFzD&w~E`3 zu1)(le}&!cgTHxZ+{t1VE?exk>B-DH*~0fXyl=eG&%n&E;IvbH^`pPBpaRF!)z4*} HQ$iB}ksr6J literal 0 HcmV?d00001 diff --git a/addons/web_mobile/static/openerp/dynamics/images/icone-folder.png b/addons/web_mobile/static/openerp/dynamics/images/icone-folder.png new file mode 100755 index 0000000000000000000000000000000000000000..c75b3475790e4919a6c6af1f9ea612a9117812ba GIT binary patch literal 796 zcmex=xo=LsQGd)Xdz%(#qMz)y>_*(H%ZtUA_wf1-a6V&ff+L&poeOhy^LPUMRic>eEf+dN_It6eYH*15#Mm_ b&$qhiFR#4QSk(19_#~Icq6QGQ|9=wztLF{4 literal 0 HcmV?d00001 diff --git a/addons/web_mobile/static/openerp/dynamics/images/icone-save.png b/addons/web_mobile/static/openerp/dynamics/images/icone-save.png new file mode 100755 index 0000000000000000000000000000000000000000..9bf9b5c7eb7ac7d77999c71baaab57f21a30606e GIT binary patch literal 416 zcmex=5}@k>nVe zm|0i_g&2e#6%Bz3MA7vzu&@G!r3D#)+K`N65Mp3t5)^hk`2Q9I4>KdsW@bSKdxq<` zQ?|^Ca@%px>$BY?f0ZqB`<1phOo|Sk6!To=`S&Ti!*6LW%zQH;_;4uK<|Pw@OE*3A zJXb3BSoz|_gSXYTnXa3;bXM!Ki=i!BwU#>cGW@);@9p9H&$g*9N^6Qzw6t2$w!~5^ W@bl-5d#_LNvUFN{M7r?O|C<0#plb90 literal 0 HcmV?d00001 diff --git a/addons/web_mobile/static/openerp/dynamics/images/icons-18-black.png b/addons/web_mobile/static/openerp/dynamics/images/icons-18-black.png new file mode 100755 index 0000000000000000000000000000000000000000..3657baea879d521240f680fbec8272359cf68146 GIT binary patch literal 935 zcmV;Y16cftP)WdJfS zGcPeQ=RdAt0000SbVXQnQ*UN;cVTj606}DLVr3vkX>w(EZ*psMAVX6%akb+%0008Y zNkl5M6dx_BGRB=jtkv&nC#^YPT+2>qa40Opv+alEUwIDW&bav1AwZ z5UISIN3%1tZ{O^!mAc@93;qx2sE_F!B$Op++X$~MeEa_-_uoSA&sh~O`vkn6SL{CZRXnf_+)qg)#lw5}kq3lxFHVDgygl)MLbqoK;LF(RrgMky#$LGi}b zb&tWnamp?IF6{_i5#7KVqJSB4qG7}=gDVBnP<{TqJ5knyJ4*#& zS`?m0HS}i-THbd?y#3ou-O%EfLH<`X`2J86F}l>~nSZzR>?)Zsi=NgF+)2Fe zbe-%(jlLL+ZxwnkDjf@_+o&^+^XS~N#v#;>*Ir&1TyVh~!gmWdJfS zGcPeQ=RdAt0000SbVXQnQ*UN;cVTj606}DLVr3vkX>w(EZ*psMAVX6%akb+%0008d zNkl5M6dx_BGRhb9EKuvk5i1dRq&wbt}jf69iW*QuzHYO{{3%STaRD zL@Mv*(d?Vqw=+9yrLMT*ivI&TKF4$kQp!`b?S$7JzQcbK`){F-m#j)w=a?>leWv0k z*up+~nF#cC`8nLea)^<5CVU>nqII*%M4d6iTv<5!$pWM5>bWy&8-RH-CxVPjQRWcq zrQ-SqRDhV_?igaZ)>zQG0%A`TgT-L*gs2IAhIXUAa<{-(VU;CV3f>2jH$JZiB(FL1 z&}+vJL03d~e9bSS0W&zFe#|Vr8|vLaD4~>HV~N{A43>fO_!k?aiZEER-dvxo;V zvg{Jva=lU^Ml&T7*i7dSZoz`tXk7AxGK0P2n@$E}5XR<(<(9_-_4hpKET3Z1c($e_ zV$n6Fx_m8@>4r92<{chAIDtd$Jtr;McR;cs*2D|X>s@m>!(G6|G@FGQ4H)%kX(773 z)pNY>cF8AT#-8=HNdvyj+3Fsx~q5kE3by&d&``)oJjVprT2@f$$3`6#zYBB{VJA^uRB$}I^B<> zG0)5v9-KhdotzBV#HS9m(4iT2vA=h7X3$?w_Z?%Zb7gpVubl*FCwul(Cj8_Aig05> zJL9!ma+>X=xoj`H?~;X>3~(u_Fc!}+gEYEA#pRs+yix&|+`(j*{WEeY_dp?Keg5oT}7Z-RNqXHMIkts-7`x}yT$7Cqf~ za3}G;)0^}lerrN87(XiXQDiz6PWN#qkN4=@vc@6Qj+e8%uDIfg4}{+gs<#9*5ij O0000yn000DZQchC<{}Gwj0a}Lu000SaNLh0L z01CqZ01CqaG$|yj0000KbVXQnLvm$dbZKvHAXI5>WdJfSGcPeQ=RdAt0000SbVXQn zQ*UN;cVTj606}DLVr3vkX>w(EZ*psMAVX6%akb+%000DLNklM99UW*S-Ol7|1csUK#tH6lltZ-I&-j};KUL_ zn575Za#!z_G<_4m*_s#K)Kyh?zpk#T?#;3pGiJ<~G2{P%mLxyI_YdD<8vjMO4T)aC zch!EAnOt{Bjgn%861N0F*CcqpMUn%OydHP+;QiNW>=H&LrR3mI;k-E6g}Y)H!xr2sq^8~OPdRPF;)F}($Sj0<^_ zFqCgm5*iSc!a6;w$jSMi3EUOOSp|c5T%RdQL3N@(SMnR|{cVv$Ey+b5X)BSfR#_a% z0<1X7oM0wp?sC+LW9@TD0(aF>)&Vh|V>?h*N`lvBcO;@!q7IoFrZ1@Si&n9?3pEIG z!To0LO7z?X2U&Slk&=_Utc^ zaBB7FIh+)GNlM(wued=uCFhcoQWo@}nQu53W0sHE1oo+r9gObedC-2UsH6QD+!YjM zRs9m@OnVyyJWKEPOHIjlg7(oR&chqU5R77oQM_WsjHwL5qdY=>b7?!BC1WIX+yrWz zMbFRm=)Ue+Q&-PNE!D*poR^QYe`WV^#NN?~FcKc8yAt;~+5p3@EwpF1lP6*Q_hnIa z3_4kHCU57v;l^TO{I0> zHn(@QE59kw&#}=PmwKc4%zCaup~jw?@*P=SmAi^E1szB$-909Lp8~_x3d(FA3xx;n z8V947hsK=@E+5PtMNo{^8c#aqlrPbGS?SW5oz9&ebzv0VrOY%aV&)ar#zH^%+k+vpvkCA&nLbiih@NXw>u; zSZB7z>Rei7VU#h}Bouk?nHdpCU%vynF6q-Y2pqaro#|qx-p}1BIosI5|OX~*1 z4+e-1S5e6tH#32|Zu!qXw5IkbI8`dVMn^&g#nGm4k5X;20=TniG6~fa!j1CM1Q_4o zZVmGps>ivXslD;&O>l@83eFw`9cplIyjaDOq9ok>55qzJ4|0#s3hjw@+>p%+6sH;MaQltnd{mUUA6}JOf%-Wj7lo zINL>R_3+eC?Ao&}i0Bf2HRNn;h$g^zb9b=5h(F2hpdEGnI^ov{_i5D40DK|3F5usK pt{?7y?+MJ9F=NJz88c?s_zVHwkoOU`qhr4Dld000DZQchC<{}Gwj0a}Lu000SaNLh0L z01CqZ01CqaG$|yj0000KbVXQnLvm$dbZKvHAXI5>WdJfSGcPeQ=RdAt0000SbVXQn zQ*UN;cVTj606}DLVr3vkX>w(EZ*psMAVX6%akb+%000DLNklM99UW*S-Ol7|1csUK#tH6lltZ-I&-j};KUL_ zn575Za#!z_G<_4m*_s#K)Kyh?zpk#T?#;3pGiJ<~G2{P%mLxyI_YdD<8vjMO4T)aC zch!EAnOt{Bjgn%861N0F*CcqpMUn%OydHP+;QiNW>=H&LrR3mI;k-E6g}Y)H!xr2sq^8~OPdRPF;)F}($Sj0<^_ zFqCgm5*iSc!a6;w$jSMi3EUOOSp|c5T%RdQL3N@(SMnR|{cVv$Ey+b5X)BSfR#_a% z0<1X7oM0wp?sC+LW9@TD0(aF>)&Vh|V>?h*N`lvBcO;@!q7IoFrZ1@Si&n9?3pEIG z!To0LO7z?X2U&Slk&=_Utc^ zaBB7FIh+)GNlM(wued=uCFhcoQWo@}nQu53W0sHE1oo+r9gObedC-2UsH6QD+!YjM zRs9m@OnVyyJWKEPOHIjlg7(oR&chqU5R77oQM_WsjHwL5qdY=>b7?!BC1WIX+yrWz zMbFRm=)Ue+Q&-PNE!D*poR^QYe`WV^#NN?~FcKc8yAt;~+5p3@EwpF1lP6*Q_hnIa z3_4kHCU57v;l^TO{I0> zHn(@QE59kw&#}=PmwKc4%zCaup~jw?@*P=SmAi^E1szB$-909Lp8~_x3d(FA3xx;n z8V947hsK=@E+5PtMNo{^8c#aqlrPbGS?SW5oz9&ebzv0VrOY%aV&)ar#zH^%+k+vpvkCA&nLbiih@NXw>u; zSZB7z>Rei7VU#h}Bouk?nHdpCU%vynF6q-Y2pqaro#|qx-p}1BIosI5|OX~*1 z4+e-1S5e6tH#32|Zu!qXw5IkbI8`dVMn^&g#nGm4k5X;20=TniG6~fa!j1CM1Q_4o zZVmGps>ivXslD;&O>l@83eFw`9cplIyjaDOq9ok>55qzJ4|0#s3hjw@+>p%+6sH;MaQltnd{mUUA6}JOf%-Wj7lo zINL>R_3+eC?Ao&}i0Bf2HRNn;h$g^zb9b=5h(F2hpdEGnI^ov{_i5D40DK|3F5usK pt{?7y?+MJ9F=NJz88c?s_zVHwkoOU`qh> tests for screen media type + $.mobile.media('screen and (min-width: 480px)') //>> tests for screen media type with window width > 480px + $.mobile.media('@media screen and (-webkit-min-device-pixel-ratio: 2)') //>> tests for webkit 2x pixel ratio (iPhone 4) +*/ +$.mobile.media = (function() { + // TODO: use window.matchMedia once at least one UA implements it + var cache = {}, + testDiv = $( "
" ), + fakeBody = $( "" ).append( testDiv ); + + return function( query ) { + if ( !( query in cache ) ) { + var styleBlock = document.createElement('style'), + cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }"; + //must set type for IE! + styleBlock.type = "text/css"; + if (styleBlock.styleSheet){ + styleBlock.styleSheet.cssText = cssrule; + } + else { + styleBlock.appendChild(document.createTextNode(cssrule)); + } + + $html.prepend( fakeBody ).prepend( styleBlock ); + cache[ query ] = testDiv.css( "position" ) === "absolute"; + fakeBody.add( styleBlock ).remove(); + } + return cache[ query ]; + }; +})(); + +/* + private function for adding/removing breakpoint classes to HTML element for faux media-query support + It does not require media query support, instead using JS to detect screen width > cross-browser support + This function is called on orientationchange, resize, and mobileinit, and is bound via the 'htmlclass' event namespace +*/ +function detectResolutionBreakpoints(){ + var currWidth = $window.width(), + minPrefix = "min-width-", + maxPrefix = "max-width-", + minBreakpoints = [], + maxBreakpoints = [], + unit = "px", + breakpointClasses; + + $html.removeClass( minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " + + maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit ); + + $.each(resolutionBreakpoints,function( i, breakPoint ){ + if( currWidth >= breakPoint ){ + minBreakpoints.push( minPrefix + breakPoint + unit ); + } + if( currWidth <= breakPoint ){ + maxBreakpoints.push( maxPrefix + breakPoint + unit ); + } + }); + + if( minBreakpoints.length ){ breakpointClasses = minBreakpoints.join(" "); } + if( maxBreakpoints.length ){ breakpointClasses += " " + maxBreakpoints.join(" "); } + + $html.addClass( breakpointClasses ); +}; + +/* $.mobile.addResolutionBreakpoints method: + pass either a number or an array of numbers and they'll be added to the min/max breakpoint classes + Examples: + $.mobile.addResolutionBreakpoints( 500 ); + $.mobile.addResolutionBreakpoints( [500, 1200] ); +*/ +$.mobile.addResolutionBreakpoints = function( newbps ){ + if( $.type( newbps ) === "array" ){ + resolutionBreakpoints = resolutionBreakpoints.concat( newbps ); + } + else { + resolutionBreakpoints.push( newbps ); + } + resolutionBreakpoints.sort(function(a,b){ return a-b; }); + detectResolutionBreakpoints(); +}; + +/* on mobileinit, add classes to HTML element + and set handlers to update those on orientationchange and resize*/ +$(document).bind("mobileinit.htmlclass", function(){ + /* bind to orientationchange and resize + to add classes to HTML element for min/max breakpoints and orientation */ + $window.bind("orientationchange.htmlclass resize.htmlclass", function(event){ + //add orientation class to HTML element on flip/resize. + if(event.orientation){ + $html.removeClass( "portrait landscape" ).addClass( event.orientation ); + } + //add classes to HTML element for min/max breakpoints + detectResolutionBreakpoints(); + }); +}); + +/* Manually trigger an orientationchange event when the dom ready event fires. + This will ensure that any viewport meta tag that may have been injected + has taken effect already, allowing us to properly calculate the width of the + document. +*/ +$(function(){ + //trigger event manually + $window.trigger( "orientationchange.htmlclass" ); +}); + +})(jQuery);/* +* jQuery Mobile Framework : support tests +* Copyright (c) jQuery Project +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* Note: Code is in draft form and is subject to change +*/ +(function($, undefined ) { + + + +var fakeBody = $( "" ).prependTo( "html" ), + fbCSS = fakeBody[0].style, + vendors = ['webkit','moz','o'], + webos = window.palmGetResource || window.PalmServiceBridge, //only used to rule out scrollTop + bb = window.blackberry; //only used to rule out box shadow, as it's filled opaque on BB + +//thx Modernizr +function propExists( prop ){ + var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1), + props = (prop + ' ' + vendors.join(uc_prop + ' ') + uc_prop).split(' '); + for(var v in props){ + if( fbCSS[ v ] !== undefined ){ + return true; + } + } +}; + +//test for dynamic-updating base tag support (allows us to avoid href,src attr rewriting) +function baseTagTest(){ + var fauxBase = location.protocol + '//' + location.host + location.pathname + "ui-dir/", + base = $("head base"), + fauxEle = null, + href = ''; + if (!base.length) { + base = fauxEle = $("", {"href": fauxBase}).appendTo("head"); + } + else { + href = base.attr("href"); + } + var link = $( "" ).prependTo( fakeBody ), + rebase = link[0].href; + base[0].href = href ? href : location.pathname; + if (fauxEle) { + fauxEle.remove(); + } + return rebase.indexOf(fauxBase) === 0; +}; + +$.extend( $.support, { + orientation: "orientation" in window, + touch: "ontouchend" in document, + cssTransitions: "WebKitTransitionEvent" in window, + pushState: !!history.pushState, + mediaquery: $.mobile.media('only all'), + cssPseudoElement: !!propExists('content'), + boxShadow: !!propExists('boxShadow') && !bb, + scrollTop: ("pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[0]) && !webos, + dynamicBaseTag: baseTagTest() +}); + +fakeBody.remove(); + +//for ruling out shadows via css +if( !$.support.boxShadow ){ $('html').addClass('ui-mobile-nosupport-boxshadow'); } + +})( jQuery );/* +* jQuery Mobile Framework : events +* Copyright (c) jQuery Project +* Dual licensed under the MIT or GPL Version 2 licenses. +* http://jquery.org/license +*/ +(function($, undefined ) { + +// add new event shortcuts +$.each( "touchstart touchmove touchend orientationchange tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) { + $.fn[ name ] = function( fn ) { + return fn ? this.bind( name, fn ) : this.trigger( name ); + }; + $.attrFn[ name ] = true; +}); + +var supportTouch = $.support.touch, + scrollEvent = "touchmove scroll", + touchStartEvent = supportTouch ? "touchstart" : "mousedown", + touchStopEvent = supportTouch ? "touchend" : "mouseup", + touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; + +// also handles scrollstop +$.event.special.scrollstart = { + enabled: true, + + setup: function() { + var thisObject = this, + $this = $( thisObject ), + scrolling, + timer; + + function trigger( event, state ) { + scrolling = state; + var originalType = event.type; + event.type = scrolling ? "scrollstart" : "scrollstop"; + $.event.handle.call( thisObject, event ); + event.type = originalType; + } + + // iPhone triggers scroll after a small delay; use touchmove instead + $this.bind( scrollEvent, function( event ) { + if ( !$.event.special.scrollstart.enabled ) { + return; + } + + if ( !scrolling ) { + trigger( event, true ); + } + + clearTimeout( timer ); + timer = setTimeout(function() { + trigger( event, false ); + }, 50 ); + }); + } +}; + +// also handles taphold +$.event.special.tap = { + setup: function() { + var thisObject = this, + $this = $( thisObject ); + + $this + .bind( "mousedown touchstart", function( event ) { + if ( event.which && event.which !== 1 || + //check if event fired once already by a device that fires both mousedown and touchstart (while supporting both events) + $this.data( "prevEvent") && $this.data( "prevEvent") !== event.type ) { + return false; + } + + //save event type so only this type is let through for a temp duration, + //allowing quick repetitive taps but not duplicative events + $this.data( "prevEvent", event.type ); + setTimeout(function(){ + $this.removeData( "prevEvent" ); + }, 800); + + var moved = false, + touching = true, + origTarget = event.target, + origEvent = event.originalEvent, + origPos = event.type == "touchstart" ? [origEvent.touches[0].pageX, origEvent.touches[0].pageY] : [ event.pageX, event.pageY ], + originalType, + timer; + + + function moveHandler( event ) { + if( event.type == "scroll" ){ + moved = true; + return; + } + var newPageXY = event.type == "touchmove" ? event.originalEvent.touches[0] : event; + if ((Math.abs(origPos[0] - newPageXY.pageX) > 10) || + (Math.abs(origPos[1] - newPageXY.pageY) > 10)) { + moved = true; + } + } + + timer = setTimeout(function() { + if ( touching && !moved ) { + originalType = event.type; + event.type = "taphold"; + $.event.handle.call( thisObject, event ); + event.type = originalType; + } + }, 750 ); + + //scroll now cancels tap + $(window).one("scroll", moveHandler); + + $this + .bind( "mousemove touchmove", moveHandler ) + .one( "mouseup touchend", function( event ) { + $this.unbind( "mousemove touchmove", moveHandler ); + $(window).unbind("scroll", moveHandler); + clearTimeout( timer ); + touching = false; + + /* ONLY trigger a 'tap' event if the start target is + * the same as the stop target. + */ + if ( !moved && ( origTarget == event.target ) ) { + originalType = event.type; + event.type = "tap"; + $.event.handle.call( thisObject, event ); + event.type = originalType; + } + }); + }); + } +}; + +// also handles swipeleft, swiperight +$.event.special.swipe = { + setup: function() { + var thisObject = this, + $this = $( thisObject ); + + $this + .bind( touchStartEvent, function( event ) { + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : + event, + start = { + time: (new Date).getTime(), + coords: [ data.pageX, data.pageY ], + origin: $( event.target ) + }, + stop; + + function moveHandler( event ) { + if ( !start ) { + return; + } + + var data = event.originalEvent.touches ? + event.originalEvent.touches[ 0 ] : + event; + stop = { + time: (new Date).getTime(), + coords: [ data.pageX, data.pageY ] + }; + + // prevent scrolling + if ( Math.abs( start.coords[0] - stop.coords[0] ) > 10 ) { + event.preventDefault(); + } + } + + $this + .bind( touchMoveEvent, moveHandler ) + .one( touchStopEvent, function( event ) { + $this.unbind( touchMoveEvent, moveHandler ); + if ( start && stop ) { + if ( stop.time - start.time < 1000 && + Math.abs( start.coords[0] - stop.coords[0]) > 30 && + Math.abs( start.coords[1] - stop.coords[1]) < 75 ) { + start.origin + .trigger( "swipe" ) + .trigger( start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight" ); + } + } + start = stop = undefined; + }); + }); + } +}; + +(function($){ + // "Cowboy" Ben Alman + + var win = $(window), + special_event, + get_orientation, + last_orientation; + + $.event.special.orientationchange = special_event = { + setup: function(){ + // If the event is supported natively, return false so that jQuery + // will bind to the event using DOM methods. + if ( $.support.orientation ) { return false; } + + // Get the current orientation to avoid initial double-triggering. + last_orientation = get_orientation(); + + // Because the orientationchange event doesn't exist, simulate the + // event by testing window dimensions on resize. + win.bind( "resize", handler ); + }, + teardown: function(){ + // If the event is not supported natively, return false so that + // jQuery will unbind the event using DOM methods. + if ( $.support.orientation ) { return false; } + + // Because the orientationchange event doesn't exist, unbind the + // resize event handler. + win.unbind( "resize", handler ); + }, + add: function( handleObj ) { + // Save a reference to the bound event handler. + var old_handler = handleObj.handler; + + handleObj.handler = function( event ) { + // Modify event object, adding the .orientation property. + event.orientation = get_orientation(); + + // Call the originally-bound event handler and return its result. + return old_handler.apply( this, arguments ); + }; + } + }; + + // If the event is not supported natively, this handler will be bound to + // the window resize event to simulate the orientationchange event. + function handler() { + // Get the current orientation. + var orientation = get_orientation(); + + if ( orientation !== last_orientation ) { + // The orientation has changed, so trigger the orientationchange event. + last_orientation = orientation; + win.trigger( "orientationchange" ); + } + }; + + // Get the current page orientation. This method is exposed publicly, should it + // be needed, as jQuery.event.special.orientationchange.orientation() + special_event.orientation = get_orientation = function() { + var elem = document.documentElement; + return elem && elem.clientWidth / elem.clientHeight < 1.1 ? "portrait" : "landscape"; + }; + +})(jQuery); + +$.each({ + scrollstop: "scrollstart", + taphold: "tap", + swipeleft: "swipe", + swiperight: "swipe" +}, function( event, sourceEvent ) { + $.event.special[ event ] = { + setup: function() { + $( this ).bind( sourceEvent, $.noop ); + } + }; +}); + +})( jQuery ); +/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ + +// Script: jQuery hashchange event +// +// *Version: 1.3, Last updated: 7/21/2010* +// +// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/ +// GitHub - http://github.com/cowboy/jquery-hashchange/ +// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js +// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped) +// +// About: License +// +// Copyright (c) 2010 "Cowboy" Ben Alman, +// Dual licensed under the MIT and GPL licenses. +// http://benalman.com/about/license/ +// +// About: Examples +// +// These working examples, complete with fully commented code, illustrate a few +// ways in which this plugin can be used. +// +// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/ +// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/ +// +// About: Support and Testing +// +// Information about what version or versions of jQuery this plugin has been +// tested with, what browsers it has been tested in, and where the unit tests +// reside (so you can test it yourself). +// +// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2 +// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5, +// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5. +// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/ +// +// About: Known issues +// +// While this jQuery hashchange event implementation is quite stable and +// robust, there are a few unfortunate browser bugs surrounding expected +// hashchange event-based behaviors, independent of any JavaScript +// window.onhashchange abstraction. See the following examples for more +// information: +// +// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/ +// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/ +// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/ +// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/ +// +// Also note that should a browser natively support the window.onhashchange +// event, but not report that it does, the fallback polling loop will be used. +// +// About: Release History +// +// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more +// "removable" for mobile-only development. Added IE6/7 document.title +// support. Attempted to make Iframe as hidden as possible by using +// techniques from http://www.paciellogroup.com/blog/?p=604. Added +// support for the "shortcut" format $(window).hashchange( fn ) and +// $(window).hashchange() like jQuery provides for built-in events. +// Renamed jQuery.hashchangeDelay to and +// lowered its default value to 50. Added +// and properties plus document-domain.html +// file to address access denied issues when setting document.domain in +// IE6/7. +// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin +// from a page on another domain would cause an error in Safari 4. Also, +// IE6/7 Iframe is now inserted after the body (this actually works), +// which prevents the page from scrolling when the event is first bound. +// Event can also now be bound before DOM ready, but it won't be usable +// before then in IE6/7. +// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug +// where browser version is incorrectly reported as 8.0, despite +// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag. +// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special +// window.onhashchange functionality into a separate plugin for users +// who want just the basic event & back button support, without all the +// extra awesomeness that BBQ provides. This plugin will be included as +// part of jQuery BBQ, but also be available separately. + +(function($,window,undefined){ + '$:nomunge'; // Used by YUI compressor. + + // Reused string. + var str_hashchange = 'hashchange', + + // Method / object references. + doc = document, + fake_onhashchange, + special = $.event.special, + + // Does the browser support window.onhashchange? Note that IE8 running in + // IE7 compatibility mode reports true for 'onhashchange' in window, even + // though the event isn't supported, so also test document.documentMode. + doc_mode = doc.documentMode, + supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); + + // Get location.hash (or what you'd expect location.hash to be) sans any + // leading #. Thanks for making this necessary, Firefox! + function get_fragment( url ) { + url = url || location.href; + return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' ); + }; + + // Method: jQuery.fn.hashchange + // + // Bind a handler to the window.onhashchange event or trigger all bound + // window.onhashchange event handlers. This behavior is consistent with + // jQuery's built-in event handlers. + // + // Usage: + // + // > jQuery(window).hashchange( [ handler ] ); + // + // Arguments: + // + // handler - (Function) Optional handler to be bound to the hashchange + // event. This is a "shortcut" for the more verbose form: + // jQuery(window).bind( 'hashchange', handler ). If handler is omitted, + // all bound window.onhashchange event handlers will be triggered. This + // is a shortcut for the more verbose + // jQuery(window).trigger( 'hashchange' ). These forms are described in + // the section. + // + // Returns: + // + // (jQuery) The initial jQuery collection of elements. + + // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and + // $(elem).hashchange() for triggering, like jQuery does for built-in events. + $.fn[ str_hashchange ] = function( fn ) { + return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange ); + }; + + // Property: jQuery.fn.hashchange.delay + // + // The numeric interval (in milliseconds) at which the + // polling loop executes. Defaults to 50. + + // Property: jQuery.fn.hashchange.domain + // + // If you're setting document.domain in your JavaScript, and you want hash + // history to work in IE6/7, not only must this property be set, but you must + // also set document.domain BEFORE jQuery is loaded into the page. This + // property is only applicable if you are supporting IE6/7 (or IE8 operating + // in "IE7 compatibility" mode). + // + // In addition, the property must be set to the + // path of the included "document-domain.html" file, which can be renamed or + // modified if necessary (note that the document.domain specified must be the + // same in both your main JavaScript as well as in this file). + // + // Usage: + // + // jQuery.fn.hashchange.domain = document.domain; + + // Property: jQuery.fn.hashchange.src + // + // If, for some reason, you need to specify an Iframe src file (for example, + // when setting document.domain as in ), you can + // do so using this property. Note that when using this property, history + // won't be recorded in IE6/7 until the Iframe src file loads. This property + // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7 + // compatibility" mode). + // + // Usage: + // + // jQuery.fn.hashchange.src = 'path/to/file.html'; + + $.fn[ str_hashchange ].delay = 50; + /* + $.fn[ str_hashchange ].domain = null; + $.fn[ str_hashchange ].src = null; + */ + + // Event: hashchange event + // + // Fired when location.hash changes. In browsers that support it, the native + // HTML5 window.onhashchange event is used, otherwise a polling loop is + // initialized, running every milliseconds to + // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7 + // compatibility" mode), a hidden Iframe is created to allow the back button + // and hash-based history to work. + // + // Usage as described in : + // + // > // Bind an event handler. + // > jQuery(window).hashchange( function(e) { + // > var hash = location.hash; + // > ... + // > }); + // > + // > // Manually trigger the event handler. + // > jQuery(window).hashchange(); + // + // A more verbose usage that allows for event namespacing: + // + // > // Bind an event handler. + // > jQuery(window).bind( 'hashchange', function(e) { + // > var hash = location.hash; + // > ... + // > }); + // > + // > // Manually trigger the event handler. + // > jQuery(window).trigger( 'hashchange' ); + // + // Additional Notes: + // + // * The polling loop and Iframe are not created until at least one handler + // is actually bound to the 'hashchange' event. + // * If you need the bound handler(s) to execute immediately, in cases where + // a location.hash exists on page load, via bookmark or page refresh for + // example, use jQuery(window).hashchange() or the more verbose + // jQuery(window).trigger( 'hashchange' ). + // * The event can be bound before DOM ready, but since it won't be usable + // before then in IE6/7 (due to the necessary Iframe), recommended usage is + // to bind it inside a DOM ready handler. + + // Override existing $.event.special.hashchange methods (allowing this plugin + // to be defined after jQuery BBQ in BBQ's source code). + special[ str_hashchange ] = $.extend( special[ str_hashchange ], { + + // Called only when the first 'hashchange' event is bound to window. + setup: function() { + // If window.onhashchange is supported natively, there's nothing to do.. + if ( supports_onhashchange ) { return false; } + + // Otherwise, we need to create our own. And we don't want to call this + // until the user binds to the event, just in case they never do, since it + // will create a polling loop and possibly even a hidden Iframe. + $( fake_onhashchange.start ); + }, + + // Called only when the last 'hashchange' event is unbound from window. + teardown: function() { + // If window.onhashchange is supported natively, there's nothing to do.. + if ( supports_onhashchange ) { return false; } + + // Otherwise, we need to stop ours (if possible). + $( fake_onhashchange.stop ); + } + + }); + + // fake_onhashchange does all the work of triggering the window.onhashchange + // event for browsers that don't natively support it, including creating a + // polling loop to watch for hash changes and in IE 6/7 creating a hidden + // Iframe to enable back and forward. + fake_onhashchange = (function(){ + var self = {}, + timeout_id, + + // Remember the initial hash so it doesn't get triggered immediately. + last_hash = get_fragment(), + + fn_retval = function(val){ return val; }, + history_set = fn_retval, + history_get = fn_retval; + + // Start the polling loop. + self.start = function() { + timeout_id || poll(); + }; + + // Stop the polling loop. + self.stop = function() { + timeout_id && clearTimeout( timeout_id ); + timeout_id = undefined; + }; + + // This polling loop checks every $.fn.hashchange.delay milliseconds to see + // if location.hash has changed, and triggers the 'hashchange' event on + // window when necessary. + function poll() { + var hash = get_fragment(), + history_hash = history_get( last_hash ); + + if ( hash !== last_hash ) { + history_set( last_hash = hash, history_hash ); + + $(window).trigger( str_hashchange ); + + } else if ( history_hash !== last_hash ) { + location.href = location.href.replace( /#.*/, '' ) + history_hash; + } + + timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay ); + }; + + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + $.browser.msie && !supports_onhashchange && (function(){ + // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8 + // when running in "IE7 compatibility" mode. + + var iframe, + iframe_src; + + // When the event is bound and polling starts in IE 6/7, create a hidden + // Iframe for history handling. + self.start = function(){ + if ( !iframe ) { + iframe_src = $.fn[ str_hashchange ].src; + iframe_src = iframe_src && iframe_src + get_fragment(); + + // Create hidden Iframe. Attempt to make Iframe as hidden as possible + // by using techniques from http://www.paciellogroup.com/blog/?p=604. + iframe = $('