Antony Lesuisse (OpenERP) has proposed merging 
lp:~openerp-dev/openerp-web/trunk-pushstate-chs into lp:openerp-web.

Requested reviews:
  OpenERP R&D Web Team (openerp-dev-web)

For more details, see:
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-pushstate-chs/+merge/85341

url
-- 
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-pushstate-chs/+merge/85341
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openerp-web/trunk-pushstate-chs.
=== modified file 'addons/web/static/src/js/chrome.js'
--- addons/web/static/src/js/chrome.js	2011-12-12 10:39:05 +0000
+++ addons/web/static/src/js/chrome.js	2011-12-12 14:24:26 +0000
@@ -1011,6 +1011,7 @@
         this.session.on_session_valid.add_last(this.header.do_update);
         this.session.on_session_invalid.add_last(this.header.do_update);
         this.session.on_session_valid.add_last(this.on_logged);
+        this.session.on_session_invalid.add_last(this.on_logged_out);
 
         this.menu = new openerp.web.Menu(this, "oe_menu", "oe_secondary_menu");
         this.menu.on_action.add(this.on_menu_action);
@@ -1047,37 +1048,55 @@
             this.action_manager.stop();
         this.action_manager = new openerp.web.ActionManager(this);
         this.action_manager.appendTo($("#oe_app"));
-        this.action_manager.do_url_set_hash.add_last(this.do_url_set_hash);
 
-        // if using saved actions, load the action and give it to action manager
-        var parameters = jQuery.deparam(jQuery.param.querystring());
-        if (parameters["s_action"] != undefined) {
-            var key = parseInt(parameters["s_action"], 10);
-            var self = this;
-            this.rpc("/web/session/get_session_action", {key:key}, function(action) {
-                self.action_manager.do_action(action);
-            });
-        } else if (openerp._modules_loaded) { // TODO: find better option than this
-            this.load_url_state()
+        if (openerp._modules_loaded) { // TODO: find better option than this
+            this.bind_statechange();
         } else {
-            this.session.on_modules_loaded.add({
-                callback: $.proxy(this, 'load_url_state'),
+            this.session.on_modules_loaded.add({        // XXX what about a $.Deferred ?
+                callback: $.proxy(this, 'bind_statechange'),
                 unique: true,
                 position: 'last'
             })
         }
     },
-    /**
-     * Loads state from URL if any, or checks if there is a home action and
-     * loads that, assuming we're at the index
-     */
-    load_url_state: function () {
-        var self = this;
-        // TODO: add actual loading if there is url state to unpack, test on window.location.hash
-        // not logged in
-        if (!this.session.uid) { return; }
-        self.action_manager.do_action({type: 'ir.actions.client', tag: 'default_home'});
-    },
+
+    state_change_event: 'hashchange',
+    
+    bind_statechange: function() {
+        $(window).bind(this.state_change_event, this.on_state_change);
+
+        var state = $.bbq.getState(true);
+        if (! _.isEmpty(state)) {
+            $(window).trigger(this.state_change_event);
+        } else {
+            this.action_manager.do_action({type: 'ir.actions.client', tag: 'default_home'});
+        }
+    },
+
+    on_logged_out: function() {
+        if(this.action_manager)
+            this.action_manager.stop();
+        this.action_manager = null;
+        $(window).unbind(this.state_change_event, this.on_state_change);
+    },
+
+    on_state_change: function(event) {
+        // as this method is bound to a event via jQuery, the argument is the jQuery Event.. we need to get the current state
+        var state = event.getState(true);       // = bbq.getState, in fact only deparam the hash
+        return this._super(state);
+    },
+
+
+    
+    do_push_state: function(state, extend) {
+        if (extend) {
+            var hash = $.deparam.fragment(true);
+            state = _.extend({}, hash, state);
+        }
+        var url = '#' + $.param(state);
+        $.bbq.pushState(url);      // will set the hash, so will call on_state_change
+    },
+
     default_home: function () {
     },
     /**
@@ -1101,22 +1120,7 @@
             self.action_manager.do_action(action);
         });
     },
-    do_url_set_hash: function(url) {
-        if(!this.url_external_hashchange) {
-            this.url_internal_hashchange = true;
-            jQuery.bbq.pushState(url);
-        }
-    },
-    on_url_hashchange: function() {
-        if(this.url_internal_hashchange) {
-            this.url_internal_hashchange = false;
-        } else {
-            var url = jQuery.deparam.fragment();
-            this.url_external_hashchange = true;
-            this.action_manager.on_url_hashchange(url);
-            this.url_external_hashchange = false;
-        }
-    },
+
     on_menu_action: function(action) {
         this.action_manager.do_action(action);
     },

=== modified file 'addons/web/static/src/js/core.js'
--- addons/web/static/src/js/core.js	2011-11-28 15:39:41 +0000
+++ addons/web/static/src/js/core.js	2011-12-12 14:24:26 +0000
@@ -985,6 +985,22 @@
         }
         return false;
     },
+
+    do_push_state: function(state) {
+        // create a new state
+        if (this.widget_parent) {
+            return this.widget_parent.do_push_state.apply(this,arguments);
+        }
+        //this.on_state_change(state); 
+        return null;
+    },
+
+    on_state_change: function(state) {
+        _.each(this.widget_children, function(child) {
+            child.on_state_change(state);
+        });
+    },
+
     rpc: function(url, data, success, error) {
         var def = $.Deferred().then(success, error);
         var self = this;

=== modified file 'addons/web/static/src/js/views.js'
--- addons/web/static/src/js/views.js	2011-12-12 14:16:56 +0000
+++ addons/web/static/src/js/views.js	2011-12-12 14:24:26 +0000
@@ -24,6 +24,7 @@
         this.dialog = null;
         this.dialog_viewmanager = null;
         this.client_widget = null;
+        this.client_widget_name = null;
     },
     render: function() {
         return "<div id='"+this.element_id+"'></div>";
@@ -44,37 +45,50 @@
         if (this.client_widget) {
             this.client_widget.stop();
             this.client_widget = null;
-        }
-    },
-    url_update: function(action) {
-        var url = {};
-        if(action.id)
-            url.action_id = action.id;
-        // this.url = {
-        //     "model": action.res_model,
-        //     "domain": action.domain,
-        // };
-        // action.res_model
-        // action.domain
-        // action.context
-        // after
-        // action.views
-        // action.res_id
-        // mode
-        // menu
-        this.do_url_set_hash(url);
-    },
-    do_url_set_hash: function(url) {
-    },
-    on_url_hashchange: function(url) {
-        var self = this;
-        if(url && url.action_id) {
-            self.rpc("/web/action/load", { action_id: url.action_id }, function(result) {
-                    self.do_action(result.result);
-                });
-        }
-    },
+            this.client_widget_name = null;
+        }
+    },
+
+    handle_state: function() {
+        // Only root ActionManager handle the state
+        return this.widget_parent instanceof session.web.WebClient;
+    },
+
+    do_push_state: function(state, extend) {
+        if (this.handle_state()) {
+            this._super.apply(this, arguments);
+        }
+    },
+
+    on_state_change: function(state) {
+        if (this.handle_state()) { 
+            if (state.action_id) {
+                var run_action = (!this.inner_viewmanager) || this.inner_viewmanager.action.id !== state.action_id;
+                if (run_action) {
+                    this.null_action();
+                    this.do_action(state.action_id);
+                }
+            }
+            else if (state.client_action) {
+                var run_client = (!this.client_widget) || this.client_widget_name !== state.client_action.tag;
+                if (run_client) {
+                    this.null_action();
+                    this.ir_actions_client(state.client_action);
+                }
+            }
+        }
+
+        return this._super.apply(this, arguments);
+    },
+
     do_action: function(action, on_close) {
+        if (_.isNumber(action)) {
+            var self = this;
+            self.rpc("/web/action/load", { action_id: action }, function(result) {
+                self.do_action(result.result, on_close);
+            });
+            return;
+        }
         if (!action.type) {
             console.error("No type for action", action);
             return;
@@ -124,14 +138,10 @@
             this.content_stop();
             this.inner_viewmanager = new session.web.ViewManagerAction(this, action);
             this.inner_viewmanager.appendTo(this.$element);
-            this.url_update(action);
+            if (action.id) {
+                this.do_push_state({action_id: action.id});
+            }
         }
-        /* new window code
-            this.rpc("/web/session/save_session_action", { the_action : action}, function(key) {
-                var url = window.location.protocol + "//" + window.location.host + window.location.pathname + "?" + jQuery.param({ s_action : "" + key });
-                window.open(url,'_blank');
-            });
-        */
     },
     ir_actions_act_window_close: function (action, on_closed) {
         if (!this.dialog && on_closed) {
@@ -150,8 +160,13 @@
     },
     ir_actions_client: function (action) {
         this.content_stop();
+        this.client_widget_name = action.tag;
         var ClientWidget = session.web.client_actions.get_object(action.tag);
         (this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
+
+        var client_action = {tag: action.tag};
+        if (action.params) _.extend(client_action, {params: action.params});
+        this.do_push_state({client_action: client_action});
     },
     ir_actions_report_xml: function(action, on_closed) {
         var self = this;
@@ -308,6 +323,8 @@
         });
         return view_promise;
     },
+
+
     /**
      * Returns to the view preceding the caller view in this manager's
      * navigation history (the navigation history is appended to via
@@ -531,8 +548,28 @@
             } else {
                 $search_prefix.remove();
             }
+
+            self.do_push_state({view_type: self.active_view}, true);
         });
     },
+
+    handle_state: function() {
+        return (this.widget_parent instanceof session.web.ActionManager) && this.widget_parent.handle_state();
+    },
+
+    do_push_state: function(state, extend) {
+        if (this.handle_state()) {
+            this._super.apply(this, arguments);
+        }
+    },
+
+    on_state_change: function(state) {
+        if (this.handle_state() && state.view_type && state.view_type !== this.active_view) {
+            this.on_mode_switch(state.view_type, true);
+        }
+        return this._super.apply(this, arguments);
+    },
+
     shortcut_check : function(view) {
         var self = this;
         var grandparent = this.widget_parent && this.widget_parent.widget_parent;

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to