• Some comments about the active tab cookie feature.

    1. As written it looks like sites could overwrite each other’s cookies in a subdirectory multisite deployment.

    To avoid this issue one would need to either

    • Add the site id into the id of the tabset
    • Set the cookiepath to limit it to the site or page

    I prefer the latter as the browser will only pass around the cookies that it needs to. In a large network if enough cookies are set you could possibly exceed the set headersize limit and cause a denial of service.

    2. The active tab feature is purely client side and would thus be better served by localStorage if it is available instead of cookies. The solution as implemented creates a cookie for each tabset and those cookies are passed back and forth with every page request and since the cookie path is not being scoped to the page all cookies are being passed back and forth.

    I wrote the code below to persist the tab states before this feature was added. The code stores the selected tabs on a page in a key-value store using the page path as the key you could also use siteid+pageid+tabsetindex as the key (you can’t scope localStorage like you can with cookiepath).

    jQuery(document).ready(function($){ 
    
            post_tabs_persistence = {
                key:"selected_post_tabs" + "-" + window.location.pathname,
                selected_post_tabs:{},
                supports_local_storage:function() {
                    try {
                      return 'localStorage' in window && window['localStorage'] !== null;
                    } catch(e){
                      return false;
                    }
                },
                init:function(){
                    if (this.supports_local_storage()) {
                        this.load_state();
    
    		    if(!this.tab_element_exists())
    	                    this.init_dom_tab_state();
    
                        this.attach_handler(this);
                    }
                },
                init_dom_tab_state:function() {
                    $.each(this.selected_post_tabs.tabs,function(i,v){
                        $("#"+v).click();
                    });
                },
                add_tab_to_state:function(tab_id){
                    if($.inArray(tab_id,this.selected_post_tabs.tabs) === -1)
                    {
                        this.selected_post_tabs.tabs.push(tab_id);
                    }
                },
                remove_tabs_from_state:function(tabs){
                    $.each(tabs,$.proxy(function(i,v){
                        index = $.inArray(v,this.selected_post_tabs.tabs);
                        if(index > -1) {
                            this.selected_post_tabs.tabs.splice(index,1);
                        }
                    },this));
                },
                load_state:function(){
                    if (window.localStorage[this.key]) {
                        this.selected_post_tabs = $.parseJSON(window.localStorage.getItem(this.key));
                    }else{
                        this.selected_post_tabs = {"last_modified":new Date().getTime(),"tabs":[]};
                    }
                },
                save_state:function(){
                    this.selected_post_tabs.last_modified = new Date().getTime();
                    window.localStorage.setItem(this.key,JSON.stringify(this.selected_post_tabs));
                },
                attach_handler:function(self){
    
                    $(".ui-tabs-nav").on("click","a",$.proxy(function(event,context){
                        sel_tab = $(event.target)
                        //console.log(sel_tab);
                        other_tab_ids = sel_tab.parents("li").siblings().children("a").map(function(val,i){
                            //console.log($(this));
                            return $(this).attr("id");
                        });
    
                        //console.log(this); 
    
                        this.remove_tabs_from_state(other_tab_ids);
                        this.add_tab_to_state(sel_tab.attr("id"));
                        this.save_state();
                    },this));
                },
    	    tab_element_exists:function(){
    		return (window.location.hash.indexOf('tabs-') !== -1);
    	    }
            }
            .init();
    });

    https://www.ads-software.com/plugins/wordpress-post-tabs/

  • The topic ‘State Persistence’ is closed to new replies.