3616 changed files with 338155 additions and 44462 deletions
@ -0,0 +1,505 @@
|
||||
dojo.provide("dijit.Calendar"); |
||||
|
||||
dojo.require("dojo.cldr.supplemental"); |
||||
dojo.require("dojo.date"); |
||||
dojo.require("dojo.date.locale"); |
||||
|
||||
dojo.require("dijit._Widget"); |
||||
dojo.require("dijit._Templated"); |
||||
dojo.require("dijit._CssStateMixin"); |
||||
|
||||
dojo.declare( |
||||
"dijit.Calendar", |
||||
[dijit._Widget, dijit._Templated, dijit._CssStateMixin], |
||||
{ |
||||
// summary:
|
||||
// A simple GUI for choosing a date in the context of a monthly calendar.
|
||||
//
|
||||
// description:
|
||||
// A simple GUI for choosing a date in the context of a monthly calendar.
|
||||
// This widget can't be used in a form because it doesn't serialize the date to an
|
||||
// `<input>` field. For a form element, use dijit.form.DateTextBox instead.
|
||||
//
|
||||
// Note that the parser takes all dates attributes passed in the
|
||||
// [RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
|
||||
// so that they are serializable and locale-independent.
|
||||
//
|
||||
// example:
|
||||
// | var calendar = new dijit.Calendar({}, dojo.byId("calendarNode"));
|
||||
//
|
||||
// example:
|
||||
// | <div dojoType="dijit.Calendar"></div>
|
||||
|
||||
templateString: dojo.cache("dijit", "templates/Calendar.html"), |
||||
|
||||
// value: Date
|
||||
// The currently selected Date
|
||||
value: new Date(), |
||||
|
||||
// datePackage: String
|
||||
// JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines
|
||||
// at dojo.date by default.
|
||||
datePackage: "dojo.date", |
||||
|
||||
// dayWidth: String
|
||||
// How to represent the days of the week in the calendar header. See dojo.date.locale
|
||||
dayWidth: "narrow", |
||||
|
||||
// tabIndex: Integer
|
||||
// Order fields are traversed when user hits the tab key
|
||||
tabIndex: "0", |
||||
|
||||
baseClass:"dijitCalendar", |
||||
|
||||
// Set node classes for various mouse events, see dijit._CssStateMixin for more details
|
||||
cssStateNodes: { |
||||
"decrementMonth": "dijitCalendarArrow", |
||||
"incrementMonth": "dijitCalendarArrow", |
||||
"previousYearLabelNode": "dijitCalendarPreviousYear", |
||||
"nextYearLabelNode": "dijitCalendarNextYear"
|
||||
}, |
||||
|
||||
attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, { |
||||
tabIndex: "domNode" |
||||
}), |
||||
|
||||
setValue: function(/*Date*/ value){ |
||||
// summary:
|
||||
// Deprecated. Used attr('value', ...) instead.
|
||||
// tags:
|
||||
// deprecated
|
||||
dojo.deprecated("dijit.Calendar:setValue() is deprecated. Use set('value', ...) instead.", "", "2.0"); |
||||
this.set('value', value); |
||||
}, |
||||
|
||||
_getValueAttr: function(){ |
||||
// summary:
|
||||
// Support getter attr('value')
|
||||
var value = new this.dateClassObj(this.value); |
||||
value.setHours(0, 0, 0, 0); // return midnight, local time for back-compat
|
||||
|
||||
// If daylight savings pushes midnight to the previous date, fix the Date
|
||||
// object to point at 1am so it will represent the correct day. See #9366
|
||||
if(value.getDate() < this.value.getDate()){ |
||||
value = this.dateFuncObj.add(value, "hour", 1); |
||||
} |
||||
return value; |
||||
}, |
||||
|
||||
_setValueAttr: function(/*Date*/ value){ |
||||
// summary:
|
||||
// Support setter attr("value", ...)
|
||||
// description:
|
||||
// Set the current date and update the UI. If the date is disabled, the value will
|
||||
// not change, but the display will change to the corresponding month.
|
||||
// tags:
|
||||
// protected
|
||||
if(!this.value || this.dateFuncObj.compare(value, this.value)){ |
||||
value = new this.dateClassObj(value); |
||||
value.setHours(1); // to avoid issues when DST shift occurs at midnight, see #8521, #9366
|
||||
this.displayMonth = new this.dateClassObj(value); |
||||
if(!this.isDisabledDate(value, this.lang)){ |
||||
this.value = value; |
||||
this.onChange(this.get('value')); |
||||
} |
||||
dojo.attr(this.domNode, "aria-label", |
||||
this.dateLocaleModule.format(value, |
||||
{selector:"date", formatLength:"full"})); |
||||
this._populateGrid(); |
||||
} |
||||
}, |
||||
|
||||
_setText: function(node, text){ |
||||
// summary:
|
||||
// This just sets the content of node to the specified text.
|
||||
// Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
|
||||
// tags:
|
||||
// private
|
||||
while(node.firstChild){ |
||||
node.removeChild(node.firstChild); |
||||
} |
||||
node.appendChild(dojo.doc.createTextNode(text)); |
||||
}, |
||||
|
||||
_populateGrid: function(){ |
||||
// summary:
|
||||
// Fills in the calendar grid with each day (1-31)
|
||||
// tags:
|
||||
// private
|
||||
var month = this.displayMonth; |
||||
month.setDate(1); |
||||
var firstDay = month.getDay(), |
||||
daysInMonth = this.dateFuncObj.getDaysInMonth(month), |
||||
daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)), |
||||
today = new this.dateClassObj(), |
||||
dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang); |
||||
if(dayOffset > firstDay){ dayOffset -= 7; } |
||||
|
||||
// Iterate through dates in the calendar and fill in date numbers and style info
|
||||
dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){ |
||||
i += dayOffset; |
||||
var date = new this.dateClassObj(month), |
||||
number, clazz = "dijitCalendar", adj = 0; |
||||
|
||||
if(i < firstDay){ |
||||
number = daysInPreviousMonth - firstDay + i + 1; |
||||
adj = -1; |
||||
clazz += "Previous"; |
||||
}else if(i >= (firstDay + daysInMonth)){ |
||||
number = i - firstDay - daysInMonth + 1; |
||||
adj = 1; |
||||
clazz += "Next"; |
||||
}else{ |
||||
number = i - firstDay + 1; |
||||
clazz += "Current"; |
||||
} |
||||
|
||||
if(adj){ |
||||
date = this.dateFuncObj.add(date, "month", adj); |
||||
} |
||||
date.setDate(number); |
||||
|
||||
if(!this.dateFuncObj.compare(date, today, "date")){ |
||||
clazz = "dijitCalendarCurrentDate " + clazz; |
||||
} |
||||
|
||||
if(this._isSelectedDate(date, this.lang)){ |
||||
clazz = "dijitCalendarSelectedDate " + clazz; |
||||
} |
||||
|
||||
if(this.isDisabledDate(date, this.lang)){ |
||||
clazz = "dijitCalendarDisabledDate " + clazz; |
||||
} |
||||
|
||||
var clazz2 = this.getClassForDate(date, this.lang); |
||||
if(clazz2){ |
||||
clazz = clazz2 + " " + clazz; |
||||
} |
||||
|
||||
template.className = clazz + "Month dijitCalendarDateTemplate"; |
||||
template.dijitDateValue = date.valueOf(); |
||||
var label = dojo.query(".dijitCalendarDateLabel", template)[0], |
||||
text = date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate(); |
||||
this._setText(label, text); |
||||
}, this); |
||||
|
||||
// Fill in localized month name
|
||||
var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month); |
||||
this._setText(this.monthLabelNode, monthNames[month.getMonth()]); |
||||
// Repopulate month list based on current year (Hebrew calendar)
|
||||
dojo.query(".dijitCalendarMonthLabelTemplate", this.domNode).forEach(function(node, i){ |
||||
dojo.toggleClass(node, "dijitHidden", !(i in monthNames)); // hide leap months (Hebrew)
|
||||
this._setText(node, monthNames[i]); |
||||
}, this); |
||||
|
||||
// Fill in localized prev/current/next years
|
||||
var y = month.getFullYear() - 1; |
||||
var d = new this.dateClassObj(); |
||||
dojo.forEach(["previous", "current", "next"], function(name){ |
||||
d.setFullYear(y++); |
||||
this._setText(this[name+"YearLabelNode"], |
||||
this.dateLocaleModule.format(d, {selector:'year', locale:this.lang})); |
||||
}, this); |
||||
}, |
||||
|
||||
goToToday: function(){ |
||||
// summary:
|
||||
// Sets calendar's value to today's date
|
||||
this.set('value', new this.dateClassObj()); |
||||
}, |
||||
|
||||
constructor: function(/*Object*/args){ |
||||
var dateClass = (args.datePackage && (args.datePackage != "dojo.date"))? args.datePackage + ".Date" : "Date"; |
||||
this.dateClassObj = dojo.getObject(dateClass, false); |
||||
this.datePackage = args.datePackage || this.datePackage; |
||||
this.dateFuncObj = dojo.getObject(this.datePackage, false); |
||||
this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false); |
||||
}, |
||||
|
||||
postMixInProperties: function(){ |
||||
// parser.instantiate sometimes passes in NaN for IE. Use default value in prototype instead.
|
||||
if(isNaN(this.value)){ delete this.value; } |
||||
this.inherited(arguments); |
||||
}, |
||||
|
||||
postCreate: function(){ |
||||
this.inherited(arguments); |
||||
dojo.setSelectable(this.domNode, false); |
||||
|
||||
var cloneClass = dojo.hitch(this, function(clazz, n){ |
||||
var template = dojo.query(clazz, this.domNode)[0]; |
||||
for(var i=0; i<n; i++){ |
||||
template.parentNode.appendChild(template.cloneNode(true)); |
||||
} |
||||
}); |
||||
|
||||
// clone the day label and calendar day templates 6 times to make 7 columns
|
||||
cloneClass(".dijitCalendarDayLabelTemplate", 6); |
||||
cloneClass(".dijitCalendarDateTemplate", 6); |
||||
|
||||
// now make 6 week rows
|
||||
cloneClass(".dijitCalendarWeekTemplate", 5); |
||||
|
||||
// insert localized day names in the header
|
||||
var dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang); |
||||
var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang); |
||||
dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){ |
||||
this._setText(label, dayNames[(i + dayOffset) % 7]); |
||||
}, this); |
||||
|
||||
var dateObj = new this.dateClassObj(this.value); |
||||
// Fill in spacer/month dropdown element with all the month names (invisible) so that the maximum width will affect layout
|
||||
var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, dateObj); |
||||
cloneClass(".dijitCalendarMonthLabelTemplate", monthNames.length-1); |
||||
dojo.query(".dijitCalendarMonthLabelTemplate", this.domNode).forEach(function(node, i){ |
||||
dojo.attr(node, "month", i); |
||||
if(i in monthNames){ this._setText(node, monthNames[i]); } |
||||
dojo.place(node.cloneNode(true), this.monthLabelSpacer); |
||||
}, this); |
||||
|
||||
this.value = null; |
||||
this.set('value', dateObj); |
||||
|
||||
// Set up repeating mouse behavior
|
||||
var _this = this; |
||||
var typematic = function(nodeProp, dateProp, adj){ |
||||
_this._connects.push( |
||||
dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){ |
||||
if(count >= 0){ _this._adjustDisplay(dateProp, adj); } |
||||
}, 0.8, 500) |
||||
); |
||||
}; |
||||
typematic("incrementMonth", "month", 1); |
||||
typematic("decrementMonth", "month", -1); |
||||
typematic("nextYearLabelNode", "year", 1); |
||||
typematic("previousYearLabelNode", "year", -1); |
||||
}, |
||||
|
||||
_onMenuHover: function(e){ |
||||
dojo.stopEvent(e); |
||||
dojo.toggleClass(e.target, "dijitMenuItemHover"); |
||||
}, |
||||
|
||||
_adjustDisplay: function(/*String*/ part, /*int*/ amount){ |
||||
// summary:
|
||||
// Moves calendar forwards or backwards by months or years
|
||||
// part:
|
||||
// "month" or "year"
|
||||
// amount:
|
||||
// Number of months or years
|
||||
// tags:
|
||||
// private
|
||||
this.displayMonth = this.dateFuncObj.add(this.displayMonth, part, amount); |
||||
this._populateGrid(); |
||||
}, |
||||
|
||||
_onMonthToggle: function(/*Event*/ evt){ |
||||
// summary:
|
||||
// Handler for when user triggers or dismisses the month list
|
||||
// tags:
|
||||
// protected
|
||||
dojo.stopEvent(evt); |
||||
|
||||
if(evt.type == "mousedown"){ |
||||
var coords = dojo.position(this.monthLabelNode); |
||||
// coords.y -= dojo.position(this.domNode, true).y;
|
||||
// Size the dropdown's width to match the label in the widget
|
||||
// so that they are horizontally aligned
|
||||
var dim = { |
||||
width: coords.w + "px", |
||||
top: -this.displayMonth.getMonth() * coords.h + "px" |
||||
}; |
||||
if((dojo.isIE && dojo.isQuirks) || dojo.isIE < 7){ |
||||
dim.left = -coords.w/2 + "px"; |
||||
} |
||||
dojo.style(this.monthDropDown, dim); |
||||
this._popupHandler = this.connect(document, "onmouseup", "_onMonthToggle"); |
||||
}else{ |
||||
this.disconnect(this._popupHandler); |
||||
delete this._popupHandler; |
||||
} |
||||
|
||||
dojo.toggleClass(this.monthDropDown, "dijitHidden"); |
||||
dojo.toggleClass(this.monthLabelNode, "dijitVisible"); |
||||
}, |
||||
|
||||
_onMonthSelect: function(/*Event*/ evt){ |
||||
// summary:
|
||||
// Handler for when user selects a month from a list
|
||||
// tags:
|
||||
// protected
|
||||
this._onMonthToggle(evt); |
||||
this.displayMonth.setMonth(dojo.attr(evt.target, "month")); |
||||
this._populateGrid(); |
||||
}, |
||||
|
||||
_onDayClick: function(/*Event*/ evt){ |
||||
// summary:
|
||||
// Handler for day clicks, selects the date if appropriate
|
||||
// tags:
|
||||
// protected
|
||||
dojo.stopEvent(evt); |
||||
for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode); |
||||
if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){ |
||||
this.set('value', node.dijitDateValue); |
||||
this.onValueSelected(this.get('value')); |
||||
} |
||||
}, |
||||
|
||||
_onDayMouseOver: function(/*Event*/ evt){ |
||||
// summary:
|
||||
// Handler for mouse over events on days, sets hovered style
|
||||
// tags:
|
||||
// protected
|
||||
|
||||
// event can occur on <td> or the <span> inside the td,
|
||||
// set node to the <td>.
|
||||
var node = |
||||
dojo.hasClass(evt.target, "dijitCalendarDateLabel") ? |
||||
evt.target.parentNode : |
||||
evt.target; |
||||
|
||||
if(node && (node.dijitDateValue || node == this.previousYearLabelNode || node == this.nextYearLabelNode) ){ |
||||
dojo.addClass(node, "dijitCalendarHoveredDate"); |
||||
this._currentNode = node; |
||||
} |
||||
}, |
||||
|
||||
_onDayMouseOut: function(/*Event*/ evt){ |
||||
// summary:
|
||||
// Handler for mouse out events on days, clears hovered style
|
||||
// tags:
|
||||
// protected
|
||||
|
||||
if(!this._currentNode){ return; } |
||||
|
||||
// if mouse out occurs moving from <td> to <span> inside <td>, ignore it
|
||||
if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; } |
||||
|
||||
dojo.removeClass(this._currentNode, "dijitCalendarHoveredDate"); |
||||
if(dojo.hasClass(this._currentNode, "dijitCalendarActiveDate")) { |
||||
dojo.removeClass(this._currentNode, "dijitCalendarActiveDate"); |
||||
} |
||||
this._currentNode = null; |
||||
}, |
||||
|
||||
_onDayMouseDown: function(/*Event*/ evt){ |
||||
var node = evt.target.parentNode; |
||||
if(node && node.dijitDateValue){ |
||||
dojo.addClass(node, "dijitCalendarActiveDate"); |
||||
this._currentNode = node; |
||||
} |
||||
}, |
||||
|
||||
_onDayMouseUp: function(/*Event*/ evt){ |
||||
var node = evt.target.parentNode; |
||||
if(node && node.dijitDateValue){ |
||||
dojo.removeClass(node, "dijitCalendarActiveDate"); |
||||
} |
||||
}, |
||||
|
||||
//TODO: use typematic
|
||||
//TODO: skip disabled dates without ending up in a loop
|
||||
//TODO: could optimize by avoiding populate grid when month does not change
|
||||
_onKeyPress: function(/*Event*/evt){ |
||||
// summary:
|
||||
// Provides keyboard navigation of calendar
|
||||
// tags:
|
||||
// protected
|
||||
var dk = dojo.keys, |
||||
increment = -1, |
||||
interval, |
||||
newValue = this.value; |
||||
switch(evt.keyCode){ |
||||
case dk.RIGHT_ARROW: |
||||
increment = 1; |
||||
//fallthrough...
|
||||
case dk.LEFT_ARROW: |
||||
interval = "day"; |
||||
if(!this.isLeftToRight()){ increment *= -1; } |
||||
break; |
||||
case dk.DOWN_ARROW: |
||||
increment = 1; |
||||
//fallthrough...
|
||||
case dk.UP_ARROW: |
||||
interval = "week"; |
||||
break; |
||||
case dk.PAGE_DOWN: |
||||
increment = 1; |
||||
//fallthrough...
|
||||
case dk.PAGE_UP: |
||||
interval = evt.ctrlKey ? "year" : "month"; |
||||
break; |
||||
case dk.END: |
||||
// go to the next month
|
||||
newValue = this.dateFuncObj.add(newValue, "month", 1); |
||||
// subtract a day from the result when we're done
|
||||
interval = "day"; |
||||
//fallthrough...
|
||||
case dk.HOME: |
||||
newValue = new Date(newValue).setDate(1); |
||||
break; |
||||
case dk.ENTER: |
||||
this.onValueSelected(this.get('value')); |
||||
break; |
||||
case dk.ESCAPE: |
||||
//TODO
|
||||
default: |
||||
return; |
||||
} |
||||
dojo.stopEvent(evt); |
||||
|
||||
if(interval){ |
||||
newValue = this.dateFuncObj.add(newValue, interval, increment); |
||||
} |
||||
|
||||
this.set("value", newValue); |
||||
}, |
||||
|
||||
onValueSelected: function(/*Date*/ date){ |
||||
// summary:
|
||||
// Notification that a date cell was selected. It may be the same as the previous value.
|
||||
// description:
|
||||
// Used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
|
||||
// to get notification when the user has clicked a date.
|
||||
// tags:
|
||||
// protected
|
||||
}, |
||||
|
||||
onChange: function(/*Date*/ date){ |
||||
// summary:
|
||||
// Called only when the selected date has changed
|
||||
}, |
||||
|
||||
_isSelectedDate: function(/*Date*/ dateObject, /*String?*/ locale){ |
||||
// summary:
|
||||
// Extension point so developers can subclass Calendar to
|
||||
// support multiple (concurrently) selected dates
|
||||
// tags:
|
||||
// protected extension
|
||||
return !this.dateFuncObj.compare(dateObject, this.value, "date") |
||||
}, |
||||
|
||||
isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){ |
||||
// summary:
|
||||
// May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
|
||||
// tags:
|
||||
// extension
|
||||
/*===== |
||||
return false; // Boolean
|
||||
=====*/ |
||||
}, |
||||
|
||||
getClassForDate: function(/*Date*/ dateObject, /*String?*/ locale){ |
||||
// summary:
|
||||
// May be overridden to return CSS classes to associate with the date entry for the given dateObject,
|
||||
// for example to indicate a holiday in specified locale.
|
||||
// tags:
|
||||
// extension
|
||||
|
||||
/*===== |
||||
return ""; // String
|
||||
=====*/ |
||||
} |
||||
} |
||||
); |
@ -0,0 +1,43 @@
|
||||
dojo.provide("dijit.CheckedMenuItem"); |
||||
|
||||
dojo.require("dijit.MenuItem"); |
||||
|
||||
dojo.declare("dijit.CheckedMenuItem", |
||||
dijit.MenuItem, |
||||
{ |
||||
// summary:
|
||||
// A checkbox-like menu item for toggling on and off
|
||||
|
||||
templateString: dojo.cache("dijit", "templates/CheckedMenuItem.html"), |
||||
|
||||
// checked: Boolean
|
||||
// Our checked state
|
||||
checked: false, |
||||
_setCheckedAttr: function(/*Boolean*/ checked){ |
||||
// summary:
|
||||
// Hook so attr('checked', bool) works.
|
||||
// Sets the class and state for the check box.
|
||||
dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked); |
||||
dijit.setWaiState(this.domNode, "checked", checked); |
||||
this.checked = checked; |
||||
}, |
||||
|
||||
onChange: function(/*Boolean*/ checked){ |
||||
// summary:
|
||||
// User defined function to handle check/uncheck events
|
||||
// tags:
|
||||
// callback
|
||||
}, |
||||
|
||||
_onClick: function(/*Event*/ e){ |
||||
// summary:
|
||||
// Clicking this item just toggles its state
|
||||
// tags:
|
||||
// private
|
||||
if(!this.disabled){ |
||||
this.set("checked", !this.checked); |
||||
this.onChange(this.checked); |
||||
} |
||||
this.inherited(arguments); |
||||
} |
||||
}); |
@ -0,0 +1,109 @@
|
||||
dojo.provide("dijit.ColorPalette"); |
||||
|
||||
dojo.require("dijit._Widget"); |
||||
dojo.require("dijit._Templated"); |
||||
dojo.require("dojo.colors"); |
||||
dojo.require("dojo.i18n"); |
||||
|
||||
dojo.require("dijit._PaletteMixin"); |
||||
|
||||
dojo.requireLocalization("dojo", "colors"); |
||||
|
||||
dojo.declare("dijit.ColorPalette", |
||||
[dijit._Widget, dijit._Templated, dijit._PaletteMixin], |
||||
{ |
||||
// summary:
|
||||
// A keyboard accessible color-picking widget
|
||||
// description:
|
||||
// Grid showing various colors, so the user can pick a certain color.
|
||||
// Can be used standalone, or as a popup.
|
||||
//
|
||||
// example:
|
||||
// | <div dojoType="dijit.ColorPalette"></div>
|
||||
//
|
||||
// example:
|
||||
// | var picker = new dijit.ColorPalette({ },srcNode);
|
||||
// | picker.startup();
|
||||
|
||||
|
||||
// palette: String
|
||||
// Size of grid, either "7x10" or "3x4".
|
||||
palette: "7x10", |
||||
|
||||
// _palettes: [protected] Map
|
||||
// This represents the value of the colors.
|
||||
// The first level is a hashmap of the different palettes available.
|
||||
// The next two dimensions represent the columns and rows of colors.
|
||||
_palettes: { |
||||
"7x10": [["white", "seashell", "cornsilk", "lemonchiffon","lightyellow", "palegreen", "paleturquoise", "lightcyan", "lavender", "plum"], |
||||
["lightgray", "pink", "bisque", "moccasin", "khaki", "lightgreen", "lightseagreen", "lightskyblue", "cornflowerblue", "violet"], |
||||
["silver", "lightcoral", "sandybrown", "orange", "palegoldenrod", "chartreuse", "mediumturquoise", "skyblue", "mediumslateblue","orchid"], |
||||
["gray", "red", "orangered", "darkorange", "yellow", "limegreen", "darkseagreen", "royalblue", "slateblue", "mediumorchid"], |
||||
["dimgray", "crimson", "chocolate", "coral", "gold", "forestgreen", "seagreen", "blue", "blueviolet", "darkorchid"], |
||||
["darkslategray","firebrick","saddlebrown", "sienna", "olive", "green", "darkcyan", "mediumblue","darkslateblue", "darkmagenta" ], |
||||
["black", "darkred", "maroon", "brown", "darkolivegreen", "darkgreen", "midnightblue", "navy", "indigo", "purple"]], |
||||
|
||||
"3x4": [["white", "lime", "green", "blue"], |
||||
["silver", "yellow", "fuchsia", "navy"], |
||||
["gray", "red", "purple", "black"]] |
||||
}, |
||||
|
||||
// _imagePaths: [protected] Map
|
||||
// This is stores the path to the palette images
|
||||
_imagePaths: { |
||||
"7x10": dojo.moduleUrl("dijit.themes", "a11y/colors7x10.png"), |
||||
"3x4": dojo.moduleUrl("dijit.themes", "a11y/colors3x4.png"), |
||||
"7x10-rtl": dojo.moduleUrl("dijit.themes", "a11y/colors7x10-rtl.png"), |
||||
"3x4-rtl": dojo.moduleUrl("dijit.themes", "a11y/colors3x4-rtl.png") |
||||
}, |
||||
|
||||
// templateString: String
|
||||
// The template of this widget.
|
||||
templateString: dojo.cache("dijit", "templates/ColorPalette.html"), |
||||
|
||||
baseClass: "dijitColorPalette", |
||||
|
||||
dyeClass: 'dijit._Color', |
||||
|
||||
buildRendering: function(){ |
||||
// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
|
||||
// <img> nodes
|
||||
|
||||
this.inherited(arguments); |
||||
|
||||
this.imageNode.setAttribute("src", this._imagePaths[this.palette + (this.isLeftToRight() ? "" : "-rtl")].toString()); |
||||
|
||||
var i18nColorNames = dojo.i18n.getLocalization("dojo", "colors", this.lang); |
||||
this._preparePalette( |
||||
this._palettes[this.palette], |
||||
i18nColorNames |
||||
); |
||||
} |
||||
}); |
||||
|
||||
dojo.declare("dijit._Color", dojo.Color, |
||||
// summary:
|
||||
// Object associated with each cell in a ColorPalette palette.
|
||||
// Implements dijit.Dye.
|
||||
{ |
||||
constructor: function(/*String*/alias){ |
||||
this._alias = alias; |
||||
this.setColor(dojo.Color.named[alias]); |
||||
}, |
||||
|
||||
getValue: function(){ |
||||
// summary:
|
||||
// Note that although dijit._Color is initialized with a value like "white" getValue() always
|
||||
// returns a hex value
|
||||
return this.toHex(); |
||||
}, |
||||
|
||||
fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){ |
||||
dojo.create("img", { |
||||
src: blankGif, |
||||
"class": "dijitPaletteImg", |
||||
alt: this._alias |
||||
}, cell); |
||||
} |
||||
} |
||||
); |
@ -0,0 +1,90 @@
|
||||
dojo.provide("dijit.Declaration"); |
||||
dojo.require("dijit._Widget"); |
||||
dojo.require("dijit._Templated"); |
||||
|
||||
dojo.declare( |
||||
"dijit.Declaration", |
||||
dijit._Widget, |
||||
{ |
||||
// summary:
|
||||
// The Declaration widget allows a developer to declare new widget
|
||||
// classes directly from a snippet of markup.
|
||||
|
||||
// _noScript: [private] Boolean
|
||||
// Flag to parser to leave alone the script tags contained inside of me
|
||||
_noScript: true, |
||||
|
||||
// stopParser: [private] Boolean
|
||||
// Flag to parser to not try and parse widgets declared inside of me
|
||||
stopParser: true, |
||||
|
||||
// widgetClass: String
|
||||
// Name of class being declared, ex: "acme.myWidget"
|
||||
widgetClass: "", |
||||
|
||||
// propList: Object
|
||||
// Set of attributes for this widget along with default values, ex:
|
||||
// {delay: 100, title: "hello world"}
|
||||
defaults: null, |
||||
|
||||
// mixins: String[]
|
||||
// List containing the prototype for this widget, and also any mixins,
|
||||
// ex: ["dijit._Widget", "dijit._Container"]
|
||||
mixins: [], |
||||
|
||||
buildRendering: function(){ |
||||
var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef), |
||||
methods = dojo.query("> script[type^='dojo/method'][event]", src).orphan(), |
||||
postscriptConnects = dojo.query("> script[type^='dojo/method']", src).orphan(), |
||||
regularConnects = dojo.query("> script[type^='dojo/connect']", src).orphan(), |
||||
srcType = src.nodeName; |
||||
|
||||
var propList = this.defaults || {}; |
||||
|
||||
// For all methods defined like <script type="dojo/method" event="foo">,
|
||||
// add that method to prototype
|
||||
dojo.forEach(methods, function(s){ |
||||
var evt = s.getAttribute("event"), |
||||
func = dojo.parser._functionFromScript(s); |
||||
propList[evt] = func; |
||||
}); |
||||
|
||||
// map array of strings like [ "dijit.form.Button" ] to array of mixin objects
|
||||
// (note that dojo.map(this.mixins, dojo.getObject) doesn't work because it passes
|
||||
// a bogus third argument to getObject(), confusing it)
|
||||
this.mixins = this.mixins.length ? |
||||
dojo.map(this.mixins, function(name){ return dojo.getObject(name); } ) : |
||||
[ dijit._Widget, dijit._Templated ]; |
||||
|
||||
propList.widgetsInTemplate = true; |
||||
propList._skipNodeCache = true; |
||||
propList.templateString = "<"+srcType+" class='"+src.className+"' dojoAttachPoint='"+(src.getAttribute("dojoAttachPoint") || '')+"' dojoAttachEvent='"+(src.getAttribute("dojoAttachEvent") || '')+"' >"+src.innerHTML.replace(/\%7B/g,"{").replace(/\%7D/g,"}")+"</"+srcType+">"; |
||||
|
||||
// strip things so we don't create stuff under us in the initial setup phase
|
||||
dojo.query("[dojoType]", src).forEach(function(node){ |
||||
node.removeAttribute("dojoType"); |
||||
}); |
||||
|
||||
// create the new widget class
|
||||
var wc = dojo.declare( |
||||
this.widgetClass, |
||||
this.mixins, |
||||
propList |
||||
); |
||||
|
||||
// Handle <script> blocks of form:
|
||||
// <script type="dojo/connect" event="foo">
|
||||
// and
|
||||
// <script type="dojo/method">
|
||||
// (Note that the second one is just shorthand for a dojo/connect to postscript)
|
||||
// Since this is a connect in the declaration, we are actually connection to the method
|
||||
// in the _prototype_.
|
||||
var connects = regularConnects.concat(postscriptConnects); |
||||
dojo.forEach(connects, function(s){ |
||||
var evt = s.getAttribute("event") || "postscript", |
||||
func = dojo.parser._functionFromScript(s); |
||||
dojo.connect(wc.prototype, evt, func); |
||||
}); |
||||
} |
||||
} |
||||
); |
@ -0,0 +1,522 @@
|
||||
dojo.provide("dijit.Dialog"); |
||||
|
||||
dojo.require("dojo.dnd.move"); |
||||
dojo.require("dojo.dnd.TimedMoveable"); |
||||
dojo.require("dojo.fx"); |
||||
dojo.require("dojo.window"); |
||||
|
||||
dojo.require("dijit._Widget"); |
||||
dojo.require("dijit._Templated"); |
||||
dojo.require("dijit._CssStateMixin"); |
||||
dojo.require("dijit.form._FormMixin"); |
||||
dojo.require("dijit._DialogMixin"); |
||||
dojo.require("dijit.DialogUnderlay"); |
||||
dojo.require("dijit.layout.ContentPane"); |
||||
dojo.requireLocalization("dijit", "common"); |
||||
|
||||
/*===== |
||||
dijit._underlay = function(kwArgs){ |
||||
// summary:
|
||||
// A shared instance of a `dijit.DialogUnderlay`
|
||||
//
|
||||
// description:
|
||||
// A shared instance of a `dijit.DialogUnderlay` created and
|
||||
// used by `dijit.Dialog`, though never created until some Dialog
|
||||
// or subclass thereof is shown.
|
||||
}; |
||||
=====*/ |
||||
|
||||
dojo.declare( |
||||
"dijit._DialogBase", |
||||
[dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin, dijit._CssStateMixin], |
||||
{ |
||||
// summary:
|
||||
// A modal dialog Widget
|
||||
//
|
||||
// description:
|
||||
// Pops up a modal dialog window, blocking access to the screen
|
||||
// and also graying out the screen Dialog is extended from
|
||||
// ContentPane so it supports all the same parameters (href, etc.)
|
||||
//
|
||||
// example:
|
||||
// | <div dojoType="dijit.Dialog" href="test.html"></div>
|
||||
//
|
||||
// example:
|
||||
// | var foo = new dijit.Dialog({ title: "test dialog", content: "test content" };
|
||||
// | dojo.body().appendChild(foo.domNode);
|
||||
// | foo.startup();
|
||||
|
||||
templateString: dojo.cache("dijit", "templates/Dialog.html"), |
||||
|
||||
baseClass: "dijitDialog", |
||||
|
||||
cssStateNodes: { |
||||
closeButtonNode: "dijitDialogCloseIcon" |
||||
}, |
||||
|
||||
attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, { |
||||
title: [ |
||||
{ node: "titleNode", type: "innerHTML" }, |
||||
{ node: "titleBar", type: "attribute" } |
||||
], |
||||
"aria-describedby":"" |
||||
}), |
||||
|
||||
// open: Boolean
|
||||
// True if Dialog is currently displayed on screen.
|
||||
open: false, |
||||
|
||||
// duration: Integer
|
||||
// The time in milliseconds it takes the dialog to fade in and out
|
||||
duration: dijit.defaultDuration, |
||||
|
||||
// refocus: Boolean
|
||||
// A Toggle to modify the default focus behavior of a Dialog, which
|
||||
// is to re-focus the element which had focus before being opened.
|
||||
// False will disable refocusing. Default: true
|
||||
refocus: true, |
||||
|
||||
// autofocus: Boolean
|
||||
// A Toggle to modify the default focus behavior of a Dialog, which
|
||||
// is to focus on the first dialog element after opening the dialog.
|
||||
// False will disable autofocusing. Default: true
|
||||
autofocus: true, |
||||
|
||||
// _firstFocusItem: [private] [readonly] DomNode
|
||||
// The pointer to the first focusable node in the dialog.
|
||||
// Set by `dijit._DialogMixin._getFocusItems`.
|
||||
_firstFocusItem: null, |
||||
|
||||
// _lastFocusItem: [private] [readonly] DomNode
|
||||
// The pointer to which node has focus prior to our dialog.
|
||||
// Set by `dijit._DialogMixin._getFocusItems`.
|
||||
_lastFocusItem: null, |
||||
|
||||
// doLayout: [protected] Boolean
|
||||
// Don't change this parameter from the default value.
|
||||
// This ContentPane parameter doesn't make sense for Dialog, since Dialog
|
||||
// is never a child of a layout container, nor can you specify the size of
|
||||
// Dialog in order to control the size of an inner widget.
|
||||
doLayout: false, |
||||
|
||||
// draggable: Boolean
|
||||
// Toggles the moveable aspect of the Dialog. If true, Dialog
|
||||
// can be dragged by it's title. If false it will remain centered
|
||||
// in the viewport.
|
||||
draggable: true, |
||||
|
||||
//aria-describedby: String
|
||||
// Allows the user to add an aria-describedby attribute onto the dialog. The value should
|
||||
// be the id of the container element of text that describes the dialog purpose (usually
|
||||
// the first text in the dialog).
|
||||
// <div dojoType="dijit.Dialog" aria-describedby="intro" .....>
|
||||
// <div id="intro">Introductory text</div>
|
||||
// <div>rest of dialog contents</div>
|
||||
// </div>
|
||||
"aria-describedby":"", |
||||
|
||||
postMixInProperties: function(){ |
||||
var _nlsResources = dojo.i18n.getLocalization("dijit", "common"); |
||||
dojo.mixin(this, _nlsResources); |
||||
this.inherited(arguments); |
||||
}, |
||||
|
||||
postCreate: function(){ |
||||
dojo.style(this.domNode, { |
||||
display: "none", |
||||
position:"absolute" |
||||
}); |
||||
dojo.body().appendChild(this.domNode); |
||||
|
||||
this.inherited(arguments); |
||||
|
||||
this.connect(this, "onExecute", "hide"); |
||||
this.connect(this, "onCancel", "hide"); |
||||
this._modalconnects = []; |
||||
}, |
||||
|
||||
onLoad: function(){ |
||||
// summary:
|
||||
// Called when data has been loaded from an href.
|
||||
// Unlike most other callbacks, this function can be connected to (via `dojo.connect`)
|
||||
// but should *not* be overriden.
|
||||
// tags:
|
||||
// callback
|
||||
|
||||
// when href is specified we need to reposition the dialog after the data is loaded
|
||||
// and find the focusable elements
|
||||
this._position(); |
||||
if(this.autofocus){ |
||||
this._getFocusItems(this.domNode); |
||||
dijit.focus(this._firstFocusItem); |
||||
} |
||||
this.inherited(arguments); |
||||
}, |
||||
|
||||
_endDrag: function(e){ |
||||
// summary:
|
||||
// Called after dragging the Dialog. Saves the position of the dialog in the viewport.
|
||||
// tags:
|
||||
// private
|
||||
if(e && e.node && e.node === this.domNode){ |
||||
this._relativePosition = dojo.position(e.node); |
||||
} |
||||
}, |
||||
|
||||
_setup: function(){ |
||||
// summary:
|
||||
// Stuff we need to do before showing the Dialog for the first
|
||||
// time (but we defer it until right beforehand, for
|
||||
// performance reasons).
|
||||
// tags:
|
||||
// private
|
||||
|
||||
var node = this.domNode; |
||||
|
||||
if(this.titleBar && this.draggable){ |
||||
this._moveable = (dojo.isIE == 6) ? |
||||
new dojo.dnd.TimedMoveable(node, { handle: this.titleBar }) : // prevent overload, see #5285
|
||||
new dojo.dnd.Moveable(node, { handle: this.titleBar, timeout: 0 }); |
||||
this._dndListener = dojo.subscribe("/dnd/move/stop",this,"_endDrag"); |
||||
}else{ |
||||
dojo.addClass(node,"dijitDialogFixed"); |
||||
} |
||||
|
||||
this.underlayAttrs = { |
||||
dialogId: this.id, |
||||
"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ") |
||||
}; |
||||
|
||||
this._fadeIn = dojo.fadeIn({ |
||||
node: node, |
||||
duration: this.duration, |
||||
beforeBegin: dojo.hitch(this, function(){ |
||||
var underlay = dijit._underlay; |
||||
if(!underlay){ |
||||
underlay = dijit._underlay = new dijit.DialogUnderlay(this.underlayAttrs); |
||||
}else{ |
||||
underlay.set(this.underlayAttrs); |
||||
} |
||||
|
||||
var ds = dijit._dialogStack, |
||||
zIndex = 948 + ds.length*2; |
||||
if(ds.length == 1){ // first dialog
|
||||
underlay.show(); |
||||
} |
||||
dojo.style(dijit._underlay.domNode, 'zIndex', zIndex); |
||||
dojo.style(this.domNode, 'zIndex', zIndex + 1); |
||||
}), |
||||
onEnd: dojo.hitch(this, function(){ |
||||
if(this.autofocus){ |
||||
// find focusable Items each time dialog is shown since if dialog contains a widget the
|
||||
// first focusable items can change
|
||||
this._getFocusItems(this.domNode); |
||||
dijit.focus(this._firstFocusItem); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
this._fadeOut = dojo.fadeOut({ |
||||
node: node, |
||||
duration: this.duration, |
||||
onEnd: dojo.hitch(this, function(){ |
||||
node.style.display = "none"; |
||||
|
||||
// Restore the previous dialog in the stack, or if this is the only dialog
|
||||
// then restore to original page
|
||||
var ds = dijit._dialogStack; |
||||
if(ds.length == 0){ |
||||
dijit._underlay.hide(); |
||||
}else{ |
||||
dojo.style(dijit._underlay.domNode, 'zIndex', 948 + ds.length*2); |
||||
dijit._underlay.set(ds[ds.length-1].underlayAttrs); |
||||
} |
||||
|
||||
// Restore focus to wherever it was before this dialog was displayed
|
||||
if(this.refocus){ |
||||
var focus = this._savedFocus; |
||||
|
||||
// If we are returning control to a previous dialog but for some reason
|
||||
// that dialog didn't have a focused field, set focus to first focusable item.
|
||||
// This situation could happen if two dialogs appeared at nearly the same time,
|
||||
// since a dialog doesn't set it's focus until the fade-in is finished.
|
||||
if(ds.length > 0){ |
||||
var pd = ds[ds.length-1]; |
||||
if(!dojo.isDescendant(focus.node, pd.domNode)){ |
||||
pd._getFocusItems(pd.domNode); |
||||
focus = pd._firstFocusItem; |
||||
} |
||||
} |
||||
|
||||
dijit.focus(focus); |
||||
} |
||||
}) |
||||
}); |
||||
}, |
||||
|
||||
uninitialize: function(){ |
||||
var wasPlaying = false; |
||||
if(this._fadeIn && this._fadeIn.status() == "playing"){ |
||||
wasPlaying = true; |
||||
this._fadeIn.stop(); |
||||
} |
||||
if(this._fadeOut && this._fadeOut.status() == "playing"){ |
||||
wasPlaying = true; |
||||
this._fadeOut.stop(); |
||||
} |
||||
|
||||
// Hide the underlay, unless the underlay widget has already been destroyed
|
||||
// because we are being called during page unload (when all widgets are destroyed)
|
||||
if((this.open || wasPlaying) && !dijit._underlay._destroyed){ |
||||
dijit._underlay.hide(); |
||||
} |
||||
|
||||
if(this._moveable){ |
||||
this._moveable.destroy(); |
||||
} |
||||
this.inherited(arguments); |
||||
}, |
||||
|
||||
_size: function(){ |
||||
// summary:
|
||||
// If necessary, shrink dialog contents so dialog fits in viewport
|
||||
// tags:
|
||||
// private
|
||||
|
||||
this._checkIfSingleChild(); |
||||
|
||||
// If we resized the dialog contents earlier, reset them back to original size, so
|
||||
// that if the user later increases the viewport size, the dialog can display w/out a scrollbar.
|
||||
// Need to do this before the dojo.marginBox(this.domNode) call below.
|
||||
if(this._singleChild){ |
||||
if(this._singleChildOriginalStyle){ |
||||
this._singleChild.domNode.style.cssText = this._singleChildOriginalStyle; |
||||
} |
||||
delete this._singleChildOriginalStyle; |
||||
}else{ |
||||
dojo.style(this.containerNode, { |
||||
width:"auto", |
||||
height:"auto" |
||||
}); |
||||
} |
||||
|
||||
var mb = dojo.marginBox(this.domNode); |
||||
var viewport = dojo.window.getBox(); |
||||
if(mb.w >= viewport.w || mb.h >= viewport.h){ |
||||
// Reduce size of dialog contents so that dialog fits in viewport
|
||||
|
||||
var w = Math.min(mb.w, Math.floor(viewport.w * 0.75)), |
||||
h = Math.min(mb.h, Math.floor(viewport.h * 0.75)); |
||||
|
||||
if(this._singleChild && this._singleChild.resize){ |
||||
this._singleChildOriginalStyle = this._singleChild.domNode.style.cssText; |
||||
this._singleChild.resize({w: w, h: h}); |
||||
}else{ |
||||
dojo.style(this.containerNode, { |
||||
width: w + "px", |
||||
height: h + "px", |
||||
overflow: "auto", |
||||
position: "relative" // workaround IE bug moving scrollbar or dragging dialog
|
||||
}); |
||||
} |
||||
}else{ |
||||
if(this._singleChild && this._singleChild.resize){ |
||||
this._singleChild.resize(); |
||||
} |
||||
} |
||||
}, |
||||
|
||||
_position: function(){ |
||||
// summary:
|
||||
// Position modal dialog in the viewport. If no relative offset
|
||||
// in the viewport has been determined (by dragging, for instance),
|
||||
// center the node. Otherwise, use the Dialog's stored relative offset,
|
||||
// and position the node to top: left: values based on the viewport.
|
||||
// tags:
|
||||
// private
|
||||
if(!dojo.hasClass(dojo.body(),"dojoMove")){ |
||||
var node = this.domNode, |
||||
viewport = dojo.window.getBox(), |
||||
p = this._relativePosition, |
||||
bb = p ? null : dojo._getBorderBox(node), |
||||
l = Math.floor(viewport.l + (p ? p.x : (viewport.w - bb.w) / 2)), |
||||
t = Math.floor(viewport.t + (p ? p.y : (viewport.h - bb.h) / 2)) |
||||
; |
||||
dojo.style(node,{ |
||||
left: l + "px", |
||||
top: t + "px" |
||||
}); |
||||
} |
||||
}, |
||||
|
||||
_onKey: function(/*Event*/ evt){ |
||||
// summary:
|
||||
// Handles the keyboard events for accessibility reasons
|
||||
// tags:
|
||||
// private
|
||||
|
||||
var ds = dijit._dialogStack; |
||||
if(ds[ds.length-1] != this){ |
||||
// console.debug(this.id + ': skipping because', this, 'is not the active dialog');
|
||||
return; |
||||
} |
||||
|
||||
if(evt.charOrCode){ |
||||
var dk = dojo.keys; |
||||
var node = evt.target; |
||||
if(evt.charOrCode === dk.TAB){ |
||||
this._getFocusItems(this.domNode); |
||||
} |
||||
var singleFocusItem = (this._firstFocusItem == this._lastFocusItem); |
||||
// see if we are shift-tabbing from first focusable item on dialog
|
||||
if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === dk.TAB){ |
||||
if(!singleFocusItem){ |
||||
dijit.focus(this._lastFocusItem); // send focus to last item in dialog
|
||||
} |
||||
dojo.stopEvent(evt); |
||||
}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){ |
||||
if(!singleFocusItem){ |
||||
dijit.focus(this._firstFocusItem); // send focus to first item in dialog
|
||||
} |
||||
dojo.stopEvent(evt); |
||||
}else{ |
||||
// see if the key is for the dialog
|
||||
while(node){ |
||||
if(node == this.domNode || dojo.hasClass(node, "dijitPopup")){ |
||||
if(evt.charOrCode == dk.ESCAPE){ |
||||
this.onCancel(); |
||||
}else{ |
||||
return; // just let it go
|
||||
} |
||||
} |
||||
node = node.parentNode; |
||||
} |
||||
// this key is for the disabled document window
|
||||
if(evt.charOrCode !== dk.TAB){ // allow tabbing into the dialog for a11y
|
||||
dojo.stopEvent(evt); |
||||
// opera won't tab to a div
|
||||
}else if(!dojo.isOpera){ |
||||
try{ |
||||
this._firstFocusItem.focus(); |
||||
}catch(e){ /*squelch*/ } |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
|
||||
show: function(){ |
||||
// summary:
|
||||
// Display the dialog
|
||||
if(this.open){ return; } |
||||
|
||||
// first time we show the dialog, there's some initialization stuff to do
|
||||
if(!this._alreadyInitialized){ |
||||
this._setup(); |
||||
this._alreadyInitialized=true; |
||||
} |
||||
|
||||
if(this._fadeOut.status() == "playing"){ |
||||
this._fadeOut.stop(); |
||||
} |
||||
|
||||
this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout")); |
||||
this._modalconnects.push(dojo.connect(window, "onresize", this, function(){ |
||||
// IE gives spurious resize events and can actually get stuck
|
||||
// in an infinite loop if we don't ignore them
|
||||
var viewport = dojo.window.getBox(); |
||||
if(!this._oldViewport || |
||||
viewport.h != this._oldViewport.h || |
||||
viewport.w != this._oldViewport.w){ |
||||
this.layout(); |
||||
this._oldViewport = viewport; |
||||
} |
||||
})); |
||||
this._modalconnects.push(dojo.connect(dojo.doc.documentElement, "onkeypress", this, "_onKey")); |
||||
|
||||
dojo.style(this.domNode, { |
||||
opacity:0, |
||||
display:"" |
||||
}); |
||||
|
||||
this.open = true; |
||||
this._onShow(); // lazy load trigger
|
||||
|
||||
this._size(); |
||||
this._position(); |
||||
dijit._dialogStack.push(this); |
||||
this._fadeIn.play(); |
||||
|
||||
this._savedFocus = dijit.getFocus(this); |
||||
}, |
||||
|
||||
hide: function(){ |
||||
// summary:
|
||||
// Hide the dialog
|
||||
|
||||
// if we haven't been initialized yet then we aren't showing and we can just return
|
||||
// or if we aren't the active dialog, don't allow us to close yet
|
||||
var ds = dijit._dialogStack; |
||||
if(!this._alreadyInitialized || this != ds[ds.length-1]){ |
||||
return; |
||||
} |
||||
|
||||
if(this._fadeIn.status() == "playing"){ |
||||
this._fadeIn.stop(); |
||||
} |
||||
|
||||
// throw away current active dialog from stack -- making the previous dialog or the node on the original page active
|
||||
ds.pop(); |
||||
|
||||
this._fadeOut.play(); |
||||
|
||||
if(this._scrollConnected){ |
||||
this._scrollConnected = false; |
||||
} |
||||
dojo.forEach(this._modalconnects, dojo.disconnect); |
||||
this._modalconnects = []; |
||||
|
||||
if(this._relativePosition){ |
||||
delete this._relativePosition; |
||||
} |
||||
this.open = false; |
||||
|
||||
this.onHide(); |
||||
}, |
||||
|
||||
layout: function(){ |
||||
// summary:
|
||||
// Position the Dialog and the underlay
|
||||
// tags:
|
||||
// private
|
||||
if(this.domNode.style.display != "none"){ |
||||
if(dijit._underlay){ // avoid race condition during show()
|
||||
dijit._underlay.layout(); |
||||
} |
||||
this._position(); |
||||
} |
||||
}, |
||||
|
||||
destroy: function(){ |
||||
dojo.forEach(this._modalconnects, dojo.disconnect); |
||||
if(this.refocus && this.open){ |
||||
setTimeout(dojo.hitch(dijit,"focus",this._savedFocus), 25); |
||||
} |
||||
if(this._dndListener){ |
||||
dojo.unsubscribe(this._dndListener); |
||||
} |
||||
this.inherited(arguments); |
||||
} |
||||
} |
||||
); |
||||
|
||||
dojo.declare( |
||||
"dijit.Dialog", |
||||
[dijit.layout.ContentPane, dijit._DialogBase], |
||||
{} |
||||
); |
||||
|
||||
// Stack of currenctly displayed dialogs, layered on top of each other
|
||||
dijit._dialogStack = []; |
||||
|
||||
// For back-compat. TODO: remove in 2.0
|
||||
dojo.require("dijit.TooltipDialog"); |
@ -0,0 +1,100 @@
|
||||
dojo.provide("dijit.DialogUnderlay"); |
||||
|
||||
dojo.require("dojo.window"); |
||||
|
||||
dojo.require("dijit._Widget"); |
||||
dojo.require("dijit._Templated"); |
||||
|
||||
dojo.declare( |
||||
"dijit.DialogUnderlay", |
||||
[dijit._Widget, dijit._Templated], |
||||
{ |
||||
// summary:
|
||||
// The component that blocks the screen behind a `dijit.Dialog`
|
||||
//
|
||||
// description:
|
||||
// A component used to block input behind a `dijit.Dialog`. Only a single
|
||||
// instance of this widget is created by `dijit.Dialog`, and saved as
|
||||
// a reference to be shared between all Dialogs as `dijit._underlay`
|
||||
//
|
||||
// The underlay itself can be styled based on and id:
|
||||
// | #myDialog_underlay { background-color:red; }
|
||||
//
|
||||