Changeset 1087

Show
Ignore:
Timestamp:
03/14/08 04:50:19
Author:
piv
Message:

added initial functionality for working without js/ajax

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/configure.zcml

    r1082 r1087  
    22    xmlns="http://namespaces.zope.org/zope" 
    33    xmlns:browser="http://namespaces.zope.org/browser"> 
     4     
     5    <include file="manage.zcml" /> 
    46     
    57    <include file="kssactions.zcml" /> 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/kssactions.zcml

    r1086 r1087  
    3535        /> 
    3636     
     37    <browser:page 
     38        for="plone.app.kss.interfaces.IPortalObject" 
     39        attribute="editAction" 
     40        class=".plonetabs.PloneTabsControlPanel" 
     41        name="plonetabs-editAction" 
     42        permission="cmf.ManagePortal" 
     43        /> 
     44     
     45    <browser:page 
     46        for="plone.app.kss.interfaces.IPortalObject" 
     47        attribute="editCancel" 
     48        class=".plonetabs.PloneTabsControlPanel" 
     49        name="plonetabs-editCancel" 
     50        permission="cmf.ManagePortal" 
     51        /> 
     52     
    3753</configure> 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py

    r1086 r1087  
     1import copy 
     2 
    13from Acquisition import aq_inner 
    24 
     
    3234    return [s.strip() for s in text.split("- ") if s] 
    3335 
     36ACTION_ATTRS = ["id", "visible", "description", "url_expr", "title", "available_expr"] 
    3437 
    3538class PloneTabsControlPanel(PloneKSSView): 
     
    210213                #withKssSetup="False") 
    211214     
     215    def validateAction(self, id, category, prefix="tabslist_"): 
     216        """ If action with given id and category doesn't exist - raise kss exception """ 
     217        portal_actions = getToolByName(self.context, "portal_actions") 
     218         
     219        # remove prefix, added for making ids on configlet unique ("tabslist_") 
     220        act_id = id[len("tabslist_"):] 
     221         
     222        if category not in portal_actions.objectIds(): 
     223            raise KSSExplicitError, "Unexistent root portal actions category %s" % category 
     224         
     225        cat_container = portal_actions[category] 
     226        if act_id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 
     227            raise KSSExplicitError, "%s action does not exist in %s category" % (act_id, category) 
     228         
     229        return (cat_container, act_id) 
     230     
    212231    @kssaction 
    213232    def toggleGeneratedTabs(self, field, checked='0'): 
     
    233252        """ Toggle visibility for portal actions """ 
    234253        portal_actions = getToolByName(self.context, "portal_actions") 
    235          
    236         if category not in portal_actions.objectIds(): 
    237             raise KSSExplicitError, "Unexistent root portal actions category %s" % category 
    238          
    239         # remove prefix, added for making ids on configlet unique ("tabslist_") 
    240         act_id = id[len("tabslist_"):] 
    241          
    242         cat_container = portal_actions[category] 
    243         if act_id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 
    244             raise KSSExplicitError, "%s action does not exist in %s category" % (act_id, category) 
     254        cat_container, act_id = self.validateAction(id, category) 
    245255         
    246256        if checked == '1': 
     
    292302        """ Delete portal action with given id & category """ 
    293303        portal_actions = getToolByName(self.context, "portal_actions") 
    294          
    295         if category not in portal_actions.objectIds(): 
    296             raise KSSExplicitError, "Unexistent root portal actions category %s" % category 
    297          
    298         # remove prefix, added for making ids on configlet unique ("tabslist_") 
    299         act_id = id[len("tabslist_"):] 
    300          
    301         cat_container = portal_actions[category] 
    302         if act_id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 
    303             raise KSSExplicitError, "%s action does not exist in %s category" % (act_id, category) 
     304        cat_container, act_id = self.validateAction(id, category) 
    304305         
    305306        cat_container.manage_delObjects(ids=[act_id,]) 
     
    320321            self.updateGlobalSections(ksscore) 
    321322     
    322  
    323  
    324  
    325  
    326  
    327  
    328  
     323    @kssaction 
     324    def editAction(self, id, category): 
     325        """ Show edit form for given action """ 
     326        cat_container, act_id = self.validateAction(id, category) 
     327         
     328        # collect data 
     329        action_info = self.copyAction(cat_container[act_id]) 
     330        action_info["editing"] = True 
     331         
     332        ksscore = self.getCommandSet("core") 
     333        content = self.actionslist_template(tabs=[action_info,]) 
     334        replace_id = id 
     335         
     336        ksscore.replaceHTML(ksscore.getHtmlIdSelector(replace_id), content) 
     337         
     338        # focus name field 
     339        ksscore.focus(ksscore.getCssSelector("#%s input[name=name_%s]" % (id, act_id))) 
     340     
     341    @kssaction 
     342    def editCancel(self, id, category): 
     343        """ Hide edit form for given action """ 
     344        cat_container, act_id = self.validateAction(id, category) 
     345         
     346        ksscore = self.getCommandSet("core") 
     347        content = self.actionslist_template(tabs=[cat_container[act_id],]) 
     348        replace_id = id 
     349         
     350        ksscore.replaceHTML(ksscore.getHtmlIdSelector(replace_id), content) 
     351     
     352     
     353    # Methods for processing configlet actions without javascript/ajax 
     354     
     355    def manage_setAutogeneration(self, generated_tabs="0", nonfolderish_tabs="0"): 
     356        """ Process managing autogeneration settings """ 
     357         
     358        # set excludeFromNav property for root objects 
     359        portal = getMultiAdapter((aq_inner(self.context), self.request), name='plone_portal_state').portal() 
     360        form = self.request.form 
     361         
     362        for item in self.getRootTabs(): 
     363            obj = getattr(portal, item['id'], None) 
     364            if obj is not None: 
     365                checked = form.get(item['id'], None) 
     366                if checked == '1': 
     367                    obj.update(excludeFromNav=False) 
     368                else: 
     369                    obj.update(excludeFromNav=True) 
     370 
     371        # set disable_folder_sections property 
     372        changeProperties = getToolByName(self.context, "portal_properties").site_properties.manage_changeProperties 
     373         
     374        if int(generated_tabs) == 1: 
     375            changeProperties(disable_folder_sections=False) 
     376        else: 
     377            changeProperties(disable_folder_sections=True) 
     378         
     379        # set disable_nonfolderish_sections property 
     380        if int(nonfolderish_tabs) == 1: 
     381            changeProperties(disable_nonfolderish_sections=False) 
     382        else: 
     383            changeProperties(disable_nonfolderish_sections=True) 
     384         
     385        self.redirect() 
     386 
     387     
     388    def redirect(self, url="", search="", hash=""): 
     389        """ Redirect to @@plonetabs-controlpanel configlet """ 
     390         
     391        if url == "": 
     392            portal_url =  getMultiAdapter((self.context, self.request), name=u"plone_portal_state").portal_url() 
     393            url = "%s/%s" % (portal_url, "@@plonetabs-controlpanel") 
     394         
     395        if search != "": 
     396            search = "?%s" % search 
     397         
     398        if hash != "": 
     399            hash = "#%s" % hash 
     400         
     401        self.request.response.redirect("%s%s%s" % (url, search, hash)) 
     402     
     403     
     404    # Utility Methods 
     405     
     406    def copyAction(self, action): 
     407        """ Copyt action to dictionary """ 
     408        action_info = {} 
     409        for attr in ACTION_ATTRS: 
     410            action_info[attr] = getattr(action, attr) 
     411        return action_info 
     412     
     413 
     414 
     415 
     416 
     417 
     418 
     419 
     420 
     421 
     422 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css

    r1082 r1087  
    4747#app.viewing li.editing             .tab-title, 
    4848#app                                .drag-handle, 
    49 #app                                .delete, 
    50 #app                                .visibility, 
     49#app.kssActive                      .delete, 
     50#app.kssActive                      .visibility, 
    5151#app                                .editform, 
    5252#app.sorting                        #addaction, 
     
    7373 
    7474/**********************************************************/ 
     75/* Additional style for functionality withou javascript   */ 
     76#app.kssActive #autogeneration_controls { 
     77    display: none; 
     78} 
     79 
     80 
     81 
     82 
     83/**********************************************************/ 
    7584 
    7685#app.sorting #tabslist img.drag-handle { 
     
    291300} 
    292301 
    293 dl.expandedBlock dt.headerAdvanced { 
     302#app dl.expandedBlock dt.headerAdvanced { 
    294303    padding: 0 6px 0 22px; 
    295     background: url(++resource++treeExpanded.gif) no-repeat 6px 50%; 
    296 } 
    297  
    298 dl.collapsedBlock dt.headerAdvanced { 
     304    background: transparent url(++resource++treeExpanded.gif) no-repeat 6px 50%; 
     305} 
     306 
     307#app dl.collapsedBlock dt.headerAdvanced { 
    299308    padding: 0 0 0 22px; 
    300     background: url(++resource++treeCollapsed.gif) no-repeat 6px 50%; 
     309    background: transparent url(++resource++treeCollapsed.gif) no-repeat 6px 50%; 
    301310 } 
    302311 
    303312#app dl.advanced {  
    304313    clear: both; 
     314} 
     315 
     316#app dl.expandedBlock dd.contentAdvanced { 
     317    display: block; 
     318} 
     319 
     320#app dl.collapsedBlock dd.contentAdvanced { 
     321    display: none; 
    305322} 
    306323 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.kss

    r1086 r1087  
    2323 
    2424 /*Hovering for IE especially */ 
    25 #app li:mouseover { 
     25/*#app li:mouseover { 
    2626    action-client: addClass; 
    2727    addClass-value: onHover; 
     
    3131    action-client: removeClass; 
    3232    removeClass-value: onHover; 
    33 } 
     33}*/ 
    3434 
    3535 
     
    4848 
    4949/* Visibility switching */ 
    50 #tabslist .visibility:click { 
     50#tabslist input.visibility:click { 
    5151    action-server: plonetabs-toggleActionsVisibility; 
    5252    plonetabs-toggleActionsVisibility-id: nodeAttr(id, true); 
     
    6363/* Delete action link */ 
    6464#tabslist .delete:click { 
    65     evt-click-preventdefault: True; 
    66     evt-click-allowbubbling: True; 
     65    evt-click-preventdefault: true; 
    6766    action-server: plonetabs-deleteAction; 
    6867    plonetabs-deleteAction-id: nodeAttr(id, true); 
     
    7069} 
    7170 
     71/* Actions edit */ 
     72#tabslist .tab-title:click { 
     73    action-server: plonetabs-editAction; 
     74    plonetabs-editAction-id: nodeAttr(id, true); 
     75    plonetabs-editAction-category: stateVar(plonetabs-category); 
     76} 
    7277 
     78/*#tabslist .url-helper:click { 
     79    action-client: executeCommand; 
     80    executeCommand-name: addClass; 
     81    executeCommand-selector: #tabslist li; 
     82    executeCommand-selectorType: parentnode; 
     83    executeCommand-value: editing; 
     84}*/ 
     85 
     86/* Edit cancel button */ 
     87#tabslist .editcancel:click { 
     88    evt-click-preventdefault: true; 
     89    action-server: plonetabs-editCancel; 
     90    plonetabs-editCancel-id: nodeAttr(id, true); 
     91    plonetabs-editCancel-category: stateVar(plonetabs-category); 
     92} 
     93 
     94/* Edit save button */ 
     95#tabslist .editsave:click { 
     96    evt-click-preventdefault: true; 
     97    action-server: plonetabs-editSave; 
     98    plonetabs-editSave-id: nodeAttr(id, true); 
     99     
     100    plonetabs-editSave-category: stateVar(plonetabs-category); 
     101} 
     102 
     103/* Collapsible sections */ 
     104.collapseAdvanced .headerAdvanced:click { 
     105    action-client: plonetabs-toggleCollapsible; 
     106} 
     107 
     108 
     109 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt

    r1082 r1087  
    22                      dummy python:request.RESPONSE.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT'); 
    33                      category python:options.get('category', None) or 'portal_tabs'" 
    4           tal:repeat="tab python:view.getPortalActions(category)"> 
     4          tal:repeat="tab options/tabs|python:view.getPortalActions(category)"> 
    55<li tal:define="id tab/id; 
    66                visible tab/visible; 
    7                 index repeat/tab/index" 
     7                editing tab/editing|nothing; 
     8                klass python:test(visible, [], ['invisible']); 
     9                klass python:test(editing, klass + ['editing'], klass)" 
    810    tal:attributes="id string:tabslist_${id}; 
    911                    title tab/description; 
    10                     class python:test(visible, '', 'invisible')"> 
     12                    class python:' '.join(klass)"> 
     13 
    1114  <img class="drag-handle" src="++resource++drag.gif" alt="" height="11" width="25" /> 
     15 
    1216  <div class="bridge"> 
    13     <input type="checkbox" class="visibility" value="1" name="visibility" title="visibility" 
     17    <input type="checkbox" class="visibility" value="1" name="visible" title="visibility" 
    1418           tal:attributes="checked python:test(visible, 'checked', None); 
    15                            name string:i${index}_${attrs/name}" /> 
     19                           name string:${attrs/name}_${id}" /> 
    1620  </div> 
     21 
    1722  <a class="delete" href="#">Delete</a> 
    1823  <span class="url-helper" tal:content="tab/url_expr">Tab Action</span> 
    1924  <span class="tab-title" tal:content="tab/title">Tab Name</span> 
     25 
    2026  <form class="editform" 
    2127        method="post" 
    2228        action="@@plonetabs-controlpanel" 
     29        name="edit_form" 
    2330        tal:attributes="action string:${context/portal_url}/${attrs/action}; 
    24                         name string:f$index"> 
    25       <input type="hidden" name="idx" tal:attributes="value index" /> 
     31                        name string:${attrs/name}_${id}"> 
     32 
    2633      <dl> 
    2734        <dt><label>Name</label></dt> 
    28         <dd><input type="text" value="" name="name" 
     35        <dd><input type="text" value="" name="title" 
    2936                   tal:attributes="value tab/title; 
    30                                    name string:i${index}_${attrs/name}"      /></dd> 
     37                                   name string:${attrs/name}_${id}" /></dd> 
    3138      </dl> 
    32       <dl class="collapseAdvanced expandedBlock"> 
     39 
     40      <dl class="collapseAdvanced collapsedBlock"> 
    3341        <dt class="headerAdvanced">Advanced</dt> 
    3442        <dd class="contentAdvanced"> 
    3543          <dl> 
    3644            <dt><label>URL (Expression)</label></dt> 
    37             <dd><input type="text" value="" name="action"     size="30" 
     45            <dd><input type="text" value="" name="url_expr"     size="30" 
    3846                       tal:attributes="value tab/url_expr; 
    39                                        name string:i${index}_${attrs/name}" /></dd> 
     47                                       name string:${attrs/name}_${id}" /></dd> 
    4048          </dl> 
    4149          <dl> 
     
    4351            <dd><input type="text" value="" name="id" 
    4452                       tal:attributes="value tab/id; 
    45                                        name string:i${index}_${attrs/name}" /></dd> 
     53                                       name string:${attrs/name}_${id}" /></dd> 
    4654          </dl> 
    4755          <dl> 
     
    4957            <dd><input type="text" value="" name="condition"  size="30" 
    5058                       tal:attributes="value tab/available_expr; 
    51                                        name string:i${index}_${attrs/name}" /></dd> 
     59                                       name string:${attrs/name}_${id}" /></dd> 
    5260          </dl> 
    5361          <div class="visualClear"><!-- --></div> 
    5462        </dd> 
    5563      </dl> 
     64 
    5665      <div> 
    5766        <input type="submit" class="editsave"   i18n:attributes="value" value="Save"   /> 
    5867        <input type="submit" class="editcancel" i18n:attributes="value" value="Cancel" /> 
    5968      </div> 
     69 
    6070  </form> 
     71 
    6172</li> 
    6273</tal:tabs> 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/autogenerated.pt

    r1084 r1087  
    1111          tal:repeat="tab view/getRootTabs"> 
    1212<li tal:define="id tab/id; 
    13                 visible python:not tab['exclude_from_nav']
     13                visible not: tab/exclude_from_nav
    1414    tal:attributes="id string:roottabs_${id}; 
    1515                    title tab/description|nothing; 
    1616                    class python:view.test(visible, '', 'invisible')"> 
    1717  <div class="bridge"> 
    18     <input type="checkbox" class="visibility" value="1" name="rootvis"  title="visibility" 
    19            tal:attributes="name string:i${repeat/tab/index}_${attrs/name}
     18    <input type="checkbox" class="visibility" value="1" name="id"  title="visibility" 
     19           tal:attributes="name id
    2020                           checked python:view.test(visible, 'checked', None)" /> 
    2121  </div> 
    22   <span class="url-helper" tal:content="python:tab['url']">Tab Action</span> 
     22  <span class="url-helper" tal:content="tab/url">Tab Action</span> 
    2323  <span class="tab-title"  tal:content="tab/name">Tab Name</span> 
    2424</li> 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt

    r1082 r1087  
    6767  <form id="addaction" 
    6868        method="post" 
    69         action="@@plonetabs_controlpanel" 
     69        action="@@plonetabs-controlpanel" 
    7070        tal:attributes="action string:${portal_url}/${attrs/action}"> 
    7171    <dl class="field-visible bridge"> 
     
    123123  <tal:autogeneration condition="python:category == 'portal_tabs'"> 
    124124 
    125     <div class="field" 
    126          tal:define="generated_tabs request/generated_tabs|view/isGeneratedTabs; 
    127                      error errors/generated_tabs|nothing" 
    128          tal:attributes="class python:test(error, 'field error', 'field')"> 
    129       <input type="checkbox" 
    130              id="generated_tabs" 
    131              name="generated_tabs" 
    132              value="1" 
    133              tal:attributes="checked python:test(generated_tabs, 'checked', None)" /> 
    134       <label for="generated_tabs" i18n:translate="label_generated_tabs_enable">Automatically generate tabs</label> 
    135       <div class="formHelp" i18n:translate="help_generated_tabs"> 
    136         By default, all folders created at the root level will have global section 
    137         navigation generated. You can turn this off if you prefer manually constructing 
    138         this part of the navigation. 
     125    <form name="generated_tabs_form" 
     126          action="@@manage-setAutogeneration" 
     127          method="post" 
     128          tal:attributes="action string:${portal_url}/${attrs/action}"> 
     129 
     130      <div class="field" 
     131           tal:define="generated_tabs request/generated_tabs|view/isGeneratedTabs; 
     132                       error errors/generated_tabs|nothing" 
     133           tal:attributes="class python:test(error, 'field error', 'field')"> 
     134        <input type="checkbox" 
     135               id="generated_tabs" 
     136               name="generated_tabs" 
     137               value="1" 
     138               tal:attributes="checked python:test(generated_tabs, 'checked', None)" /> 
     139        <label for="generated_tabs" i18n:translate="label_generated_tabs_enable">Automatically generate tabs</label> 
     140        <div class="formHelp" i18n:translate="help_generated_tabs"> 
     141          By default, all folders created at the root level will have global section 
     142          navigation generated. You can turn this off if you prefer manually constructing 
     143          this part of the navigation. 
     144        </div> 
    139145      </div> 
    140     </div> 
    141146 
    142     <div class="field" 
    143          tal:define="nonfolderish_tabs request/nonfolderish_tabs|view/isNotFoldersGenerated; 
    144                      error errors/nonfolderish_tabs|nothing" 
    145          tal:attributes="class python:test(error, 'field error', 'field')"> 
    146       <input type="checkbox" 
    147              id="nonfolderish_tabs" 
    148              name="nonfolderish_tabs" 
    149              value="1" 
    150              tal:attributes="checked python:test(nonfolderish_tabs, 'checked', None)" /> 
    151       <label for="nonfolderish_tabs" i18n:translate="label_nonfolderish_tabs_enable">Generate tabs for items other than folders</label> 
    152       <div class="formHelp" i18n:translate="help_nonfolderish_tabs"> 
    153         By default, any content item in the root of the portal will be shown as 
    154         a global section. If you turn this option off, only folders will be shown. 
    155         This only has an effect if "Automatically generate tabs" is enabled 
     147      <div class="field" 
     148           tal:define="nonfolderish_tabs request/nonfolderish_tabs|view/isNotFoldersGenerated; 
     149                       error errors/nonfolderish_tabs|nothing" 
     150           tal:attributes="class python:test(error, 'field error', 'field')"> 
     151        <input type="checkbox" 
     152               id="nonfolderish_tabs" 
     153               name="nonfolderish_tabs" 
     154               value="1" 
     155               tal:attributes="checked python:test(nonfolderish_tabs, 'checked', None)" /> 
     156        <label for="nonfolderish_tabs" i18n:translate="label_nonfolderish_tabs_enable">Generate tabs for items other than folders</label> 
     157        <div class="formHelp" i18n:translate="help_nonfolderish_tabs"> 
     158          By default, any content item in the root of the portal will be shown as 
     159          a global section. If you turn this option off, only folders will be shown. 
     160          This only has an effect if "Automatically generate tabs" is enabled 
     161        </div> 
    156162      </div> 
    157     </div> 
    158163 
    159     <ul class="csshover" id="roottabs" 
    160         tal:content="structure view/getGeneratedTabs" /> 
     164      <ul class="csshover" id="roottabs" 
     165          tal:content="structure view/getGeneratedTabs" /> 
     166 
     167      <div id="autogeneration_controls"> 
     168          <input class="submit-button" type="submit" name="generated_roots_button" value="Save" /> 
     169      </div> 
     170 
     171    </form> 
    161172 
    162173  </tal:autogeneration> 
  • qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/plugins/plugin.js

    r1086 r1087  
    44/* Base kukit plugins for plonetabs */ 
    55 
    6 kukit.actionsGlobalRegistry.register('plonetabs-redirectTo', function(oper) { 
    7 ;;; oper.componentName = '[plonetabs-redirectTo] action'
     6kukit.actionsGlobalRegistry.register("plonetabs-redirectTo", function(oper) { 
     7;;; oper.componentName = "[plonetabs-redirectTo] action"
    88    var wl = window.location; 
    9     oper.evaluateParameters([], {'protocol' : wl.protocol, 
    10                                  'host'     : wl.host, 
    11                                  'pathname' : wl.pathname, 
    12                                  'search'   : wl.search, 
    13                                  'hash'     : wl.hash}); 
     9    oper.evaluateParameters([], {"protocol" : wl.protocol, 
     10                                 "host"     : wl.host, 
     11                                 "pathname" : wl.pathname, 
     12                                 "search"   : wl.search, 
     13                                 "hash"     : wl.hash}); 
    1414 
    1515    // normalize parameters 
     
    2525}); 
    2626 
    27 kukit.commandsGlobalRegistry.registerFromAction('plonetabs-redirectTo', kukit.cr.makeSelectorCommand); 
     27kukit.commandsGlobalRegistry.registerFromAction("plonetabs-redirectTo", kukit.cr.makeSelectorCommand); 
    2828 
     29kukit.actionsGlobalRegistry.register("plonetabs-toggleCollapsible", function(oper) { 
     30;;; oper.componentName = "[plonetabs-toggleCollapsible] action"; 
     31    oper.evaluateParameters([], {"collapsed" : "collapsedBlock", "expanded" : "expandedBlock"}); 
     32 
     33    var node = oper.node.parentNode;  // collapsible section 
     34 
     35    if (hasClassName(node, oper.parms.collapsed)) { 
     36        removeClassName(node, oper.parms.collapsed); 
     37        addClassName(node, oper.parms.expanded); 
     38    } else { 
     39        removeClassName(node, oper.parms.expanded); 
     40        addClassName(node, oper.parms.collapsed); 
     41    } 
     42 
     43}); 
     44 
     45kukit.commandsGlobalRegistry.registerFromAction("plonetabs-toggleCollapsible", kukit.cr.makeSelectorCommand); 
     46 
     47