<?xml version="1.0"?>

<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->

<bindings id="toolbarBindings"
          xmlns="http://www.mozilla.org/xbl"
          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
          xmlns:xbl="http://www.mozilla.org/xbl">

  <!-- With the move to the new toolkit, SeaMonkey needs to overwrite certain
       bindings if it wants to keep its distinctive likeness. The bindings
       found here reimplement the XPFE toolbar behaviour by providing toolbar
       bindings in in the chrome://communicator/ domain that are based upon the
       new toolkit's toolbar bindings in the chrome://global/ domain.
       The now hidden new toolkit bindings are accessible via a set xpfe="false"
       attribute, though.
    -->

  <binding id="grippytoolbox" extends="chrome://global/content/bindings/toolbar.xml#toolbox">
    <content orient="vertical">
      <xul:vbox flex="1" class="toolbar-internal-box">
        <children/>
      </xul:vbox>
      <xul:hbox tbattr="collapsed-tray-holder" class="collapsed-tray-holder" moz-collapsed="true" xbl:inherits="collapsed=inFullscreen">
        <xul:hbox tbattr="collapsed-tray" class="collapsed-tray"/>
        <xul:spacer flex="1" class="collapsed-tray-spacer"/>
      </xul:hbox>
    </content>
    <implementation>
      <field name="palette">
        this.getElementsByTagName("toolbarpalette").item(0);
      </field>

      <constructor>
        <![CDATA[
          var set = this.toolbarset;
          if (!set)
            return;
          var toolbars = this.getElementsByAttribute("customindex", "*");
          for (let i = 0; i < toolbars.length; ++i) {
            let bar = toolbars[i];
            let name = bar.getAttribute("toolbarname").replace(" ", "_");
            if (name) {
              let attrs = ["mode", "iconsize", "labelalign", "hidden",
                           "collapsed", "moz-collapsed"];
              for (let j = 0; j < attrs.length; j++) {
                let attr = set.getAttribute(name + attrs[j]);
                if (attr)
                  bar.setAttribute(attrs[j], attr);
              }
              bar.setAttribute("grippytooltiptext", name);
            }
          }
        ]]>
      </constructor>

      <method name="collapseToolbar">
        <parameter name="toolbar"/>
        <body>
        <![CDATA[
          try {
            this.createCollapsedGrippy(toolbar);
            toolbar.setAttribute("collapsed", "true");
            document.persist(toolbar.id, "collapsed");
            toolbar.removeAttribute("moz-collapsed");
            document.persist(toolbar.id, "moz-collapsed");
            if (toolbar.hasAttribute("customindex"))
              this.persistCustomCollapse(toolbar, "true");
          }
          catch(e) {
          }
        ]]>
        </body>
      </method>

      <method name="expandToolbar">
        <parameter name="aGrippyID"/>
        <body>
        <![CDATA[
          var idString = aGrippyID.substring("moz_tb_collapsed_".length, aGrippyID.length);
          var toolbar = document.getElementById(idString);
          toolbar.setAttribute("collapsed", "false");
          var collapsedTray = document.getAnonymousElementByAttribute(this, "tbattr", "collapsed-tray");
          var collapsedToolbar = document.getElementById("moz_tb_collapsed_" + toolbar.id);
          collapsedToolbar.remove();
          if (!collapsedTray.hasChildNodes())
            document.getAnonymousElementByAttribute(this, "tbattr", "collapsed-tray-holder").setAttribute("moz-collapsed", "true");
          document.persist(toolbar.id, "collapsed");
          if (toolbar.hasAttribute("customindex"))
            this.persistCustomCollapse(toolbar, "false");
        ]]>
        </body>
      </method>

      <method name="createCollapsedGrippy">
        <parameter name="aToolbar"/>
        <body>
        <![CDATA[
          const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
          var existingGrippy = document.getAnonymousElementByAttribute(this, "id", "moz_tb_collapsed_" + aToolbar.id);
          if (!existingGrippy) {
            var grippy = document.getAnonymousElementByAttribute(aToolbar, "tbattr", "toolbar-grippy");
            var boxObject = grippy.boxObject.QueryInterface(Components.interfaces.nsIBoxObject);
            var collapsedGrippy = document.createElementNS(XUL_NS, "toolbargrippy");
            if (collapsedGrippy) {
              var width = boxObject.height > 20 ? boxObject.height : 23;
              var height = boxObject.width > 10 ? boxObject.width : 12;
              var styleString = "width: " + width + "px; height: " + height + "px;";
              collapsedGrippy.setAttribute("style", styleString);
              collapsedGrippy.setAttribute("tooltiptext", aToolbar.getAttribute("grippytooltiptext"));
              collapsedGrippy.setAttribute("id", "moz_tb_collapsed_" + aToolbar.id);
              collapsedGrippy.setAttribute("moz_grippy_collapsed", "true");
              collapsedGrippy.setAttribute("tbgrippy-collapsed", "true");
              var collapsedTrayHolder = document.getAnonymousElementByAttribute(this, "tbattr", "collapsed-tray-holder");
              if (collapsedTrayHolder.getAttribute("moz-collapsed") == "true")
                collapsedTrayHolder.removeAttribute("moz-collapsed");
              document.getAnonymousElementByAttribute(this, "tbattr", "collapsed-tray").appendChild(collapsedGrippy);
            }
          }
        ]]>
        </body>
      </method>

      <method name="persistCustomCollapse">
        <parameter name="toolbar"/>
        <parameter name="collapsed"/>
        <body>
        <![CDATA[
          var attr = toolbar.getAttribute("toolbarname").replace(" ", "_") + "collapsed";
          this.toolbarset.setAttribute(attr, collapsed);
          document.persist(this.toolbarset.id, attr);
          var attr = toolbar.getAttribute("toolbarname").replace(" ", "_") + "moz-collapsed";
          this.toolbarset.removeAttribute(attr);
          document.persist(this.toolbarset.id, attr);
        ]]>
        </body>
      </method>
    </implementation>
  </binding>

  <binding id="grippytoolbar" extends="chrome://global/content/bindings/toolbar.xml#toolbar">
    <content>
      <xul:hbox flex="1" class="toolbar-box box-inherit">
        <xul:toolbargrippy xbl:inherits="last-toolbar,hidden=grippyhidden,collapsed=inFullscreen"
                           tbattr="toolbar-grippy"
                           class="toolbar-grippy"/>
        <xul:hbox flex="1" class="toolbar-holder box-inherit"
                  xbl:inherits="collapsed,last-toolbar,orient,align,pack">
          <children/>
        </xul:hbox>
      </xul:hbox>
    </content>

    <implementation>
      <constructor>
        <![CDATA[
          if (this.getAttribute("moz-collapsed") == "true" &&
              this.parentNode.localName == "toolbox")
            this.parentNode.collapseToolbar(this);
          else if (this.getAttribute("collapsed") == "true" &&
                   this.parentNode.localName == "toolbox")
            this.parentNode.createCollapsedGrippy(this);
        ]]>
      </constructor>
    </implementation>
  </binding>

  <binding id="grippytoolbar-primary" extends="chrome://communicator/content/bindings/toolbar.xml#grippytoolbar">
    <implementation implements="nsIObserver">
      <constructor>
        <![CDATA[
          this.prefs.addObserver(this.domain, this, false);
          if (this.prefs.getIntPref(this.domain) != 2)
            this.observe(this.prefs, "nsPref:changed", this.domain);
        ]]>
      </constructor>

      <destructor>
        this.prefs.removeObserver(this.domain, this);
      </destructor>

      <field name="domain" readonly="true">
        "browser.chrome.toolbar_style"
      </field>

      <field name="prefs" readonly="true">
        Components.classes["@mozilla.org/preferences-service;1"]
                  .getService(Components.interfaces.nsIPrefService).getBranch(null)
      </field>

      <method name="observe">
        <parameter name="subject"/>
        <parameter name="topic"/>
        <parameter name="name"/>
        <body>
          <![CDATA[
            if (topic == "nsPref:changed" && name == this.domain) {
              const styles = ["icons", "text", "full"];
              const style = styles[this.prefs.getIntPref(name)];
              this.parentNode.setAttribute("mode", style); // toolbox
              if (!this.hasAttribute("customizable") ||
                  !this.hasAttribute("ignoremodepref"))
                this.setAttribute("mode", style);
            }
          ]]>
        </body>
      </method>
    </implementation>
  </binding>

  <binding id="grippytoolbar-drag"
           extends="chrome://communicator/content/bindings/toolbar.xml#grippytoolbar">
    <implementation>
      <field name="_dragBindingAlive">true</field>
      <constructor>
        <![CDATA[
          if (!this._draggableStarted) {
            this._draggableStarted = true;
            try {
              let tmp = {};
              Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
              let draggableThis = new tmp.WindowDraggingElement(this);
              draggableThis.mouseDownCheck = function(e) {
                // Don't move while customizing.
                return this._dragBindingAlive &&
                       this.getAttribute("customizing") != "true";
              }
            } catch (e) {}
          }
        ]]>
      </constructor>
    </implementation>
  </binding>

  <binding id="grippytoolbar-menubar"
           extends="chrome://communicator/content/bindings/toolbar.xml#grippytoolbar"
           display="xul:menubar"/>

  <binding id="grippymenubar" extends="chrome://global/content/bindings/toolbar.xml#menubar">
    <content>
      <xul:hbox flex="1" class="toolbar-box">
        <xul:toolbargrippy xbl:inherits="last-toolbar,hidden=grippyhidden"
                           tbattr="toolbar-grippy" class="toolbar-grippy"/>
        <xul:hbox flex="1" class="toolbar-holder" xbl:inherits="collapsed,last-toolbar">
          <children/>
        </xul:hbox>
      </xul:hbox>
    </content>
    <implementation>
      <constructor>
        <![CDATA[
          if (this.getAttribute("moz-collapsed") == "true" &&
              this.parentNode.localName == "toolbox")
            this.parentNode.collapseToolbar(this);
          else if (this.getAttribute("collapsed") == "true" &&
                   this.parentNode.localName == "toolbox")
            this.parentNode.createCollapsedGrippy(this);
        ]]>
      </constructor>
    </implementation>
  </binding>

  <binding id="toolbargrippy" display="xul:button"
           extends="chrome://global/content/bindings/toolbar.xml#toolbar-base">
    <content>
      <xul:image class="toolbargrippy-arrow"/>
      <xul:spacer class="toolbargrippy-texture" flex="1"/>
    </content>

    <implementation>
      <property name="collapsed">
        <getter>
          return this.hasAttribute("moz_grippy_collapsed");
        </getter>
        <setter>
          if (val)
            this.setAttribute("moz_grippy_collapsed", "true");
          else
            this.removeAttribute("moz_grippy_collapsed");
          return val;
        </setter>
      </property>

      <method name="returnNode">
        <parameter name="aNodeA"/>
        <parameter name="aNodeB"/>
        <body>
        <![CDATA[
          var node = this.parentNode;
          while (node && node.localName != "window" &&
                 (node.localName != aNodeA && (node.localName != aNodeB)))  {
            node = node.parentNode;
          }
          return node;
        ]]>
        </body>
      </method>

      <method name="grippyTriggered">
        <body>
        <![CDATA[
          var toolbox = this.returnNode("toolbox");
          var toolbar = this.returnNode("toolbar", "menubar");
          if (this.collapsed)
            toolbox.expandToolbar(this.id);
          else
            toolbox.collapseToolbar(toolbar);
        ]]>
        </body>
      </method>
    </implementation>

    <handlers>
      <handler event="command">
      <![CDATA[
        this.grippyTriggered();
      ]]>
      </handler>
    </handlers>
  </binding>

</bindings>

