Merge pull request #561 from odoo-dev/master-branding-ref-rim
authorRichard Mathot <rim@openerp.com>
Tue, 17 Jun 2014 12:31:52 +0000 (14:31 +0200)
committerRichard Mathot <rim@openerp.com>
Tue, 17 Jun 2014 12:31:52 +0000 (14:31 +0200)
[REF] website: change URL to new Odoo website

13 files changed:
addons/crm/crm_lead.py
addons/crm_claim/crm_claim_view.xml
addons/mrp/mrp_view.xml
addons/point_of_sale/point_of_sale_view.xml
addons/purchase/purchase_view.xml
addons/stock/stock_view.xml
addons/website/controllers/main.py
addons/website/static/src/js/website.snippets.editor.js
addons/website_instantclick/__init__.py [new file with mode: 0644]
addons/website_instantclick/__openerp__.py [new file with mode: 0644]
addons/website_instantclick/static/lib/instantclick/instantclick.js [new file with mode: 0644]
addons/website_instantclick/views/website_instantclick.xml [new file with mode: 0644]
addons/website_sale/views/templates.xml

index db9de6a..0e0b734 100644 (file)
@@ -305,7 +305,8 @@ class crm_lead(format_address, osv.osv):
         if partner_id:
             partner = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
             values = {
-                'partner_name': partner.name,
+                'partner_name': partner.parent_id.name if partner.parent_id else partner.name,
+                'contact_name': partner.name if partner.parent_id else False,
                 'street': partner.street,
                 'street2': partner.street2,
                 'city': partner.city,
index 7f6309e..43df3d0 100644 (file)
                                 <group colspan="2" col="2">
                                     <separator colspan="2" string="Resolution Actions"/>
                                     <field name="type_action"/>
-                                    <field name="resolution" colspan="2" nolabel="1"/>
+                                    <field name="resolution" colspan="2" nolabel="1" placeholder="Action Description..."/>
                                 </group>
                             </page>
                         </notebook>
index 5831966..8aae006 100644 (file)
             </field>
         </record>
         
-        <record id="product_supply_method_produce" model="ir.actions.act_window">
+        <record id="product_template_action" model="ir.actions.act_window">
             <field name="name">Products</field>
-            <field name="res_model">product.product</field>
+            <field name="res_model">product.template</field>
             <field name="view_type">form</field>
             <field name="view_mode">kanban,tree,form</field>
             <field name="context">{}</field>
-            <field name="search_view_id" ref="product.product_search_form_view"/>
         </record>
         <!-- BOM menus -->
 
             sequence="10"/>
        <menuitem name="Products" 
             id="menu_mrp_product_form" 
-            action="product_supply_method_produce"
+            action="product_template_action"
             parent="menu_mrp_bom"/>
         <menuitem
             action="mrp_bom_form_action2"
index 9103cbd..af0a815 100644 (file)
         <menuitem parent="menu_point_of_sale" id="menu_point_ofsale" action="action_pos_pos_form" sequence="2" groups="group_pos_manager,group_pos_user"/>
         <menuitem name="Products" id="menu_point_of_sale_product" parent="menu_point_root" sequence="15" />
 
-        <record id="product_normal_action" model="ir.actions.act_window">
+        <record id="product_template_action" model="ir.actions.act_window">
             <field name="name">Products</field>
             <field name="type">ir.actions.act_window</field>
-            <field name="res_model">product.product</field>
+            <field name="res_model">product.template</field>
             <field name="view_type">form</field>
             <field name="view_mode">tree,form,kanban</field>
             <field name="context" eval="{}"/>
             <field name="domain" eval="[('available_in_pos','&lt;&gt;',False)]"/>
-            <field name="view_id" ref="product.product_product_tree_view"/>
-            <field name="search_view_id" ref="product.product_search_form_view"/>
             <field name="help" type="html">
               <p class="oe_view_nocontent_create">
                 Click to add a new product.
             </field>
         </record>
         <menuitem
-            action="product_normal_action"
+            action="product_template_action"
             id="menu_pos_products"
             parent="menu_point_of_sale_product" sequence="2"/>
 
index 1320764..5062ecc 100644 (file)
     <record id="product_normal_action_puchased" model="ir.actions.act_window">
         <field name="name">Products</field>
         <field name="type">ir.actions.act_window</field>
-        <field name="res_model">product.product</field>
+        <field name="res_model">product.template</field>
         <field name="view_type">form</field>
         <field name="view_mode">kanban,tree,form</field>
         <field name="context">{"search_default_filter_to_purchase":1}</field>
-        <field name="view_id" ref="product.product_kanban_view"/>
-        <field name="search_view_id" ref="product.product_search_form_view"/>
         <field name="help" type="html">
           <p class="oe_view_nocontent_create">
             Click to define a new product.
index 66c97aa..fc7a94f 100644 (file)
@@ -12,7 +12,7 @@
         <menuitem id="menu_stock_product" name="Products" parent="menu_stock_root" sequence="6"/>
         <menuitem name="Products by Category" id="menu_product_by_category_stock_form" action="product.product_category_action"
             parent="stock.menu_stock_product" sequence="0" groups="base.group_no_one"/>
-        <menuitem action="product.product_normal_action" id="menu_stock_products_menu" parent="menu_stock_product" sequence="1"/>
+        <menuitem action="product.product_template_action" id="menu_stock_products_menu" parent="menu_stock_product" sequence="1"/>
         <menuitem id="menu_stock_configuration" name="Configuration" parent="menu_stock_root" sequence="15" groups="group_stock_manager"/>
         <menuitem id="menu_warehouse_config" name="Warehouse Management" parent="menu_stock_configuration" sequence="40" groups="base.group_no_one"/>
         <menuitem id="menu_stock_inventory_control" name="Inventory Control" parent="menu_stock_root" sequence="2"/>
index e7a9350..5d90867 100644 (file)
@@ -49,7 +49,7 @@ class Website(openerp.addons.web.controllers.main.Home):
         # TODO: can't we just put auth=public, ... in web client ?
         return super(Website, self).web_login(*args, **kw)
 
-    @http.route('/page/<path:page>', type='http', auth="public", website=True)
+    @http.route('/page/<page:page>', type='http', auth="public", website=True)
     def page(self, page, **opt):
         values = {
             'path': page,
index 7e94895..6485444 100644 (file)
         },
         clean_for_save: function () {
             var self = this;
-            $("*[contentEditable], *[attributeEditable]")
-                .removeAttr('contentEditable')
-                .removeAttr('attributeEditable');
-
             var options = website.snippet.options;
             var template = website.snippet.templateOptions;
             for (var k in options) {
                     });
                 }
             }
+            $("*[contentEditable], *[attributeEditable]")
+                .removeAttr('contentEditable')
+                .removeAttr('attributeEditable');
         },
         make_active: function ($snippet) {
             if ($snippet && this.$active_snipped_id && this.$active_snipped_id.get(0) === $snippet.get(0)) {
diff --git a/addons/website_instantclick/__init__.py b/addons/website_instantclick/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/addons/website_instantclick/__openerp__.py b/addons/website_instantclick/__openerp__.py
new file mode 100644 (file)
index 0000000..5047bdd
--- /dev/null
@@ -0,0 +1,17 @@
+{
+    'name': 'Website Instantclick',
+    'category': 'Website',
+    'summary': 'Preloads and speeds up website on public browsing of the website using Instantclick.',
+    'version': '1.0',
+    'description': """
+Preloads data on anonymous mode of website
+==========================================
+
+        """,
+    'author': 'OpenERP SA',
+    'depends': ['website'],
+    'installable': True,
+    'data': [
+        'views/website_instantclick.xml',
+    ],
+}
diff --git a/addons/website_instantclick/static/lib/instantclick/instantclick.js b/addons/website_instantclick/static/lib/instantclick/instantclick.js
new file mode 100644 (file)
index 0000000..e5e4e34
--- /dev/null
@@ -0,0 +1,430 @@
+/* InstantClick 2.1 | (C) 2014 Alexandre Dieulot | http://instantclick.io/license.html */
+var InstantClick = function(document, location) {
+       // Internal variables
+       var $currentLocationWithoutHash
+       var $urlToPreload
+       var $preloadTimer
+
+       // Preloading-related variables
+       var $history = {}
+       var $xhr
+       var $url = false
+       var $title = false
+       var $hasBody = true
+       var $body = false
+       var $timing = {}
+       var $isPreloading = false
+       var $isWaitingForCompletion = false
+
+       // Variables defined by public functions
+       var $useWhitelist
+       var $preloadOnMousedown
+       var $delayBeforePreload
+       var $eventsCallbacks = {
+               change: []
+       }
+
+
+       ////////// HELPERS //////////
+
+
+       function removeHash(url) {
+               var index = url.indexOf('#')
+               if (index < 0) {
+                       return url
+               }
+               return url.substr(0, index)
+       }
+
+       function getLinkTarget(target) {
+               while (target.nodeName != 'A') {
+                       target = target.parentNode
+               }
+               return target
+       }
+
+       function triggerPageEvent(eventType) {
+               for (var i = 0; i < $eventsCallbacks[eventType].length; i++) {
+                       $eventsCallbacks[eventType][i]()
+               }
+       }
+
+       function changePage(title, body, newUrl, scrollY_) {
+               var doc = document.implementation.createHTMLDocument('')
+               doc.documentElement.innerHTML = body
+               document.documentElement.replaceChild(doc.body, document.body)
+               /* We cannot just use `document.body = doc.body` as it causes Safari 5.1, 6.0,
+                  and Mobile 7.0 to execute script tags directly.
+               */
+
+               var elem = document.createElement('i')
+               elem.innerHTML = title
+               document.title = elem.textContent
+
+               if (newUrl) {
+                       history.pushState(null, null, newUrl)
+
+                       var hashIndex = newUrl.indexOf('#')
+                       var hashElem = hashIndex > -1 && document.getElementById(newUrl.substr(hashIndex + 1))
+                       var offset = 0
+                       if (hashElem) {
+                               for (; hashElem.offsetParent; hashElem = hashElem.offsetParent) {
+                                       offset += hashElem.offsetTop
+                               }
+                       }
+                       scrollTo(0, offset)
+
+                       $currentLocationWithoutHash = removeHash(newUrl)
+               }
+               else {
+                       scrollTo(0, scrollY_)
+               }
+
+               instantanize()
+
+               triggerPageEvent('change')
+       }
+
+       function setPreloadingAsHalted() {
+               $isPreloading = false
+               $isWaitingForCompletion = false
+       }
+
+
+       ////////// EVENT HANDLERS //////////
+
+
+       function mousedown(e) {
+               preload(getLinkTarget(e.target).href)
+       }
+
+       function mouseover(e) {
+               var a = getLinkTarget(e.target)
+               a.addEventListener('mouseout', mouseout)
+               if (!$delayBeforePreload) {
+                       preload(a.href)
+               }
+               else {
+                       $urlToPreload = a.href
+                       $preloadTimer = setTimeout(preload, $delayBeforePreload)
+               }
+       }
+
+       function click(e) {
+               if (e.which > 1 || e.metaKey || e.ctrlKey) { // Opening in new tab
+                       return
+               }
+               e.preventDefault()
+               display(getLinkTarget(e.target).href)
+       }
+
+       function mouseout() {
+               if ($preloadTimer) {
+                       clearTimeout($preloadTimer)
+                       $preloadTimer = false
+                       return
+               }
+
+               if (!$isPreloading || $isWaitingForCompletion) {
+                       return
+               }
+               $xhr.abort()
+               setPreloadingAsHalted()
+       }
+
+       function readystatechange() {
+               if ($xhr.readyState < 4) {
+                       return
+               }
+               if ($xhr.status == 0) {
+                       /* Request aborted */
+                       return
+               }
+
+               $timing.ready = +new Date - $timing.start
+
+               var text = $xhr.responseText
+
+               var titleIndex = text.indexOf('<title')
+               if (titleIndex > -1) {
+                       $title = text.substr(text.indexOf('>', titleIndex) + 1)
+                       $title = $title.substr(0, $title.indexOf('</title'))
+               }
+
+               var bodyIndex = text.indexOf('<body')
+               if (bodyIndex > -1) {
+                       $body = text.substr(bodyIndex)
+                       var closingIndex = $body.indexOf('</body')
+                       if (closingIndex > -1) {
+                               $body = $body.substr(0, closingIndex)
+                       }
+
+                       var urlWithoutHash = removeHash($url)
+                       $history[urlWithoutHash] = {
+                               body: $body,
+                               title: $title,
+                               scrollY: urlWithoutHash in $history ? $history[urlWithoutHash].scrollY : 0
+                       }
+               }
+               else {
+                       $hasBody = false
+               }
+
+               if ($isWaitingForCompletion) {
+                       $isWaitingForCompletion = false
+                       display($url)
+               }
+       }
+
+
+       ////////// MAIN FUNCTIONS //////////
+
+
+       function instantanize(isInitializing) {
+               var as = document.getElementsByTagName('a'), a, domain = location.protocol + '//' + location.host
+               for (var i = as.length - 1; i >= 0; i--) {
+                       a = as[i]
+                       if (a.target || // target="_blank" etc.
+                               a.hasAttribute('download') ||
+                               a.href.indexOf(domain + '/') != 0 || // another domain (or no href attribute)
+                               a.href.indexOf('#') > -1 && removeHash(a.href) == $currentLocationWithoutHash || // link to an anchor
+                               ($useWhitelist ? !a.hasAttribute('data-instant') : a.hasAttribute('data-no-instant'))) {
+                               continue
+                       }
+                       if ($preloadOnMousedown) {
+                               a.addEventListener('mousedown', mousedown)
+                       }
+                       else {
+                               a.addEventListener('mouseover', mouseover)
+                       }
+                       a.addEventListener('click', click)
+               }
+               if (!isInitializing) {
+                       var scripts = document.getElementsByTagName('script'), script, copy, parentNode, nextSibling
+                       for (i = 0, j = scripts.length; i < j; i++) {
+                               script = scripts[i]
+                               if (script.hasAttribute('data-no-instant')) {
+                                       continue
+                               }
+                               copy = document.createElement('script')
+                               if (script.src) {
+                                       copy.src = script.src
+                               }
+                               if (script.innerHTML) {
+                                       copy.innerHTML = script.innerHTML
+                               }
+                               parentNode = script.parentNode
+                               nextSibling = script.nextSibling
+                               parentNode.removeChild(script)
+                               parentNode.insertBefore(copy, nextSibling)
+                       }
+               }
+       }
+
+       function preload(url) {
+               if (!$preloadOnMousedown && 'display' in $timing && +new Date - ($timing.start + $timing.display) < 100) {
+                       /* After a page is displayed, if the user's cursor happens to be above a link
+                          a mouseover event will be in most browsers triggered automatically, and in
+                          other browsers it will be triggered when the user moves his mouse by 1px.
+
+                          Here are the behavior I noticed, all on Windows:
+                          - Safari 5.1: auto-triggers after 0 ms
+                          - IE 11: auto-triggers after 30-80 ms (looks like it depends on page's size)
+                          - Firefox: auto-triggers after 10 ms
+                          - Opera 18: auto-triggers after 10 ms
+
+                          - Chrome: triggers when cursor moved
+                          - Opera 12.16: triggers when cursor moved
+
+                          To remedy to this, we do not start preloading if last display occurred less than
+                          100 ms ago. If they happen to click on the link, they will be redirected.
+                       */
+
+                       return
+               }
+               if ($preloadTimer) {
+                       $clearTimeout($preloadTimer)
+                       $preloadTimer = false
+               }
+
+               if (!url) {
+                       url = $urlToPreload
+               }
+
+               if ($isPreloading && (url == $url || $isWaitingForCompletion)) {
+                       return
+               }
+               $isPreloading = true
+               $isWaitingForCompletion = false
+
+               $url = url
+               $body = false
+               $hasBody = true
+               $timing = {
+                       start: +new Date
+               }
+               $xhr.open('GET', url)
+               $xhr.send()
+       }
+
+       function display(url) {
+               if (!('display' in $timing)) {
+                       $timing.display = +new Date - $timing.start
+               }
+               if ($preloadTimer) {
+                       /* Happens when there’s a delay before preloading and that delay
+                          hasn't expired (preloading didn't kick in).
+                       */
+
+                       if ($url && $url != url) {
+                               /* Happens when the user clicks on a link before preloading
+                                  kicks in while another link is already preloading.
+                               */
+
+                               location.href = url
+                               return
+                       }
+                       preload(url)
+                       $isWaitingForCompletion = true
+                       return
+               }
+               if (!$isPreloading || $isWaitingForCompletion) {
+                       /* If the page isn't preloaded, it likely means
+                          the user has focused on a link (with his Tab
+                          key) and then pressed Return, which triggered a click.
+                          Because very few people do this, it isn't worth handling this
+                          case and preloading on focus (also, focusing on a link
+                          doesn't mean it's likely that you'll "click" on it), so we just
+                          redirect them when they "click".
+                          It could also mean the user hovered over a link less than 100 ms
+                          after a page display, thus we didn't start the preload (see
+                          comments in `preload()` for the rationale behind this.)
+
+                          If the page is waiting for completion, the user clicked twice
+                          while the page was preloading.
+                          Two possibilities:
+                          1) He clicks on the same link again, either because it's slow
+                             to load (there's no browser loading indicator with
+                             InstantClick, so he might think his click hasn't registered
+                             if the page isn't loading fast enough) or because he has
+                             a habit of double clicking on the web;
+                          2) He clicks on another link.
+
+                          In the first case, we redirect him (send him to the page the old
+                          way) so that he can have the browser's loading indicator back.
+                          In the second case, we redirect him because we haven't preloaded
+                          that link, since we were already preloading the last one.
+
+                          Determining if it's a double click might be overkill as there is
+                          (hopefully) not that many people that double click on the web.
+                          Fighting against the perception that the page is stuck is
+                          interesting though, a seemingly good way to do that would be to
+                          later incorporate a progress bar.
+                       */
+
+                       location.href = url
+                       return
+               }
+               if (!$hasBody) {
+                       location.href = $url
+                       return
+               }
+               if (!$body) {
+                       $isWaitingForCompletion = true
+                       return
+               }
+               $history[$currentLocationWithoutHash].scrollY = pageYOffset
+               setPreloadingAsHalted()
+               changePage($title, $body, $url)
+       }
+
+
+       ////////// PUBLIC VARIABLE AND FUNCTIONS //////////
+
+
+       var supported = 'pushState' in history
+
+       function init() {
+               if ($currentLocationWithoutHash) {
+                       /* Already initialized */
+                       return
+               }
+               if (!supported) {
+                       triggerPageEvent('change')
+                       return
+               }
+               for (var i = arguments.length - 1; i >= 0; i--) {
+                       var arg = arguments[i]
+                       if (arg === true) {
+                               $useWhitelist = true
+                       }
+                       else if (arg == 'mousedown') {
+                               $preloadOnMousedown = true
+                       }
+                       else if (typeof arg == 'number') {
+                               $delayBeforePreload = arg
+                       }
+               }
+               $currentLocationWithoutHash = removeHash(location.href)
+               $history[$currentLocationWithoutHash] = {
+                       body: document.body.outerHTML,
+                       title: document.title,
+                       scrollY: pageYOffset
+               }
+               $xhr = new XMLHttpRequest()
+               $xhr.addEventListener('readystatechange', readystatechange)
+
+               instantanize(true)
+
+               triggerPageEvent('change')
+
+               addEventListener('popstate', function() {
+                       var loc = removeHash(location.href)
+                       if (loc == $currentLocationWithoutHash) {
+                               return
+                       }
+                       if (!(loc in $history)) {
+                               location.href = location.href // Reloads the page and makes use of cache for assets, unlike location.reload()
+                               return
+                       }
+                       $history[$currentLocationWithoutHash].scrollY = pageYOffset
+                       $currentLocationWithoutHash = loc
+                       changePage($history[loc].title, $history[loc].body, false, $history[loc].scrollY)
+               })
+       }
+
+       function on(eventType, callback) {
+               $eventsCallbacks[eventType].push(callback)
+       }
+
+       /* The debug function isn't included by default to reduce file size.
+          To enable it, add a slash at the beginning of the comment englobing
+          the debug function, and uncomment "debug: debug," in the return
+          statement below the function. */
+
+       /*
+       function debug() {
+               return {
+                       currentLocationWithoutHash: $currentLocationWithoutHash,
+                       history: $history,
+                       xhr: $xhr,
+                       url: $url,
+                       title: $title,
+                       hasBody: $hasBody,
+                       body: $body,
+                       timing: $timing,
+                       isPreloading: $isPreloading,
+                       isWaitingForCompletion: $isWaitingForCompletion
+               }
+       }
+       //*/
+
+
+       return {
+               // debug: debug,
+               supported: supported,
+               init: init,
+               on: on
+       }
+
+}(document, location);
diff --git a/addons/website_instantclick/views/website_instantclick.xml b/addons/website_instantclick/views/website_instantclick.xml
new file mode 100644 (file)
index 0000000..39afa93
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- vim:fdn=3:
+-->
+<openerp>
+    <data>
+
+<template id="show_sign_in_anonymous" inherit_id="website.show_sign_in" name="Show Sign In" groups="base.group_public">
+    <xpath expr="//div[@id='wrapwrap']" position="after">
+        <script type="text/javascript" src="/website_instantclick/static/lib/instantclick/instantclick.js" data-no-instant=""></script>
+        <script data-no-instant="">
+            InstantClick.init();
+        </script>
+    </xpath>
+</template>
+
+
+     </data>
+</openerp>
index 470ca83..c43363b 100644 (file)
                               <td>
                                   <div class="input-group">
                                       <span class="input-group-addon">
-                                          <a t-attf-href="#" class="mb8 js_add_cart_json">
+                                          <a t-attf-href="#" class="mb8 js_add_cart_json" data-no-instant="">
                                               <i class="fa fa-minus"></i>
                                           </a>
                                       </span>
                                           t-att-data-product-id="line.product_id.id"
                                           t-att-value="int(line.product_uom_qty)"/>
                                       <span class="input-group-addon">
-                                          <a t-attf-href="#" class="mb8 float_left js_add_cart_json">
+                                          <a t-attf-href="#" class="mb8 float_left js_add_cart_json" data-no-instant="">
                                               <i class="fa fa-plus"></i>
                                           </a>
                                       </span>