Dual sidebars for standalone Composer with movable and detachable sidebar items; b=354691, r=neil@httl.net

This commit is contained in:
daniel%glazman.org 2006-10-05 07:58:11 +00:00
Родитель 2ad5c13cae
Коммит daef4d8093
13 изменённых файлов: 1158 добавлений и 12 удалений

Просмотреть файл

@ -0,0 +1,55 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Glazman <daniel.glazman@disruptive-innovations.com>, Original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
sidebar {
width: 200px;
-moz-box-orient: vertical;
-moz-binding: url('chrome://composer/content/bindings/sidebar.xml#sidebar');
}
sidebarcontent {
-moz-box-orient: vertical;
-moz-binding: url('chrome://composer/content/bindings/sidebar.xml#sidebarcontent');
-moz-box-flex: 1;
}
sidebaritems {
-moz-binding: url('chrome://composer/content/bindings/sidebar.xml#sidebaritems');
display: none ! important;
}

Просмотреть файл

@ -0,0 +1,652 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Composer.
-
- The Initial Developer of the Original Code is
- Disruptive Innovations SARL.
- Portions created by the Initial Developer are Copyright (C) 2006
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Daniel Glazman (daniel.glazman@disruptive-innovations.com), Original Author
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE bindings [
<!ENTITY % sidebarDTD SYSTEM "chrome://composer/locale/sidebar.dtd" >
%sidebarDTD;
]>
<bindings id="sidebarBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="sidebaritems">
<resources>
<stylesheet src="chrome://composer/skin/sidebar.css"/>
</resources>
<implementation>
<constructor>
<![CDATA[
// let's find all sidebaritems living in their own window
var items = this.getElementsByAttribute("standalone", "true");
for (var i = 0; i < items.length; i++)
{
var item = items[i];
// retrieve all the data it carries
var name = item.getAttribute("name");
var properties = item.getAttribute("properties");
var src = item.getAttribute("src");
// let's see if we have a localized string for that
// item name
var label = item.getAttribute("title");
// show it
window.openDialog("chrome://composer/content/dialogs/standaloneSidebar.xul","_blank",
"all,dialog=no", name,
label ? label : name, src, item);
}
]]>
</constructor>
<property name="mItems"
readonly="true"
onget="return this.getElementsByTagName('sidebaritem');" />
<method name="_getItemsFromName">
<parameter name="aName"/>
<body>
<![CDATA[
return this.getElementsByAttribute("name", aName);
]]>
</body>
</method>
</implementation>
</binding>
<binding id="sidebar">
<resources>
<stylesheet src="chrome://composer/skin/sidebar.css"/>
</resources>
<content>
<xul:hbox align="center" class="titlebox">
<xul:toolbarbutton label="&addSidebarContent.label;" class="sidebar-morebutton" type="menu"
tooltiptext="&addSidebarContent.tooltip;">
<xul:menupopup onpopupshowing="this.parentNode.parentNode.parentNode._updateMissingSidebarItems(this)"/>
</xul:toolbarbutton>
<xul:spacer flex="1"/>
<xul:toolbarbutton class="sidebar-closebutton"
tooltiptext="&closeSidebar.tooltip;"
oncommand="this.parentNode.parentNode._close()"/>
</xul:hbox>
<xul:separator class="groove-thin"/>
<xul:vbox flex="1" anonid="content">
<children/>
</xul:vbox>
</content>
<implementation>
<field name="mXUL_NS">"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</field>
<field name="mSidebarItems">null</field>
<field name="mOtherSidebar">null</field>
<field name="mSplitter">null</field>
<property name="mContents"
readonly="true"
onget="return this.getElementsByTagName('sidebarcontent');" />
<property name="mSplitters"
readonly="true"
onget="return this.getElementsByTagName('splitter');" />
<method name="init">
<parameter name="aSidebarItems"/>
<parameter name="aOtherSidebar"/>
<parameter name="aSplitter"/>
<body>
<![CDATA[
if (!aSidebarItems)
return;
this.mSidebarItems = aSidebarItems;
this.mOtherSidebar = aOtherSidebar;
this.mSplitter = aSplitter;
// get the list of sidebaritems shown in this sidebar
var itemsAttr = this.getAttribute("sidebaritems");
var itemsArray = itemsAttr.split(",");
var ordinalIndex = 1;
for (var i = 0; i < itemsArray.length; i++)
{
// sanity case
if (itemsArray[i])
{
// now, find the corresponding sidebaritem
var item = aSidebarItems._getItemsFromName(itemsArray[i]).item(0);
if (item)
{
// retrieve all the data it carries
var properties = item.getAttribute("properties");
var src = item.getAttribute("src");
// the height on the sidebaritem is persistent, and is updated
// each time a splitter between sidebarcontent elements is moved
var height = item.getAttribute("height");
// let's see if we have a localized string for that
// item name
var label = item.getAttribute("title");
// create a sidebarcontent
var sidebarcontent = document.createElementNS(this.mXUL_NS, "sidebarcontent");
// set the name and the height
sidebarcontent.setAttribute("name", itemsArray[i]);
sidebarcontent.setAttribute("height", height);
// append it to the sidebar
this.appendChild(sidebarcontent);
// and init it
sidebarcontent._setLabel(label ? label : itemsArray[i]);
// now create the iframe
var iframe = document.createElementNS(this.mXUL_NS, "iframe");
iframe.setAttribute("flex", "1");
iframe.setAttribute("src", src);
sidebarcontent.appendChild(iframe);
sidebarcontent.setAttribute("ordinal", ordinalIndex++);
// and this is not the last sidebaritem for this sidebar,
// let's add a splitter
if (i < itemsArray.length - 1)
{
var splitter = document.createElementNS(this.mXUL_NS, "splitter");
// we need to know when the splitter is moved.
splitter.setAttribute("oncommand",
"this.parentNode._setPersistentHeights()");
// append the splitter to the sidebar
splitter.setAttribute("ordinal", ordinalIndex++);
this.appendChild(splitter);
}
}
}
}
]]>
</body>
</method>
<method name="_setPersistentHeights">
<body>
<![CDATA[
// early way out if no sidebaritems
if (!this.mSidebarItems)
return;
// browse all sidebarcontent elements in this sidebar
var contents = this.mContents;
for (var i = 0; i < contents.length; i++)
{
var child = contents[i];
// find their unique identifier
var name = child.getAttribute("name");
if (name.length)
{
// find the corresponding sidebaritem
var items = this.mSidebarItems._getItemsFromName(name);
if (items && items.length)
{
var item = items[0];
// get the sidebarcontent's height and store it in the
// sidebaritem
item.setAttribute("height", child.getAttribute("height"));
// make it persist so we get it back next session
document.persist(item.getAttribute("id"), "height");
}
}
}
]]>
</body>
</method>
<method name="_updatePersistentItemsList">
<body>
<![CDATA[
function compare(a, b) {
return a.ordinal - b.ordinal;
}
// early way out if no sidebaritems
if (!this.mSidebarItems)
return;
// find all sidebarcontents in the current sidebar
var contents = this.mContents;
if (!contents || !contents.length)
{
// none, zilch, nada... Make that persist and leave
this.setAttribute("sidebaritems", "");
document.persist(this, "sidebaritems");
return;
}
// make an array storing all sidebarcontents
var itemsArray = [];
for (var i = 0; i < contents.length; i++)
itemsArray.push( contents[i] );
// sort it by ordinal
itemsArray.sort(compare);
// now rebuild the sidebaritems attribute on the sidebar
var newList = "";
for (var i = 0; i < itemsArray.length; i++)
{
var item = itemsArray[i];
item.setAttribute("ordinal", i * 2 + 1);
if (i)
newList += ",";
newList += item.getAttribute("name");
}
// store and persist
this.setAttribute("sidebaritems", newList);
document.persist(this, "sidebaritems");
// don't forget to update splitters' ordinal !
var splitters = this.mSplitters;
for (var i = 0; i < splitters.length; i++)
{
splitters[i].setAttribute("ordinal", i * 2 + 2);
}
]]>
</body>
</method>
<method name="_addToOtherSidebar">
<parameter name="aName"/>
<parameter name="aTitle"/>
<parameter name="aURL"/>
<body>
<![CDATA[
this.mOtherSidebar._addContent(aName, aTitle, aURL);
]]>
</body>
</method>
<method name="_addContent">
<parameter name="aName"/>
<parameter name="aTitle"/>
<parameter name="aURL"/>
<body>
<![CDATA[
// what should be the default original for this new content ?
var ordinalIndex = this.childNodes.length;
if (ordinalIndex)
{
var splitter = document.createElementNS(this.mXUL_NS, "splitter");
// we need to know when the splitter is moved.
splitter.setAttribute("oncommand",
"this.parentNode._setPersistentHeights()");
// append the splitter to the sidebar
splitter.setAttribute("ordinal", ++ordinalIndex);
this.appendChild(splitter);
}
// create a sidebarcontent
var sidebarcontent = document.createElementNS(this.mXUL_NS, "sidebarcontent");
// set the name and the height
sidebarcontent.setAttribute("name", aName);
// append it to the sidebar
this.appendChild(sidebarcontent);
// and init it
sidebarcontent._setLabel(aTitle);
// now create the iframe
var iframe = document.createElementNS(this.mXUL_NS, "iframe");
iframe.setAttribute("flex", "1");
iframe.setAttribute("src", aURL);
sidebarcontent.appendChild(iframe);
sidebarcontent.setAttribute("ordinal", ordinalIndex++);
this._updatePersistentItemsList();
]]>
</body>
</method>
<method name="_addSidebarItem">
<parameter name="aMenuitem"/>
<body>
<![CDATA[
this._addContent( aMenuitem.getAttribute("name"),
aMenuitem.getAttribute("label"),
aMenuitem.getAttribute("src") );
]]>
</body>
</method>
<method name="_updateMissingSidebarItems">
<parameter name="aPopup"/>
<body>
<![CDATA[
// early way out if no sidebaritems
if (!this.mSidebarItems)
return;
// find all sidebaritems
var items = this.mSidebarItems.mItems;
var missingItems = {};
for (var i = 0; i < items.length; i++)
{
var item = items[i];
var name = item.getAttribute("name");
var title = item.getAttribute("title");
var src = item.getAttribute("src");
// don't offer to them to a sidebar if they are
// already shown in standalone windows
if (item.getAttribute("standalone") != "true")
missingItems[name] = [ title, src ]
}
// remove from list the ones already in the current sidebar
var contents = this.mContents;
for (var i = 0; i < contents.length; i++)
{
var content = contents[i];
name = content.getAttribute("name");
delete missingItems[name];
}
// and remove from list the ones already in the other sidebar
// if there is one
if (this.mOtherSidebar)
{
contents = this.mOtherSidebar.mContents;
for (var i = 0; i < contents.length; i++)
{
content = contents[i];
name = content.getAttribute("name");
delete missingItems[name];
}
}
// popup cleanup
while (aPopup.hasChildNodes())
aPopup.removeChild(aPopup.lastChild);
var empty = true;
for (i in missingItems)
{
empty = false;
var menuitem = document.createElementNS(this.mXUL_NS, "menuitem");
var label = missingItems[i][0];
menuitem.setAttribute("label", label ? label : i);
menuitem.setAttribute("tooltiptext", label ? label : i);
menuitem.setAttribute("name", i);
menuitem.setAttribute("src", missingItems[i][1]);
menuitem.setAttribute("oncommand", "this.parentNode.parentNode.parentNode.parentNode._addSidebarItem(this)");
aPopup.appendChild(menuitem);
}
if (empty)
{
var menuitem = document.createElementNS(this.mXUL_NS, "menuitem");
menuitem.setAttribute("label", " -- ");
menuitem.setAttribute("disabled", "true");
aPopup.appendChild(menuitem);
}
]]>
</body>
</method>
<method name="_close">
<body>
<![CDATA[
if (this.mSplitter)
this.mSplitter.setAttribute("state", "collapsed");
else
this.setAttribute("collapsed", "true");
]]>
</body>
</method>
</implementation>
</binding>
<binding id="sidebarcontent">
<resources>
<stylesheet src="chrome://composer/skin/sidebarcontent.css"/>
</resources>
<content>
<xul:hbox align="center" class="titlebox" anonid="titlebox">
<xul:label anonid="name" class="sidebarcontent-name"/>
<xul:spacer flex="1"/>
<xul:toolbarbutton label="&actions.label;" class="sidebar-arrowbutton" type="menu">
<xul:menupopup onpopupshowing="this.parentNode.parentNode.parentNode._updateActionsPopup(this)">
<xul:menuitem anonid="closemenu"
label="&closeMenu.label;"
accesskey="&closeMenu.accesskey;"
oncommand="this.parentNode.parentNode.parentNode.parentNode._close()"/>
<xul:menuseparator/>
<xul:menuitem anonid="moveupmenu"
label="&moveUpMenu.label;"
accesskey="&moveUpMenu.accesskey;"
oncommand="this.parentNode.parentNode.parentNode.parentNode._move(-2)" />
<xul:menuitem anonid="movedownmenu"
label="&moveDownMenu.label;"
accesskey="&moveDownMenu.accesskey;"
oncommand="this.parentNode.parentNode.parentNode.parentNode._move(+2)" />
<xul:menuseparator/>
<xul:menuitem anonid="moveothermenu"
label="&moveOtherMenu.label;"
accesskey="&moveOtherMenu.accesskey;"
oncommand="this.parentNode.parentNode.parentNode.parentNode._moveToOtherSidebar()" />
<xul:menuseparator/>
<xul:menuitem anonid="detachmenu"
label="&detachMenu.label;"
accesskey="&detachMenu.accesskey;"
oncommand="this.parentNode.parentNode.parentNode.parentNode._detach()" />
</xul:menupopup>
</xul:toolbarbutton>
</xul:hbox>
<xul:separator class="groove-thin"/>
<children/>
</content>
<implementation>
<property name="mTitleBox">
<getter>
<![CDATA[
return document.getAnonymousElementByAttribute(this, "anonid", "titlebox");
]]>
</getter>
</property>
<property name="mLabel">
<getter>
<![CDATA[
return this.mTitleBox.firstChild;
]]>
</getter>
</property>
<property name="mTitle">
<getter>
<![CDATA[
return this.mLabel.value;
]]>
</getter>
</property>
<property name="mContent">
<getter>
<![CDATA[
return this.getElementsByTagName("iframe").item(0);
]]>
</getter>
</property>
<method name="_updateActionsPopup">
<parameter name="aPopup"/>
<body>
<![CDATA[
var isFirst = (this.getAttribute("ordinal") == "1");
var isLast = (this.getAttribute("ordinal") == this.parentNode.childNodes.length);
var moveupmenu = aPopup.getElementsByAttribute("anonid", "moveupmenu")[0];
var movedownmenu = aPopup.getElementsByAttribute("anonid", "movedownmenu")[0];
moveupmenu.setAttribute("disabled", isFirst);
movedownmenu.setAttribute("disabled", isLast);
var moveothermenu = aPopup.getElementsByAttribute("anonid", "moveothermenu")[0];
if (this.parentNode.mOtherSidebar)
moveothermenu.removeAttribute("disabled");
else
moveothermenu.setAttribute("disabled", "true");
]]>
</body>
</method>
<method name="_setLabel">
<parameter name="aLabel"/>
<body>
<![CDATA[
this.mLabel.value = aLabel;
]]>
</body>
</method>
<method name="_close">
<body>
<![CDATA[
var currentOrdinal = parseInt(this.getAttribute("ordinal"));
var sidebar = this.parentNode;
if (currentOrdinal == 1)
{
// we have a splitter after the current item and we have
// to remove it
var splitterOrdinal = currentOrdinal + 1;
var splitters = this.parentNode.getElementsByAttribute("ordinal", splitterOrdinal);
if (splitters && splitters.length)
sidebar.removeChild(splitters[0]);
}
else
{
// we have a splitter before the current item and we have
// to remove it
var splitterOrdinal = currentOrdinal - 1;
var splitters = this.parentNode.getElementsByAttribute("ordinal", splitterOrdinal);
if (splitters && splitters.length)
sidebar.removeChild(splitters[0]);
}
sidebar.removeChild(this);
sidebar._updatePersistentItemsList();
]]>
</body>
</method>
<method name="_move">
<parameter name="aOffset"/>
<body>
<![CDATA[
// we always have a splitter before the current element
// as we always have another sidebarcontent before the splitter
var currentOrdinal = this.getAttribute("ordinal");
var otherOrdinal = parseInt(currentOrdinal) + aOffset;
var otherContent = this.parentNode.getElementsByAttribute("ordinal", otherOrdinal).item(0);
otherContent.setAttribute("ordinal", currentOrdinal);
this.setAttribute("ordinal", otherOrdinal);
this.parentNode._updatePersistentItemsList();
]]>
</body>
</method>
<method name="_moveToOtherSidebar">
<body>
<![CDATA[
var sidebar = this.parentNode;
var title = this.mTitle;
var src = this.mContent.getAttribute("src");
var name = this.getAttribute("name");
// we cannot really move a sidebarcontent from one
// sidebar to the other because the iframe's context is
// lost anyway
sidebar._addToOtherSidebar(name, title, src);
// close this one
this._close();
]]>
</body>
</method>
<method name="_detach">
<body>
<![CDATA[
var label = this.mTitle;
var name = this.getAttribute("name");
// find the corresponding sidebaritem
var sidebar = this.parentNode;
var items = sidebar.mSidebarItems._getItemsFromName(name);
if (items && items.length)
{
var item = items[0];
// remember that we want this sidebaritem to be floating alone
item.setAttribute("standalone", "true");
document.persist(item.getAttribute("id"), "standalone");
var src = item.getAttribute("src");
// make it float, make it float
window.openDialog("chrome://composer/content/dialogs/standaloneSidebar.xul","_blank",
"chrome,modal=no,titlebar,scrollbars=yes,resizable", name, label, src, item);
// close this one
this._close();
}
]]>
</body>
</method>
</implementation>
</binding>
</bindings>

Просмотреть файл

@ -11,7 +11,7 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Composer.
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
@ -35,8 +35,6 @@
*
* ***** END LICENSE BLOCK ***** */
var gDialog = {};
function Startup()
{
var url = null;
@ -44,14 +42,16 @@ function Startup()
if (window.arguments.length == 2)
url = window.arguments[1];
gDialog.status = dgid("status");
gDialog.progress = dgid("progress");
GetUIElements();
// let's finish with the url
if (url)
OpenFile(url, true);
ComposerCommands.setupMainCommands();
gDialog.sidebar1.init(gDialog.sidebaritems, gDialog.sidebar2, gDialog.splitter1);
gDialog.sidebar2.init(gDialog.sidebaritems, gDialog.sidebar1, gDialog.splitter2);
}
function OpenLocation(aEvent, type)

Просмотреть файл

@ -13,7 +13,7 @@
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Mozilla Composer.
- The Original Code is Composer.
-
- The Initial Developer of the Original Code is
- Disruptive Innovations SARL.
@ -48,6 +48,7 @@
title = "&window.title;"
width = "800"
height = "600"
persist="screenX screenY width height"
onload = "Startup()"
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
@ -74,7 +75,26 @@
<toolbarset id="customToolbars" context="format-toolbar-context-menu"/>
</toolbox>
<!-- XXX the following sidebaritems element is here only for test purposes
will be removed later -->
<sidebaritems id="sidebaritems">
<sidebaritem id="sidebaritem-glazman" name="glazman" src="http://glazman.org" title="Glazou's cave"/>
<sidebaritem id="sidebaritem-blank" name="blank" src="about:blank" title="Blanc de blanc"/>
<sidebaritem id="sidebaritem-inria" name="inria" src="http://www.inria.fr" title="Inria.fr"/>
</sidebaritems>
<hbox flex="1">
<sidebar id="sidebar1" sidebaritems="" persist="sidebaritems"/>
<splitter id="splitter1" collapse="before" resizebefore="closest"/>
<vbox flex="1">
<tabeditor id="tabeditor" flex="1"/>
<hbox>
<label value="structure toolbar" />
</hbox>
</vbox>
<splitter id="splitter2" collapse="after" resizeafter="closest"/>
<sidebar id="sidebar2" sidebaritems="" persist="sidebaritems"/>
</hbox>
<statusbar>
<deck flex="1" id="statusbarDeck">

Просмотреть файл

@ -0,0 +1,86 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Glazman <daniel.glazman@disruptive-innovations.com>, Original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
function Startup()
{
if(window.arguments.length != 4)
return;
GetUIElements();
gDialog.name = window.arguments[0];
gDialog.label = window.arguments[1];
gDialog.src = window.arguments[2];
gDialog.sidebaritem = window.arguments[3];
document.documentElement.setAttribute("id", gDialog.name);
gDialog.iframe.setAttribute("src", gDialog.src);
document.title = gDialog.label;
var root = document.documentElement;
var item = gDialog.sidebaritem;
root.setAttribute("screenX", item.getAttribute("screenX"));
root.setAttribute("screenY", item.getAttribute("screenY"));
root.setAttribute("width", item.getAttribute("width"));
root.setAttribute("height", item.getAttribute("height"));
}
function Onclose()
{
gDialog.sidebaritem.removeAttribute("standalone");
return true;
}
function Shutdown()
{
var item = gDialog.sidebaritem;
var root = document.documentElement;
item.setAttribute("screenX", window.screenX);
item.setAttribute("screenY", window.screenY);
item.setAttribute("width", document.documentElement.width);
item.setAttribute("height", document.documentElement.height);
var doc = gDialog.sidebaritem.ownerDocument;
var id = item.getAttribute("id");
doc.persist(id, "standalone");
doc.persist(id, "screenX");
doc.persist(id, "screenY");
doc.persist(id, "width");
doc.persist(id, "height");
}

Просмотреть файл

@ -0,0 +1,58 @@
<?xml version="1.0"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Composer.
-
- The Initial Developer of the Original Code is
- Disruptive Innovations SARL.
- Portions created by the Initial Developer are Copyright (C) 2006
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Daniel Glazman (daniel.glazman@disruptive-innovations.com), Original Author
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window
id = "standaloneSidebar"
windowtype = "Composer:standaloneSidebar"
width = "300"
height = "300"
onload = "Startup()"
onclose = "Onclose()"
onunload = "Shutdown()"
persist="screenX screenY width height"
xmlns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://composer/content/utils/dgid.js"/>
<script type="application/x-javascript" src="chrome://composer/content/dialogs/standaloneSidebar.js"/>
<iframe flex="1" id="iframe"/>
</window>

Просмотреть файл

@ -11,7 +11,7 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Composer.
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
@ -35,7 +35,15 @@
*
* ***** END LICENSE BLOCK ***** */
function dgid(aStr)
// we store all globals in a gDialog object for convenience
var gDialog = {};
function GetUIElements()
{
return document.getElementById(aStr);
var elts = document.getElementsByAttribute("id", "*");
for (var i = 0; i < elts.length; i++)
{
var elt = elts.item(i);
gDialog[ elt.getAttribute("id") ] = elt;
}
}

Просмотреть файл

@ -6,12 +6,16 @@ composer.jar:
content/composer/about-logo.png (content/composer/about-logo.png)
content/composer/logo-anim.gif (content/composer/logo-anim.gif)
content/composer/aboutDialog.xul (content/composer/aboutDialog.xul)
content/composer/bindings/sidebar.css (content/composer/bindings/sidebar.css)
content/composer/bindings/sidebar.xml (content/composer/bindings/sidebar.xml)
content/composer/bindings/tabeditor.xml (content/composer/bindings/tabeditor.xml)
content/composer/composer.js (content/composer/composer.js)
* content/composer/composer.xul (content/composer/composer.xul)
content/composer/DI.png (content/composer/DI.png)
content/composer/dialogs/openLocation.js (content/composer/dialogs/openLocation.js)
content/composer/dialogs/openLocation.xul (content/composer/dialogs/openLocation.xul)
content/composer/dialogs/standaloneSidebar.js (content/composer/dialogs/standaloneSidebar.js)
content/composer/dialogs/standaloneSidebar.xul (content/composer/dialogs/standaloneSidebar.xul)
content/composer/EditorContent.css (content/composer/EditorContent.css)
content/composer/EditorOverride.css (content/composer/EditorOverride.css)
content/composer/mainCore.js (content/composer/mainCore.js)
@ -29,6 +33,8 @@ composer.jar:
skin/classic/composer/icons/stop.png (skin/classic/composer/icons/stop.png)
skin/classic/composer/logo-hover.png (skin/classic/composer/logo-hover.png)
skin/classic/composer/logo.png (skin/classic/composer/logo.png)
skin/classic/composer/sidebar.css (skin/classic/composer/sidebar.css)
skin/classic/composer/sidebarcontent.css (skin/classic/composer/sidebarcontent.css)
skin/classic/composer/tabeditor.css (skin/classic/composer/tabeditor.css)
composer-locale.jar:
@ -40,4 +46,4 @@ composer-locale.jar:
locale/en-US/composer/tabeditor.dtd (locale/en-US/composer/tabeditor.dtd)
* locale/en-US/branding/brand.dtd (locale/en-US/branding/brand.dtd)
locale/en-US/branding/brand.properties (locale/en-US/branding/brand.properties)
locale/en-US/composer/sidebar.dtd (locale/en-US/composer/sidebar.dtd)

Просмотреть файл

@ -0,0 +1,59 @@
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Composer.
-
- The Initial Developer of the Original Code is
- Disruptive Innovations SARL.
- Portions created by the Initial Developer are Copyright (C) 2006
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Daniel Glazman (daniel.glazman@disruptive-innovations.com), Original Author
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!ENTITY sidebar.title "Sidebar">
<!ENTITY actions.label "actions">
<!ENTITY closeMenu.label "Close">
<!ENTITY closeMenu.accesskey "c">
<!ENTITY moveUpMenu.label "Move up">
<!ENTITY moveUpMenu.accesskey "u">
<!ENTITY moveDownMenu.label "Move down">
<!ENTITY moveDownMenu.accesskey "d">
<!ENTITY moveOtherMenu.label "Move to other sidebar">
<!ENTITY moveOtherMenu.accesskey "d">
<!ENTITY detachMenu.label "Detach">
<!ENTITY detachMenu.accesskey "t">
<!ENTITY addSidebarContent.label "Add">
<!ENTITY addSidebarContent.tooltip "Add more content to this sidebar">
<!ENTITY closeSidebar.tooltip "Close sidebar">

Просмотреть файл

@ -11,7 +11,7 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Composer.
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
@ -35,6 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
@import url("chrome://composer/content/bindings/sidebar.css");
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
.toolbarbutton-1 {
@ -82,3 +84,7 @@ tabeditor {
#stopButton {
list-style-image: url("chrome://composer/skin/icons/stop.png");
}
sidebar {
width: 200px;
}

Просмотреть файл

@ -0,0 +1,78 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Glazman <daniel.glazman@disruptive-innovations.com>, Original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
label {
}
.titlebox {
padding-left: 0.5em;
font-size: smaller;
}
.sidebar-closebutton > .toolbarbutton-icon {
-moz-margin-end: 0px !important;
-moz-padding-end: 2px !important;
-moz-padding-start: 2px !important;
}
.sidebar-closebutton {
list-style-image: url("chrome://global/skin/icons/close.png");
-moz-appearance: none;
-moz-image-region: rect(0px, 16px, 16px, 0px);
padding: 4px 2px;
border: none !important;
}
.sidebar-closebutton:hover {
-moz-image-region: rect(0px, 32px, 16px, 16px);
}
.sidebar-closebutton:hover:active {
-moz-image-region: rect(0px, 48px, 16px, 32px);
}
.sidebar-morebutton {
border: thin groove;
-moz-border-radius: 3px;
-moz-margin-end: 4px;
}
.sidebar-morebutton > .toolbarbutton-menu-dropmarker {
-moz-margin-start: 2px;
}

Просмотреть файл

@ -0,0 +1,61 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Composer.
*
* The Initial Developer of the Original Code is
* Disruptive Innovations SARL.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Glazman <daniel.glazman@disruptive-innovations.com>, Original author
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
.sidebarcontent-name {
font-weight: bold;
}
label {
font-size: smaller;
}
.titlebox {
padding-left: 1em;
}
.sidebar-arrowbutton {
border: thin groove;
-moz-border-radius: 3px;
-moz-margin-end: 4px;
}
.sidebar-arrowbutton > .toolbarbutton-menu-dropmarker {
-moz-margin-start: 2px;
}

Просмотреть файл

@ -0,0 +1,57 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=us-ascii"
http-equiv="content-type">
<title>Developing a sidebar for Composer</title>
<style type="text/css">
body { font-family: Arial,Helvetica,sans-serif;
}
</style>
</head>
<body>
<h1>Developing a sidebar for Composer</h1>
<p>To offer new sidebar content to Composer users, you have to
distribute your application as an installable extension to
Composer, a *.xpi file.</p>
<p>The application id for Composer is
<code>{8fa6f1b4-7ed3-4895-bac6-01f1cc206ab3}</code> .</p>
<p>Your extension should add elements to
chrome://composer/content/composer.xul through a XUL overlay
:</p>
<ul>
<li>append a new <code>sidebaritem</code> element to
<code>&lt;sidebaritems id="sidebaritems"&gt;</code></li>
<li>that element must have an ID, unique in the ID name space
of composer.xul</li>
<li>that element must have a <code>name</code> attribute,
representing your sidebar content ; that sidebar should be a
NAME ; it is recommended that the ID and that attribute have
the same value</li>
<li>that element must have a <code>src</code> attribute,
containing the URL of the document to be shown in your
sidebar content; this is typically going to be a chrome URL
in your XPI</li>
<li>that element can have a&nbsp;<code>title</code>
containing a (possibly localized) string representing the
sidebar item. That string will be used in the sidebar to list
the available sidebar items or title the visible sidebar
items. If absent, the value of the <code>name</code>
attribute is used.</li>
</ul>
<h1>Make your sidebar observe editor events</h1>
<p>TBD</p>
</body>
</html>