gecko-dev/browser/components/places/content/places.xml

560 lines
23 KiB
XML
Executable File

<?xml version="1.0"?>
<bindings id="placesBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="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">
<!-- XXXben - replace this upon checkin by allowing generic textboxes to show
arbitrary content before the html:input itself using a
<children/> -->
<binding id="textbox-timed-arbitrary"
extends="chrome://global/content/bindings/textbox.xml#timed-textbox">
<resources>
<stylesheet src="chrome://browser/skin/places/places.css"/>
</resources>
<content>
<children/>
<xul:hbox class="textbox-input-box" flex="1" xbl:inherits="context">
<html:input class="textbox-input" flex="1" anonid="input"
xbl:inherits="onfocus,onblur,value,type,maxlength,disabled,size,readonly,tabindex,accesskey"/>
</xul:hbox>
<xul:hbox>
<xul:button class="textbox-input-closebutton"/>
</xul:hbox>
</content>
<implementation>
<property name="grayText"
onget="return this.getAttribute('grayText');"
onset="this.setAttribute('grayText', val); return val;"/>
<method name="reset">
<body><![CDATA[
this.setAttribute("empty", "true");
this.removeAttribute("filtered");
this.value = this.grayText;
]]></body>
</method>
<method name="_resetInternal">
<body><![CDATA[
this.value = "";
this.removeAttribute("empty");
this.removeAttribute("filtered");
]]></body>
</method>
<method name="_fireEvent">
<parameter name="type"/>
<body><![CDATA[
var event = document.createEvent("Events");
event.initEvent(type, true, true);
var cancel = !this.dispatchEvent(event);
var handler = this.getAttribute("on" + type);
if (handler) {
var handlerFunction = new Function("event", handler);
var handlerCanceled = handlerFunction(event) === false;
if (handlerCanceled)
cancel = handlerCanceled;
}
return !cancel;
]]></body>
</method>
<method name="_clearReliably">
<body><![CDATA[
// This method exists to clear the field's text. The reason this does
// not work reliably is unknown... appears to be some kind of event
// handling synchronization issue. We need to clear the field
// asynchronously.
var field = this;
setTimeout(function() {
field.value = "";
field.removeAttribute("empty");
}, 0);
]]></body>
</method>
<method name="onFocus">
<body><![CDATA[
if (this.hasAttribute("empty"))
this._clearReliably();
else
this.select();
]]></body>
</method>
<method name="onBlur">
<body><![CDATA[
if (this.hasAttribute("empty") || !this.value)
this.reset();
]]></body>
</method>
</implementation>
<handlers>
<handler event="focus" phase="capturing"><![CDATA[
if (event.originalTarget.className != "textbox-input-closebutton")
this.onFocus();
]]></handler>
<handler event="blur" phase="capturing"><![CDATA[
if (event.originalTarget.className != "textbox-input-closebutton")
this.onBlur();
]]></handler>
<handler event="click"><![CDATA[
if (event.originalTarget.className == "textbox-input-closebutton") {
this._resetInternal();
this._fireEvent("reset");
}
]]></handler>
<handler event="keypress" keycode="VK_ESCAPE"><![CDATA[
this._resetInternal();
this._fireEvent("reset");
]]></handler>
</handlers>
</binding>
<binding id="command-button" extends="chrome://global/content/bindings/button.xml#button">
<implementation>
<method name="updateActiveView">
<body><![CDATA[
if (this.hasAttribute("view"))
PlacesController.activeView = document.getElementById(this.getAttribute("view"));
]]></body>
</method>
</implementation>
<handlers>
<handler event="click" button="0" action="this.updateActiveView();"/>
<handler event="keypress" keycode="VK_SPACE" action="this.updateActiveView();"/>
</handlers>
</binding>
<binding id="filter-button" extends="chrome://global/content/bindings/button.xml#menu">
<content>
<xul:stack flex="1" class="box-inherit button-box">
<xul:image class="button-icon" xbl:inherits="src=image"/>
<xul:dropmarker class="button-menu-dropmarker" xbl:inherits="open,disabled"/>
</xul:stack>
<children includes="menupopup"/>
</content>
<handlers>
<handler event="command"><![CDATA[
PlacesSearchBox.filterCollection = event.target.getAttribute("value");
]]></handler>
</handlers>
</binding>
<binding id="calendar">
<content>
<xul:vbox class="calendar-box">
<xul:hbox class="calendar-header">
<xul:label anonid="prevmonth" class="calendar-month-jump">&#xab;</xul:label>
<xul:label anonid="monthtitle" class="calendar-month-title" flex="1"/>
<xul:label anonid="nextmonth" class="calendar-month-jump">&#xbb;</xul:label>
</xul:hbox>
<xul:tooltip anonid="calendartooltip">
<!-- FIXME -->
</xul:tooltip>
<xul:grid anonid="calendargrid" class="calendar-grid">
<xul:columns><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/></xul:columns>
<xul:rows>
<xul:row class="calendar-day-header">
<xul:label anonid="calendarhead0"></xul:label>
<xul:label anonid="calendarhead1"></xul:label>
<xul:label anonid="calendarhead2"></xul:label>
<xul:label anonid="calendarhead3"></xul:label>
<xul:label anonid="calendarhead4"></xul:label>
<xul:label anonid="calendarhead5"></xul:label>
<xul:label anonid="calendarhead6"></xul:label>
</xul:row>
<!-- The "00" is so that the table has the correct dimensions (most
numbers are the same width) when it is first displayed. The
default definition for "calendar-day" should have the same color
fore- and background so you won't see this. -->
<xul:row>
<xul:label anonid="calendar0" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar1" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar2" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar3" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar4" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar5" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar6" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar7" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar8" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar9" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar10" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar11" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar12" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar13" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar14" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar15" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar16" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar17" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar18" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar19" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar20" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar21" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar22" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar23" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar24" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar25" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar26" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar27" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar28" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar29" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar30" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar31" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar32" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar33" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar34" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar35" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar36" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar37" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar38" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar39" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar40" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar41" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
</xul:rows>
</xul:grid>
</xul:vbox>
</content>
<implementation>
<constructor><![CDATA[
var grid = document.getAnonymousElementByAttribute(this, "anonid",
"calendargrid");
this._numCells = 42; // max number of cells displayable in the calendar
this._cellPrefix = "calendar"; // value before the number in the ID of cells
this._currentMonth = -1;
this._currentYear = -1;
this._cell0Date = null; // date for top left of calendar
this._selectNothing = false;
this._selectBegin = null;
this._selectEnd = null;
// localized stuff, FIXME: move somewhere else
this._pref_firstDayOfWeek = 0; // 0 = Sunday, 1 = Monday
this._pref_dayHeaders = ["S", "M", "T", "W", "T", "F", "S"];
this._pref_shortMonthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
// day headers
for (var i = 0; i < 7; i ++) {
var cell = document.getAnonymousElementByAttribute(this, "anonid",
"calendarhead" + i);
cell.value = this._pref_dayHeaders[i];
}
// cell item
var calendargrid = document.getAnonymousElementByAttribute(this, "anonid", "calendargrid");
this._days = new Array(this._numCells);
this._selected = new Array(this._numCells);
for (var i = 0; i < this._numCells; i ++) {
this._days[i] = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + i);
this._selected[i] = false;
}
// month navigation hooks
var myself = this;
document.getAnonymousElementByAttribute(this, "anonid", "prevmonth").
addEventListener("click", function() { myself.jumpMonth(-1); }, false);
document.getAnonymousElementByAttribute(this, "anonid", "nextmonth").
addEventListener("click", function() { myself.jumpMonth(1); }, false);
// day selection hooks
calendargrid.addEventListener("mousedown", function(event) { myself.mouseDown(event); }, false);
calendargrid.addEventListener("mouseup", function(event) { myself.mouseUp(event); }, false);
calendargrid.addEventListener("mousemove", function(event) { myself.mouseMove(event); }, false);
this.visibleMonth = new Date(); // today
]]></constructor>
<property name="visibleMonth">
<getter>
return new Date(this._visibleMonth);
</getter>
<setter>
this._visibleMonth = new Date(val.getFullYear(), val.getMonth(), 1);
this.drawMonth();
</setter>
</property>
<property name="beginrange">
<getter>
if (! this._selectBegin)
return null;
else
return new Date(this._selectBegin);
</getter>
<setter>
this._selectNothing = false;
this._selectBegin = val;
this.updateSelection(this._selectBegin, this._selectEnd);
this.fireRangeEvent();
</setter>
</property>
<property name="endrange">
<getter>
if (! this._selectEnd)
return null;
else
return new Date(this._selectEnd);
</getter>
<setter>
this._selectNothing = false;
this._selectEnd = val;
this.updateSelection(this._selectBegin, this._selectEnd);
this.fireRangeEvent();
</setter>
</property>
<!-- Use this to set the range at once. It will be more efficient than
setting begin and end independently since there will be only one
redraw. Set updateVisible to have the calendar change the active
month if necessary. -->
<method name="setRange">
<parameter name="begin"/>
<parameter name="end"/>
<parameter name="updateVisible"/>
<body><![CDATA[
if (updateVisible && end) {
// this just tries to make the end range visible. If there is no
// end range, we don't do anything. We might want to set the visible
// month to the begin range in this case, but I don't think this
// situation arises in practice.
var daysToEnd = this.daysBetweenDates(end, this._cell0Date);
if (daysToEnd < 0 || daysToEnd >= this._numCells) {
// reselect month for end range
this.visibleMonth = end;
}
}
this._selectNothing = false;
this.updateSelection(begin, end);
this.fireRangeEvent();
]]></body>
</method>
<!-- Normally, null begin and end means select all, so you can set
this if you don't want anything selected.-->
<property name="selectNothing">
<getter>
return this._selectNothing;
</getter>
<setter>
this._selectNothing = val;
</setter>
</property>
<!--===== jumpMonth =====-->
<method name="jumpMonth">
<parameter name="relative"/>
<body><![CDATA[
var newMonth = this._visibleMonth.getMonth() + relative;
var newYear = this._visibleMonth.getFullYear() + Math.floor(newMonth / 12);
newMonth = (newMonth + 12) % 12;
this._visibleMonth = new Date(newYear, newMonth, 1);
this.drawMonth();
]]></body>
</method>
<!--===== mouseDown =====-->
<method name="mouseDown">
<parameter name="event"/>
<body><![CDATA[
var date = this.cellToDate(event.target.getAttribute("anonid"));
if (! date)
return;
this._selectNothing = false;
this._dragging = true;
this._mouseDownOn = date;
this.updateSelection(date, date);
]]></body>
</method>
<!--===== mouseUp =====-->
<method name="mouseUp">
<parameter name="event"/>
<body><![CDATA[
this._dragging = false;
this.fireRangeEvent();
]]></body>
</method>
<!--===== mouseMove =====-->
<method name="mouseMove">
<parameter name="event"/>
<body><![CDATA[
if (! this._dragging)
return;
var date = this.cellToDate(event.target.getAttribute("anonid"));
if (! date)
return;
this.updateSelection(this._mouseDownOn, date);
]]></body>
</method>
<!--===== updateSelection =====-->
<method name="updateSelection">
<parameter name="begin"/>
<parameter name="end"/>
<body><![CDATA[
var realBegin = begin;
var realEnd = end;
if (begin && end && begin.getTime() > end.getTime()) {
this._selectBegin = end;
this._selectEnd = begin;
} else {
this._selectBegin = begin;
this._selectEnd = end;
}
this.drawSelection();
]]></body>
</method>
<!--===== daysBetweenDates =====-->
<method name="daysBetweenDates">
<parameter name="a"/>
<parameter name="b"/>
<body>
var msDiff = a.getTime() - b.getTime();
return Math.floor(msDiff / 86400000); // 1000ms/s * 60s/m * 60m/h * 24h/d = 86400000ms/d
</body>
</method>
<!--===== suppressRangeEvents =====-->
<field name="suppressRangeEvents">false</field>
<!--===== fireRangeEvent =====-->
<method name="fireRangeEvent"><body><![CDATA[
if (this.suppressRangeEvents)
return true;
var event = document.createEvent("Events");
event.initEvent("selectionchanged", false, true);
// handle dom event handlers
var noCancel = this.dispatchEvent(event);
// handle any xml attribute event handlers
var handler = this.getAttribute("onselectionchanged");
if (handler != "") {
var fn = new Function("event", handler);
var returned = fn(event);
if (returned == false)
noCancel = false;
}
return noCancel;
]]></body></method>
<!--===== drawSelection =====-->
<method name="drawSelection"><body><![CDATA[
var beginIndex;
var endIndex;
if (this._selectNothing) {
beginIndex = -1;
endIndex = -1;
} else {
if (! this._selectBegin) {
beginIndex = 0;
} else {
beginIndex = this.daysBetweenDates(this._selectBegin, this._cell0Date);
}
if (! this._selectEnd) {
endIndex = this._numCells - 1;
} else {
endIndex = this.daysBetweenDates(this._selectEnd, this._cell0Date);
}
}
for (var i = 0; i < this._numCells; i ++) {
var sel = (i >= beginIndex && i <= endIndex);
if (sel != this._selected[i]) {
this._days[i].setAttribute("selected", sel ? "true" : "");
this._selected[i] = sel;
}
}
]]></body></method>
<!--===== cellToDate =====-->
<method name="cellToDate">
<parameter name="cellName"/>
<body><![CDATA[
if (! cellName)
return null;
var tail = cellName.substring(this._cellPrefix.length);
if (tail[0] < "0" || tail[0] > '9') {
return null;
}
var cellNumber = Number(tail);
var d = new Date(this._cell0Date);
d.setDate(d.getDate() + cellNumber);
return d;
]]></body>
</method>
<!--===== drawMonth =====-->
<method name="drawMonth"><body><![CDATA[
var curCell = 0;
var monthIndex = this._visibleMonth.getMonth();
var yearNumber = this._visibleMonth.getFullYear();
var firstOfMonth = new Date(yearNumber, monthIndex, 1);
// update title
document.getAnonymousElementByAttribute(this, "anonid", "monthtitle").value =
this._pref_shortMonthNames[monthIndex] + " " + yearNumber;
// first, fill in any days of the previous month in the first week
var numPrefixDays = firstOfMonth.getDay() - this._pref_firstDayOfWeek;
var curDay = firstOfMonth;
curDay.setDate(firstOfMonth.getDate() - numPrefixDays);
this._cell0Date = new Date(curDay); // save the first cell
for (var i = 0; i < numPrefixDays; i ++) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "other");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
// now fill in the rest of this month
while (curDay.getMonth() == monthIndex) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "this");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
// fill out the end of this week with next month
while (curDay.getDay() != this._pref_firstDayOfWeek) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "other");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
// fill the bottom row with days from the next month
while (curCell < this._numCells) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "other");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
this.drawSelection();
]]></body></method>
</implementation>
</binding> <!-- end calendar -->
</bindings>