New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit

git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f
This commit is contained in:
mensonge 2008-11-13 09:49:11 +00:00
parent a62b9742ee
commit e44a7e37b6
2431 changed files with 301410 additions and 33 deletions

51
ajax/gettags.php Normal file
View file

@ -0,0 +1,51 @@
<?php
/***************************************************************************
Copyright (C) 2004 - 2006 Scuttle project
http://sourceforge.net/projects/scuttle/
http://scuttle.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/
/* Return a json file with list of tags according to current user and sort by popularity*/
require_once('../header.inc.php');
$b2tservice =& ServiceFactory::getServiceInstance('Bookmark2TagService');
$bookmarkservice =& ServiceFactory::getServiceInstance('TagService');
$userservice =& ServiceFactory::getServiceInstance('UserService');
if ($userservice->isLoggedOn()) {
$loggedon = true;
$currentUser = $userservice->getCurrentUser();
$currentUserID = $userservice->getCurrentUserId();
$currentUsername = $currentUser[$userservice->getFieldName('username')];
}
?>
{identifier:"tag",
items: [
<?php
$listTags = $b2tservice->getPopularTags($currentUserID, 1000, $currentUserID);
foreach($listTags as $t) {
echo "{tag: \"".$t['tag']."\"},";
}
?>
]}

View file

@ -0,0 +1,292 @@
if(!dojo._hasResource["dijit.ColorPalette"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.ColorPalette"] = true;
dojo.provide("dijit.ColorPalette");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dojo.colors");
dojo.require("dojo.i18n");
dojo.requireLocalization("dojo", "colors", null, "zh,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,pt-pt,cs,fr,es,nl,ko,zh-tw,pl,it,hu,ROOT");
dojo.declare("dijit.ColorPalette",
[dijit._Widget, dijit._Templated],
{
// 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();
//
// defaultTimeout: Number
// number of milliseconds before a held key or button becomes typematic
defaultTimeout: 500,
// timeoutChangeRate: Number
// fraction of time used to change the typematic timer between events
// 1.0 means that each typematic event fires at defaultTimeout intervals
// < 1.0 means that each typematic event fires at an increasing faster rate
timeoutChangeRate: 0.90,
// palette: String
// Size of grid, either "7x10" or "3x4".
palette: "7x10",
//_value: String
// The value of the selected color.
value: null,
//_currentFocus: Integer
// Index of the currently focused color.
_currentFocus: 0,
// _xDim: Integer
// This is the number of colors horizontally across.
_xDim: null,
// _yDim: Integer
/// This is the number of colors vertically down.
_yDim: null,
// _palettes: Map
// This represents the value of the colors.
// The first level is a hashmap of the different arrays 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: Map
// This is stores the path to the palette images
_imagePaths: {
"7x10": dojo.moduleUrl("dijit", "templates/colors7x10.png"),
"3x4": dojo.moduleUrl("dijit", "templates/colors3x4.png")
},
// _paletteCoords: Map
// This is a map that is used to calculate the coordinates of the
// images that make up the palette.
_paletteCoords: {
"leftOffset": 3, "topOffset": 3,
"cWidth": 20, "cHeight": 20
},
// templatePath: String
// Path to the template of this widget.
templateString:"<div class=\"dijitInline dijitColorPalette\">\n\t<div class=\"dijitColorPaletteInner\" dojoAttachPoint=\"divNode\" waiRole=\"grid\" tabIndex=\"${tabIndex}\">\n\t\t<img class=\"dijitColorPaletteUnder\" dojoAttachPoint=\"imageNode\" waiRole=\"presentation\">\n\t</div>\t\n</div>\n",
// _paletteDims: Object
// Size of the supported palettes for alignment purposes.
_paletteDims: {
"7x10": {"width": "206px", "height": "145px"},
"3x4": {"width": "86px", "height": "64px"}
},
// tabIndex: String
// Widget tabindex.
tabIndex: "0",
postCreate: function(){
// A name has to be given to the colorMap, this needs to be unique per Palette.
dojo.mixin(this.divNode.style, this._paletteDims[this.palette]);
this.imageNode.setAttribute("src", this._imagePaths[this.palette]);
var choices = this._palettes[this.palette];
this.domNode.style.position = "relative";
this._cellNodes = [];
this.colorNames = dojo.i18n.getLocalization("dojo", "colors", this.lang);
var url = dojo.moduleUrl("dojo", "resources/blank.gif"),
colorObject = new dojo.Color(),
coords = this._paletteCoords;
for(var row=0; row < choices.length; row++){
for(var col=0; col < choices[row].length; col++) {
var imgNode = dojo.doc.createElement("img");
imgNode.src = url;
dojo.addClass(imgNode, "dijitPaletteImg");
var color = choices[row][col],
colorValue = colorObject.setColor(dojo.Color.named[color]);
imgNode.alt = this.colorNames[color];
imgNode.color = colorValue.toHex();
var imgStyle = imgNode.style;
imgStyle.color = imgStyle.backgroundColor = imgNode.color;
var cellNode = dojo.doc.createElement("span");
cellNode.appendChild(imgNode);
dojo.forEach(["Dijitclick", "MouseEnter", "Focus", "Blur"], function(handler) {
this.connect(cellNode, "on" + handler.toLowerCase(), "_onCell" + handler);
}, this);
this.divNode.appendChild(cellNode);
var cellStyle = cellNode.style;
cellStyle.top = coords.topOffset + (row * coords.cHeight) + "px";
cellStyle.left = coords.leftOffset + (col * coords.cWidth) + "px";
dojo.attr(cellNode, "tabindex", "-1");
cellNode.title = this.colorNames[color];
dojo.addClass(cellNode, "dijitPaletteCell");
dijit.setWaiRole(cellNode, "gridcell");
cellNode.index = this._cellNodes.length;
this._cellNodes.push(cellNode);
}
}
this._xDim = choices[0].length;
this._yDim = choices.length;
this.connect(this.divNode, "onfocus", "_onDivNodeFocus");
// Now set all events
// The palette itself is navigated to with the tab key on the keyboard
// Keyboard navigation within the Palette is with the arrow keys
// Spacebar selects the color.
// For the up key the index is changed by negative the x dimension.
var keyIncrementMap = {
UP_ARROW: -this._xDim,
// The down key the index is increase by the x dimension.
DOWN_ARROW: this._xDim,
// Right and left move the index by 1.
RIGHT_ARROW: 1,
LEFT_ARROW: -1
};
for(var key in keyIncrementMap){
this._connects.push(dijit.typematic.addKeyListener(this.domNode,
{keyCode:dojo.keys[key], ctrlKey:false, altKey:false, shiftKey:false},
this,
function(){
var increment = keyIncrementMap[key];
return function(count){ this._navigateByKey(increment, count); };
}(),
this.timeoutChangeRate, this.defaultTimeout));
}
},
focus: function(){
// summary:
// Focus this ColorPalette. Puts focus on the first swatch.
this._focusFirst();
},
onChange: function(color){
// summary:
// Callback when a color is selected.
// color: String
// Hex value corresponding to color.
// console.debug("Color selected is: "+color);
},
_focusFirst: function(){
this._currentFocus = 0;
var cellNode = this._cellNodes[this._currentFocus];
window.setTimeout(function(){dijit.focus(cellNode)}, 0);
},
_onDivNodeFocus: function(evt){
// focus bubbles on Firefox 2, so just make sure that focus has really
// gone to the container
if(evt.target === this.divNode){
this._focusFirst();
}
},
_onFocus: function(){
// while focus is on the palette, set its tabindex to -1 so that on a
// shift-tab from a cell, the container is not in the tab order
dojo.attr(this.divNode, "tabindex", "-1");
},
_onBlur: function(){
this._removeCellHighlight(this._currentFocus);
// when focus leaves the palette, restore its tabindex, since it was
// modified by _onFocus().
dojo.attr(this.divNode, "tabindex", this.tabIndex);
},
_onCellDijitclick: function(/*Event*/ evt){
// summary:
// Handler for click, enter key & space key. Selects the color.
// evt:
// The event.
var target = evt.currentTarget;
if (this._currentFocus != target.index){
this._currentFocus = target.index;
window.setTimeout(function(){dijit.focus(target)}, 0);
}
this._selectColor(target);
dojo.stopEvent(evt);
},
_onCellMouseEnter: function(/*Event*/ evt){
// summary:
// Handler for onMouseOver. Put focus on the color under the mouse.
// evt:
// The mouse event.
var target = evt.currentTarget;
window.setTimeout(function(){dijit.focus(target)}, 0);
},
_onCellFocus: function(/*Event*/ evt){
// summary:
// Handler for onFocus. Removes highlight of
// the color that just lost focus, and highlights
// the new color.
// evt:
// The focus event.
this._removeCellHighlight(this._currentFocus);
this._currentFocus = evt.currentTarget.index;
dojo.addClass(evt.currentTarget, "dijitPaletteCellHighlight");
},
_onCellBlur: function(/*Event*/ evt){
// summary:
// needed for Firefox 2 on Mac OS X
this._removeCellHighlight(this._currentFocus);
},
_removeCellHighlight: function(index){
dojo.removeClass(this._cellNodes[index], "dijitPaletteCellHighlight");
},
_selectColor: function(selectNode){
// summary:
// This selects a color. It triggers the onChange event
// area:
// The area node that covers the color being selected.
var img = selectNode.getElementsByTagName("img")[0];
this.onChange(this.value = img.color);
},
_navigateByKey: function(increment, typeCount){
// summary:
// This is the callback for typematic.
// It changes the focus and the highlighed color.
// increment:
// How much the key is navigated.
// typeCount:
// How many times typematic has fired.
// typecount == -1 means the key is released.
if(typeCount == -1){ return; }
var newFocusIndex = this._currentFocus + increment;
if(newFocusIndex < this._cellNodes.length && newFocusIndex > -1)
{
var focusNode = this._cellNodes[newFocusIndex];
focusNode.focus();
}
}
});
}

View file

@ -0,0 +1,76 @@
if(!dojo._hasResource["dijit.Declaration"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Declaration"] = true;
dojo.provide("dijit.Declaration");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare(
"dijit.Declaration",
dijit._Widget,
{
// summary:
// The Declaration widget allows a user to declare new widget
// classes directly from a snippet of markup.
_noScript: true,
widgetClass: "",
replaceVars: true,
defaults: null,
mixins: [],
buildRendering: function(){
var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef);
var preambles = dojo.query("> script[type='dojo/method'][event='preamble']", src).orphan();
var scripts = dojo.query("> script[type^='dojo/']", src).orphan();
var srcType = src.nodeName;
var propList = this.defaults||{};
// 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 ];
if(preambles.length){
// we only support one preamble. So be it.
propList.preamble = dojo.parser._functionFromScript(preambles[0]);
}
var parsedScripts = dojo.map(scripts, function(s){
var evt = s.getAttribute("event")||"postscript";
return {
event: evt,
func: dojo.parser._functionFromScript(s)
};
});
// do the connects for each <script type="dojo/connect" event="foo"> block and make
// all <script type="dojo/method"> tags execute right after construction
this.mixins.push(function(){
dojo.forEach(parsedScripts, function(s){
dojo.connect(this, s.event, this, s.func);
}, this);
});
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+">";
// console.debug(propList.templateString);
// 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
dojo.declare(
this.widgetClass,
this.mixins,
propList
);
}
}
);
}

480
includes/js/dijit/Dialog.js Normal file
View file

@ -0,0 +1,480 @@
if(!dojo._hasResource["dijit.Dialog"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Dialog"] = true;
dojo.provide("dijit.Dialog");
dojo.require("dojo.dnd.TimedMoveable");
dojo.require("dojo.fx");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.form.Form");
dojo.requireLocalization("dijit", "common", null, "zh,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,ROOT,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu");
dojo.declare(
"dijit.DialogUnderlay",
[dijit._Widget, dijit._Templated],
{
// summary: The component that grays out the screen behind the dialog
// Template has two divs; outer div is used for fade-in/fade-out, and also to hold background iframe.
// Inner div has opacity specified in CSS file.
templateString: "<div class='dijitDialogUnderlayWrapper' id='${id}_wrapper'><div class='dijitDialogUnderlay ${class}' id='${id}' dojoAttachPoint='node'></div></div>",
attributeMap: {},
postCreate: function(){
// summary: Append the underlay to the body
dojo.body().appendChild(this.domNode);
this.bgIframe = new dijit.BackgroundIframe(this.domNode);
},
layout: function(){
// summary: Sets the background to the size of the viewport
//
// description:
// Sets the background to the size of the viewport (rather than the size
// of the document) since we need to cover the whole browser window, even
// if the document is only a few lines long.
var viewport = dijit.getViewport();
var is = this.node.style,
os = this.domNode.style;
os.top = viewport.t + "px";
os.left = viewport.l + "px";
is.width = viewport.w + "px";
is.height = viewport.h + "px";
// process twice since the scroll bar may have been removed
// by the previous resizing
var viewport2 = dijit.getViewport();
if(viewport.w != viewport2.w){ is.width = viewport2.w + "px"; }
if(viewport.h != viewport2.h){ is.height = viewport2.h + "px"; }
},
show: function(){
// summary: Show the dialog underlay
this.domNode.style.display = "block";
this.layout();
if(this.bgIframe.iframe){
this.bgIframe.iframe.style.display = "block";
}
this._resizeHandler = this.connect(window, "onresize", "layout");
},
hide: function(){
// summary: hides the dialog underlay
this.domNode.style.display = "none";
if(this.bgIframe.iframe){
this.bgIframe.iframe.style.display = "none";
}
this.disconnect(this._resizeHandler);
},
uninitialize: function(){
if(this.bgIframe){
this.bgIframe.destroy();
}
}
}
);
dojo.declare("dijit._DialogMixin", null,
{
attributeMap: dijit._Widget.prototype.attributeMap,
// execute: Function
// User defined function to do stuff when the user hits the submit button
execute: function(/*Object*/ formContents){},
// onCancel: Function
// Callback when user has canceled dialog, to notify container
// (user shouldn't override)
onCancel: function(){},
// onExecute: Function
// Callback when user is about to execute dialog, to notify container
// (user shouldn't override)
onExecute: function(){},
_onSubmit: function(){
// summary: callback when user hits submit button
this.onExecute(); // notify container that we are about to execute
this.execute(this.getValues());
},
_getFocusItems: function(/*Node*/ dialogNode){
// find focusable Items each time a dialog is opened
var focusItem = dijit.getFirstInTabbingOrder(dialogNode);
this._firstFocusItem = focusItem ? focusItem : dialogNode;
focusItem = dijit.getLastInTabbingOrder(dialogNode);
this._lastFocusItem = focusItem ? focusItem : this._firstFocusItem;
if(dojo.isMoz && this._firstFocusItem.tagName.toLowerCase() == "input" && dojo.attr(this._firstFocusItem, "type").toLowerCase() == "file"){
//FF doesn't behave well when first element is input type=file, set first focusable to dialog container
dojo.attr(dialogNode, "tabindex", "0");
this._firstFocusItem = dialogNode;
}
}
}
);
dojo.declare(
"dijit.Dialog",
[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
{
// 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:
// | <div id="test">test content</div>
// | ...
// | var foo = new dijit.Dialog({ title: "test dialog" },dojo.byId("test"));
// | foo.startup();
templateString: null,
templateString:"<div class=\"dijitDialog\" tabindex=\"-1\" waiRole=\"dialog\" waiState=\"labelledby-${id}_title\">\n\t<div dojoAttachPoint=\"titleBar\" class=\"dijitDialogTitleBar\">\n\t<span dojoAttachPoint=\"titleNode\" class=\"dijitDialogTitle\" id=\"${id}_title\">${title}</span>\n\t<span dojoAttachPoint=\"closeButtonNode\" class=\"dijitDialogCloseIcon\" dojoAttachEvent=\"onclick: onCancel\">\n\t\t<span dojoAttachPoint=\"closeText\" class=\"closeText\">x</span>\n\t</span>\n\t</div>\n\t\t<div dojoAttachPoint=\"containerNode\" class=\"dijitDialogPaneContent\"></div>\n</div>\n",
// open: Boolean
// is True or False depending on state of dialog
open: false,
// duration: Integer
// The time in milliseconds it takes the dialog to fade in and out
duration: 400,
// 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,
// _firstFocusItem: DomNode
// The pointer to the first focusable node in the dialog
_firstFocusItem:null,
// _lastFocusItem: DomNode
// The pointer to which node has focus prior to our dialog
_lastFocusItem:null,
// doLayout: 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,
attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap),
{title: "titleBar"}),
postCreate: function(){
dojo.body().appendChild(this.domNode);
this.inherited(arguments);
var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
if(this.closeButtonNode){
this.closeButtonNode.setAttribute("title", _nlsResources.buttonCancel);
}
if(this.closeText){
this.closeText.setAttribute("title", _nlsResources.buttonCancel);
}
var s = this.domNode.style;
s.visibility = "hidden";
s.position = "absolute";
s.display = "";
s.top = "-9999px";
this.connect(this, "onExecute", "hide");
this.connect(this, "onCancel", "hide");
this._modalconnects = [];
},
onLoad: function(){
// summary: when href is specified we need to reposition the dialog after the data is loaded
this._position();
this.inherited(arguments);
},
_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)
if(this.titleBar){
this._moveable = new dojo.dnd.TimedMoveable(this.domNode, { handle: this.titleBar, timeout: 0 });
}
this._underlay = new dijit.DialogUnderlay({
id: this.id+"_underlay",
"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
});
var node = this.domNode;
this._fadeIn = dojo.fx.combine(
[dojo.fadeIn({
node: node,
duration: this.duration
}),
dojo.fadeIn({
node: this._underlay.domNode,
duration: this.duration,
onBegin: dojo.hitch(this._underlay, "show")
})
]
);
this._fadeOut = dojo.fx.combine(
[dojo.fadeOut({
node: node,
duration: this.duration,
onEnd: function(){
node.style.visibility="hidden";
node.style.top = "-9999px";
}
}),
dojo.fadeOut({
node: this._underlay.domNode,
duration: this.duration,
onEnd: dojo.hitch(this._underlay, "hide")
})
]
);
},
uninitialize: function(){
if(this._fadeIn && this._fadeIn.status() == "playing"){
this._fadeIn.stop();
}
if(this._fadeOut && this._fadeOut.status() == "playing"){
this._fadeOut.stop();
}
if(this._underlay){
this._underlay.destroy();
}
},
_position: function(){
// summary: position modal dialog in center of screen
if(dojo.hasClass(dojo.body(),"dojoMove")){ return; }
var viewport = dijit.getViewport();
var mb = dojo.marginBox(this.domNode);
var style = this.domNode.style;
style.left = Math.floor((viewport.l + (viewport.w - mb.w)/2)) + "px";
style.top = Math.floor((viewport.t + (viewport.h - mb.h)/2)) + "px";
},
_onKey: function(/*Event*/ evt){
// summary: handles the keyboard events for accessibility reasons
if(evt.keyCode){
var node = evt.target;
if (evt.keyCode == dojo.keys.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.keyCode == dojo.keys.TAB){
if(!singleFocusItem){
dijit.focus(this._lastFocusItem); // send focus to last item in dialog
}
dojo.stopEvent(evt);
}else if(node == this._lastFocusItem && evt.keyCode == dojo.keys.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){
if(evt.keyCode == dojo.keys.ESCAPE){
this.hide();
}else{
return; // just let it go
}
}
node = node.parentNode;
}
// this key is for the disabled document window
if(evt.keyCode != dojo.keys.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(dojo.doc.documentElement, "onkeypress", this, "_onKey"));
dojo.style(this.domNode, "opacity", 0);
this.domNode.style.visibility="";
this.open = true;
this._loadCheck(); // lazy load trigger
this._position();
this._fadeIn.play();
this._savedFocus = dijit.getFocus(this);
// find focusable Items each time dialog is shown since if dialog contains a widget the
// first focusable items can change
this._getFocusItems(this.domNode);
// set timeout to allow the browser to render dialog
setTimeout(dojo.hitch(this, function(){
dijit.focus(this._firstFocusItem);
}), 50);
},
hide: function(){
// summary: Hide the dialog
// if we haven't been initialized yet then we aren't showing and we can just return
if(!this._alreadyInitialized){
return;
}
if(this._fadeIn.status() == "playing"){
this._fadeIn.stop();
}
this._fadeOut.play();
if (this._scrollConnected){
this._scrollConnected = false;
}
dojo.forEach(this._modalconnects, dojo.disconnect);
this._modalconnects = [];
if(this.refocus){
this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
}
this.open = false;
},
layout: function() {
// summary: position the Dialog and the underlay
if(this.domNode.style.visibility != "hidden"){
this._underlay.layout();
this._position();
}
},
destroy: function(){
dojo.forEach(this._modalconnects, dojo.disconnect);
if(this.refocus && this.open){
var fo = this._savedFocus;
setTimeout(dojo.hitch(dijit,"focus",fo),25);
}
this.inherited(arguments);
}
}
);
dojo.declare(
"dijit.TooltipDialog",
[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
{
// summary:
// Pops up a dialog that appears like a Tooltip
//
// title: String
// Description of tooltip dialog (required for a11Y)
title: "",
// doLayout: Boolean
// Don't change this parameter from the default value.
// This ContentPane parameter doesn't make sense for TooltipDialog, since TooltipDialog
// is never a child of a layout container, nor can you specify the size of
// TooltipDialog in order to control the size of an inner widget.
doLayout: false,
// _firstFocusItem: DomNode
// The pointer to the first focusable node in the dialog
_firstFocusItem:null,
// _lastFocusItem: DomNode
// The domNode that had focus before we took it.
_lastFocusItem: null,
templateString: null,
templateString:"<div class=\"dijitTooltipDialog\" waiRole=\"presentation\">\n\t<div class=\"dijitTooltipContainer\" waiRole=\"presentation\">\n\t\t<div class =\"dijitTooltipContents dijitTooltipFocusNode\" dojoAttachPoint=\"containerNode\" tabindex=\"-1\" waiRole=\"dialog\"></div>\n\t</div>\n\t<div class=\"dijitTooltipConnector\" waiRole=\"presenation\"></div>\n</div>\n",
postCreate: function(){
this.inherited(arguments);
this.connect(this.containerNode, "onkeypress", "_onKey");
this.containerNode.title = this.title;
},
orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ corner){
// summary: configure widget to be displayed in given position relative to the button
this.domNode.className="dijitTooltipDialog " +" dijitTooltipAB"+(corner.charAt(1)=='L'?"Left":"Right")+" dijitTooltip"+(corner.charAt(0)=='T' ? "Below" : "Above");
},
onOpen: function(/*Object*/ pos){
// summary: called when dialog is displayed
this._getFocusItems(this.containerNode);
this.orient(this.domNode,pos.aroundCorner, pos.corner);
this._loadCheck(); // lazy load trigger
dijit.focus(this._firstFocusItem);
},
_onKey: function(/*Event*/ evt){
// summary: keep keyboard focus in dialog; close dialog on escape key
var node = evt.target;
if (evt.keyCode == dojo.keys.TAB){
this._getFocusItems(this.containerNode);
}
var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
if(evt.keyCode == dojo.keys.ESCAPE){
this.onCancel();
}else if(node == this._firstFocusItem && evt.shiftKey && evt.keyCode == dojo.keys.TAB){
if(!singleFocusItem){
dijit.focus(this._lastFocusItem); // send focus to last item in dialog
}
dojo.stopEvent(evt);
}else if(node == this._lastFocusItem && evt.keyCode == dojo.keys.TAB && !evt.shiftKey){
if(!singleFocusItem){
dijit.focus(this._firstFocusItem); // send focus to first item in dialog
}
dojo.stopEvent(evt);
}else if(evt.keyCode == dojo.keys.TAB){
// we want the browser's default tab handling to move focus
// but we don't want the tab to propagate upwards
evt.stopPropagation();
}
}
}
);
}

373
includes/js/dijit/Editor.js Normal file
View file

@ -0,0 +1,373 @@
if(!dojo._hasResource["dijit.Editor"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Editor"] = true;
dojo.provide("dijit.Editor");
dojo.require("dijit._editor.RichText");
dojo.require("dijit.Toolbar");
dojo.require("dijit._editor._Plugin");
dojo.require("dijit._Container");
dojo.require("dojo.i18n");
dojo.requireLocalization("dijit._editor", "commands", null, "zh,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu,ROOT");
dojo.declare(
"dijit.Editor",
dijit._editor.RichText,
{
// summary: A rich-text Editing widget
// plugins: Array
// a list of plugin names (as strings) or instances (as objects)
// for this widget.
plugins: null,
// extraPlugins: Array
// a list of extra plugin names which will be appended to plugins array
extraPlugins: null,
constructor: function(){
if(!dojo.isArray(this.plugins)){
this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull"/*"createLink"*/];
}
this._plugins=[];
this._editInterval = this.editActionInterval * 1000;
},
postCreate: function(){
//for custom undo/redo
if(this.customUndo){
dojo['require']("dijit._editor.range");
this._steps=this._steps.slice(0);
this._undoedSteps=this._undoedSteps.slice(0);
// this.addKeyHandler('z',this.KEY_CTRL,this.undo);
// this.addKeyHandler('y',this.KEY_CTRL,this.redo);
}
if(dojo.isArray(this.extraPlugins)){
this.plugins=this.plugins.concat(this.extraPlugins);
}
// try{
this.inherited(arguments);
// dijit.Editor.superclass.postCreate.apply(this, arguments);
this.commands = dojo.i18n.getLocalization("dijit._editor", "commands", this.lang);
if(!this.toolbar){
// if we haven't been assigned a toolbar, create one
this.toolbar = new dijit.Toolbar({});
dojo.place(this.toolbar.domNode, this.editingArea, "before");
}
dojo.forEach(this.plugins, this.addPlugin, this);
this.onNormalizedDisplayChanged(); //update toolbar button status
// }catch(e){ console.debug(e); }
},
destroy: function(){
dojo.forEach(this._plugins, function(p){
if(p && p.destroy){
p.destroy();
}
});
this._plugins=[];
this.toolbar.destroy(); delete this.toolbar;
this.inherited(arguments);
},
addPlugin: function(/*String||Object*/plugin, /*Integer?*/index){
// summary:
// takes a plugin name as a string or a plugin instance and
// adds it to the toolbar and associates it with this editor
// instance. The resulting plugin is added to the Editor's
// plugins array. If index is passed, it's placed in the plugins
// array at that index. No big magic, but a nice helper for
// passing in plugin names via markup.
// plugin: String, args object or plugin instance. Required.
// args: This object will be passed to the plugin constructor.
// index:
// Integer, optional. Used when creating an instance from
// something already in this.plugins. Ensures that the new
// instance is assigned to this.plugins at that index.
var args=dojo.isString(plugin)?{name:plugin}:plugin;
if(!args.setEditor){
var o={"args":args,"plugin":null,"editor":this};
dojo.publish(dijit._scopeName + ".Editor.getPlugin",[o]);
if(!o.plugin){
var pc = dojo.getObject(args.name);
if(pc){
o.plugin=new pc(args);
}
}
if(!o.plugin){
console.warn('Cannot find plugin',plugin);
return;
}
plugin=o.plugin;
}
if(arguments.length > 1){
this._plugins[index] = plugin;
}else{
this._plugins.push(plugin);
}
plugin.setEditor(this);
if(dojo.isFunction(plugin.setToolbar)){
plugin.setToolbar(this.toolbar);
}
},
/* beginning of custom undo/redo support */
// customUndo: Boolean
// Whether we shall use custom undo/redo support instead of the native
// browser support. By default, we only enable customUndo for IE, as it
// has broken native undo/redo support. Note: the implementation does
// support other browsers which have W3C DOM2 Range API.
customUndo: dojo.isIE,
// editActionInterval: Integer
// When using customUndo, not every keystroke will be saved as a step.
// Instead typing (including delete) will be grouped together: after
// a user stop typing for editActionInterval seconds, a step will be
// saved; if a user resume typing within editActionInterval seconds,
// the timeout will be restarted. By default, editActionInterval is 3
// seconds.
editActionInterval: 3,
beginEditing: function(cmd){
if(!this._inEditing){
this._inEditing=true;
this._beginEditing(cmd);
}
if(this.editActionInterval>0){
if(this._editTimer){
clearTimeout(this._editTimer);
}
this._editTimer = setTimeout(dojo.hitch(this, this.endEditing), this._editInterval);
}
},
_steps:[],
_undoedSteps:[],
execCommand: function(cmd){
if(this.customUndo && (cmd=='undo' || cmd=='redo')){
return this[cmd]();
}else{
try{
if(this.customUndo){
this.endEditing();
this._beginEditing();
}
var r = this.inherited('execCommand',arguments);
if(this.customUndo){
this._endEditing();
}
return r;
}catch(e){
if(dojo.isMoz && /copy|cut|paste/.test(cmd)){
// Warn user of platform limitation. Cannot programmatically access keyboard. See ticket #4136
var sub = dojo.string.substitute,
accel = {cut:'X', copy:'C', paste:'V'},
isMac = navigator.userAgent.indexOf("Macintosh") != -1;
alert(sub(this.commands.systemShortcutFF,
[this.commands[cmd], sub(this.commands[isMac ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
}
return false;
}
}
},
queryCommandEnabled: function(cmd){
if(this.customUndo && (cmd=='undo' || cmd=='redo')){
return cmd=='undo'?(this._steps.length>1):(this._undoedSteps.length>0);
}else{
return this.inherited('queryCommandEnabled',arguments);
}
},
_moveToBookmark: function(b){
var bookmark=b;
if(dojo.isIE){
if(dojo.isArray(b)){//IE CONTROL
bookmark=[];
dojo.forEach(b,function(n){
bookmark.push(dijit.range.getNode(n,this.editNode));
},this);
}
}else{//w3c range
var r=dijit.range.create();
r.setStart(dijit.range.getNode(b.startContainer,this.editNode),b.startOffset);
r.setEnd(dijit.range.getNode(b.endContainer,this.editNode),b.endOffset);
bookmark=r;
}
dojo.withGlobal(this.window,'moveToBookmark',dijit,[bookmark]);
},
_changeToStep: function(from,to){
this.setValue(to.text);
var b=to.bookmark;
if(!b){ return; }
this._moveToBookmark(b);
},
undo: function(){
// console.log('undo');
this.endEditing(true);
var s=this._steps.pop();
if(this._steps.length>0){
this.focus();
this._changeToStep(s,this._steps[this._steps.length-1]);
this._undoedSteps.push(s);
this.onDisplayChanged();
return true;
}
return false;
},
redo: function(){
// console.log('redo');
this.endEditing(true);
var s=this._undoedSteps.pop();
if(s && this._steps.length>0){
this.focus();
this._changeToStep(this._steps[this._steps.length-1],s);
this._steps.push(s);
this.onDisplayChanged();
return true;
}
return false;
},
endEditing: function(ignore_caret){
if(this._editTimer){
clearTimeout(this._editTimer);
}
if(this._inEditing){
this._endEditing(ignore_caret);
this._inEditing=false;
}
},
_getBookmark: function(){
var b=dojo.withGlobal(this.window,dijit.getBookmark);
var tmp=[];
if(dojo.isIE){
if(dojo.isArray(b)){//CONTROL
dojo.forEach(b,function(n){
tmp.push(dijit.range.getIndex(n,this.editNode).o);
},this);
b=tmp;
}
}else{//w3c range
tmp=dijit.range.getIndex(b.startContainer,this.editNode).o;
b={startContainer:tmp,
startOffset:b.startOffset,
endContainer:b.endContainer===b.startContainer?tmp:dijit.range.getIndex(b.endContainer,this.editNode).o,
endOffset:b.endOffset};
}
return b;
},
_beginEditing: function(cmd){
if(this._steps.length===0){
this._steps.push({'text':this.savedContent,'bookmark':this._getBookmark()});
}
},
_endEditing: function(ignore_caret){
var v=this.getValue(true);
this._undoedSteps=[];//clear undoed steps
this._steps.push({text: v, bookmark: this._getBookmark()});
},
onKeyDown: function(e){
if(!this.customUndo){
this.inherited('onKeyDown',arguments);
return;
}
var k = e.keyCode, ks = dojo.keys;
if(e.ctrlKey && !e.altKey){//undo and redo only if the special right Alt + z/y are not pressed #5892
if(k == 90 || k == 122){ //z
dojo.stopEvent(e);
this.undo();
return;
}else if(k == 89 || k == 121){ //y
dojo.stopEvent(e);
this.redo();
return;
}
}
this.inherited('onKeyDown',arguments);
switch(k){
case ks.ENTER:
case ks.BACKSPACE:
case ks.DELETE:
this.beginEditing();
break;
case 88: //x
case 86: //v
if(e.ctrlKey && !e.altKey && !e.metaKey){
this.endEditing();//end current typing step if any
if(e.keyCode == 88){
this.beginEditing('cut');
//use timeout to trigger after the cut is complete
setTimeout(dojo.hitch(this, this.endEditing), 1);
}else{
this.beginEditing('paste');
//use timeout to trigger after the paste is complete
setTimeout(dojo.hitch(this, this.endEditing), 1);
}
break;
}
//pass through
default:
if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<dojo.keys.F1 || e.keyCode>dojo.keys.F15)){
this.beginEditing();
break;
}
//pass through
case ks.ALT:
this.endEditing();
break;
case ks.UP_ARROW:
case ks.DOWN_ARROW:
case ks.LEFT_ARROW:
case ks.RIGHT_ARROW:
case ks.HOME:
case ks.END:
case ks.PAGE_UP:
case ks.PAGE_DOWN:
this.endEditing(true);
break;
//maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
case ks.CTRL:
case ks.SHIFT:
case ks.TAB:
break;
}
},
_onBlur: function(){
this.inherited('_onBlur',arguments);
this.endEditing(true);
},
onClick: function(){
this.endEditing(true);
this.inherited('onClick',arguments);
}
/* end of custom undo/redo support */
}
);
/* the following code is to registered a handler to get default plugins */
dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
if(o.plugin){ return; }
var args = o.args, p;
var _p = dijit._editor._Plugin;
var name = args.name;
switch(name){
case "undo": case "redo": case "cut": case "copy": case "paste": case "insertOrderedList":
case "insertUnorderedList": case "indent": case "outdent": case "justifyCenter":
case "justifyFull": case "justifyLeft": case "justifyRight": case "delete":
case "selectAll": case "removeFormat":
case "insertHorizontalRule":
p = new _p({ command: name });
break;
case "bold": case "italic": case "underline": case "strikethrough":
case "subscript": case "superscript":
p = new _p({ buttonClass: dijit.form.ToggleButton, command: name });
break;
case "|":
p = new _p({ button: new dijit.ToolbarSeparator() });
}
// console.log('name',name,p);
o.plugin=p;
});
}

View file

@ -0,0 +1,422 @@
if(!dojo._hasResource["dijit.InlineEditBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.InlineEditBox"] = true;
dojo.provide("dijit.InlineEditBox");
dojo.require("dojo.i18n");
dojo.require("dijit._Widget");
dojo.require("dijit._Container");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");
dojo.requireLocalization("dijit", "common", null, "zh,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,ROOT,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu");
dojo.declare("dijit.InlineEditBox",
dijit._Widget,
{
// summary: An element with in-line edit capabilitites
//
// description:
// Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
// when you click it, an editor shows up in place of the original
// text. Optionally, Save and Cancel button are displayed below the edit widget.
// When Save is clicked, the text is pulled from the edit
// widget and redisplayed and the edit widget is again hidden.
// By default a plain Textarea widget is used as the editor (or for
// inline values a TextBox), but you can specify an editor such as
// dijit.Editor (for editing HTML) or a Slider (for adjusting a number).
// An edit widget must support the following API to be used:
// String getDisplayedValue() OR String getValue()
// void setDisplayedValue(String) OR void setValue(String)
// void focus()
//
// editing: Boolean
// Is the node currently in edit mode?
editing: false,
// autoSave: Boolean
// Changing the value automatically saves it; don't have to push save button
// (and save button isn't even displayed)
autoSave: true,
// buttonSave: String
// Save button label
buttonSave: "",
// buttonCancel: String
// Cancel button label
buttonCancel: "",
// renderAsHtml: Boolean
// Set this to true if the specified Editor's value should be interpreted as HTML
// rather than plain text (ie, dijit.Editor)
renderAsHtml: false,
// editor: String
// Class name for Editor widget
editor: "dijit.form.TextBox",
// editorParams: Object
// Set of parameters for editor, like {required: true}
editorParams: {},
onChange: function(value){
// summary: User should set this handler to be notified of changes to value
},
// width: String
// Width of editor. By default it's width=100% (ie, block mode)
width: "100%",
// value: String
// The display value of the widget in read-only mode
value: "",
// noValueIndicator: String
// The text that gets displayed when there is no value (so that the user has a place to click to edit)
noValueIndicator: "<span style='font-family: wingdings; text-decoration: underline;'>&nbsp;&nbsp;&nbsp;&nbsp;&#x270d;&nbsp;&nbsp;&nbsp;&nbsp;</span>",
postMixInProperties: function(){
this.inherited('postMixInProperties', arguments);
// save pointer to original source node, since Widget nulls-out srcNodeRef
this.displayNode = this.srcNodeRef;
// connect handlers to the display node
var events = {
ondijitclick: "_onClick",
onmouseover: "_onMouseOver",
onmouseout: "_onMouseOut",
onfocus: "_onMouseOver",
onblur: "_onMouseOut"
};
for(var name in events){
this.connect(this.displayNode, name, events[name]);
}
dijit.setWaiRole(this.displayNode, "button");
if(!this.displayNode.getAttribute("tabIndex")){
this.displayNode.setAttribute("tabIndex", 0);
}
this.setValue(this.value || this.displayNode.innerHTML);
},
setDisabled: function(/*Boolean*/ disabled){
// summary:
// Set disabled state of widget.
this.disabled = disabled;
dijit.setWaiState(this.focusNode || this.domNode, "disabled", disabled);
},
_onMouseOver: function(){
dojo.addClass(this.displayNode, this.disabled ? "dijitDisabledClickableRegion" : "dijitClickableRegion");
},
_onMouseOut: function(){
dojo.removeClass(this.displayNode, this.disabled ? "dijitDisabledClickableRegion" : "dijitClickableRegion");
},
_onClick: function(/*Event*/ e){
if(this.disabled){ return; }
if(e){ dojo.stopEvent(e); }
this._onMouseOut();
// Since FF gets upset if you move a node while in an event handler for that node...
setTimeout(dojo.hitch(this, "_edit"), 0);
},
_edit: function(){
// summary: display the editor widget in place of the original (read only) markup
this.editing = true;
var editValue =
(this.renderAsHtml ?
this.value :
this.value.replace(/\s*\r?\n\s*/g,"").replace(/<br\/?>/gi, "\n").replace(/&gt;/g,">").replace(/&lt;/g,"<").replace(/&amp;/g,"&"));
// Placeholder for edit widget
// Put place holder (and eventually editWidget) before the display node so that it's positioned correctly
// when Calendar dropdown appears, which happens automatically on focus.
var placeholder = dojo.doc.createElement("span");
dojo.place(placeholder, this.domNode, "before");
var ew = this.editWidget = new dijit._InlineEditor({
value: dojo.trim(editValue),
autoSave: this.autoSave,
buttonSave: this.buttonSave,
buttonCancel: this.buttonCancel,
renderAsHtml: this.renderAsHtml,
editor: this.editor,
editorParams: this.editorParams,
style: dojo.getComputedStyle(this.displayNode),
save: dojo.hitch(this, "save"),
cancel: dojo.hitch(this, "cancel"),
width: this.width
}, placeholder);
// to avoid screen jitter, we first create the editor with position:absolute, visibility:hidden,
// and then when it's finished rendering, we switch from display mode to editor
var ews = ew.domNode.style;
this.displayNode.style.display="none";
ews.position = "static";
ews.visibility = "visible";
// Replace the display widget with edit widget, leaving them both displayed for a brief time so that
// focus can be shifted without incident. (browser may needs some time to render the editor.)
this.domNode = ew.domNode;
setTimeout(function(){
ew.focus();
}, 100);
},
_showText: function(/*Boolean*/ focus){
// summary: revert to display mode, and optionally focus on display node
// display the read-only text and then quickly hide the editor (to avoid screen jitter)
this.displayNode.style.display="";
var ew = this.editWidget;
var ews = ew.domNode.style;
ews.position="absolute";
ews.visibility="hidden";
this.domNode = this.displayNode;
if(focus){
dijit.focus(this.displayNode);
}
ews.display = "none";
// give the browser some time to render the display node and then shift focus to it
// and hide the edit widget before garbage collecting the edit widget
setTimeout(function(){
ew.destroy();
delete ew;
if(dojo.isIE){
// messing with the DOM tab order can cause IE to focus the body - so restore
dijit.focus(dijit.getFocus());
}
}, 1000); // no hurry - wait for things to quiesce
},
save: function(/*Boolean*/ focus){
// summary:
// Save the contents of the editor and revert to display mode.
// focus: Boolean
// Focus on the display mode text
this.editing = false;
var value = this.editWidget.getValue() + "";
if(!this.renderAsHtml){
value = value.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;")
.replace(/\n/g, "<br>");
}
this.setValue(value);
// tell the world that we have changed
this.onChange(value);
this._showText(focus);
},
setValue: function(/*String*/ val){
// summary: inserts specified HTML value into this node, or an "input needed" character if node is blank
this.value = val;
this.displayNode.innerHTML = dojo.trim(val) || this.noValueIndicator;
},
getValue: function(){
return this.value;
},
cancel: function(/*Boolean*/ focus){
// summary:
// Revert to display mode, discarding any changes made in the editor
this.editing = false;
this._showText(focus);
}
});
dojo.declare(
"dijit._InlineEditor",
[dijit._Widget, dijit._Templated],
{
// summary:
// internal widget used by InlineEditBox, displayed when in editing mode
// to display the editor and maybe save/cancel buttons. Calling code should
// connect to save/cancel methods to detect when editing is finished
//
// Has mainly the same parameters as InlineEditBox, plus these values:
//
// style: Object
// Set of CSS attributes of display node, to replicate in editor
//
// value: String
// Value as an HTML string or plain text string, depending on renderAsHTML flag
templateString:"<fieldset dojoAttachPoint=\"editNode\" waiRole=\"presentation\" style=\"position: absolute; visibility:hidden\" class=\"dijitReset dijitInline\"\n\tdojoAttachEvent=\"onkeypress: _onKeyPress\" \n\t><input dojoAttachPoint=\"editorPlaceholder\"\n\t/><span dojoAttachPoint=\"buttonContainer\"\n\t\t><button class='saveButton' dojoAttachPoint=\"saveButton\" dojoType=\"dijit.form.Button\" dojoAttachEvent=\"onClick:save\" disabled=\"true\">${buttonSave}</button\n\t\t><button class='cancelButton' dojoAttachPoint=\"cancelButton\" dojoType=\"dijit.form.Button\" dojoAttachEvent=\"onClick:cancel\">${buttonCancel}</button\n\t></span\n></fieldset>\n",
widgetsInTemplate: true,
postMixInProperties: function(){
this.inherited('postMixInProperties', arguments);
this.messages = dojo.i18n.getLocalization("dijit", "common", this.lang);
dojo.forEach(["buttonSave", "buttonCancel"], function(prop){
if(!this[prop]){ this[prop] = this.messages[prop]; }
}, this);
},
postCreate: function(){
// Create edit widget in place in the template
var cls = dojo.getObject(this.editor);
var ew = this.editWidget = new cls(this.editorParams, this.editorPlaceholder);
// Copy the style from the source
// Don't copy ALL properties though, just the necessary/applicable ones
var srcStyle = this.style;
dojo.forEach(["fontWeight","fontFamily","fontSize","fontStyle"], function(prop){
ew.focusNode.style[prop]=srcStyle[prop];
}, this);
dojo.forEach(["marginTop","marginBottom","marginLeft", "marginRight"], function(prop){
this.domNode.style[prop]=srcStyle[prop];
}, this);
if(this.width=="100%"){
// block mode
ew.domNode.style.width = "100%"; // because display: block doesn't work for table widgets
this.domNode.style.display="block";
}else{
// inline-block mode
ew.domNode.style.width = this.width + (Number(this.width)==this.width ? "px" : "");
}
this.connect(ew, "onChange", "_onChange");
// Monitor keypress on the edit widget. Note that edit widgets do a stopEvent() on ESC key (to
// prevent Dialog from closing when the user just wants to revert the value in the edit widget),
// so this is the only way we can see the key press event.
this.connect(ew.focusNode || ew.domNode, "onkeypress", "_onKeyPress");
// priorityChange=false will prevent bogus onChange event
(this.editWidget.setDisplayedValue||this.editWidget.setValue).call(this.editWidget, this.value, false);
this._initialText = this.getValue();
if(this.autoSave){
this.buttonContainer.style.display="none";
}
},
destroy: function(){
this.editWidget.destroy();
this.inherited(arguments);
},
getValue: function(){
var ew = this.editWidget;
return ew.getDisplayedValue ? ew.getDisplayedValue() : ew.getValue();
},
_onKeyPress: function(e){
// summary: Callback when keypress in the edit box (see template).
// description:
// For autoSave widgets, if Esc/Enter, call cancel/save.
// For non-autoSave widgets, enable save button if the text value is
// different than the original value.
if(this._exitInProgress){
return;
}
if(this.autoSave){
if(e.altKey || e.ctrlKey){ return; }
// If Enter/Esc pressed, treat as save/cancel.
if(e.keyCode == dojo.keys.ESCAPE){
dojo.stopEvent(e);
this._exitInProgress = true;
this.cancel(true);
}else if(e.keyCode == dojo.keys.ENTER){
dojo.stopEvent(e);
this._exitInProgress = true;
this.save(true);
}else if(e.keyCode == dojo.keys.TAB){
this._exitInProgress = true;
// allow the TAB to change focus before we mess with the DOM: #6227
// Expounding by request:
// The current focus is on the edit widget input field.
// save() will hide and destroy this widget.
// We want the focus to jump from the currently hidden
// displayNode, but since it's hidden, it's impossible to
// unhide it, focus it, and then have the browser focus
// away from it to the next focusable element since each
// of these events is asynchronous and the focus-to-next-element
// is already queued.
// So we allow the browser time to unqueue the move-focus event
// before we do all the hide/show stuff.
setTimeout(dojo.hitch(this, "save", false), 0);
}
}else{
var _this = this;
// Delay before calling getValue().
// The delay gives the browser a chance to update the Textarea.
setTimeout(
function(){
_this.saveButton.setAttribute("disabled", _this.getValue() == _this._initialText);
}, 100);
}
},
_onBlur: function(){
// summary:
// Called when focus moves outside the editor
this.inherited(arguments);
if(this._exitInProgress){
// when user clicks the "save" button, focus is shifted back to display text, causing this
// function to be called, but in that case don't do anything
return;
}
if(this.autoSave){
this._exitInProgress = true;
if(this.getValue() == this._initialText){
this.cancel(false);
}else{
this.save(false);
}
}
},
enableSave: function(){
// summary: User replacable function returning a Boolean to indicate
// if the Save button should be enabled or not - usually due to invalid conditions
return this.editWidget.isValid ? this.editWidget.isValid() : true; // Boolean
},
_onChange: function(){
// summary:
// Called when the underlying widget fires an onChange event,
// which means that the user has finished entering the value
if(this._exitInProgress){
// TODO: the onChange event might happen after the return key for an async widget
// like FilteringSelect. Shouldn't be deleting the edit widget on end-of-edit
return;
}
if(this.autoSave){
this._exitInProgress = true;
this.save(true);
}else{
// in case the keypress event didn't get through (old problem with Textarea that has been fixed
// in theory) or if the keypress event comes too quickly and the value inside the Textarea hasn't
// been updated yet)
this.saveButton.setAttribute("disabled", (this.getValue() == this._initialText) || !this.enableSave());
}
},
enableSave: function(){
// summary: User replacable function returning a Boolean to indicate
// if the Save button should be enabled or not - usually due to invalid conditions
return this.editWidget.isValid ? this.editWidget.isValid() : true;
},
focus: function(){
this.editWidget.focus();
dijit.selectInputText(this.editWidget.focusNode);
}
});
}

195
includes/js/dijit/LICENSE Normal file
View file

@ -0,0 +1,195 @@
Dojo is available under *either* the terms of the modified BSD license *or* the
Academic Free License version 2.1. As a recipient of Dojo, you may choose which
license to receive this code under (except as noted in per-module LICENSE
files). Some modules may not be the copyright of the Dojo Foundation. These
modules contain explicit declarations of copyright in both the LICENSE files in
the directories in which they reside and in the code itself. No external
contributions are allowed under licenses which are fundamentally incompatible
with the AFL or BSD licenses that Dojo is distributed under.
The text of the AFL and BSD licenses is reproduced below.
-------------------------------------------------------------------------------
The "New" BSD License:
**********************
Copyright (c) 2005-2008, The Dojo Foundation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dojo Foundation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------------------
The Academic Free License, v. 2.1:
**********************************
This Academic Free License (the "License") applies to any original work of
authorship (the "Original Work") whose owner (the "Licensor") has placed the
following notice immediately following the copyright notice for the Original
Work:
Licensed under the Academic Free License version 2.1
1) Grant of Copyright License. Licensor hereby grants You a world-wide,
royalty-free, non-exclusive, perpetual, sublicenseable license to do the
following:
a) to reproduce the Original Work in copies;
b) to prepare derivative works ("Derivative Works") based upon the Original
Work;
c) to distribute copies of the Original Work and Derivative Works to the
public;
d) to perform the Original Work publicly; and
e) to display the Original Work publicly.
2) Grant of Patent License. Licensor hereby grants You a world-wide,
royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
claims owned or controlled by the Licensor that are embodied in the Original
Work as furnished by the Licensor, to make, use, sell and offer for sale the
Original Work and Derivative Works.
3) Grant of Source Code License. The term "Source Code" means the preferred
form of the Original Work for making modifications to it and all available
documentation describing how to modify the Original Work. Licensor hereby
agrees to provide a machine-readable copy of the Source Code of the Original
Work along with each copy of the Original Work that Licensor distributes.
Licensor reserves the right to satisfy this obligation by placing a
machine-readable copy of the Source Code in an information repository
reasonably calculated to permit inexpensive and convenient access by You for as
long as Licensor continues to distribute the Original Work, and by publishing
the address of that information repository in a notice immediately following
the copyright notice that applies to the Original Work.
4) Exclusions From License Grant. Neither the names of Licensor, nor the names
of any contributors to the Original Work, nor any of their trademarks or
service marks, may be used to endorse or promote products derived from this
Original Work without express prior written permission of the Licensor. Nothing
in this License shall be deemed to grant any rights to trademarks, copyrights,
patents, trade secrets or any other intellectual property of Licensor except as
expressly stated herein. No patent license is granted to make, use, sell or
offer to sell embodiments of any patent claims other than the licensed claims
defined in Section 2. No right is granted to the trademarks of Licensor even if
such marks are included in the Original Work. Nothing in this License shall be
interpreted to prohibit Licensor from licensing under different terms from this
License any Original Work that Licensor otherwise would have a right to
license.
5) This section intentionally omitted.
6) Attribution Rights. You must retain, in the Source Code of any Derivative
Works that You create, all copyright, patent or trademark notices from the
Source Code of the Original Work, as well as any notices of licensing and any
descriptive text identified therein as an "Attribution Notice." You must cause
the Source Code for any Derivative Works that You create to carry a prominent
Attribution Notice reasonably calculated to inform recipients that You have
modified the Original Work.
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
the copyright in and to the Original Work and the patent rights granted herein
by Licensor are owned by the Licensor or are sublicensed to You under the terms
of this License with the permission of the contributor(s) of those copyrights
and patent rights. Except as expressly stated in the immediately proceeding
sentence, the Original Work is provided under this License on an "AS IS" BASIS
and WITHOUT WARRANTY, either express or implied, including, without limitation,
the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
license to Original Work is granted hereunder except under this disclaimer.
8) Limitation of Liability. Under no circumstances and under no legal theory,
whether in tort (including negligence), contract, or otherwise, shall the
Licensor be liable to any person for any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License
or the use of the Original Work including, without limitation, damages for loss
of goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses. This limitation of liability shall not
apply to liability for death or personal injury resulting from Licensor's
negligence to the extent applicable law prohibits such limitation. Some
jurisdictions do not allow the exclusion or limitation of incidental or
consequential damages, so this exclusion and limitation may not apply to You.
9) Acceptance and Termination. If You distribute copies of the Original Work or
a Derivative Work, You must make a reasonable effort under the circumstances to
obtain the express assent of recipients to the terms of this License. Nothing
else but this License (or another written agreement between Licensor and You)
grants You permission to create Derivative Works based upon the Original Work
or to exercise any of the rights granted in Section 1 herein, and any attempt
to do so except under the terms of this License (or another written agreement
between Licensor and You) is expressly prohibited by U.S. copyright law, the
equivalent laws of other countries, and by international treaty. Therefore, by
exercising any of the rights granted to You in Section 1 herein, You indicate
Your acceptance of this License and all of its terms and conditions.
10) Termination for Patent Action. This License shall terminate automatically
and You may no longer exercise any of the rights granted to You by this License
as of the date You commence an action, including a cross-claim or counterclaim,
against Licensor or any licensee alleging that the Original Work infringes a
patent. This termination provision shall not apply for an action alleging
patent infringement by combinations of the Original Work with other software or
hardware.
11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
License may be brought only in the courts of a jurisdiction wherein the
Licensor resides or in which Licensor conducts its primary business, and under
the laws of that jurisdiction excluding its conflict-of-law provisions. The
application of the United Nations Convention on Contracts for the International
Sale of Goods is expressly excluded. Any use of the Original Work outside the
scope of this License or after its termination shall be subject to the
requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
seq., the equivalent laws of other countries, and international treaty. This
section shall survive the termination of this License.
12) Attorneys Fees. In any action to enforce the terms of this License or
seeking damages relating thereto, the prevailing party shall be entitled to
recover its costs and expenses, including, without limitation, reasonable
attorneys' fees and costs incurred in connection with such action, including
any appeal of such action. This section shall survive the termination of this
License.
13) Miscellaneous. This License represents the complete agreement concerning
the subject matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent necessary to
make it enforceable.
14) Definition of "You" in This License. "You" throughout this License, whether
in upper or lower case, means an individual or a legal entity exercising rights
under, and complying with all of the terms of, this License. For legal
entities, "You" includes any entity that controls, is controlled by, or is
under common control with you. For purposes of this definition, "control" means
(i) the power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty percent
(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
entity.
15) Right to Use. You may use the Original Work in all ways not otherwise
restricted or conditioned by this License or by law, and Licensor promises not
to interfere with or be responsible for such uses by You.
This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
Permission is hereby granted to copy and distribute this license without
modification. This license may not be modified without the express written
permission of its copyright owner.

487
includes/js/dijit/Menu.js Normal file
View file

@ -0,0 +1,487 @@
if(!dojo._hasResource["dijit.Menu"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Menu"] = true;
dojo.provide("dijit.Menu");
dojo.require("dijit._Widget");
dojo.require("dijit._Container");
dojo.require("dijit._Templated");
dojo.declare("dijit.Menu",
[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
{
// summary
// A context menu you can assign to multiple elements
constructor: function(){
this._bindings = [];
},
templateString:
'<table class="dijit dijitMenu dijitReset dijitMenuTable" waiRole="menu" dojoAttachEvent="onkeypress:_onKeyPress">' +
'<tbody class="dijitReset" dojoAttachPoint="containerNode"></tbody>'+
'</table>',
// targetNodeIds: String[]
// Array of dom node ids of nodes to attach to.
// Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
targetNodeIds: [],
// contextMenuForWindow: Boolean
// if true, right clicking anywhere on the window will cause this context menu to open;
// if false, must specify targetNodeIds
contextMenuForWindow: false,
// leftClickToOpen: Boolean
// If true, menu will open on left click instead of right click, similiar to a file menu.
leftClickToOpen: false,
// parentMenu: Widget
// pointer to menu that displayed me
parentMenu: null,
// popupDelay: Integer
// number of milliseconds before hovering (without clicking) causes the popup to automatically open
popupDelay: 500,
// _contextMenuWithMouse: Boolean
// used to record mouse and keyboard events to determine if a context
// menu is being opened with the keyboard or the mouse
_contextMenuWithMouse: false,
postCreate: function(){
if(this.contextMenuForWindow){
this.bindDomNode(dojo.body());
}else{
dojo.forEach(this.targetNodeIds, this.bindDomNode, this);
}
this.connectKeyNavHandlers([dojo.keys.UP_ARROW], [dojo.keys.DOWN_ARROW]);
},
startup: function(){
if(this._started){ return; }
dojo.forEach(this.getChildren(), function(child){ child.startup(); });
this.startupKeyNavChildren();
this.inherited(arguments);
},
onExecute: function(){
// summary: attach point for notification about when a menu item has been executed
},
onCancel: function(/*Boolean*/ closeAll){
// summary: attach point for notification about when the user cancels the current menu
},
_moveToPopup: function(/*Event*/ evt){
if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
this.focusedChild._onClick(evt);
}
},
_onKeyPress: function(/*Event*/ evt){
// summary: Handle keyboard based menu navigation.
if(evt.ctrlKey || evt.altKey){ return; }
switch(evt.keyCode){
case dojo.keys.RIGHT_ARROW:
this._moveToPopup(evt);
dojo.stopEvent(evt);
break;
case dojo.keys.LEFT_ARROW:
if(this.parentMenu){
this.onCancel(false);
}else{
dojo.stopEvent(evt);
}
break;
}
},
onItemHover: function(/*MenuItem*/ item){
// summary: Called when cursor is over a MenuItem
this.focusChild(item);
if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
}
},
_onChildBlur: function(item){
// summary: Close all popups that are open and descendants of this menu
dijit.popup.close(item.popup);
item._blur();
this._stopPopupTimer();
},
onItemUnhover: function(/*MenuItem*/ item){
// summary: Callback fires when mouse exits a MenuItem
},
_stopPopupTimer: function(){
if(this.hover_timer){
clearTimeout(this.hover_timer);
this.hover_timer = null;
}
},
_getTopMenu: function(){
for(var top=this; top.parentMenu; top=top.parentMenu);
return top;
},
onItemClick: function(/*Widget*/ item, /*Event*/ evt){
// summary: user defined function to handle clicks on an item
if(item.disabled){ return false; }
if(item.popup){
if(!this.is_open){
this._openPopup();
}
}else{
// before calling user defined handler, close hierarchy of menus
// and restore focus to place it was when menu was opened
this.onExecute();
// user defined handler for click
item.onClick(evt);
}
},
// thanks burstlib!
_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
// summary:
// Returns the window reference of the passed iframe
var win = dijit.getDocumentWindow(dijit.Menu._iframeContentDocument(iframe_el)) ||
// Moz. TODO: is this available when defaultView isn't?
dijit.Menu._iframeContentDocument(iframe_el)['__parent__'] ||
(iframe_el.name && dojo.doc.frames[iframe_el.name]) || null;
return win; // Window
},
_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
// summary:
// Returns a reference to the document object inside iframe_el
var doc = iframe_el.contentDocument // W3
|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
|| (iframe_el.name && dojo.doc.frames[iframe_el.name] && dojo.doc.frames[iframe_el.name].document)
|| null;
return doc; // HTMLDocument
},
bindDomNode: function(/*String|DomNode*/ node){
// summary: attach menu to given node
node = dojo.byId(node);
//TODO: this is to support context popups in Editor. Maybe this shouldn't be in dijit.Menu
var win = dijit.getDocumentWindow(node.ownerDocument);
if(node.tagName.toLowerCase()=="iframe"){
win = this._iframeContentWindow(node);
node = dojo.withGlobal(win, dojo.body);
}
// to capture these events at the top level,
// attach to document, not body
var cn = (node == dojo.body() ? dojo.doc : node);
node[this.id] = this._bindings.push([
dojo.connect(cn, (this.leftClickToOpen)?"onclick":"oncontextmenu", this, "_openMyself"),
dojo.connect(cn, "onkeydown", this, "_contextKey"),
dojo.connect(cn, "onmousedown", this, "_contextMouse")
]);
},
unBindDomNode: function(/*String|DomNode*/ nodeName){
// summary: detach menu from given node
var node = dojo.byId(nodeName);
if(node){
var bid = node[this.id]-1, b = this._bindings[bid];
dojo.forEach(b, dojo.disconnect);
delete this._bindings[bid];
}
},
_contextKey: function(e){
this._contextMenuWithMouse = false;
if(e.keyCode == dojo.keys.F10){
dojo.stopEvent(e);
if(e.shiftKey && e.type=="keydown"){
// FF: copying the wrong property from e will cause the system
// context menu to appear in spite of stopEvent. Don't know
// exactly which properties cause this effect.
var _e = { target: e.target, pageX: e.pageX, pageY: e.pageY };
_e.preventDefault = _e.stopPropagation = function(){};
// IE: without the delay, focus work in "open" causes the system
// context menu to appear in spite of stopEvent.
window.setTimeout(dojo.hitch(this, function(){ this._openMyself(_e); }), 1);
}
}
},
_contextMouse: function(e){
this._contextMenuWithMouse = true;
},
_openMyself: function(/*Event*/ e){
// summary:
// Internal function for opening myself when the user
// does a right-click or something similar
if(this.leftClickToOpen&&e.button>0){
return;
}
dojo.stopEvent(e);
// Get coordinates.
// if we are opening the menu with the mouse or on safari open
// the menu at the mouse cursor
// (Safari does not have a keyboard command to open the context menu
// and we don't currently have a reliable way to determine
// _contextMenuWithMouse on Safari)
var x,y;
if(dojo.isSafari || this._contextMenuWithMouse){
x=e.pageX;
y=e.pageY;
}else{
// otherwise open near e.target
var coords = dojo.coords(e.target, true);
x = coords.x + 10;
y = coords.y + 10;
}
var self=this;
var savedFocus = dijit.getFocus(this);
function closeAndRestoreFocus(){
// user has clicked on a menu or popup
dijit.focus(savedFocus);
dijit.popup.close(self);
}
dijit.popup.open({
popup: this,
x: x,
y: y,
onExecute: closeAndRestoreFocus,
onCancel: closeAndRestoreFocus,
orient: this.isLeftToRight() ? 'L' : 'R'
});
this.focus();
this._onBlur = function(){
this.inherited('_onBlur', arguments);
// Usually the parent closes the child widget but if this is a context
// menu then there is no parent
dijit.popup.close(this);
// don't try to restore focus; user has clicked another part of the screen
// and set focus there
}
},
onOpen: function(/*Event*/ e){
// summary: Open menu relative to the mouse
this.isShowingNow = true;
},
onClose: function(){
// summary: callback when this menu is closed
this._stopPopupTimer();
this.parentMenu = null;
this.isShowingNow = false;
this.currentPopup = null;
if(this.focusedChild){
this._onChildBlur(this.focusedChild);
this.focusedChild = null;
}
},
_openPopup: function(){
// summary: open the popup to the side of the current menu item
this._stopPopupTimer();
var from_item = this.focusedChild;
var popup = from_item.popup;
if(popup.isShowingNow){ return; }
popup.parentMenu = this;
var self = this;
dijit.popup.open({
parent: this,
popup: popup,
around: from_item.arrowCell,
orient: this.isLeftToRight() ? {'TR': 'TL', 'TL': 'TR'} : {'TL': 'TR', 'TR': 'TL'},
onCancel: function(){
// called when the child menu is canceled
dijit.popup.close(popup);
from_item.focus(); // put focus back on my node
self.currentPopup = null;
}
});
this.currentPopup = popup;
if(popup.focus){
popup.focus();
}
},
uninitialize: function(){
dojo.forEach(this.targetNodeIds, this.unBindDomNode, this);
this.inherited(arguments);
}
}
);
dojo.declare("dijit.MenuItem",
[dijit._Widget, dijit._Templated, dijit._Contained],
{
// summary: A line item in a Menu Widget
// Make 3 columns
// icon, label, and expand arrow (BiDi-dependent) indicating sub-menu
templateString:
'<tr class="dijitReset dijitMenuItem" '
+'dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">'
+'<td class="dijitReset"><div class="dijitMenuItemIcon ${iconClass}" dojoAttachPoint="iconNode"></div></td>'
+'<td tabIndex="-1" class="dijitReset dijitMenuItemLabel" dojoAttachPoint="containerNode,focusNode" waiRole="menuitem"></td>'
+'<td class="dijitReset" dojoAttachPoint="arrowCell">'
+'<div class="dijitMenuExpand" dojoAttachPoint="expand" style="display:none">'
+'<span class="dijitInline dijitArrowNode dijitMenuExpandInner">+</span>'
+'</div>'
+'</td>'
+'</tr>',
// label: String
// menu text
label: '',
// iconClass: String
// class to apply to div in button to make it display an icon
iconClass: "",
// disabled: Boolean
// if true, the menu item is disabled
// if false, the menu item is enabled
disabled: false,
postCreate: function(){
dojo.setSelectable(this.domNode, false);
this.setDisabled(this.disabled);
if(this.label){
this.setLabel(this.label);
}
},
_onHover: function(){
// summary: callback when mouse is moved onto menu item
this.getParent().onItemHover(this);
},
_onUnhover: function(){
// summary: callback when mouse is moved off of menu item
// if we are unhovering the currently selected item
// then unselect it
this.getParent().onItemUnhover(this);
},
_onClick: function(evt){
this.getParent().onItemClick(this, evt);
dojo.stopEvent(evt);
},
onClick: function(/*Event*/ evt){
// summary: User defined function to handle clicks
},
focus: function(){
dojo.addClass(this.domNode, 'dijitMenuItemHover');
try{
dijit.focus(this.containerNode);
}catch(e){
// this throws on IE (at least) in some scenarios
}
},
_blur: function(){
dojo.removeClass(this.domNode, 'dijitMenuItemHover');
},
setLabel: function(/*String*/ value){
this.containerNode.innerHTML=this.label=value;
},
setDisabled: function(/*Boolean*/ value){
// summary: enable or disable this menu item
this.disabled = value;
dojo[value ? "addClass" : "removeClass"](this.domNode, 'dijitMenuItemDisabled');
dijit.setWaiState(this.containerNode, 'disabled', value ? 'true' : 'false');
}
});
dojo.declare("dijit.PopupMenuItem",
dijit.MenuItem,
{
_fillContent: function(){
// summary: The innerHTML contains both the menu item text and a popup widget
// description: the first part holds the menu item text and the second part is the popup
// example:
// | <div dojoType="dijit.PopupMenuItem">
// | <span>pick me</span>
// | <popup> ... </popup>
// | </div>
if(this.srcNodeRef){
var nodes = dojo.query("*", this.srcNodeRef);
dijit.PopupMenuItem.superclass._fillContent.call(this, nodes[0]);
// save pointer to srcNode so we can grab the drop down widget after it's instantiated
this.dropDownContainer = this.srcNodeRef;
}
},
startup: function(){
if(this._started){ return; }
this.inherited(arguments);
// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
// land now. move it to dojo.doc.body.
if(!this.popup){
var node = dojo.query("[widgetId]", this.dropDownContainer)[0];
this.popup = dijit.byNode(node);
}
dojo.body().appendChild(this.popup.domNode);
this.popup.domNode.style.display="none";
dojo.addClass(this.expand, "dijitMenuExpandEnabled");
dojo.style(this.expand, "display", "");
dijit.setWaiState(this.containerNode, "haspopup", "true");
},
destroyDescendants: function(){
if(this.popup){
this.popup.destroyRecursive();
delete this.popup;
}
this.inherited(arguments);
}
});
dojo.declare("dijit.MenuSeparator",
[dijit._Widget, dijit._Templated, dijit._Contained],
{
// summary: A line between two menu items
templateString: '<tr class="dijitMenuSeparator"><td colspan=3>'
+'<div class="dijitMenuSeparatorTop"></div>'
+'<div class="dijitMenuSeparatorBottom"></div>'
+'</td></tr>',
postCreate: function(){
dojo.setSelectable(this.domNode, false);
},
isFocusable: function(){
// summary: over ride to always return false
return false; // Boolean
}
});
}

View file

@ -0,0 +1,95 @@
if(!dojo._hasResource["dijit.ProgressBar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.ProgressBar"] = true;
dojo.provide("dijit.ProgressBar");
dojo.require("dojo.fx");
dojo.require("dojo.number");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
// summary: A progress indication widget
//
// example:
// | <div dojoType="ProgressBar"
// | places="0"
// | progress="..." maximum="...">
// | </div>
//
// progress: String (Percentage or Number)
// initial progress value.
// with "%": percentage value, 0% <= progress <= 100%
// or without "%": absolute value, 0 <= progress <= maximum
progress: "0",
// maximum: Float
// max sample number
maximum: 100,
// places: Number
// number of places to show in values; 0 by default
places: 0,
// indeterminate: Boolean
// If false: show progress.
// If true: show that a process is underway but that the progress is unknown
indeterminate: false,
templateString:"<div class=\"dijitProgressBar dijitProgressBarEmpty\"\n\t><div waiRole=\"progressbar\" tabindex=\"0\" dojoAttachPoint=\"internalProgress\" class=\"dijitProgressBarFull\"\n\t\t><div class=\"dijitProgressBarTile\"></div\n\t\t><span style=\"visibility:hidden\">&nbsp;</span\n\t></div\n\t><div dojoAttachPoint=\"label\" class=\"dijitProgressBarLabel\" id=\"${id}_label\">&nbsp;</div\n\t><img dojoAttachPoint=\"inteterminateHighContrastImage\" class=\"dijitProgressBarIndeterminateHighContrastImage\"\n\t></img\n></div>\n",
_indeterminateHighContrastImagePath:
dojo.moduleUrl("dijit", "themes/a11y/indeterminate_progress.gif"),
// public functions
postCreate: function(){
this.inherited("postCreate",arguments);
this.inteterminateHighContrastImage.setAttribute("src",
this._indeterminateHighContrastImagePath);
this.update();
},
update: function(/*Object?*/attributes){
// summary: update progress information
//
// attributes: may provide progress and/or maximum properties on this parameter,
// see attribute specs for details.
dojo.mixin(this, attributes||{});
var percent = 1, classFunc;
if(this.indeterminate){
classFunc = "addClass";
dijit.removeWaiState(this.internalProgress, "valuenow");
dijit.removeWaiState(this.internalProgress, "valuemin");
dijit.removeWaiState(this.internalProgress, "valuemax");
}else{
classFunc = "removeClass";
if(String(this.progress).indexOf("%") != -1){
percent = Math.min(parseFloat(this.progress)/100, 1);
this.progress = percent * this.maximum;
}else{
this.progress = Math.min(this.progress, this.maximum);
percent = this.progress / this.maximum;
}
var text = this.report(percent);
this.label.firstChild.nodeValue = text;
dijit.setWaiState(this.internalProgress, "describedby", this.label.id);
dijit.setWaiState(this.internalProgress, "valuenow", this.progress);
dijit.setWaiState(this.internalProgress, "valuemin", 0);
dijit.setWaiState(this.internalProgress, "valuemax", this.maximum);
}
dojo[classFunc](this.domNode, "dijitProgressBarIndeterminate");
this.internalProgress.style.width = (percent * 100) + "%";
this.onChange();
},
report: function(/*float*/percent){
// Generates message to show; may be overridden by user
return dojo.number.format(percent, {type: "percent", places: this.places, locale: this.lang});
},
onChange: function(){
// summary: User definable function fired when progress updates.
}
});
}

View file

@ -0,0 +1,157 @@
if(!dojo._hasResource["dijit.TitlePane"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.TitlePane"] = true;
dojo.provide("dijit.TitlePane");
dojo.require("dojo.fx");
dojo.require("dijit._Templated");
dojo.require("dijit.layout.ContentPane");
dojo.declare(
"dijit.TitlePane",
[dijit.layout.ContentPane, dijit._Templated],
{
// summary: A pane with a title on top, that can be opened or collapsed.
//
// description: An accessible container with a Title Heading, and a content
// section that slides open and closed. TitlePane is an extension to
// ContentPane, providing all the usesful content-control aspects from.
//
// example:
// | // load a TitlePane from remote file:
// | var foo = new dijit.TitlePane({ href: "foobar.html", title:"Title" });
// | foo.startup();
//
// example:
// | <!-- markup href example: -->
// | <div dojoType="dijit.TitlePane" href="foobar.html" title="Title"></div>
//
// example:
// | <!-- markup with inline data -->
// | <div dojoType="dijit.TitlePane" title="Title">
// | <p>I am content</p>
// | </div>
//
// title: String
// Title of the pane
title: "",
// open: Boolean
// Whether pane is opened or closed.
open: true,
// duration: Integer
// Time in milliseconds to fade in/fade out
duration: 250,
// baseClass: String
// The root className to use for the various states of this widget
baseClass: "dijitTitlePane",
templateString:"<div class=\"${baseClass}\">\n\t<div dojoAttachEvent=\"onclick:toggle,onkeypress: _onTitleKey,onfocus:_handleFocus,onblur:_handleFocus\" tabindex=\"0\"\n\t\t\twaiRole=\"button\" class=\"dijitTitlePaneTitle\" dojoAttachPoint=\"titleBarNode,focusNode\">\n\t\t<div dojoAttachPoint=\"arrowNode\" class=\"dijitInline dijitArrowNode\"><span dojoAttachPoint=\"arrowNodeInner\" class=\"dijitArrowNodeInner\"></span></div>\n\t\t<div dojoAttachPoint=\"titleNode\" class=\"dijitTitlePaneTextNode\"></div>\n\t</div>\n\t<div class=\"dijitTitlePaneContentOuter\" dojoAttachPoint=\"hideNode\">\n\t\t<div class=\"dijitReset\" dojoAttachPoint=\"wipeNode\">\n\t\t\t<div class=\"dijitTitlePaneContentInner\" dojoAttachPoint=\"containerNode\" waiRole=\"region\" tabindex=\"-1\">\n\t\t\t\t<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc. Put padding on inner div. -->\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n",
postCreate: function(){
this.setTitle(this.title);
if(!this.open){
this.hideNode.style.display = this.wipeNode.style.display = "none";
}
this._setCss();
dojo.setSelectable(this.titleNode, false);
this.inherited(arguments);
dijit.setWaiState(this.containerNode, "labelledby", this.titleNode.id);
dijit.setWaiState(this.focusNode, "haspopup", "true");
// setup open/close animations
var hideNode = this.hideNode, wipeNode = this.wipeNode;
this._wipeIn = dojo.fx.wipeIn({
node: this.wipeNode,
duration: this.duration,
beforeBegin: function(){
hideNode.style.display="";
}
});
this._wipeOut = dojo.fx.wipeOut({
node: this.wipeNode,
duration: this.duration,
onEnd: function(){
hideNode.style.display="none";
}
});
},
setContent: function(content){
// summary:
// Typically called when an href is loaded. Our job is to make the animation smooth
if(!this.open || this._wipeOut.status() == "playing"){
// we are currently *closing* the pane (or the pane is closed), so just let that continue
this.inherited(arguments);
}else{
if(this._wipeIn.status() == "playing"){
this._wipeIn.stop();
}
// freeze container at current height so that adding new content doesn't make it jump
dojo.marginBox(this.wipeNode, { h: dojo.marginBox(this.wipeNode).h });
// add the new content (erasing the old content, if any)
this.inherited(arguments);
// call _wipeIn.play() to animate from current height to new height
this._wipeIn.play();
}
},
toggle: function(){
// summary: switches between opened and closed state
dojo.forEach([this._wipeIn, this._wipeOut], function(animation){
if(animation.status() == "playing"){
animation.stop();
}
});
this[this.open ? "_wipeOut" : "_wipeIn"].play();
this.open =! this.open;
// load content (if this is the first time we are opening the TitlePane
// and content is specified as an href, or we have setHref when hidden)
this._loadCheck();
this._setCss();
},
_setCss: function(){
// summary: set the open/close css state for the TitlePane
var classes = ["dijitClosed", "dijitOpen"];
var boolIndex = this.open;
var node = this.titleBarNode || this.focusNode
dojo.removeClass(node, classes[!boolIndex+0]);
node.className += " " + classes[boolIndex+0];
// provide a character based indicator for images-off mode
this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
},
_onTitleKey: function(/*Event*/ e){
// summary: callback when user hits a key
if(e.keyCode == dojo.keys.ENTER || e.charCode == dojo.keys.SPACE){
this.toggle();
}else if(e.keyCode == dojo.keys.DOWN_ARROW && this.open){
this.containerNode.focus();
e.preventDefault();
}
},
_handleFocus: function(/*Event*/ e){
// summary: handle blur and focus for this widget
// add/removeClass is safe to call without hasClass in this case
dojo[(e.type == "focus" ? "addClass" : "removeClass")](this.focusNode, this.baseClass + "Focused");
},
setTitle: function(/*String*/ title){
// summary: sets the text of the title
this.titleNode.innerHTML = title;
}
});
}

View file

@ -0,0 +1,54 @@
if(!dojo._hasResource["dijit.Toolbar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Toolbar"] = true;
dojo.provide("dijit.Toolbar");
dojo.require("dijit._Widget");
dojo.require("dijit._Container");
dojo.require("dijit._Templated");
dojo.declare("dijit.Toolbar",
[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
{
// summary: A Toolbar widget, used to hold things like dijit.Editor buttons
templateString:
'<div class="dijit dijitToolbar" waiRole="toolbar" tabIndex="${tabIndex}" dojoAttachPoint="containerNode">' +
// '<table style="table-layout: fixed" class="dijitReset dijitToolbarTable">' + // factor out style
// '<tr class="dijitReset" dojoAttachPoint="containerNode"></tr>'+
// '</table>' +
'</div>',
tabIndex: "0",
postCreate: function(){
this.connectKeyNavHandlers(
this.isLeftToRight() ? [dojo.keys.LEFT_ARROW] : [dojo.keys.RIGHT_ARROW],
this.isLeftToRight() ? [dojo.keys.RIGHT_ARROW] : [dojo.keys.LEFT_ARROW]
);
},
startup: function(){
if(this._started){ return; }
this.startupKeyNavChildren();
this.inherited(arguments);
}
}
);
// Combine with dijit.MenuSeparator??
dojo.declare("dijit.ToolbarSeparator",
[ dijit._Widget, dijit._Templated ],
{
// summary: A spacer between two Toolbar items
templateString: '<div class="dijitToolbarSeparator dijitInline"></div>',
postCreate: function(){ dojo.setSelectable(this.domNode, false); },
isFocusable: function(){
// summary: This widget isn't focusable, so pass along that fact.
return false;
}
});
}

View file

@ -0,0 +1,292 @@
if(!dojo._hasResource["dijit.Tooltip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit.Tooltip"] = true;
dojo.provide("dijit.Tooltip");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare(
"dijit._MasterTooltip",
[dijit._Widget, dijit._Templated],
{
// summary
// Internal widget that holds the actual tooltip markup,
// which occurs once per page.
// Called by Tooltip widgets which are just containers to hold
// the markup
// duration: Integer
// Milliseconds to fade in/fade out
duration: 200,
templateString:"<div class=\"dijitTooltip dijitTooltipLeft\" id=\"dojoTooltip\">\n\t<div class=\"dijitTooltipContainer dijitTooltipContents\" dojoAttachPoint=\"containerNode\" waiRole='alert'></div>\n\t<div class=\"dijitTooltipConnector\"></div>\n</div>\n",
postCreate: function(){
dojo.body().appendChild(this.domNode);
this.bgIframe = new dijit.BackgroundIframe(this.domNode);
// Setup fade-in and fade-out functions.
this.fadeIn = dojo.fadeIn({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onShow") });
this.fadeOut = dojo.fadeOut({ node: this.domNode, duration: this.duration, onEnd: dojo.hitch(this, "_onHide") });
},
show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
// summary:
// Display tooltip w/specified contents to right specified node
// (To left if there's no space on the right, or if LTR==right)
if(this.aroundNode && this.aroundNode === aroundNode){
return;
}
if(this.fadeOut.status() == "playing"){
// previous tooltip is being hidden; wait until the hide completes then show new one
this._onDeck=arguments;
return;
}
this.containerNode.innerHTML=innerHTML;
// Firefox bug. when innerHTML changes to be shorter than previous
// one, the node size will not be updated until it moves.
this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
// position the element and change CSS according to position[] (a list of positions to try)
var align = {};
var ltr = this.isLeftToRight();
dojo.forEach( (position && position.length) ? position : dijit.Tooltip.defaultPosition, function(pos){
switch(pos){
case "after":
align[ltr ? "BR" : "BL"] = ltr ? "BL" : "BR";
break;
case "before":
align[ltr ? "BL" : "BR"] = ltr ? "BR" : "BL";
break;
case "below":
// first try to align left borders, next try to align right borders (or reverse for RTL mode)
align[ltr ? "BL" : "BR"] = ltr ? "TL" : "TR";
align[ltr ? "BR" : "BL"] = ltr ? "TR" : "TL";
break;
case "above":
default:
// first try to align left borders, next try to align right borders (or reverse for RTL mode)
align[ltr ? "TL" : "TR"] = ltr ? "BL" : "BR";
align[ltr ? "TR" : "TL"] = ltr ? "BR" : "BL";
break;
}
});
var pos = dijit.placeOnScreenAroundElement(this.domNode, aroundNode, align, dojo.hitch(this, "orient"));
// show it
dojo.style(this.domNode, "opacity", 0);
this.fadeIn.play();
this.isShowingNow = true;
this.aroundNode = aroundNode;
},
orient: function(/* DomNode */ node, /* String */ aroundCorner, /* String */ tooltipCorner){
// summary: private function to set CSS for tooltip node based on which position it's in
node.className = "dijitTooltip " +
{
"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
"BR-BL": "dijitTooltipRight",
"BL-BR": "dijitTooltipLeft"
}[aroundCorner + "-" + tooltipCorner];
},
_onShow: function(){
if(dojo.isIE){
// the arrow won't show up on a node w/an opacity filter
this.domNode.style.filter="";
}
},
hide: function(aroundNode){
// summary: hide the tooltip
if(!this.aroundNode || this.aroundNode !== aroundNode){
return;
}
if(this._onDeck){
// this hide request is for a show() that hasn't even started yet;
// just cancel the pending show()
this._onDeck=null;
return;
}
this.fadeIn.stop();
this.isShowingNow = false;
this.aroundNode = null;
this.fadeOut.play();
},
_onHide: function(){
this.domNode.style.cssText=""; // to position offscreen again
if(this._onDeck){
// a show request has been queued up; do it now
this.show.apply(this, this._onDeck);
this._onDeck=null;
}
}
}
);
dijit.showTooltip = function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position){
// summary:
// Display tooltip w/specified contents in specified position.
// See description of dijit.Tooltip.defaultPosition for details on position parameter.
// If position is not specified then dijit.Tooltip.defaultPosition is used.
if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
return dijit._masterTT.show(innerHTML, aroundNode, position);
};
dijit.hideTooltip = function(aroundNode){
// summary: hide the tooltip
if(!dijit._masterTT){ dijit._masterTT = new dijit._MasterTooltip(); }
return dijit._masterTT.hide(aroundNode);
};
dojo.declare(
"dijit.Tooltip",
dijit._Widget,
{
// summary
// Pops up a tooltip (a help message) when you hover over a node.
// label: String
// Text to display in the tooltip.
// Specified as innerHTML when creating the widget from markup.
label: "",
// showDelay: Integer
// Number of milliseconds to wait after hovering over/focusing on the object, before
// the tooltip is displayed.
showDelay: 400,
// connectId: String[]
// Id(s) of domNodes to attach the tooltip to.
// When user hovers over any of the specified dom nodes, the tooltip will appear.
connectId: [],
// position: String[]
// See description of dijit.Tooltip.defaultPosition for details on position parameter.
position: [],
postCreate: function(){
if(this.srcNodeRef){
this.srcNodeRef.style.display = "none";
}
this._connectNodes = [];
dojo.forEach(this.connectId, function(id) {
var node = dojo.byId(id);
if (node) {
this._connectNodes.push(node);
dojo.forEach(["onMouseOver", "onMouseOut", "onFocus", "onBlur", "onHover", "onUnHover"], function(event){
this.connect(node, event.toLowerCase(), "_"+event);
}, this);
if(dojo.isIE){
// BiDi workaround
node.style.zoom = 1;
}
}
}, this);
},
_onMouseOver: function(/*Event*/ e){
this._onHover(e);
},
_onMouseOut: function(/*Event*/ e){
if(dojo.isDescendant(e.relatedTarget, e.target)){
// false event; just moved from target to target child; ignore.
return;
}
this._onUnHover(e);
},
_onFocus: function(/*Event*/ e){
this._focus = true;
this._onHover(e);
this.inherited(arguments);
},
_onBlur: function(/*Event*/ e){
this._focus = false;
this._onUnHover(e);
this.inherited(arguments);
},
_onHover: function(/*Event*/ e){
if(!this._showTimer){
var target = e.target;
this._showTimer = setTimeout(dojo.hitch(this, function(){this.open(target)}), this.showDelay);
}
},
_onUnHover: function(/*Event*/ e){
// keep a tooltip open if the associated element has focus
if(this._focus){ return; }
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
this.close();
},
open: function(/*DomNode*/ target){
// summary: display the tooltip; usually not called directly.
target = target || this._connectNodes[0];
if(!target){ return; }
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
dijit.showTooltip(this.label || this.domNode.innerHTML, target, this.position);
this._connectNode = target;
},
close: function(){
// summary: hide the tooltip; usually not called directly.
dijit.hideTooltip(this._connectNode);
delete this._connectNode;
if(this._showTimer){
clearTimeout(this._showTimer);
delete this._showTimer;
}
},
uninitialize: function(){
this.close();
}
}
);
// dijit.Tooltip.defaultPosition: String[]
// This variable controls the position of tooltips, if the position is not specified to
// the Tooltip widget or *TextBox widget itself. It's an array of strings with the following values:
//
// * before: places tooltip to the left of the target node/widget, or to the right in
// the case of RTL scripts like Hebrew and Arabic
// * after: places tooltip to the right of the target node/widget, or to the left in
// the case of RTL scripts like Hebrew and Arabic
// * above: tooltip goes above target node
// * below: tooltip goes below target node
//
// The list is positions is tried, in order, until a position is found where the tooltip fits
// within the viewport.
//
// Be careful setting this parameter. A value of "above" may work fine until the user scrolls
// the screen so that there's no room above the target node. Nodes with drop downs, like
// DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
// that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
// is only room below (or above) the target node, but not both.
dijit.Tooltip.defaultPosition = ["after", "before"];
}

1336
includes/js/dijit/Tree.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,239 @@
if(!dojo._hasResource["dijit._Calendar"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._Calendar"] = true;
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.declare(
"dijit._Calendar",
[dijit._Widget, dijit._Templated],
{
//
// 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 is used internally by other widgets and is not accessible
// as a standalone widget.
// 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:"<table cellspacing=\"0\" cellpadding=\"0\" class=\"dijitCalendarContainer\">\n\t<thead>\n\t\t<tr class=\"dijitReset dijitCalendarMonthContainer\" valign=\"top\">\n\t\t\t<th class='dijitReset' dojoAttachPoint=\"decrementMonth\">\n\t\t\t\t<div class=\"dijitInline dijitCalendarIncrementControl dijitCalendarDecrease\"><span dojoAttachPoint=\"decreaseArrowNode\" class=\"dijitA11ySideArrow dijitCalendarIncrementControl dijitCalendarDecreaseInner\">-</span></div>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' colspan=\"5\">\n\t\t\t\t<div dojoAttachPoint=\"monthLabelSpacer\" class=\"dijitCalendarMonthLabelSpacer\"></div>\n\t\t\t\t<div dojoAttachPoint=\"monthLabelNode\" class=\"dijitCalendarMonthLabel\"></div>\n\t\t\t</th>\n\t\t\t<th class='dijitReset' dojoAttachPoint=\"incrementMonth\">\n\t\t\t\t<div class=\"dijitInline dijitCalendarIncrementControl dijitCalendarIncrease\"><span dojoAttachPoint=\"increaseArrowNode\" class=\"dijitA11ySideArrow dijitCalendarIncrementControl dijitCalendarIncreaseInner\">+</span></div>\n\t\t\t</th>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<th class=\"dijitReset dijitCalendarDayLabelTemplate\"><span class=\"dijitCalendarDayLabel\"></span></th>\n\t\t</tr>\n\t</thead>\n\t<tbody dojoAttachEvent=\"onclick: _onDayClick\" class=\"dijitReset dijitCalendarBodyContainer\">\n\t\t<tr class=\"dijitReset dijitCalendarWeekTemplate\">\n\t\t\t<td class=\"dijitReset dijitCalendarDateTemplate\"><span class=\"dijitCalendarDateLabel\"></span></td>\n\t\t</tr>\n\t</tbody>\n\t<tfoot class=\"dijitReset dijitCalendarYearContainer\">\n\t\t<tr>\n\t\t\t<td class='dijitReset' valign=\"top\" colspan=\"7\">\n\t\t\t\t<h3 class=\"dijitCalendarYearLabel\">\n\t\t\t\t\t<span dojoAttachPoint=\"previousYearLabelNode\" class=\"dijitInline dijitCalendarPreviousYear\"></span>\n\t\t\t\t\t<span dojoAttachPoint=\"currentYearLabelNode\" class=\"dijitInline dijitCalendarSelectedYear\"></span>\n\t\t\t\t\t<span dojoAttachPoint=\"nextYearLabelNode\" class=\"dijitInline dijitCalendarNextYear\"></span>\n\t\t\t\t</h3>\n\t\t\t</td>\n\t\t</tr>\n\t</tfoot>\n</table>\t\n",
// value: Date
// the currently selected Date
value: new Date(),
// dayWidth: String
// How to represent the days of the week in the calendar header. See dojo.date.locale
dayWidth: "narrow",
setValue: function(/*Date*/ value){
// summary: set the current date and update the UI. If the date is disabled, the selection will
// not change, but the display will change to the corresponding month.
if(!this.value || dojo.date.compare(value, this.value)){
value = new Date(value);
this.displayMonth = new Date(value);
if(!this.isDisabledDate(value, this.lang)){
this.value = value;
this.value.setHours(0,0,0,0);
this.onChange(this.value);
}
this._populateGrid();
}
},
_setText: function(node, text){
while(node.firstChild){
node.removeChild(node.firstChild);
}
node.appendChild(dojo.doc.createTextNode(text));
},
_populateGrid: function(){
var month = this.displayMonth;
month.setDate(1);
var firstDay = month.getDay();
var daysInMonth = dojo.date.getDaysInMonth(month);
var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(month, "month", -1));
var today = new Date();
var selected = this.value;
var 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 Date(month);
var 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 = dojo.date.add(date, "month", adj);
}
date.setDate(number);
if(!dojo.date.compare(date, today, "date")){
clazz = "dijitCalendarCurrentDate " + clazz;
}
if(!dojo.date.compare(date, selected, "date")){
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];
this._setText(label, date.getDate());
}, this);
// Fill in localized month name
var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
this._setText(this.monthLabelNode, monthNames[month.getMonth()]);
// Fill in localized prev/current/next years
var y = month.getFullYear() - 1;
var d = new Date();
dojo.forEach(["previous", "current", "next"], function(name){
d.setFullYear(y++);
this._setText(this[name+"YearLabelNode"],
dojo.date.locale.format(d, {selector:'year', locale:this.lang}));
}, this);
// Set up repeating mouse behavior
var _this = this;
var typematic = function(nodeProp, dateProp, adj){
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);
},
goToToday: function(){
this.setValue(new Date());
},
postCreate: function(){
this.inherited(arguments);
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 = dojo.date.locale.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);
// Fill in spacer element with all the month names (invisible) so that the maximum width will affect layout
var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
dojo.forEach(monthNames, function(name){
var monthSpacer = dojo.doc.createElement("div");
this._setText(monthSpacer, name);
this.monthLabelSpacer.appendChild(monthSpacer);
}, this);
this.value = null;
this.setValue(new Date());
},
_adjustDisplay: function(/*String*/part, /*int*/amount){
this.displayMonth = dojo.date.add(this.displayMonth, part, amount);
this._populateGrid();
},
_onDayClick: function(/*Event*/evt){
var node = evt.target;
dojo.stopEvent(evt);
while(!node.dijitDateValue){
node = node.parentNode;
}
if(!dojo.hasClass(node, "dijitCalendarDisabledDate")){
this.setValue(node.dijitDateValue);
this.onValueSelected(this.value);
}
},
onValueSelected: function(/*Date*/date){
// summary: a date cell was selected. It may be the same as the previous value.
},
onChange: function(/*Date*/date){
// summary: called only when the selected date has changed
},
isDisabledDate: function(/*Date*/dateObject, /*String?*/locale){
// summary:
// May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
/*=====
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.
/*=====
return ""; // String
=====*/
}
}
);
}

View file

@ -0,0 +1,346 @@
if(!dojo._hasResource["dijit._Container"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._Container"] = true;
dojo.provide("dijit._Container");
dojo.declare("dijit._Contained",
null,
{
// summary
// Mixin for widgets that are children of a container widget
//
// example:
// | // make a basic custom widget that knows about it's parents
// | dojo.declare("my.customClass",[dijit._Widget,dijit._Contained],{});
//
getParent: function(){
// summary:
// Returns the parent widget of this widget, assuming the parent
// implements dijit._Container
for(var p=this.domNode.parentNode; p; p=p.parentNode){
var id = p.getAttribute && p.getAttribute("widgetId");
if(id){
var parent = dijit.byId(id);
return parent.isContainer ? parent : null;
}
}
return null;
},
_getSibling: function(which){
var node = this.domNode;
do{
node = node[which+"Sibling"];
}while(node && node.nodeType != 1);
if(!node){ return null; } // null
var id = node.getAttribute("widgetId");
return dijit.byId(id);
},
getPreviousSibling: function(){
// summary:
// Returns null if this is the first child of the parent,
// otherwise returns the next element sibling to the "left".
return this._getSibling("previous"); // Mixed
},
getNextSibling: function(){
// summary:
// Returns null if this is the last child of the parent,
// otherwise returns the next element sibling to the "right".
return this._getSibling("next"); // Mixed
}
}
);
dojo.declare("dijit._Container",
null,
{
// summary:
// Mixin for widgets that contain a list of children.
// description:
// Use this mixin when the widget needs to know about and
// keep track of it's widget children. Widgets like SplitContainer
// and TabContainer.
isContainer: true,
addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
// summary:
// Process the given child widget, inserting it's dom node as
// a child of our dom node
if(insertIndex === undefined){
insertIndex = "last";
}
var refNode = this.containerNode || this.domNode;
if(insertIndex && typeof insertIndex == "number"){
var children = dojo.query("> [widgetid]", refNode);
if(children && children.length >= insertIndex){
refNode = children[insertIndex-1]; insertIndex = "after";
}
}
dojo.place(widget.domNode, refNode, insertIndex);
// If I've been started but the child widget hasn't been started,
// start it now. Make sure to do this after widget has been
// inserted into the DOM tree, so it can see that it's being controlled by me,
// so it doesn't try to size itself.
if(this._started && !widget._started){
widget.startup();
}
},
removeChild: function(/*Widget*/ widget){
// summary:
// Removes the passed widget instance from this widget but does
// not destroy it
var node = widget.domNode;
node.parentNode.removeChild(node); // detach but don't destroy
},
_nextElement: function(node){
do{
node = node.nextSibling;
}while(node && node.nodeType != 1);
return node;
},
_firstElement: function(node){
node = node.firstChild;
if(node && node.nodeType != 1){
node = this._nextElement(node);
}
return node;
},
getChildren: function(){
// summary:
// Returns array of children widgets
return dojo.query("> [widgetId]", this.containerNode || this.domNode).map(dijit.byNode); // Array
},
hasChildren: function(){
// summary:
// Returns true if widget has children
var cn = this.containerNode || this.domNode;
return !!this._firstElement(cn); // Boolean
},
_getSiblingOfChild: function(/*Widget*/ child, /*int*/ dir){
// summary:
// Get the next or previous widget sibling of child
// dir:
// if 1, get the next sibling
// if -1, get the previous sibling
var node = child.domNode;
var which = (dir>0 ? "nextSibling" : "previousSibling");
do{
node = node[which];
}while(node && (node.nodeType != 1 || !dijit.byNode(node)));
return node ? dijit.byNode(node) : null;
}
}
);
dojo.declare("dijit._KeyNavContainer",
[dijit._Container],
{
// summary: A _Container with keyboard navigation of its children.
// decscription:
// To use this mixin, call connectKeyNavHandlers() in
// postCreate() and call startupKeyNavChildren() in startup().
// It provides normalized keyboard and focusing code for Container
// widgets.
/*=====
// focusedChild: Widget
// The currently focused child widget, or null if there isn't one
focusedChild: null,
=====*/
_keyNavCodes: {},
connectKeyNavHandlers: function(/*Array*/ prevKeyCodes, /*Array*/ nextKeyCodes){
// summary:
// Call in postCreate() to attach the keyboard handlers
// to the container.
// preKeyCodes: Array
// Key codes for navigating to the previous child.
// nextKeyCodes: Array
// Key codes for navigating to the next child.
var keyCodes = this._keyNavCodes = {};
var prev = dojo.hitch(this, this.focusPrev);
var next = dojo.hitch(this, this.focusNext);
dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev });
dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next });
this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
this.connect(this.domNode, "onfocus", "_onContainerFocus");
},
startupKeyNavChildren: function(){
// summary:
// Call in startup() to set child tabindexes to -1
dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
},
addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
// summary: Add a child to our _Container
dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
this._startupChild(widget);
},
focus: function(){
// summary: Default focus() implementation: focus the first child.
this.focusFirstChild();
},
focusFirstChild: function(){
// summary: Focus the first focusable child in the container.
this.focusChild(this._getFirstFocusableChild());
},
focusNext: function(){
// summary: Focus the next widget or focal node (for widgets
// with multiple focal nodes) within this container.
if(this.focusedChild && this.focusedChild.hasNextFocalNode
&& this.focusedChild.hasNextFocalNode()){
this.focusedChild.focusNext();
return;
}
var child = this._getNextFocusableChild(this.focusedChild, 1);
if(child.getFocalNodes){
this.focusChild(child, child.getFocalNodes()[0]);
}else{
this.focusChild(child);
}
},
focusPrev: function(){
// summary: Focus the previous widget or focal node (for widgets
// with multiple focal nodes) within this container.
if(this.focusedChild && this.focusedChild.hasPrevFocalNode
&& this.focusedChild.hasPrevFocalNode()){
this.focusedChild.focusPrev();
return;
}
var child = this._getNextFocusableChild(this.focusedChild, -1);
if(child.getFocalNodes){
var nodes = child.getFocalNodes();
this.focusChild(child, nodes[nodes.length-1]);
}else{
this.focusChild(child);
}
},
focusChild: function(/*Widget*/ widget, /*Node?*/ node){
// summary: Focus widget. Optionally focus 'node' within widget.
if(widget){
if(this.focusedChild && widget !== this.focusedChild){
this._onChildBlur(this.focusedChild);
}
this.focusedChild = widget;
if(node && widget.focusFocalNode){
widget.focusFocalNode(node);
}else{
widget.focus();
}
}
},
_startupChild: function(/*Widget*/ widget){
// summary:
// Set tabindex="-1" on focusable widgets so that we
// can focus them programmatically and by clicking.
// Connect focus and blur handlers.
if(widget.getFocalNodes){
dojo.forEach(widget.getFocalNodes(), function(node){
dojo.attr(node, "tabindex", -1);
this._connectNode(node);
}, this);
}else{
var node = widget.focusNode || widget.domNode;
if(widget.isFocusable()){
dojo.attr(node, "tabindex", -1);
}
this._connectNode(node);
}
},
_connectNode: function(/*Element*/ node){
this.connect(node, "onfocus", "_onNodeFocus");
this.connect(node, "onblur", "_onNodeBlur");
},
_onContainerFocus: function(evt){
// focus bubbles on Firefox,
// so just make sure that focus has really gone to the container
if(evt.target === this.domNode){
this.focusFirstChild();
}
},
_onContainerKeypress: function(evt){
if(evt.ctrlKey || evt.altKey){ return; }
var func = this._keyNavCodes[evt.keyCode];
if(func){
func();
dojo.stopEvent(evt);
}
},
_onNodeFocus: function(evt){
// while focus is on a child,
// take the container out of the tab order so that
// we can shift-tab to the element before the container
dojo.attr(this.domNode, "tabindex", -1);
// record the child that has been focused
var widget = dijit.getEnclosingWidget(evt.target);
if(widget && widget.isFocusable()){
this.focusedChild = widget;
}
dojo.stopEvent(evt);
},
_onNodeBlur: function(evt){
// when focus leaves a child,
// reinstate the container's tabindex
if(this.tabIndex){
dojo.attr(this.domNode, "tabindex", this.tabIndex);
}
dojo.stopEvent(evt);
},
_onChildBlur: function(/*Widget*/ widget){
// summary:
// Called when focus leaves a child widget to go
// to a sibling widget.
},
_getFirstFocusableChild: function(){
return this._getNextFocusableChild(null, 1);
},
_getNextFocusableChild: function(child, dir){
if(child){
child = this._getSiblingOfChild(child, dir);
}
var children = this.getChildren();
for(var i=0; i < children.length; i++){
if(!child){
child = children[(dir>0) ? 0 : (children.length-1)];
}
if(child.isFocusable()){
return child;
}
child = this._getSiblingOfChild(child, dir);
}
// no focusable child found
return null;
}
}
);
}

View file

@ -0,0 +1,329 @@
if(!dojo._hasResource["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._Templated"] = true;
dojo.provide("dijit._Templated");
dojo.require("dijit._Widget");
dojo.require("dojo.string");
dojo.require("dojo.parser");
dojo.declare("dijit._Templated",
null,
{
// summary:
// Mixin for widgets that are instantiated from a template
//
// templateNode: DomNode
// a node that represents the widget template. Pre-empts both templateString and templatePath.
templateNode: null,
// templateString: String
// a string that represents the widget template. Pre-empts the
// templatePath. In builds that have their strings "interned", the
// templatePath is converted to an inline templateString, thereby
// preventing a synchronous network call.
templateString: null,
// templatePath: String
// Path to template (HTML file) for this widget relative to dojo.baseUrl
templatePath: null,
// widgetsInTemplate: Boolean
// should we parse the template to find widgets that might be
// declared in markup inside it? false by default.
widgetsInTemplate: false,
// containerNode: DomNode
// holds child elements. "containerNode" is generally set via a
// dojoAttachPoint assignment and it designates where children of
// the src dom node will be placed
containerNode: null,
// skipNodeCache: Boolean
// if using a cached widget template node poses issues for a
// particular widget class, it can set this property to ensure
// that its template is always re-built from a string
_skipNodeCache: false,
_stringRepl: function(tmpl){
var className = this.declaredClass, _this = this;
// Cache contains a string because we need to do property replacement
// do the property replacement
return dojo.string.substitute(tmpl, this, function(value, key){
if(key.charAt(0) == '!'){ value = _this[key.substr(1)]; }
if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide
if(!value){ return ""; }
// Substitution keys beginning with ! will skip the transform step,
// in case a user wishes to insert unescaped markup, e.g. ${!foo}
return key.charAt(0) == "!" ? value :
// Safer substitution, see heading "Attribute values" in
// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
value.toString().replace(/"/g,"&quot;"); //TODO: add &amp? use encodeXML method?
}, this);
},
// method over-ride
buildRendering: function(){
// summary:
// Construct the UI for this widget from a template, setting this.domNode.
// Lookup cached version of template, and download to cache if it
// isn't there already. Returns either a DomNode or a string, depending on
// whether or not the template contains ${foo} replacement parameters.
var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache);
var node;
if(dojo.isString(cached)){
node = dijit._Templated._createNodesFromText(this._stringRepl(cached))[0];
}else{
// if it's a node, all we have to do is clone it
node = cached.cloneNode(true);
}
// recurse through the node, looking for, and attaching to, our
// attachment points which should be defined on the template node.
this._attachTemplateNodes(node);
var source = this.srcNodeRef;
if(source && source.parentNode){
source.parentNode.replaceChild(node, source);
}
this.domNode = node;
if(this.widgetsInTemplate){
var cw = this._supportingWidgets = dojo.parser.parse(node);
this._attachTemplateNodes(cw, function(n,p){
return n[p];
});
}
this._fillContent(source);
},
_fillContent: function(/*DomNode*/ source){
// summary:
// relocate source contents to templated container node
// this.containerNode must be able to receive children, or exceptions will be thrown
var dest = this.containerNode;
if(source && dest){
while(source.hasChildNodes()){
dest.appendChild(source.firstChild);
}
}
},
_attachTemplateNodes: function(rootNode, getAttrFunc){
// summary: Iterate through the template and attach functions and nodes accordingly.
// description:
// Map widget properties and functions to the handlers specified in
// the dom node and it's descendants. This function iterates over all
// nodes and looks for these properties:
// * dojoAttachPoint
// * dojoAttachEvent
// * waiRole
// * waiState
// rootNode: DomNode|Array[Widgets]
// the node to search for properties. All children will be searched.
// getAttrFunc: function?
// a function which will be used to obtain property for a given
// DomNode/Widget
getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); };
var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
var x=dojo.isArray(rootNode)?0:-1;
for(; x<nodes.length; x++){
var baseNode = (x == -1) ? rootNode : nodes[x];
if(this.widgetsInTemplate && getAttrFunc(baseNode,'dojoType')){
continue;
}
// Process dojoAttachPoint
var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint");
if(attachPoint){
var point, points = attachPoint.split(/\s*,\s*/);
while((point = points.shift())){
if(dojo.isArray(this[point])){
this[point].push(baseNode);
}else{
this[point]=baseNode;
}
}
}
// Process dojoAttachEvent
var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent");
if(attachEvent){
// NOTE: we want to support attributes that have the form
// "domEvent: nativeEvent; ..."
var event, events = attachEvent.split(/\s*,\s*/);
var trim = dojo.trim;
while((event = events.shift())){
if(event){
var thisFunc = null;
if(event.indexOf(":") != -1){
// oh, if only JS had tuple assignment
var funcNameArr = event.split(":");
event = trim(funcNameArr[0]);
thisFunc = trim(funcNameArr[1]);
}else{
event = trim(event);
}
if(!thisFunc){
thisFunc = event;
}
this.connect(baseNode, event, thisFunc);
}
}
}
// waiRole, waiState
var role = getAttrFunc(baseNode, "waiRole");
if(role){
dijit.setWaiRole(baseNode, role);
}
var values = getAttrFunc(baseNode, "waiState");
if(values){
dojo.forEach(values.split(/\s*,\s*/), function(stateValue){
if(stateValue.indexOf('-') != -1){
var pair = stateValue.split('-');
dijit.setWaiState(baseNode, pair[0], pair[1]);
}
});
}
}
}
}
);
// key is either templatePath or templateString; object is either string or DOM tree
dijit._Templated._templateCache = {};
dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){
// summary:
// Static method to get a template based on the templatePath or
// templateString key
// templatePath: String
// The URL to get the template from. dojo.uri.Uri is often passed as well.
// templateString: String?
// a string to use in lieu of fetching the template from a URL. Takes precedence
// over templatePath
// Returns: Mixed
// Either string (if there are ${} variables that need to be replaced) or just
// a DOM tree (if the node can be cloned directly)
// is it already cached?
var tmplts = dijit._Templated._templateCache;
var key = templateString || templatePath;
var cached = tmplts[key];
if(cached){
return cached;
}
// If necessary, load template string from template path
if(!templateString){
templateString = dijit._Templated._sanitizeTemplateString(dojo._getText(templatePath));
}
templateString = dojo.string.trim(templateString);
if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){
// there are variables in the template so all we can do is cache the string
return (tmplts[key] = templateString); //String
}else{
// there are no variables in the template so we can cache the DOM tree
return (tmplts[key] = dijit._Templated._createNodesFromText(templateString)[0]); //Node
}
};
dijit._Templated._sanitizeTemplateString = function(/*String*/tString){
// summary:
// Strips <?xml ...?> declarations so that external SVG and XML
// documents can be added to a document without worry. Also, if the string
// is an HTML document, only the part inside the body tag is returned.
if(tString){
tString = tString.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, "");
var matches = tString.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);
if(matches){
tString = matches[1];
}
}else{
tString = "";
}
return tString; //String
};
if(dojo.isIE){
dojo.addOnUnload(function(){
var cache = dijit._Templated._templateCache;
for(var key in cache){
var value = cache[key];
if(!isNaN(value.nodeType)){ // isNode equivalent
dojo._destroyElement(value);
}
delete cache[key];
}
});
}
(function(){
var tagMap = {
cell: {re: /^<t[dh][\s\r\n>]/i, pre: "<table><tbody><tr>", post: "</tr></tbody></table>"},
row: {re: /^<tr[\s\r\n>]/i, pre: "<table><tbody>", post: "</tbody></table>"},
section: {re: /^<(thead|tbody|tfoot)[\s\r\n>]/i, pre: "<table>", post: "</table>"}
};
// dummy container node used temporarily to hold nodes being created
var tn;
dijit._Templated._createNodesFromText = function(/*String*/text){
// summary:
// Attempts to create a set of nodes based on the structure of the passed text.
if(!tn){
tn = dojo.doc.createElement("div");
tn.style.display="none";
dojo.body().appendChild(tn);
}
var tableType = "none";
var rtext = text.replace(/^\s+/, "");
for(var type in tagMap){
var map = tagMap[type];
if(map.re.test(rtext)){
tableType = type;
text = map.pre + text + map.post;
break;
}
}
tn.innerHTML = text;
if(tn.normalize){
tn.normalize();
}
var tag = { cell: "tr", row: "tbody", section: "table" }[tableType];
var _parent = (typeof tag != "undefined") ?
tn.getElementsByTagName(tag)[0] :
tn;
var nodes = [];
while(_parent.firstChild){
nodes.push(_parent.removeChild(_parent.firstChild));
}
tn.innerHTML="";
return nodes; // Array
}
})();
// These arguments can be specified for widgets which are used in templates.
// Since any widget can be specified as sub widgets in template, mix it
// into the base widget class. (This is a hack, but it's effective.)
dojo.extend(dijit._Widget,{
dojoAttachEvent: "",
dojoAttachPoint: "",
waiRole: "",
waiState:""
})
}

View file

@ -0,0 +1,249 @@
if(!dojo._hasResource["dijit._TimePicker"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._TimePicker"] = true;
dojo.provide("dijit._TimePicker");
dojo.require("dijit.form._FormWidget");
dojo.require("dojo.date.locale");
/*=====
dojo.declare(
"dijit._TimePicker.__Constraints",
[dojo.date.locale.__FormatOptions],
{
// clickableIncrement: String
// see dijit._TimePicker.clickableIncrement
clickableIncrement: "T00:15:00",
// visibleIncrement: String
// see dijit._TimePicker.visibleIncrement
visibleIncrement: "T01:00:00",
// visibleRange: String
// see dijit._TimePicker.visibleRange
visibleRange: "T05:00:00"
}
);
=====*/
dojo.declare("dijit._TimePicker",
[dijit._Widget, dijit._Templated],
{
// summary:
// A graphical time picker.
// This widget is used internally by other widgets and is not accessible
// as a standalone widget.
templateString:"<div id=\"widget_${id}\" class=\"dijitMenu\"\n ><div dojoAttachPoint=\"upArrow\" class=\"dijitButtonNode\"><span class=\"dijitTimePickerA11yText\">&#9650;</span></div\n ><div dojoAttachPoint=\"timeMenu,focusNode\" dojoAttachEvent=\"onclick:_onOptionSelected,onmouseover,onmouseout\"></div\n ><div dojoAttachPoint=\"downArrow\" class=\"dijitButtonNode\"><span class=\"dijitTimePickerA11yText\">&#9660;</span></div\n></div>\n",
baseClass: "dijitTimePicker",
// clickableIncrement: String
// ISO-8601 string representing the amount by which
// every clickable element in the time picker increases.
// Set in local time, without a time zone.
// Example: `T00:15:00` creates 15 minute increments
// Must divide dijit._TimePicker.visibleIncrement evenly
clickableIncrement: "T00:15:00",
// visibleIncrement: String
// ISO-8601 string representing the amount by which
// every element with a visible time in the time picker increases.
// Set in local time, without a time zone.
// Example: `T01:00:00` creates text in every 1 hour increment
visibleIncrement: "T01:00:00",
// visibleRange: String
// ISO-8601 string representing the range of this TimePicker.
// The TimePicker will only display times in this range.
// Example: `T05:00:00` displays 5 hours of options
visibleRange: "T05:00:00",
// value: String
// Date to display.
// Defaults to current time and date.
// Can be a Date object or an ISO-8601 string.
// If you specify the GMT time zone (`-01:00`),
// the time will be converted to the local time in the local time zone.
// Otherwise, the time is considered to be in the local time zone.
// If you specify the date and isDate is true, the date is used.
// Example: if your local time zone is `GMT -05:00`,
// `T10:00:00` becomes `T10:00:00-05:00` (considered to be local time),
// `T10:00:00-01:00` becomes `T06:00:00-05:00` (4 hour difference),
// `T10:00:00Z` becomes `T05:00:00-05:00` (5 hour difference between Zulu and local time)
// `yyyy-mm-ddThh:mm:ss` is the format to set the date and time
// Example: `2007-06-01T09:00:00`
value: new Date(),
_visibleIncrement:2,
_clickableIncrement:1,
_totalIncrements:10,
// constraints: dijit._TimePicker.__Constraints
constraints:{},
serialize: dojo.date.stamp.toISOString,
//TODOC: what is priority?
setValue:function(/*Date*/ date, /*Boolean*/ priority){
// summary:
// Set the value of the TimePicker
// Redraws the TimePicker around the new date
//dijit._TimePicker.superclass.setValue.apply(this, arguments);
this.value=date;
this._showText();
},
isDisabledDate: function(/*Date*/dateObject, /*String?*/locale){
// summary:
// May be overridden to disable certain dates in the TimePicker e.g. `isDisabledDate=dojo.date.locale.isWeekend`
return false; // Boolean
},
_showText:function(){
this.timeMenu.innerHTML = "";
var fromIso = dojo.date.stamp.fromISOString;
this._clickableIncrementDate=fromIso(this.clickableIncrement);
this._visibleIncrementDate=fromIso(this.visibleIncrement);
this._visibleRangeDate=fromIso(this.visibleRange);
// get the value of the increments and the range in seconds (since 00:00:00) to find out how many divs to create
var sinceMidnight = function(/*Date*/ date){
return date.getHours() * 60 * 60 + date.getMinutes() * 60 + date.getSeconds();
};
var clickableIncrementSeconds = sinceMidnight(this._clickableIncrementDate);
var visibleIncrementSeconds = sinceMidnight(this._visibleIncrementDate);
var visibleRangeSeconds = sinceMidnight(this._visibleRangeDate);
// round reference date to previous visible increment
var time = this.value.getTime();
this._refDate = new Date(time - time % (visibleIncrementSeconds*1000));
this._refDate.setFullYear(1970,0,1); // match parse defaults
// assume clickable increment is the smallest unit
this._clickableIncrement = 1;
// divide the visible range by the clickable increment to get the number of divs to create
// example: 10:00:00/00:15:00 -> display 40 divs
this._totalIncrements = visibleRangeSeconds / clickableIncrementSeconds;
// divide the visible increments by the clickable increments to get how often to display the time inline
// example: 01:00:00/00:15:00 -> display the time every 4 divs
this._visibleIncrement = visibleIncrementSeconds / clickableIncrementSeconds;
for(var i = -(this._totalIncrements >> 1); i < (this._totalIncrements >> 1); i += this._clickableIncrement){
this.timeMenu.appendChild(this._createOption(i));
}
// TODO:
// I commented this out because it
// causes problems for a TimeTextBox in a Dialog, or as the editor of an InlineEditBox,
// because the timeMenu node isn't visible yet. -- Bill (Bug #????)
// dijit.focus(this.timeMenu);
},
postCreate:function(){
// instantiate constraints
if(this.constraints===dijit._TimePicker.prototype.constraints){
this.constraints={};
}
// brings in visibleRange, increments, etc.
dojo.mixin(this, this.constraints);
// dojo.date.locale needs the lang in the constraints as locale
if(!this.constraints.locale){
this.constraints.locale=this.lang;
}
// assign typematic mouse listeners to the arrow buttons
this.connect(this.timeMenu, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
var typematic = dijit.typematic.addMouseListener;
typematic(this.upArrow,this,this._onArrowUp, 0.8, 500);
typematic(this.downArrow,this,this._onArrowDown, 0.8, 500);
//dijit.typematic.addListener(this.upArrow,this.timeMenu, {keyCode:dojo.keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_onArrowUp", 0.8, 500);
//dijit.typematic.addListener(this.downArrow, this.timeMenu, {keyCode:dojo.keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_onArrowDown", 0.8,500);
this.inherited(arguments);
this.setValue(this.value);
},
_createOption:function(/*Number*/ index){
// summary: creates a clickable time option
var div = dojo.doc.createElement("div");
var date = (div.date = new Date(this._refDate));
div.index = index;
var incrementDate = this._clickableIncrementDate;
date.setHours(date.getHours() + incrementDate.getHours() * index,
date.getMinutes() + incrementDate.getMinutes() * index,
date.getSeconds() + incrementDate.getSeconds() * index);
var innerDiv = dojo.doc.createElement('div');
dojo.addClass(div,this.baseClass+"Item");
dojo.addClass(innerDiv,this.baseClass+"ItemInner");
innerDiv.innerHTML = dojo.date.locale.format(date, this.constraints);
div.appendChild(innerDiv);
if(index%this._visibleIncrement<1 && index%this._visibleIncrement>-1){
dojo.addClass(div, this.baseClass+"Marker");
}else if(!(index%this._clickableIncrement)){
dojo.addClass(div, this.baseClass+"Tick");
}
if(this.isDisabledDate(date)){
// set disabled
dojo.addClass(div, this.baseClass+"ItemDisabled");
}
if(!dojo.date.compare(this.value, date, this.constraints.selector)){
div.selected = true;
dojo.addClass(div, this.baseClass+"ItemSelected");
}
return div;
},
_onOptionSelected:function(/*Object*/ tgt){
var tdate = tgt.target.date || tgt.target.parentNode.date;
if(!tdate || this.isDisabledDate(tdate)){ return; }
this.setValue(tdate);
this.onValueSelected(tdate);
},
onValueSelected:function(value){
},
onmouseover:function(/*Event*/ e){
var tgr = (e.target.parentNode === this.timeMenu) ? e.target : e.target.parentNode;
this._highlighted_option=tgr;
dojo.addClass(tgr, this.baseClass+"ItemHover");
},
onmouseout:function(/*Event*/ e){
var tgr = (e.target.parentNode === this.timeMenu) ? e.target : e.target.parentNode;
if(this._highlighted_option===tgr){
dojo.removeClass(tgr, this.baseClass+"ItemHover");
}
},
_mouseWheeled:function(/*Event*/e){
// summary: handle the mouse wheel listener
dojo.stopEvent(e);
// we're not _measuring_ the scroll amount, just direction
var scrollAmount = (dojo.isIE ? e.wheelDelta : -e.detail);
this[(scrollAmount>0 ? "_onArrowUp" : "_onArrowDown")](); // yes, we're making a new dom node every time you mousewheel, or click
},
_onArrowUp:function(){
// summary: remove the bottom time and add one to the top
var index = this.timeMenu.childNodes[0].index - 1;
var div = this._createOption(index);
this.timeMenu.removeChild(this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
this.timeMenu.insertBefore(div, this.timeMenu.childNodes[0]);
},
_onArrowDown:function(){
// summary: remove the top time and add one to the bottom
var index = this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1].index + 1;
var div = this._createOption(index);
this.timeMenu.removeChild(this.timeMenu.childNodes[0]);
this.timeMenu.appendChild(div);
}
}
);
}

View file

@ -0,0 +1,407 @@
if(!dojo._hasResource["dijit._Widget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._Widget"] = true;
dojo.provide("dijit._Widget");
dojo.require( "dijit._base" );
dojo.declare("dijit._Widget", null, {
// summary:
// The foundation of dijit widgets.
//
// id: String
// a unique, opaque ID string that can be assigned by users or by the
// system. If the developer passes an ID which is known not to be
// unique, the specified ID is ignored and the system-generated ID is
// used instead.
id: "",
// lang: String
// Rarely used. Overrides the default Dojo locale used to render this widget,
// as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
// Value must be among the list of locales specified during by the Dojo bootstrap,
// formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
lang: "",
// dir: String
// Unsupported by Dijit, but here for completeness. Dijit only supports setting text direction on the
// entire document.
// Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
// attribute. Either left-to-right "ltr" or right-to-left "rtl".
dir: "",
// class: String
// HTML class attribute
"class": "",
// style: String
// HTML style attribute
style: "",
// title: String
// HTML title attribute
title: "",
// srcNodeRef: DomNode
// pointer to original dom node
srcNodeRef: null,
// domNode: DomNode
// this is our visible representation of the widget! Other DOM
// Nodes may by assigned to other properties, usually through the
// template system's dojoAttachPonit syntax, but the domNode
// property is the canonical "top level" node in widget UI.
domNode: null,
// attributeMap: Object
// A map of attributes and attachpoints -- typically standard HTML attributes -- to set
// on the widget's dom, at the "domNode" attach point, by default.
// Other node references can be specified as properties of 'this'
attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""}, // TODO: add on* handlers?
//////////// INITIALIZATION METHODS ///////////////////////////////////////
//TODOC: params and srcNodeRef need docs. Is srcNodeRef optional?
//TODOC: summary needed for postscript
postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
this.create(params, srcNodeRef);
},
create: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
// summary:
// Kick off the life-cycle of a widget
// description:
// To understand the process by which widgets are instantiated, it
// is critical to understand what other methods create calls and
// which of them you'll want to override. Of course, adventurous
// developers could override create entirely, but this should
// only be done as a last resort.
//
// Below is a list of the methods that are called, in the order
// they are fired, along with notes about what they do and if/when
// you should over-ride them in your widget:
//
// * postMixInProperties:
// | * a stub function that you can over-ride to modify
// variables that may have been naively assigned by
// mixInProperties
// * widget is added to manager object here
// * buildRendering:
// | * Subclasses use this method to handle all UI initialization
// Sets this.domNode. Templated widgets do this automatically
// and otherwise it just uses the source dom node.
// * postCreate:
// | * a stub function that you can over-ride to modify take
// actions once the widget has been placed in the UI
// store pointer to original dom tree
this.srcNodeRef = dojo.byId(srcNodeRef);
// For garbage collection. An array of handles returned by Widget.connect()
// Each handle returned from Widget.connect() is an array of handles from dojo.connect()
this._connects=[];
// _attaches: String[]
// names of all our dojoAttachPoint variables
this._attaches=[];
//mixin our passed parameters
if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
if(params){
this.params = params;
dojo.mixin(this,params);
}
this.postMixInProperties();
// generate an id for the widget if one wasn't specified
// (be sure to do this before buildRendering() because that function might
// expect the id to be there.
if(!this.id){
this.id=dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
}
dijit.registry.add(this);
this.buildRendering();
// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
// The placement of these attributes is according to the property mapping in attributeMap.
// Note special handling for 'style' and 'class' attributes which are lists and can
// have elements from both old and new structures, and some attributes like "type"
// cannot be processed this way as they are not mutable.
if(this.domNode){
for(var attr in this.attributeMap){
var value = this[attr];
if(typeof value != "object" && ((value !== "" && value !== false) || (params && params[attr]))){
this.setAttribute(attr, value);
}
}
}
if(this.domNode){
this.domNode.setAttribute("widgetId", this.id);
}
this.postCreate();
// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
if(this.srcNodeRef && !this.srcNodeRef.parentNode){
delete this.srcNodeRef;
}
},
postMixInProperties: function(){
// summary
// Called after the parameters to the widget have been read-in,
// but before the widget template is instantiated.
// Especially useful to set properties that are referenced in the widget template.
},
buildRendering: function(){
// summary:
// Construct the UI for this widget, setting this.domNode.
// Most widgets will mixin TemplatedWidget, which overrides this method.
this.domNode = this.srcNodeRef || dojo.doc.createElement('div');
},
postCreate: function(){
// summary:
// Called after a widget's dom has been setup
},
startup: function(){
// summary:
// Called after a widget's children, and other widgets on the page, have been created.
// Provides an opportunity to manipulate any children before they are displayed.
// This is useful for composite widgets that need to control or layout sub-widgets.
// Many layout widgets can use this as a wiring phase.
this._started = true;
},
//////////// DESTROY FUNCTIONS ////////////////////////////////
destroyRecursive: function(/*Boolean*/ finalize){
// summary:
// Destroy this widget and it's descendants. This is the generic
// "destructor" function that all widget users should call to
// cleanly discard with a widget. Once a widget is destroyed, it's
// removed from the manager object.
// finalize: Boolean
// is this function being called part of global environment
// tear-down?
this.destroyDescendants();
this.destroy();
},
destroy: function(/*Boolean*/ finalize){
// summary:
// Destroy this widget, but not its descendants
// finalize: Boolean
// is this function being called part of global environment
// tear-down?
this.uninitialize();
dojo.forEach(this._connects, function(array){
dojo.forEach(array, dojo.disconnect);
});
// destroy widgets created as part of template, etc.
dojo.forEach(this._supportingWidgets || [], function(w){ w.destroy(); });
this.destroyRendering(finalize);
dijit.registry.remove(this.id);
},
destroyRendering: function(/*Boolean*/ finalize){
// summary:
// Destroys the DOM nodes associated with this widget
// finalize: Boolean
// is this function being called part of global environment
// tear-down?
if(this.bgIframe){
this.bgIframe.destroy();
delete this.bgIframe;
}
if(this.domNode){
dojo._destroyElement(this.domNode);
delete this.domNode;
}
if(this.srcNodeRef){
dojo._destroyElement(this.srcNodeRef);
delete this.srcNodeRef;
}
},
destroyDescendants: function(){
// summary:
// Recursively destroy the children of this widget and their
// descendants.
// TODO: should I destroy in the reverse order, to go bottom up?
dojo.forEach(this.getDescendants(), function(widget){ widget.destroy(); });
},
uninitialize: function(){
// summary:
// stub function. Override to implement custom widget tear-down
// behavior.
return false;
},
////////////////// MISCELLANEOUS METHODS ///////////////////
onFocus: function(){
// summary:
// stub function. Override or connect to this method to receive
// notifications for when the widget moves into focus.
},
onBlur: function(){
// summary:
// stub function. Override or connect to this method to receive
// notifications for when the widget moves out of focus.
},
_onFocus: function(e){
this.onFocus();
},
_onBlur: function(){
this.onBlur();
},
setAttribute: function(/*String*/ attr, /*anything*/ value){
// summary
// Set native HTML attributes reflected in the widget,
// such as readOnly, disabled, and maxLength in TextBox widgets.
// description
// In general, a widget's "value" is controlled via setValue()/getValue(),
// rather than this method. The exception is for widgets where the
// end user can't adjust the value, such as Button and CheckBox;
// in the unusual case that you want to change the value attribute of
// those widgets, use setAttribute().
var mapNode = this[this.attributeMap[attr]||'domNode'];
this[attr] = value;
switch(attr){
case "class":
dojo.addClass(mapNode, value);
break;
case "style":
if(mapNode.style.cssText){
mapNode.style.cssText += "; " + value;// FIXME: Opera
}else{
mapNode.style.cssText = value;
}
break;
default:
if(/^on[A-Z]/.test(attr)){ // eg. onSubmit needs to be onsubmit
attr = attr.toLowerCase();
}
if(typeof value == "function"){ // functions execute in the context of the widget
value = dojo.hitch(this, value);
}
dojo.attr(mapNode, attr, value);
}
},
toString: function(){
// summary:
// returns a string that represents the widget. When a widget is
// cast to a string, this method will be used to generate the
// output. Currently, it does not implement any sort of reversable
// serialization.
return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
},
getDescendants: function(){
// summary:
// Returns all the widgets that contained by this, i.e., all widgets underneath this.containerNode.
if(this.containerNode){
var list= dojo.query('[widgetId]', this.containerNode);
return list.map(dijit.byNode); // Array
}else{
return [];
}
},
//TODOC
nodesWithKeyClick: ["input", "button"],
connect: function(
/*Object|null*/ obj,
/*String*/ event,
/*String|Function*/ method){
// summary:
// Connects specified obj/event to specified method of this object
// and registers for disconnect() on widget destroy.
// Special event: "ondijitclick" triggers on a click or enter-down or space-up
// Similar to dojo.connect() but takes three arguments rather than four.
var handles =[];
if(event == "ondijitclick"){
// add key based click activation for unsupported nodes.
if(!this.nodesWithKeyClick[obj.nodeName]){
handles.push(dojo.connect(obj, "onkeydown", this,
function(e){
if(e.keyCode == dojo.keys.ENTER){
return (dojo.isString(method))?
this[method](e) : method.call(this, e);
}else if(e.keyCode == dojo.keys.SPACE){
// stop space down as it causes IE to scroll
// the browser window
dojo.stopEvent(e);
}
}));
handles.push(dojo.connect(obj, "onkeyup", this,
function(e){
if(e.keyCode == dojo.keys.SPACE){
return dojo.isString(method) ?
this[method](e) : method.call(this, e);
}
}));
}
event = "onclick";
}
handles.push(dojo.connect(obj, event, this, method));
// return handles for FormElement and ComboBox
this._connects.push(handles);
return handles;
},
disconnect: function(/*Object*/ handles){
// summary:
// Disconnects handle created by this.connect.
// Also removes handle from this widget's list of connects
for(var i=0; i<this._connects.length; i++){
if(this._connects[i]==handles){
dojo.forEach(handles, dojo.disconnect);
this._connects.splice(i, 1);
return;
}
}
},
isLeftToRight: function(){
// summary:
// Checks the DOM to for the text direction for bi-directional support
// description:
// This method cannot be used during widget construction because the widget
// must first be connected to the DOM tree. Parent nodes are searched for the
// 'dir' attribute until one is found, otherwise left to right mode is assumed.
// See HTML spec, DIR attribute for more information.
if(!("_ltr" in this)){
this._ltr = dojo.getComputedStyle(this.domNode).direction != "rtl";
}
return this._ltr; //Boolean
},
isFocusable: function(){
// summary:
// Return true if this widget can currently be focused
// and false if not
return this.focus && (dojo.style(this.domNode, "display") != "none");
}
});
}

View file

@ -0,0 +1,27 @@
if(!dojo._hasResource["dijit._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base"] = true;
dojo.provide("dijit._base");
dojo.require("dijit._base.focus");
dojo.require("dijit._base.manager");
dojo.require("dijit._base.place");
dojo.require("dijit._base.popup");
dojo.require("dijit._base.scroll");
dojo.require("dijit._base.sniff");
dojo.require("dijit._base.bidi");
dojo.require("dijit._base.typematic");
dojo.require("dijit._base.wai");
dojo.require("dijit._base.window");
// FIXME: Find a better way of solving this bug!
if(dojo.isSafari){
// Ugly-ass hack to solve bug #5626 for 1.1; basically force Safari to re-layout.
// Note that we can't reliably use dojo.addOnLoad here because this bug is basically
// a timing / race condition; so instead we use window.onload.
dojo.connect(window, "load", function(){
window.resizeBy(1,0);
setTimeout(function(){ window.resizeBy(-1,0); }, 10);
});
}
}

View file

@ -0,0 +1,13 @@
if(!dojo._hasResource["dijit._base.bidi"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.bidi"] = true;
dojo.provide("dijit._base.bidi");
// summary: applies a class to the top of the document for right-to-left stylesheet rules
dojo.addOnLoad(function(){
if(!dojo._isBodyLtr()){
dojo.addClass(dojo.body(), "dijitRtl");
}
});
}

View file

@ -0,0 +1,342 @@
if(!dojo._hasResource["dijit._base.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.focus"] = true;
dojo.provide("dijit._base.focus");
// summary:
// These functions are used to query or set the focus and selection.
//
// Also, they trace when widgets become actived/deactivated,
// so that the widget can fire _onFocus/_onBlur events.
// "Active" here means something similar to "focused", but
// "focus" isn't quite the right word because we keep track of
// a whole stack of "active" widgets. Example: Combobutton --> Menu -->
// MenuItem. The onBlur event for Combobutton doesn't fire due to focusing
// on the Menu or a MenuItem, since they are considered part of the
// Combobutton widget. It only happens when focus is shifted
// somewhere completely different.
dojo.mixin(dijit,
{
// _curFocus: DomNode
// Currently focused item on screen
_curFocus: null,
// _prevFocus: DomNode
// Previously focused item on screen
_prevFocus: null,
isCollapsed: function(){
// summary: tests whether the current selection is empty
var _window = dojo.global;
var _document = dojo.doc;
if(_document.selection){ // IE
return !_document.selection.createRange().text; // Boolean
}else{
var selection = _window.getSelection();
if(dojo.isString(selection)){ // Safari
return !selection; // Boolean
}else{ // Mozilla/W3
return selection.isCollapsed || !selection.toString(); // Boolean
}
}
},
getBookmark: function(){
// summary: Retrieves a bookmark that can be used with moveToBookmark to return to the same range
var bookmark, selection = dojo.doc.selection;
if(selection){ // IE
var range = selection.createRange();
if(selection.type.toUpperCase()=='CONTROL'){
if(range.length){
bookmark=[];
var i=0,len=range.length;
while(i<len){
bookmark.push(range.item(i++));
}
}else{
bookmark=null;
}
}else{
bookmark = range.getBookmark();
}
}else{
if(window.getSelection){
selection = dojo.global.getSelection();
if(selection){
range = selection.getRangeAt(0);
bookmark = range.cloneRange();
}
}else{
console.warn("No idea how to store the current selection for this browser!");
}
}
return bookmark; // Array
},
moveToBookmark: function(/*Object*/bookmark){
// summary: Moves current selection to a bookmark
// bookmark: This should be a returned object from dojo.html.selection.getBookmark()
var _document = dojo.doc;
if(_document.selection){ // IE
var range;
if(dojo.isArray(bookmark)){
range = _document.body.createControlRange();
dojo.forEach(bookmark, "range.addElement(item)"); //range.addElement does not have call/apply method, so can not call it directly
}else{
range = _document.selection.createRange();
range.moveToBookmark(bookmark);
}
range.select();
}else{ //Moz/W3C
var selection = dojo.global.getSelection && dojo.global.getSelection();
if(selection && selection.removeAllRanges){
selection.removeAllRanges();
selection.addRange(bookmark);
}else{
console.warn("No idea how to restore selection for this browser!");
}
}
},
getFocus: function(/*Widget?*/menu, /*Window?*/openedForWindow){
// summary:
// Returns the current focus and selection.
// Called when a popup appears (either a top level menu or a dialog),
// or when a toolbar/menubar receives focus
//
// menu:
// The menu that's being opened
//
// openedForWindow:
// iframe in which menu was opened
//
// returns:
// A handle to restore focus/selection
return {
// Node to return focus to
node: menu && dojo.isDescendant(dijit._curFocus, menu.domNode) ? dijit._prevFocus : dijit._curFocus,
// Previously selected text
bookmark:
!dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed) ?
dojo.withGlobal(openedForWindow||dojo.global, dijit.getBookmark) :
null,
openedForWindow: openedForWindow
}; // Object
},
focus: function(/*Object || DomNode */ handle){
// summary:
// Sets the focused node and the selection according to argument.
// To set focus to an iframe's content, pass in the iframe itself.
// handle:
// object returned by get(), or a DomNode
if(!handle){ return; }
var node = "node" in handle ? handle.node : handle, // because handle is either DomNode or a composite object
bookmark = handle.bookmark,
openedForWindow = handle.openedForWindow;
// Set the focus
// Note that for iframe's we need to use the <iframe> to follow the parentNode chain,
// but we need to set focus to iframe.contentWindow
if(node){
var focusNode = (node.tagName.toLowerCase()=="iframe") ? node.contentWindow : node;
if(focusNode && focusNode.focus){
try{
// Gecko throws sometimes if setting focus is impossible,
// node not displayed or something like that
focusNode.focus();
}catch(e){/*quiet*/}
}
dijit._onFocusNode(node);
}
// set the selection
// do not need to restore if current selection is not empty
// (use keyboard to select a menu item)
if(bookmark && dojo.withGlobal(openedForWindow||dojo.global, dijit.isCollapsed)){
if(openedForWindow){
openedForWindow.focus();
}
try{
dojo.withGlobal(openedForWindow||dojo.global, dijit.moveToBookmark, null, [bookmark]);
}catch(e){
/*squelch IE internal error, see http://trac.dojotoolkit.org/ticket/1984 */
}
}
},
// _activeStack: Array
// List of currently active widgets (focused widget and it's ancestors)
_activeStack: [],
registerWin: function(/*Window?*/targetWindow){
// summary:
// Registers listeners on the specified window (either the main
// window or an iframe) to detect when the user has clicked somewhere.
// Anyone that creates an iframe should call this function.
if(!targetWindow){
targetWindow = window;
}
dojo.connect(targetWindow.document, "onmousedown", function(evt){
dijit._justMouseDowned = true;
setTimeout(function(){ dijit._justMouseDowned = false; }, 0);
dijit._onTouchNode(evt.target||evt.srcElement);
});
//dojo.connect(targetWindow, "onscroll", ???);
// Listen for blur and focus events on targetWindow's body
var body = targetWindow.document.body || targetWindow.document.getElementsByTagName("body")[0];
if(body){
if(dojo.isIE){
body.attachEvent('onactivate', function(evt){
if(evt.srcElement.tagName.toLowerCase() != "body"){
dijit._onFocusNode(evt.srcElement);
}
});
body.attachEvent('ondeactivate', function(evt){ dijit._onBlurNode(evt.srcElement); });
}else{
body.addEventListener('focus', function(evt){ dijit._onFocusNode(evt.target); }, true);
body.addEventListener('blur', function(evt){ dijit._onBlurNode(evt.target); }, true);
}
}
body = null; // prevent memory leak (apparent circular reference via closure)
},
_onBlurNode: function(/*DomNode*/ node){
// summary:
// Called when focus leaves a node.
// Usually ignored, _unless_ it *isn't* follwed by touching another node,
// which indicates that we tabbed off the last field on the page,
// in which case every widget is marked inactive
dijit._prevFocus = dijit._curFocus;
dijit._curFocus = null;
if(dijit._justMouseDowned){
// the mouse down caused a new widget to be marked as active; this blur event
// is coming late, so ignore it.
return;
}
// if the blur event isn't followed by a focus event then mark all widgets as inactive.
if(dijit._clearActiveWidgetsTimer){
clearTimeout(dijit._clearActiveWidgetsTimer);
}
dijit._clearActiveWidgetsTimer = setTimeout(function(){
delete dijit._clearActiveWidgetsTimer;
dijit._setStack([]);
dijit._prevFocus = null;
}, 100);
},
_onTouchNode: function(/*DomNode*/ node){
// summary:
// Callback when node is focused or mouse-downed
// ignore the recent blurNode event
if(dijit._clearActiveWidgetsTimer){
clearTimeout(dijit._clearActiveWidgetsTimer);
delete dijit._clearActiveWidgetsTimer;
}
// compute stack of active widgets (ex: ComboButton --> Menu --> MenuItem)
var newStack=[];
try{
while(node){
if(node.dijitPopupParent){
node=dijit.byId(node.dijitPopupParent).domNode;
}else if(node.tagName && node.tagName.toLowerCase()=="body"){
// is this the root of the document or just the root of an iframe?
if(node===dojo.body()){
// node is the root of the main document
break;
}
// otherwise, find the iframe this node refers to (can't access it via parentNode,
// need to do this trick instead). window.frameElement is supported in IE/FF/Webkit
node=dijit.getDocumentWindow(node.ownerDocument).frameElement;
}else{
var id = node.getAttribute && node.getAttribute("widgetId");
if(id){
newStack.unshift(id);
}
node=node.parentNode;
}
}
}catch(e){ /* squelch */ }
dijit._setStack(newStack);
},
_onFocusNode: function(/*DomNode*/ node){
// summary
// Callback when node is focused
if(node && node.tagName && node.tagName.toLowerCase() == "body"){
return;
}
dijit._onTouchNode(node);
if(node==dijit._curFocus){ return; }
if(dijit._curFocus){
dijit._prevFocus = dijit._curFocus;
}
dijit._curFocus = node;
dojo.publish("focusNode", [node]);
},
_setStack: function(newStack){
// summary
// The stack of active widgets has changed. Send out appropriate events and record new stack
var oldStack = dijit._activeStack;
dijit._activeStack = newStack;
// compare old stack to new stack to see how many elements they have in common
for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
if(oldStack[nCommon] != newStack[nCommon]){
break;
}
}
// for all elements that have gone out of focus, send blur event
for(var i=oldStack.length-1; i>=nCommon; i--){
var widget = dijit.byId(oldStack[i]);
if(widget){
widget._focused = false;
widget._hasBeenBlurred = true;
if(widget._onBlur){
widget._onBlur();
}
if (widget._setStateClass){
widget._setStateClass();
}
dojo.publish("widgetBlur", [widget]);
}
}
// for all element that have come into focus, send focus event
for(i=nCommon; i<newStack.length; i++){
widget = dijit.byId(newStack[i]);
if(widget){
widget._focused = true;
if(widget._onFocus){
widget._onFocus();
}
if (widget._setStateClass){
widget._setStateClass();
}
dojo.publish("widgetFocus", [widget]);
}
}
}
});
// register top window and all the iframes it contains
dojo.addOnLoad(dijit.registerWin);
}

View file

@ -0,0 +1,194 @@
if(!dojo._hasResource["dijit._base.manager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.manager"] = true;
dojo.provide("dijit._base.manager");
dojo.declare("dijit.WidgetSet", null, {
// summary:
// A set of widgets indexed by id
constructor: function(){
this._hash={};
},
add: function(/*Widget*/ widget){
if(this._hash[widget.id]){
throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
}
this._hash[widget.id]=widget;
},
remove: function(/*String*/ id){
delete this._hash[id];
},
forEach: function(/*Function*/ func){
for(var id in this._hash){
func(this._hash[id]);
}
},
filter: function(/*Function*/ filter){
var res = new dijit.WidgetSet();
this.forEach(function(widget){
if(filter(widget)){ res.add(widget); }
});
return res; // dijit.WidgetSet
},
byId: function(/*String*/ id){
return this._hash[id];
},
byClass: function(/*String*/ cls){
return this.filter(function(widget){ return widget.declaredClass==cls; }); // dijit.WidgetSet
}
});
/*=====
dijit.registry = {
// summary: A list of widgets on a page.
// description: Is an instance of dijit.WidgetSet
};
=====*/
dijit.registry = new dijit.WidgetSet();
dijit._widgetTypeCtr = {};
dijit.getUniqueId = function(/*String*/widgetType){
// summary
// Generates a unique id for a given widgetType
var id;
do{
id = widgetType + "_" +
(widgetType in dijit._widgetTypeCtr ?
++dijit._widgetTypeCtr[widgetType] : dijit._widgetTypeCtr[widgetType] = 0);
}while(dijit.byId(id));
return id; // String
};
if(dojo.isIE){
// Only run this for IE because we think it's only necessary in that case,
// and because it causes problems on FF. See bug #3531 for details.
dojo.addOnUnload(function(){
dijit.registry.forEach(function(widget){ widget.destroy(); });
});
}
dijit.byId = function(/*String|Widget*/id){
// summary:
// Returns a widget by its id, or if passed a widget, no-op (like dojo.byId())
return (dojo.isString(id)) ? dijit.registry.byId(id) : id; // Widget
};
dijit.byNode = function(/* DOMNode */ node){
// summary:
// Returns the widget as referenced by node
return dijit.registry.byId(node.getAttribute("widgetId")); // Widget
};
dijit.getEnclosingWidget = function(/* DOMNode */ node){
// summary:
// Returns the widget whose dom tree contains node or null if
// the node is not contained within the dom tree of any widget
while(node){
if(node.getAttribute && node.getAttribute("widgetId")){
return dijit.registry.byId(node.getAttribute("widgetId"));
}
node = node.parentNode;
}
return null;
};
// elements that are tab-navigable if they have no tabindex value set
// (except for "a", which must have an href attribute)
dijit._tabElements = {
area: true,
button: true,
input: true,
object: true,
select: true,
textarea: true
};
dijit._isElementShown = function(/*Element*/elem){
var style = dojo.style(elem);
return (style.visibility != "hidden")
&& (style.visibility != "collapsed")
&& (style.display != "none");
}
dijit.isTabNavigable = function(/*Element*/elem){
// summary:
// Tests if an element is tab-navigable
if(dojo.hasAttr(elem, "disabled")){ return false; }
var hasTabindex = dojo.hasAttr(elem, "tabindex");
var tabindex = dojo.attr(elem, "tabindex");
if(hasTabindex && tabindex >= 0) {
return true; // boolean
}
var name = elem.nodeName.toLowerCase();
if(((name == "a" && dojo.hasAttr(elem, "href"))
|| dijit._tabElements[name])
&& (!hasTabindex || tabindex >= 0)){
return true; // boolean
}
return false; // boolean
};
dijit._getTabNavigable = function(/*DOMNode*/root){
// summary:
// Finds the following descendants of the specified root node:
// * the first tab-navigable element in document order
// without a tabindex or with tabindex="0"
// * the last tab-navigable element in document order
// without a tabindex or with tabindex="0"
// * the first element in document order with the lowest
// positive tabindex value
// * the last element in document order with the highest
// positive tabindex value
var first, last, lowest, lowestTabindex, highest, highestTabindex;
var walkTree = function(/*DOMNode*/parent){
dojo.query("> *", parent).forEach(function(child){
var isShown = dijit._isElementShown(child);
if(isShown && dijit.isTabNavigable(child)){
var tabindex = dojo.attr(child, "tabindex");
if(!dojo.hasAttr(child, "tabindex") || tabindex == 0){
if(!first){ first = child; }
last = child;
}else if(tabindex > 0){
if(!lowest || tabindex < lowestTabindex){
lowestTabindex = tabindex;
lowest = child;
}
if(!highest || tabindex >= highestTabindex){
highestTabindex = tabindex;
highest = child;
}
}
}
if(isShown){ walkTree(child) }
});
};
if(dijit._isElementShown(root)){ walkTree(root) }
return { first: first, last: last, lowest: lowest, highest: highest };
}
dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/root){
// summary:
// Finds the descendant of the specified root node
// that is first in the tabbing order
var elems = dijit._getTabNavigable(dojo.byId(root));
return elems.lowest ? elems.lowest : elems.first; // Element
};
dijit.getLastInTabbingOrder = function(/*String|DOMNode*/root){
// summary:
// Finds the descendant of the specified root node
// that is last in the tabbing order
var elems = dijit._getTabNavigable(dojo.byId(root));
return elems.last ? elems.last : elems.highest; // Element
};
}

View file

@ -0,0 +1,213 @@
if(!dojo._hasResource["dijit._base.place"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.place"] = true;
dojo.provide("dijit._base.place");
// ported from dojo.html.util
dijit.getViewport = function(){
// summary
// Returns the dimensions and scroll position of the viewable area of a browser window
var _window = dojo.global;
var _document = dojo.doc;
// get viewport size
var w = 0, h = 0;
var de = _document.documentElement;
var dew = de.clientWidth, deh = de.clientHeight;
if(dojo.isMozilla){
// mozilla
// _window.innerHeight includes the height taken by the scroll bar
// clientHeight is ideal but has DTD issues:
// #4539: FF reverses the roles of body.clientHeight/Width and documentElement.clientHeight/Width based on the DTD!
// check DTD to see whether body or documentElement returns the viewport dimensions using this algorithm:
var minw, minh, maxw, maxh;
var dbw = _document.body.clientWidth;
if(dbw > dew){
minw = dew;
maxw = dbw;
}else{
maxw = dew;
minw = dbw;
}
var dbh = _document.body.clientHeight;
if(dbh > deh){
minh = deh;
maxh = dbh;
}else{
maxh = deh;
minh = dbh;
}
w = (maxw > _window.innerWidth) ? minw : maxw;
h = (maxh > _window.innerHeight) ? minh : maxh;
}else if(!dojo.isOpera && _window.innerWidth){
//in opera9, dojo.body().clientWidth should be used, instead
//of window.innerWidth/document.documentElement.clientWidth
//so we have to check whether it is opera
w = _window.innerWidth;
h = _window.innerHeight;
}else if(dojo.isIE && de && deh){
w = dew;
h = deh;
}else if(dojo.body().clientWidth){
// IE5, Opera
w = dojo.body().clientWidth;
h = dojo.body().clientHeight;
}
// get scroll position
var scroll = dojo._docScroll();
return { w: w, h: h, l: scroll.x, t: scroll.y }; // object
};
dijit.placeOnScreen = function(
/* DomNode */ node,
/* Object */ pos,
/* Object */ corners,
/* boolean? */ tryOnly){
// summary:
// Keeps 'node' in the visible area of the screen while trying to
// place closest to pos.x, pos.y. The input coordinates are
// expected to be the desired document position.
//
// Set which corner(s) you want to bind to, such as
//
// placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
//
// The desired x/y will be treated as the topleft(TL)/topright(TR) or
// BottomLeft(BL)/BottomRight(BR) corner of the node. Each corner is tested
// and if a perfect match is found, it will be used. Otherwise, it goes through
// all of the specified corners, and choose the most appropriate one.
//
// NOTE: node is assumed to be absolutely or relatively positioned.
var choices = dojo.map(corners, function(corner){ return { corner: corner, pos: pos }; });
return dijit._place(node, choices);
}
dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
// summary:
// Given a list of spots to put node, put it at the first spot where it fits,
// of if it doesn't fit anywhere then the place with the least overflow
// choices: Array
// Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
// Above example says to put the top-left corner of the node at (10,20)
// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
// for things like tooltip, they are displayed differently (and have different dimensions)
// based on their orientation relative to the parent. This adjusts the popup based on orientation.
// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
// viewport over document
var view = dijit.getViewport();
// This won't work if the node is inside a <div style="position: relative">,
// so reattach it to dojo.doc.body. (Otherwise, the positioning will be wrong
// and also it might get cutoff)
if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
dojo.body().appendChild(node);
}
var best = null;
dojo.some(choices, function(choice){
var corner = choice.corner;
var pos = choice.pos;
// configure node to be displayed in given position relative to button
// (need to do this in order to get an accurate size for the node, because
// a tooltips size changes based on position, due to triangle)
if(layoutNode){
layoutNode(node, choice.aroundCorner, corner);
}
// get node's size
var style = node.style;
var oldDisplay = style.display;
var oldVis = style.visibility;
style.visibility = "hidden";
style.display = "";
var mb = dojo.marginBox(node);
style.display = oldDisplay;
style.visibility = oldVis;
// coordinates and size of node with specified corner placed at pos,
// and clipped by viewport
var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)),
startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y - mb.h)),
endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x),
endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y),
width = endX - startX,
height = endY - startY,
overflow = (mb.w - width) + (mb.h - height);
if(best == null || overflow < best.overflow){
best = {
corner: corner,
aroundCorner: choice.aroundCorner,
x: startX,
y: startY,
w: width,
h: height,
overflow: overflow
};
}
return !overflow;
});
node.style.left = best.x + "px";
node.style.top = best.y + "px";
if(best.overflow && layoutNode){
layoutNode(node, best.aroundCorner, best.corner);
}
return best;
}
dijit.placeOnScreenAroundElement = function(
/* DomNode */ node,
/* DomNode */ aroundNode,
/* Object */ aroundCorners,
/* Function */ layoutNode){
// summary
// Like placeOnScreen, except it accepts aroundNode instead of x,y
// and attempts to place node around it. Uses margin box dimensions.
//
// aroundCorners
// specify Which corner of aroundNode should be
// used to place the node => which corner(s) of node to use (see the
// corners parameter in dijit.placeOnScreen)
// e.g. {'TL': 'BL', 'BL': 'TL'}
//
// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
// for things like tooltip, they are displayed differently (and have different dimensions)
// based on their orientation relative to the parent. This adjusts the popup based on orientation.
// get coordinates of aroundNode
aroundNode = dojo.byId(aroundNode);
var oldDisplay = aroundNode.style.display;
aroundNode.style.display="";
// #3172: use the slightly tighter border box instead of marginBox
var aroundNodeW = aroundNode.offsetWidth; //mb.w;
var aroundNodeH = aroundNode.offsetHeight; //mb.h;
var aroundNodePos = dojo.coords(aroundNode, true);
aroundNode.style.display=oldDisplay;
// Generate list of possible positions for node
var choices = [];
for(var nodeCorner in aroundCorners){
choices.push( {
aroundCorner: nodeCorner,
corner: aroundCorners[nodeCorner],
pos: {
x: aroundNodePos.x + (nodeCorner.charAt(1) == 'L' ? 0 : aroundNodeW),
y: aroundNodePos.y + (nodeCorner.charAt(0) == 'T' ? 0 : aroundNodeH)
}
});
}
return dijit._place(node, choices, layoutNode);
}
}

View file

@ -0,0 +1,269 @@
if(!dojo._hasResource["dijit._base.popup"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.popup"] = true;
dojo.provide("dijit._base.popup");
dojo.require("dijit._base.focus");
dojo.require("dijit._base.place");
dojo.require("dijit._base.window");
dijit.popup = new function(){
// summary:
// This class is used to show/hide widgets as popups.
//
var stack = [],
beginZIndex=1000,
idGen = 1;
this.prepare = function(/*DomNode*/ node){
// summary:
// Prepares a node to be used as a popup
//
// description:
// Attaches node to dojo.doc.body, and
// positions it off screen, but not display:none, so that
// the widget doesn't appear in the page flow and/or cause a blank
// area at the bottom of the viewport (making scrollbar longer), but
// initialization of contained widgets works correctly
dojo.body().appendChild(node);
var s = node.style;
if(s.display == "none"){
s.display="";
}
s.visibility = "hidden"; // not needed for hiding, but used as flag that node is off-screen
s.position = "absolute";
s.top = "-9999px";
};
this.open = function(/*Object*/ args){
// summary:
// Popup the widget at the specified position
//
// args: Object
// popup: Widget
// widget to display,
// parent: Widget
// the button etc. that is displaying this popup
// around: DomNode
// DOM node (typically a button); place popup relative to this node
// orient: Object
// structure specifying possible positions of popup relative to "around" node
// onCancel: Function
// callback when user has canceled the popup by
// 1. hitting ESC or
// 2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
// ie: whenever popupWidget.onCancel() is called, args.onCancel is called
// onClose: Function
// callback whenever this popup is closed
// onExecute: Function
// callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
//
// examples:
// 1. opening at the mouse position
// dijit.popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
// 2. opening the widget as a dropdown
// dijit.popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...} });
//
// Note that whatever widget called dijit.popup.open() should also listen to it's own _onBlur callback
// (fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
var widget = args.popup,
orient = args.orient || {'BL':'TL', 'TL':'BL'},
around = args.around,
id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+idGen++);
// make wrapper div to hold widget and possibly hold iframe behind it.
// we can't attach the iframe as a child of the widget.domNode because
// widget.domNode might be a <table>, <ul>, etc.
var wrapper = dojo.doc.createElement("div");
dijit.setWaiRole(wrapper, "presentation");
wrapper.id = id;
wrapper.className="dijitPopup";
wrapper.style.zIndex = beginZIndex + stack.length;
wrapper.style.visibility = "hidden";
if(args.parent){
wrapper.dijitPopupParent=args.parent.id;
}
dojo.body().appendChild(wrapper);
var s = widget.domNode.style;
s.display = "";
s.visibility = "";
s.position = "";
wrapper.appendChild(widget.domNode);
var iframe = new dijit.BackgroundIframe(wrapper);
// position the wrapper node
var best = around ?
dijit.placeOnScreenAroundElement(wrapper, around, orient, widget.orient ? dojo.hitch(widget, "orient") : null) :
dijit.placeOnScreen(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR']);
wrapper.style.visibility = "visible";
// TODO: use effects to fade in wrapper
var handlers = [];
// Compute the closest ancestor popup that's *not* a child of another popup.
// Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
var getTopPopup = function(){
for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
/* do nothing, just trying to get right value for pi */
}
return stack[pi];
}
// provide default escape and tab key handling
// (this will work for any widget, not just menu)
handlers.push(dojo.connect(wrapper, "onkeypress", this, function(evt){
if(evt.keyCode == dojo.keys.ESCAPE && args.onCancel){
dojo.stopEvent(evt);
args.onCancel();
}else if(evt.keyCode == dojo.keys.TAB){
dojo.stopEvent(evt);
var topPopup = getTopPopup();
if(topPopup && topPopup.onCancel){
topPopup.onCancel();
}
}
}));
// watch for cancel/execute events on the popup and notify the caller
// (for a menu, "execute" means clicking an item)
if(widget.onCancel){
handlers.push(dojo.connect(widget, "onCancel", null, args.onCancel));
}
handlers.push(dojo.connect(widget, widget.onExecute ? "onExecute" : "onChange", null, function(){
var topPopup = getTopPopup();
if(topPopup && topPopup.onExecute){
topPopup.onExecute();
}
}));
stack.push({
wrapper: wrapper,
iframe: iframe,
widget: widget,
parent: args.parent,
onExecute: args.onExecute,
onCancel: args.onCancel,
onClose: args.onClose,
handlers: handlers
});
if(widget.onOpen){
widget.onOpen(best);
}
return best;
};
this.close = function(/*Widget*/ popup){
// summary:
// Close specified popup and any popups that it parented
while(dojo.some(stack, function(elem){return elem.widget == popup;})){
var top = stack.pop(),
wrapper = top.wrapper,
iframe = top.iframe,
widget = top.widget,
onClose = top.onClose;
if(widget.onClose){
widget.onClose();
}
dojo.forEach(top.handlers, dojo.disconnect);
// #2685: check if the widget still has a domNode so ContentPane can change its URL without getting an error
if(!widget||!widget.domNode){ return; }
this.prepare(widget.domNode);
iframe.destroy();
dojo._destroyElement(wrapper);
if(onClose){
onClose();
}
}
};
}();
dijit._frames = new function(){
// summary: cache of iframes
var queue = [];
this.pop = function(){
var iframe;
if(queue.length){
iframe = queue.pop();
iframe.style.display="";
}else{
if(dojo.isIE){
var html="<iframe src='javascript:\"\"'"
+ " style='position: absolute; left: 0px; top: 0px;"
+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
iframe = dojo.doc.createElement(html);
}else{
iframe = dojo.doc.createElement("iframe");
iframe.src = 'javascript:""';
iframe.className = "dijitBackgroundIframe";
}
iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
dojo.body().appendChild(iframe);
}
return iframe;
};
this.push = function(iframe){
iframe.style.display="";
if(dojo.isIE){
iframe.style.removeExpression("width");
iframe.style.removeExpression("height");
}
queue.push(iframe);
}
}();
// fill the queue
if(dojo.isIE && dojo.isIE < 7){
dojo.addOnLoad(function(){
var f = dijit._frames;
dojo.forEach([f.pop()], f.push);
});
}
dijit.BackgroundIframe = function(/* DomNode */node){
// summary:
// For IE z-index schenanigans. id attribute is required.
//
// description:
// new dijit.BackgroundIframe(node)
// Makes a background iframe as a child of node, that fills
// area (and position) of node
if(!node.id){ throw new Error("no id"); }
if((dojo.isIE && dojo.isIE < 7) || (dojo.isFF && dojo.isFF < 3 && dojo.hasClass(dojo.body(), "dijit_a11y"))){
var iframe = dijit._frames.pop();
node.appendChild(iframe);
if(dojo.isIE){
iframe.style.setExpression("width", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetWidth");
iframe.style.setExpression("height", dojo._scopeName + ".doc.getElementById('" + node.id + "').offsetHeight");
}
this.iframe = iframe;
}
};
dojo.extend(dijit.BackgroundIframe, {
destroy: function(){
// summary: destroy the iframe
if(this.iframe){
dijit._frames.push(this.iframe);
delete this.iframe;
}
}
});
}

View file

@ -0,0 +1,29 @@
if(!dojo._hasResource["dijit._base.scroll"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.scroll"] = true;
dojo.provide("dijit._base.scroll");
dijit.scrollIntoView = function(/* DomNode */node){
// summary
// Scroll the passed node into view, if it is not.
// don't rely on that node.scrollIntoView works just because the function is there
// it doesnt work in Konqueror or Opera even though the function is there and probably
// not safari either
// native scrollIntoView() causes FF3's whole window to scroll if there is no scroll bar
// on the immediate parent
// dont like browser sniffs implementations but sometimes you have to use it
// #6146: IE scrollIntoView is broken
// It's not enough just to scroll the menu node into view if
// node.scrollIntoView hides part of the parent's scrollbar,
// so just manage the parent scrollbar ourselves
var parent = node.parentNode;
var parentBottom = parent.scrollTop + dojo.marginBox(parent).h; //PORT was getBorderBox
var nodeBottom = node.offsetTop + dojo.marginBox(node).h;
if(parentBottom < nodeBottom){
parent.scrollTop += (nodeBottom - parentBottom);
}else if(parent.scrollTop > node.offsetTop){
parent.scrollTop -= (parent.scrollTop - node.offsetTop);
}
};
}

View file

@ -0,0 +1,45 @@
if(!dojo._hasResource["dijit._base.sniff"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.sniff"] = true;
dojo.provide("dijit._base.sniff");
// ported from dojo.html.applyBrowserClass (style.js)
// summary:
// Applies pre-set class names based on browser & version to the
// top-level HTML node. Simply doing a require on this module will
// establish this CSS. Modified version of Morris' CSS hack.
(function(){
var d = dojo;
var ie = d.isIE;
var opera = d.isOpera;
var maj = Math.floor;
var ff = d.isFF;
var classes = {
dj_ie: ie,
// dj_ie55: ie == 5.5,
dj_ie6: maj(ie) == 6,
dj_ie7: maj(ie) == 7,
dj_iequirks: ie && d.isQuirks,
// NOTE: Opera not supported by dijit
dj_opera: opera,
dj_opera8: maj(opera) == 8,
dj_opera9: maj(opera) == 9,
dj_khtml: d.isKhtml,
dj_safari: d.isSafari,
dj_gecko: d.isMozilla,
dj_ff2: maj(ff) == 2
}; // no dojo unsupported browsers
for(var p in classes){
if(classes[p]){
var html = dojo.doc.documentElement; //TODO browser-specific DOM magic needed?
if(html.className){
html.className += " " + p;
}else{
html.className = p;
}
}
}
})();
}

View file

@ -0,0 +1,139 @@
if(!dojo._hasResource["dijit._base.typematic"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.typematic"] = true;
dojo.provide("dijit._base.typematic");
dijit.typematic = {
// summary:
// These functions are used to repetitively call a user specified callback
// method when a specific key or mouse click over a specific DOM node is
// held down for a specific amount of time.
// Only 1 such event is allowed to occur on the browser page at 1 time.
_fireEventAndReload: function(){
this._timer = null;
this._callback(++this._count, this._node, this._evt);
this._currentTimeout = (this._currentTimeout < 0) ? this._initialDelay : ((this._subsequentDelay > 1) ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay));
this._timer = setTimeout(dojo.hitch(this, "_fireEventAndReload"), this._currentTimeout);
},
trigger: function(/*Event*/ evt, /* Object */ _this, /*DOMNode*/ node, /* Function */ callback, /* Object */ obj, /* Number */ subsequentDelay, /* Number */ initialDelay){
// summary:
// Start a timed, repeating callback sequence.
// If already started, the function call is ignored.
// This method is not normally called by the user but can be
// when the normal listener code is insufficient.
// Parameters:
// evt: key or mouse event object to pass to the user callback
// _this: pointer to the user's widget space.
// node: the DOM node object to pass the the callback function
// callback: function to call until the sequence is stopped called with 3 parameters:
// count: integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
// node: the DOM node object passed in
// evt: key or mouse event object
// obj: user space object used to uniquely identify each typematic sequence
// subsequentDelay: if > 1, the number of milliseconds until the 3->n events occur
// or else the fractional time multiplier for the next event's delay, default=0.9
// initialDelay: the number of milliseconds until the 2nd event occurs, default=500ms
if(obj != this._obj){
this.stop();
this._initialDelay = initialDelay || 500;
this._subsequentDelay = subsequentDelay || 0.90;
this._obj = obj;
this._evt = evt;
this._node = node;
this._currentTimeout = -1;
this._count = -1;
this._callback = dojo.hitch(_this, callback);
this._fireEventAndReload();
}
},
stop: function(){
// summary:
// Stop an ongoing timed, repeating callback sequence.
if(this._timer){
clearTimeout(this._timer);
this._timer = null;
}
if(this._obj){
this._callback(-1, this._node, this._evt);
this._obj = null;
}
},
addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
// summary: Start listening for a specific typematic key.
// keyObject: an object defining the key to listen for.
// key: (mandatory) the keyCode (number) or character (string) to listen for.
// ctrlKey: desired ctrl key state to initiate the calback sequence:
// pressed (true)
// released (false)
// either (unspecified)
// altKey: same as ctrlKey but for the alt key
// shiftKey: same as ctrlKey but for the shift key
// See the trigger method for other parameters.
// Returns an array of dojo.connect handles
return [
dojo.connect(node, "onkeypress", this, function(evt){
if(evt.keyCode == keyObject.keyCode && (!keyObject.charCode || keyObject.charCode == evt.charCode) &&
(keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
(keyObject.altKey === undefined || keyObject.altKey == evt.ctrlKey) &&
(keyObject.shiftKey === undefined || keyObject.shiftKey == evt.ctrlKey)){
dojo.stopEvent(evt);
dijit.typematic.trigger(keyObject, _this, node, callback, keyObject, subsequentDelay, initialDelay);
}else if(dijit.typematic._obj == keyObject){
dijit.typematic.stop();
}
}),
dojo.connect(node, "onkeyup", this, function(evt){
if(dijit.typematic._obj == keyObject){
dijit.typematic.stop();
}
})
];
},
addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
// summary: Start listening for a typematic mouse click.
// See the trigger method for other parameters.
// Returns an array of dojo.connect handles
var dc = dojo.connect;
return [
dc(node, "mousedown", this, function(evt){
dojo.stopEvent(evt);
dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
}),
dc(node, "mouseup", this, function(evt){
dojo.stopEvent(evt);
dijit.typematic.stop();
}),
dc(node, "mouseout", this, function(evt){
dojo.stopEvent(evt);
dijit.typematic.stop();
}),
dc(node, "mousemove", this, function(evt){
dojo.stopEvent(evt);
}),
dc(node, "dblclick", this, function(evt){
dojo.stopEvent(evt);
if(dojo.isIE){
dijit.typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay);
setTimeout(dojo.hitch(this, dijit.typematic.stop), 50);
}
})
];
},
addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay){
// summary: Start listening for a specific typematic key and mouseclick.
// This is a thin wrapper to addKeyListener and addMouseListener.
// mouseNode: the DOM node object to listen on for mouse events.
// keyNode: the DOM node object to listen on for key events.
// See the addMouseListener and addKeyListener methods for other parameters.
// Returns an array of dojo.connect handles
return this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay).concat(
this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay));
}
};
}

View file

@ -0,0 +1,143 @@
if(!dojo._hasResource["dijit._base.wai"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.wai"] = true;
dojo.provide("dijit._base.wai");
dijit.wai = {
onload: function(){
// summary:
// Detects if we are in high-contrast mode or not
// This must be a named function and not an anonymous
// function, so that the widget parsing code can make sure it
// registers its onload function after this function.
// DO NOT USE "this" within this function.
// create div for testing if high contrast mode is on or images are turned off
var div = dojo.doc.createElement("div");
div.id = "a11yTestNode";
div.style.cssText = 'border: 1px solid;'
+ 'border-color:red green;'
+ 'position: absolute;'
+ 'height: 5px;'
+ 'top: -999px;'
+ 'background-image: url("' + dojo.moduleUrl("dojo", "resources/blank.gif") + '");';
dojo.body().appendChild(div);
// test it
var cs = dojo.getComputedStyle(div);
if(cs){
var bkImg = cs.backgroundImage;
var needsA11y = (cs.borderTopColor==cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
dojo[needsA11y ? "addClass" : "removeClass"](dojo.body(), "dijit_a11y");
dojo.body().removeChild(div);
}
}
};
// Test if computer is in high contrast mode.
// Make sure the a11y test runs first, before widgets are instantiated.
if(dojo.isIE || dojo.isMoz){ // NOTE: checking in Safari messes things up
dojo._loaders.unshift(dijit.wai.onload);
}
dojo.mixin(dijit,
{
hasWaiRole: function(/*Element*/ elem){
// summary: Determines if an element has a role.
// returns: true if elem has a role attribute and false if not.
return elem.hasAttribute ? elem.hasAttribute("role") : !!elem.getAttribute("role");
},
getWaiRole: function(/*Element*/ elem){
// summary: Gets the role for an element.
// returns:
// The role of elem or an empty string if elem
// does not have a role.
var value = elem.getAttribute("role");
if(value){
var prefixEnd = value.indexOf(":");
return prefixEnd == -1 ? value : value.substring(prefixEnd+1);
}else{
return "";
}
},
setWaiRole: function(/*Element*/ elem, /*String*/ role){
// summary: Sets the role on an element.
// description:
// On Firefox 2 and below, "wairole:" is
// prepended to the provided role value.
elem.setAttribute("role", (dojo.isFF && dojo.isFF < 3) ? "wairole:" + role : role);
},
removeWaiRole: function(/*Element*/ elem){
// summary: Removes the role from an element.
elem.removeAttribute("role");
},
hasWaiState: function(/*Element*/ elem, /*String*/ state){
// summary: Determines if an element has a given state.
// description:
// On Firefox 2 and below, we check for an attribute in namespace
// "http://www.w3.org/2005/07/aaa" with a name of the given state.
// On all other browsers, we check for an attribute
// called "aria-"+state.
// returns:
// true if elem has a value for the given state and
// false if it does not.
if(dojo.isFF && dojo.isFF < 3){
return elem.hasAttributeNS("http://www.w3.org/2005/07/aaa", state);
}else{
return elem.hasAttribute ? elem.hasAttribute("aria-"+state) : !!elem.getAttribute("aria-"+state);
}
},
getWaiState: function(/*Element*/ elem, /*String*/ state){
// summary: Gets the value of a state on an element.
// description:
// On Firefox 2 and below, we check for an attribute in namespace
// "http://www.w3.org/2005/07/aaa" with a name of the given state.
// On all other browsers, we check for an attribute called
// "aria-"+state.
// returns:
// The value of the requested state on elem
// or an empty string if elem has no value for state.
if(dojo.isFF && dojo.isFF < 3){
return elem.getAttributeNS("http://www.w3.org/2005/07/aaa", state);
}else{
var value = elem.getAttribute("aria-"+state);
return value ? value : "";
}
},
setWaiState: function(/*Element*/ elem, /*String*/ state, /*String*/ value){
// summary: Sets a state on an element.
// description:
// On Firefox 2 and below, we set an attribute in namespace
// "http://www.w3.org/2005/07/aaa" with a name of the given state.
// On all other browsers, we set an attribute called
// "aria-"+state.
if(dojo.isFF && dojo.isFF < 3){
elem.setAttributeNS("http://www.w3.org/2005/07/aaa",
"aaa:"+state, value);
}else{
elem.setAttribute("aria-"+state, value);
}
},
removeWaiState: function(/*Element*/ elem, /*String*/ state){
// summary: Removes a state from an element.
// description:
// On Firefox 2 and below, we remove the attribute in namespace
// "http://www.w3.org/2005/07/aaa" with a name of the given state.
// On all other browsers, we remove the attribute called
// "aria-"+state.
if(dojo.isFF && dojo.isFF < 3){
elem.removeAttributeNS("http://www.w3.org/2005/07/aaa", state);
}else{
elem.removeAttribute("aria-"+state);
}
}
});
}

View file

@ -0,0 +1,47 @@
if(!dojo._hasResource["dijit._base.window"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._base.window"] = true;
dojo.provide("dijit._base.window");
dijit.getDocumentWindow = function(doc){
// summary
// Get window object associated with document doc
// With Safari, there is not way to retrieve the window from the document, so we must fix it.
if(dojo.isSafari && !doc._parentWindow){
/*
This is a Safari specific function that fix the reference to the parent
window from the document object.
TODO: #5711: should the use of document below reference dojo.doc instead
in case they're not the same?
*/
var fix=function(win){
win.document._parentWindow=win;
for(var i=0; i<win.frames.length; i++){
fix(win.frames[i]);
}
}
fix(window.top);
}
//In some IE versions (at least 6.0), document.parentWindow does not return a
//reference to the real window object (maybe a copy), so we must fix it as well
//We use IE specific execScript to attach the real window reference to
//document._parentWindow for later use
//TODO: #5711: should the use of document below reference dojo.doc instead in case they're not the same?
if(dojo.isIE && window !== document.parentWindow && !doc._parentWindow){
/*
In IE 6, only the variable "window" can be used to connect events (others
may be only copies).
*/
doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
//to prevent memory leak, unset it after use
//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
var win = doc._parentWindow;
doc._parentWindow = null;
return win; // Window
}
return doc._parentWindow || doc.parentWindow || doc.defaultView; // Window
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,101 @@
if(!dojo._hasResource["dijit._editor._Plugin"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor._Plugin"] = true;
dojo.provide("dijit._editor._Plugin");
dojo.require("dijit._Widget");
dojo.require("dijit.Editor");
dojo.require("dijit.form.Button");
dojo.declare("dijit._editor._Plugin", null, {
// summary
// This represents a "plugin" to the editor, which is basically
// a single button on the Toolbar and some associated code
constructor: function(/*Object?*/args, /*DomNode?*/node){
if(args){
dojo.mixin(this, args);
}
this._connects=[];
},
editor: null,
iconClassPrefix: "dijitEditorIcon",
button: null,
queryCommand: null,
command: "",
commandArg: null,
useDefaultCommand: true,
buttonClass: dijit.form.Button,
getLabel: function(key){
return this.editor.commands[key];
},
_initButton: function(props){
if(this.command.length){
var label = this.getLabel(this.command);
var className = this.iconClassPrefix+" "+this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1);
if(!this.button){
props = dojo.mixin({
label: label,
showLabel: false,
iconClass: className,
dropDown: this.dropDown,
tabIndex: "-1"
}, props || {});
this.button = new this.buttonClass(props);
}
}
},
destroy: function(f){
dojo.forEach(this._connects, dojo.disconnect);
},
connect: function(o, f, tf){
this._connects.push(dojo.connect(o, f, this, tf));
},
updateState: function(){
var _e = this.editor;
var _c = this.command;
if(!_e){ return; }
if(!_e.isLoaded){ return; }
if(!_c.length){ return; }
if(this.button){
try{
var enabled = _e.queryCommandEnabled(_c);
this.button.setAttribute('disabled', !enabled);
if(typeof this.button.checked == 'boolean'){
this.button.setAttribute('checked', _e.queryCommandState(_c));
}
}catch(e){
console.debug(e);
}
}
},
setEditor: function(/*Widget*/editor){
// FIXME: detatch from previous editor!!
this.editor = editor;
// FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command)
this._initButton();
// FIXME: wire up editor to button here!
if(this.command.length &&
!this.editor.queryCommandAvailable(this.command)
){
// console.debug("hiding:", this.command);
if(this.button){
this.button.domNode.style.display = "none";
}
}
if(this.button && this.useDefaultCommand){
this.connect(this.button, "onClick",
dojo.hitch(this.editor, "execCommand", this.command, this.commandArg)
);
}
this.connect(this.editor, "onNormalizedDisplayChanged", "updateState");
},
setToolbar: function(/*Widget*/toolbar){
if(this.button){
toolbar.addChild(this.button);
}
// console.debug("adding", this.button, "to:", toolbar);
}
});
}

View file

@ -0,0 +1,106 @@
if(!dojo._hasResource["dijit._editor.html"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dijit._editor.html"] = true;
dojo.provide("dijit._editor.html");
dijit._editor.escapeXml=function(/*String*/str, /*Boolean*/noSingleQuotes){
//summary:
// Adds escape sequences for special characters in XML: &<>"'
// Optionally skips escapes for single quotes
str = str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;").replace(/>/gm, "&gt;").replace(/"/gm, "&quot;");
if(!noSingleQuotes){
str = str.replace(/'/gm, "&#39;");
}
return str; // string
};
dijit._editor.getNodeHtml=function(/* DomNode */node){
var output;
switch(node.nodeType){
case 1: //element node
output = '<'+node.nodeName.toLowerCase();
//store the list of attributes and sort it to have the
//attributes appear in the dictionary order
var attrarray = [];
if(dojo.isIE && node.outerHTML){
var s = node.outerHTML;
s = s.substr(0,s.indexOf('>'));
s = s.replace(/(['"])[^"']*\1/g, '');//to make the following regexp safe
var reg = /([^\s=]+)=/g;
var m, key;
while((m = reg.exec(s))){
key=m[1];
if(key.substr(0,3) != '_dj'){
if(key == 'src' || key == 'href'){
if(node.getAttribute('_djrealurl')){
attrarray.push([key,node.getAttribute('_djrealurl')]);
continue;
}
}
if(key=='style'){
attrarray.push([key, node.style.cssText.toLowerCase()]);
}else{
attrarray.push([key, key=='class'?node.className:node.getAttribute(key)]);
}
}
}
}else{
var attr, i=0, attrs = node.attributes;
while((attr=attrs[i++])){
//ignore all attributes starting with _dj which are
//internal temporary attributes used by the editor
var n=attr.name;
if(n.substr(0,3) != '_dj' /*&&
(attr.specified == undefined || attr.specified)*/){
var v = attr.value;
if(n == 'src' || n == 'href'){
if(node.getAttribute('_djrealurl')){
v = node.getAttribute('_djrealurl');
}
}
attrarray.push([n,v]);
}
}
}
attrarray.sort(function(a,b){
return a[0]<b[0]?-1:(a[0]==b[0]?0:1);
});
i=0;
while((attr=attrarray[i++])){
output += ' '+attr[0]+'="'+
(dojo.isString(attr[1]) ? dijit._editor.escapeXml(attr[1],true) : attr[1])+'"';
}
if(node.childNodes.length){
output += '>' + dijit._editor.getChildrenHtml(node)+'</'+node.nodeName.toLowerCase()+'>';
}else{
output += ' />';
}
break;
case 3: //text
// FIXME:
output = dijit._editor.escapeXml(node.nodeValue,true);
break;
case 8: //comment
// FIXME:
output = '<!--'+dijit._editor.escapeXml(node.nodeValue,true)+'-->';
break;
default:
output = "Element not recognized - Type: " + node.nodeType + " Name: " + node.nodeName;
}
return output;
};
dijit._editor.getChildrenHtml = function(/* DomNode */dom){
// summary: Returns the html content of a DomNode and children
var out = "";
if(!dom){ return out; }
var nodes = dom["childNodes"]||dom;
var i=0;
var node;
while((node=nodes[i++])){
out += dijit._editor.getNodeHtml(node);
}
return out; // String
}
}

View file

@ -0,0 +1 @@
({"1":"xx-small","2":"x-small","formatBlock":"Format","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Paragraph","pre":"Pre-formatted","sans-serif":"sans-serif","fontName":"Font","h1":"Heading","h2":"Subheading","h3":"Sub-subheading","monospace":"monospace","fontSize":"Size","cursive":"cursive"})

View file

@ -0,0 +1 @@
({"set":"Set","text":"Description:","insertImageTitle":"Image Properties","url":"URL:","createLinkTitle":"Link Properties"})

View file

@ -0,0 +1 @@
({"1":"صغير جدا جدا ","2":"صغير جدا ","formatBlock":"النسق","monospaced":"خط أحادي المسافة ","3":"صغير ","4":"متوسط ","5":"كبير ","6":"كبير جدا ","7":"كبير جدا جدا ","fantasy":"خيالي ","serif":"serif","p":"فقرة ","pre":"منسق بصفة مسبقة ","sans-serif":"sans-serif","fontName":"طاقم طباعة","h1":"عنوان","h2":"عنوان فرعي ","h3":"فرعي-عنوان فرعي ","fontSize":"الحجم","cursive":"كتابة بحروف متصلة ","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"تحديد","text":"الوصف: ","insertImageTitle":"خصائص الصورة ","url":"عنوان URL:","createLinkTitle":"خصائص الوصلة "})

View file

@ -0,0 +1 @@
({"removeFormat":"ازالة النسق","copy":"نسخ","paste":"لصق","selectAll":"اختيار كل","insertOrderedList":"كشف مرقم","insertTable":"ادراج/تحرير جدول ","underline":"تسطير","foreColor":"لون الواجهة الأمامية","htmlToggle":"مصدر HTML","formatBlock":"نمط الفقرة","insertHorizontalRule":"مسطرة أفقية","delete":"حذف","insertUnorderedList":"كشف نقطي","tableProp":"خصائص الجدول ","insertImage":"ادراج صورة","superscript":"رمز علوي","subscript":"رمز سفلي","createLink":"تكوين وصلة","undo":"تراجع","italic":"مائل","fontName":"اسم طاقم الطباعة","justifyLeft":"محاذاة الى اليسار","unlink":"ازالة وصلة","toggleTableBorder":"تبديل حدود الجدول ","fontSize":"حجم طاقم الطباعة","indent":"ازاحة للداخل","redo":"اعادة","strikethrough":"تشطيب","justifyFull":"ضبط","justifyCenter":"محاذاة في الوسط","hiliteColor":"لون الخلفية","deleteTable":"حذف جدول ","outdent":"ازاحة للخارج","cut":"قص","plainFormatBlock":"نمط الفقرة","toggleDir":"تبديل الاتجاه ","bold":"عريض","systemShortcutFF":"يكون التصرف \"${0}\" متاحا فقط في برنامج Mozilla Firefox باستخدام اختصارات لوحة المفاتيح. استخدم ${1}.","justifyRight":"محاذاة الى اليمين","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"removeFormat":"Remove Format","copy":"Copy","paste":"Paste","selectAll":"Select All","insertOrderedList":"Numbered List","insertTable":"Insert/Edit Table","underline":"Underline","foreColor":"Foreground Color","htmlToggle":"HTML Source","formatBlock":"Paragraph Style","insertHorizontalRule":"Horizontal Rule","delete":"Delete","appleKey":"⌘${0}","insertUnorderedList":"Bullet List","tableProp":"Table Property","insertImage":"Insert Image","superscript":"Superscript","subscript":"Subscript","createLink":"Create Link","undo":"Undo","italic":"Italic","fontName":"Font Name","justifyLeft":"Align Left","unlink":"Remove Link","toggleTableBorder":"Toggle Table Border","ctrlKey":"ctrl+${0}","fontSize":"Font Size","indent":"Indent","redo":"Redo","strikethrough":"Strikethrough","justifyFull":"Justify","justifyCenter":"Align Center","hiliteColor":"Background Color","deleteTable":"Delete Table","outdent":"Outdent","cut":"Cut","plainFormatBlock":"Paragraph Style","toggleDir":"Toggle Direction","bold":"Bold","systemShortcutFF":"The \"${0}\" action is only available in Mozilla Firefox using a keyboard shortcut. Use ${1}.","justifyRight":"Align Right"})

View file

@ -0,0 +1 @@
({"1":"extra malé","2":"velmi malé","formatBlock":"Formát","monospaced":"monospaced","3":"malé","4":"střední","5":"velké","6":"velmi velké","7":"extra velké","fantasy":"fantasy","serif":"serif","p":"Odstavec","pre":"Předformátované","sans-serif":"sans-serif","fontName":"Písmo","h1":"Nadpis","h2":"Podnadpis","h3":"Podnadpis 2","fontSize":"Velikost","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Nastavit","text":"Popis:","insertImageTitle":"Vlastnosti obrázku","url":"Adresa URL:","createLinkTitle":"Vlastnosti odkazu"})

View file

@ -0,0 +1 @@
({"removeFormat":"Odebrat formát","copy":"Kopírovat","paste":"Vložit","selectAll":"Vybrat vše","insertOrderedList":"Číslovaný seznam","insertTable":"Vložit/upravit tabulku","underline":"Podtržení","foreColor":"Barva popředí","htmlToggle":"Zdroj HTML","formatBlock":"Styl odstavce","insertHorizontalRule":"Vodorovné pravítko","delete":"Odstranit","insertUnorderedList":"Seznam s odrážkami","tableProp":"Vlastnost tabulky","insertImage":"Vložit obraz","superscript":"Horní index","subscript":"Dolní index","createLink":"Vytvořit odkaz","undo":"Zpět","italic":"Kurzíva","fontName":"Název písma","justifyLeft":"Zarovnat vlevo","unlink":"Odebrat odkaz","toggleTableBorder":"Přepnout ohraničení tabulky","ctrlKey":"Ctrl+${0}","fontSize":"Velikost písma","indent":"Odsadit","redo":"Opakovat","strikethrough":"Přeškrtnutí","justifyFull":"Do bloku","justifyCenter":"Zarovnat na střed","hiliteColor":"Barva pozadí","deleteTable":"Odstranit tabulku","outdent":"Předsadit","cut":"Vyjmout","plainFormatBlock":"Styl odstavce","toggleDir":"Přepnout směr","bold":"Tučné","systemShortcutFF":"Akce \"${0}\" je v prohlížeči Mozilla Firefox dostupná pouze prostřednictvím klávesové zkratky. Použijte klávesy ${1}.","justifyRight":"Zarovnat vpravo","appleKey":"⌘${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-small","2":"x-small","formatBlock":"Format","monospaced":"monospaced","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Afsnit","pre":"Forudformateret","sans-serif":"sans-serif","fontName":"Skrifttype","h1":"Overskrift","h2":"Underoverskrift","h3":"Underunderoverskrift","fontSize":"Størrelse","cursive":"kursiv","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Definér","text":"Beskrivelse:","insertImageTitle":"Billedegenskaber","url":"URL:","createLinkTitle":"Linkegenskaber"})

View file

@ -0,0 +1 @@
({"removeFormat":"Fjern format","copy":"Kopiér","paste":"Sæt ind","selectAll":"Markér alle","insertOrderedList":"Nummereret liste","insertTable":"Indsæt/redigér tabel","underline":"Understreget","foreColor":"Forgrundsfarve","htmlToggle":"HTML-kilde","formatBlock":"Afsnitstypografi","insertHorizontalRule":"Vandret linje","delete":"Slet","insertUnorderedList":"Punktliste","tableProp":"Tabelegenskab","insertImage":"Indsæt billede","superscript":"Hævet skrift","subscript":"Sænket skrift","createLink":"Opret link","undo":"Fortryd","italic":"Kursiv","fontName":"Skriftnavn","justifyLeft":"Venstrejusteret","unlink":"Fjern link","toggleTableBorder":"Skift tabelramme","fontSize":"Skriftstørrelse","indent":"Indrykning","redo":"Annullér Fortryd","strikethrough":"Gennemstreget","justifyFull":"Lige margener","justifyCenter":"Centreret","hiliteColor":"Baggrundsfarve","deleteTable":"Slet tabel","outdent":"Udrykning","cut":"Klip","plainFormatBlock":"Afsnitstypografi","toggleDir":"Skift retning","bold":"Fed","systemShortcutFF":"Funktionen \"${0}\" kan kun bruges i Mozilla Firefox med en tastaturgenvej. Brug ${1}.","justifyRight":"Højrejusteret","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"XXS","2":"XS","formatBlock":"Format","monospaced":"Monospace","3":"S","4":"M","5":"L","6":"XL","7":"XXL","fantasy":"Fantasie","serif":"Serife","p":"Absatz","pre":"Vorformatiert","sans-serif":"Serifenlos","fontName":"Schriftart","h1":"Überschrift","h2":"Unterüberschrift","h3":"Unterunterüberschrift","fontSize":"Größe","cursive":"Kursiv","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Festlegen","text":"Beschreibung:","insertImageTitle":"Grafikeigenschaften","url":"URL:","createLinkTitle":"Linkeigenschaften"})

View file

@ -0,0 +1 @@
({"removeFormat":"Formatierung entfernen","copy":"Kopieren","paste":"Einfügen","selectAll":"Alles auswählen","insertOrderedList":"Nummerierung","insertTable":"Tabelle einfügen/bearbeiten","underline":"Unterstrichen","foreColor":"Vordergrundfarbe","htmlToggle":"HTML-Quelltext","formatBlock":"Absatzstil","insertHorizontalRule":"Horizontaler Strich","delete":"Löschen","insertUnorderedList":"Aufzählungszeichen","tableProp":"Tabelleneigenschaft","insertImage":"Grafik einfügen","superscript":"Hochgestellt","subscript":"Tiefgestellt","createLink":"Link erstellen","undo":"Rückgängig","italic":"Kursiv","fontName":"Schriftartname","justifyLeft":"Linksbündig","unlink":"Link entfernen","toggleTableBorder":"Tabellenumrandung ein-/ausschalten","ctrlKey":"Strg+${0}","fontSize":"Schriftgröße","indent":"Einrücken","redo":"Wiederherstellen","strikethrough":"Durchgestrichen","justifyFull":"Blocksatz","justifyCenter":"Zentriert","hiliteColor":"Hintergrundfarbe","deleteTable":"Tabelle löschen","outdent":"Ausrücken","cut":"Ausschneiden","plainFormatBlock":"Absatzstil","toggleDir":"Richtung wechseln","bold":"Fett","systemShortcutFF":"Die Aktion \"${0}\" ist in Mozilla Firefox nur über einen Tastaturkurzbefehl verfügbar. Verwenden Sie ${1}.","justifyRight":"Rechtsbündig","appleKey":"⌘${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-μικρά","2":"x-μικρά","formatBlock":"Μορφή","monospaced":"σταθερού πλάτους","3":"μικρά","4":"μεσαία","5":"μεγάλα","6":"x-μεγάλα","7":"xx-μεγάλα","fantasy":"φαντασίας","serif":"με πατούρες (serif)","p":"Παράγραφος","pre":"Προ-μορφοποιημένο","sans-serif":"χωρίς πατούρες (sans-serif)","fontName":"Γραμματοσειρά","h1":"Επικεφαλίδα","h2":"Δευτερεύουσα επικεφαλίδα","h3":"Δευτερεύουσα επικεφαλίδα τρίτου επιπέδου","fontSize":"Μέγεθος","cursive":"πλάγιοι","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Ορισμός","text":"Περιγραφή:","insertImageTitle":"Ιδιότητες εικόνας","url":"Διεύθυνση URL:","createLinkTitle":"Ιδιότητες διασύνδεσης"})

View file

@ -0,0 +1 @@
({"removeFormat":"Αφαίρεση μορφοποίησης","copy":"Αντιγραφή","paste":"Επικόλληση","selectAll":"Επιλογή όλων","insertOrderedList":"Αριθμημένη λίστα","insertTable":"Εισαγωγή/Τροποποίηση πίνακα","underline":"Υπογράμμιση","foreColor":"Χρώμα προσκηνίου","htmlToggle":"Πρωτογενής κώδικας HTML","formatBlock":"Στυλ παραγράφου","insertHorizontalRule":"Οριζόντια γραμμή","delete":"Διαγραφή","insertUnorderedList":"Λίστα με κουκίδες","tableProp":"Ιδιότητα πίνακα","insertImage":"Εισαγωγή εικόνας","superscript":"Εκθέτης","subscript":"Δείκτης","createLink":"Δημιουργία διασύνδεσης","undo":"Αναίρεση","italic":"Πλάγια","fontName":"Όνομα γραμματοσειράς","justifyLeft":"Στοίχιση αριστερά","unlink":"Αφαίρεση διασύνδεσης","toggleTableBorder":"Εναλλαγή εμφάνισης περιγράμματος πίνακα","fontSize":"Μέγεθος γραμματοσειράς","indent":"Εσοχή","redo":"Επανάληψη","strikethrough":"Διαγράμμιση","justifyFull":"Πλήρης στοίχιση","justifyCenter":"Στοίχιση στο κέντρο","hiliteColor":"Χρώμα φόντου","deleteTable":"Διαγραφή πίνακα","outdent":"Μείωση περιθωρίου","cut":"Αποκοπή","plainFormatBlock":"Στυλ παραγράφου","toggleDir":"Εναλλαγή κατεύθυνσης","bold":"Έντονα","systemShortcutFF":"Η ενέργεια \"${0}\" είναι διαθέσιμη μόνο στο Mozilla Firefox με τη χρήση συντόμευσης πληκτρολογίου. Χρησιμοποιήστε το ${1}.","justifyRight":"Στοίχιση δεξιά","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-pequeño","2":"x-pequeño","formatBlock":"Formato","monospaced":"monoespacio","3":"pequeño","4":"medio","5":"grande","6":"x-grande","7":"xx-grande","fantasy":"fantasía","serif":"serif","p":"Párrafo","pre":"Preformateado","sans-serif":"sans-serif","fontName":"Font","h1":"Cabecera","h2":"Subcabecera","h3":"Sub-subcabecera","fontSize":"Tamaño","cursive":"cursiva","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Establecer","text":"Descripción:","insertImageTitle":"Propiedades de la imagen","url":"URL:","createLinkTitle":"Propiedades del enlace"})

View file

@ -0,0 +1 @@
({"removeFormat":"Eliminar formato","copy":"Copiar","paste":"Pegar","selectAll":"Seleccionar todo","insertOrderedList":"Lista numerada","insertTable":"Insertar/Editar tabla","underline":"Subrayado","foreColor":"Color de primer plano","htmlToggle":"Fuente HTML","formatBlock":"Estilo de párrafo","insertHorizontalRule":"Regla horizontal","delete":"Suprimir","insertUnorderedList":"Lista con viñetas","tableProp":"Propiedad de tabla","insertImage":"Insertar imagen","superscript":"Superíndice","subscript":"Subíndice","createLink":"Crear enlace","undo":"Deshacer","italic":"Cursiva","fontName":"Nombre de font","justifyLeft":"Alinear izquierda","unlink":"Eliminar enlace","toggleTableBorder":"Conmutar borde de tabla","ctrlKey":"Control+${0}","fontSize":"Tamaño de font","indent":"Sangría","redo":"Rehacer","strikethrough":"Tachado","justifyFull":"Justificar","justifyCenter":"Alinear centro","hiliteColor":"Color de segundo plano","deleteTable":"Suprimir tabla","outdent":"Anular sangría","cut":"Cortar","plainFormatBlock":"Estilo de párrafo","toggleDir":"Conmutar dirección","bold":"Negrita","systemShortcutFF":"La acción \"${0}\" sólo está disponible en Mozilla Firefox mediante un atajo de teclado. Utilice ${1}.","justifyRight":"Alinear derecha","appleKey":"⌘${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-small","2":"x-small","formatBlock":"Muoto","monospaced":"monospaced","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Kappale","pre":"Esimuotoiltu","sans-serif":"sans-serif","fontName":"Fontti","h1":"Otsikko","h2":"Alatason otsikko","h3":"Alimman tason otsikko","fontSize":"Koko","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Aseta","text":"Kuvaus:","insertImageTitle":"Kuvan ominaisuudet","url":"URL-osoite:","createLinkTitle":"Linkin ominaisuudet"})

View file

@ -0,0 +1 @@
({"removeFormat":"Poista muotoilu","copy":"Kopioi","paste":"Liitä","selectAll":"Valitse kaikki","insertOrderedList":"Numeroitu luettelo","insertTable":"Lisää taulukko/muokkaa taulukkoa","underline":"Alleviivaus","foreColor":"Edustaväri","htmlToggle":"HTML-lähde","formatBlock":"Kappaletyyli","insertHorizontalRule":"Vaakasuuntainen viiva","delete":"Poista","insertUnorderedList":"Numeroimaton luettelo","tableProp":"Taulukon ominaisuudet","insertImage":"Lisää kuva","superscript":"Yläindeksi","subscript":"Alaindeksi","createLink":"Luo linkki","undo":"Kumoa","italic":"Kursivointi","fontName":"Fontin nimi","justifyLeft":"Tasaus vasemmalle","unlink":"Poista linkki","toggleTableBorder":"Ota taulukon kehys käyttöön/poista kehys käytöstä","fontSize":"Fontin koko","indent":"Sisennä","redo":"Tee uudelleen","strikethrough":"Yliviivaus","justifyFull":"Tasaus","justifyCenter":"Tasaus keskelle","hiliteColor":"Taustaväri","deleteTable":"Poista taulukko","outdent":"Ulonna","cut":"Leikkaa","plainFormatBlock":"Kappaletyyli","toggleDir":"Vaihda suuntaa","bold":"Lihavointi","systemShortcutFF":"Toiminto \"${0}\" on käytettävissä vain Mozilla Firefox -ohjelmassa, kun käytetään pikanäppäimiä. Käytä kohdetta ${1}.","justifyRight":"Tasaus oikealle","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xxs","2":"xs","formatBlock":"Mise en forme","monospaced":"espacement constant","3":"s","4":"m","5":"l","6":"xl","7":"xxl","fantasy":"fantaisie","serif":"serif","p":"Paragraphe","pre":"Pré-mise en forme","sans-serif":"sans serif","fontName":"Police","h1":"En-tête","h2":"Sous-en-tête","h3":"Sous-sous-en-tête","fontSize":"Taille","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Définir","text":"Description :","insertImageTitle":"Propriétés de l'image","url":"URL :","createLinkTitle":"Propriétés du lien"})

View file

@ -0,0 +1 @@
({"removeFormat":"Supprimer la mise en forme","copy":"Copier","paste":"Coller","selectAll":"Sélectionner tout","insertOrderedList":"Liste numérotée","insertTable":"Insérer/Modifier un tableau","underline":"Souligner","foreColor":"Couleur d'avant-plan","htmlToggle":"Source HTML","formatBlock":"Style de paragraphe","insertHorizontalRule":"Règle horizontale","delete":"Supprimer","insertUnorderedList":"Liste à puces","tableProp":"Propriété du tableau","insertImage":"Insérer une image","superscript":"Exposant","subscript":"Indice","createLink":"Créer un lien","undo":"Annuler","italic":"Italique","fontName":"Nom de police","justifyLeft":"Aligner à gauche","unlink":"Supprimer le lien","toggleTableBorder":"Afficher/Masquer la bordure du tableau","fontSize":"Taille de police","indent":"Retrait","redo":"Rétablir","strikethrough":"Barrer","justifyFull":"Justifier","justifyCenter":"Aligner au centre","hiliteColor":"Couleur d'arrière-plan","deleteTable":"Supprimer le tableau","outdent":"Retrait négatif","cut":"Couper","plainFormatBlock":"Style de paragraphe","toggleDir":"Afficher/Masquer la direction","bold":"Gras","systemShortcutFF":"L'action \"${0}\" est disponible dans Mozilla Firefox uniquement, par le biais d'un raccourci-clavier. Utilisez ${1}.","justifyRight":"Aligner à droite","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"קטן ביות","2":"קטן מאוד","formatBlock":"עיצוב","monospaced":"monospaced","3":"קטן ","4":"בינוני","5":"גדול","6":"גדול מאוד","7":"גדול ביותר","fantasy":"fantasy","serif":"serif","p":"פיסקה","pre":"מעוצב מראש","sans-serif":"sans-serif","fontName":"גופן","h1":"כותרת","h2":"תת-כותרת","h3":"תת-תת-כותרת","fontSize":"גודל","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"הגדרה","text":"תיאור:","insertImageTitle":"תכונות תמונה","url":"URL:","createLinkTitle":"תכונות קישור"})

View file

@ -0,0 +1 @@
({"removeFormat":"סילוק עיצוב","copy":"העתקה","paste":"הדבקה","selectAll":"בחירת הכל","insertOrderedList":"רשימה ממוספרת","insertTable":"הוספת/עריכת טבלה","underline":"קו תחתי","foreColor":"צבע חזית ","htmlToggle":"מקור HTML","formatBlock":"סגנון פיסקה","insertHorizontalRule":"קו אופקי","delete":"מחיקה","insertUnorderedList":"רשימה עם תבליטים","tableProp":"תכונת טבלה","insertImage":"הוספת תמונה","superscript":"כתב עילי","subscript":"כתב תחתי","createLink":"יצירת קישור","undo":"ביטול פעולה","italic":"נטוי","fontName":"שם גופן","justifyLeft":"יישור לשמאל","unlink":"סילוק הקישור","toggleTableBorder":"מיתוג גבול טבלה","fontSize":"גופן יחסי","indent":"הגדלת כניסה","redo":"שחזור פעולה","strikethrough":"קו חוצה","justifyFull":"יישור דו-צדדי","justifyCenter":"יישור למרכז","hiliteColor":"צבע רקע","deleteTable":"מחיקת טבלה","outdent":"הקטנת כניסה","cut":"גזירה","plainFormatBlock":"סגנון פיסקה","toggleDir":"מיתוג כיוון ","bold":"מודגש","systemShortcutFF":"הפעולה \"${0}\" זמינה בדפדפן Mozilla Firefox רק באמצעות קיצור דרך במקלדת. נא להשתמש ב-${1}.","justifyRight":"יישור לימין","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-kicsi","2":"x-kicsi","formatBlock":"Formátum","monospaced":"egyenközű","3":"kicsi","4":"közepes","5":"nagy","6":"x-nagy","7":"xx-nagy","fantasy":"fantázia","serif":"talpas","p":"Bekezdés","pre":"Előformázott","sans-serif":"talpatlan","fontName":"Betűtípus","h1":"Címsor","h2":"Alcím","h3":"Al-alcím","fontSize":"Méret","cursive":"kurzív","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Beállítás","text":"Leírás:","insertImageTitle":"Kép tulajdonságai","url":"URL:","createLinkTitle":"Hivatkozás tulajdonságai"})

View file

@ -0,0 +1 @@
({"removeFormat":"Formázás eltávolítása","copy":"Másolás","paste":"Beillesztés","selectAll":"Összes kijelölése","insertOrderedList":"Számozott lista","insertTable":"Táblázat beszúrása/szerkesztése","underline":"Aláhúzott","foreColor":"Előtérszín","htmlToggle":"HTML forrás","formatBlock":"Bekezdés stílusa","insertHorizontalRule":"Vízszintes vonalzó","delete":"Törlés","insertUnorderedList":"Felsorolásjeles lista","tableProp":"Táblázat tulajdonságai","insertImage":"Kép beszúrása","superscript":"Felső index","subscript":"Alsó index","createLink":"Hivatkozás létrehozása","undo":"Visszavonás","italic":"Dőlt","fontName":"Betűtípus","justifyLeft":"Balra igazítás","unlink":"Hivatkozás eltávolítása","toggleTableBorder":"Táblázatszegély ki-/bekapcsolása","fontSize":"Betűméret","indent":"Behúzás","redo":"Újra","strikethrough":"Áthúzott","justifyFull":"Sorkizárás","justifyCenter":"Középre igazítás","hiliteColor":"Háttérszín","deleteTable":"Táblázat törlése","outdent":"Negatív behúzás","cut":"Kivágás","plainFormatBlock":"Bekezdés stílusa","toggleDir":"Irányváltás","bold":"Félkövér","systemShortcutFF":"A(z) \"${0}\" művelet csak Mozilla Firefox böngészőben érhető el billentyűparancs használatával. Használja a következőt: ${1}.","justifyRight":"Jobbra igazítás","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-small","2":"x-small","formatBlock":"Formato","monospaced":"monospaced","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Paragrafo","pre":"Preformattato","sans-serif":"sans-serif","fontName":"Carattere","h1":"Intestazione","h2":"Sottointestazione","h3":"Sottointestazione secondaria","fontSize":"Dimensione","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Imposta","text":"Descrizione:","insertImageTitle":"Proprietà immagine","url":"URL:","createLinkTitle":"Proprietà collegamento"})

View file

@ -0,0 +1 @@
({"removeFormat":"Rimuovi formato","copy":"Copia","paste":"Incolla","selectAll":"Seleziona tutto","insertOrderedList":"Elenco numerato","insertTable":"Inserisci/Modifica tabella","underline":"Sottolineato","foreColor":"Colore primo piano","htmlToggle":"Origine HTML","formatBlock":"Stile paragrafo","insertHorizontalRule":"Righello orizzontale","delete":"Elimina","insertUnorderedList":"Elenco puntato","tableProp":"Proprietà tabella","insertImage":"Inserisci immagine","superscript":"Apice","subscript":"Pedice","createLink":"Crea collegamento","undo":"Annulla","italic":"Corsivo","fontName":"Nome carattere","justifyLeft":"Allinea a sinistra","unlink":"Rimuovi collegamento","toggleTableBorder":"Mostra/Nascondi margine tabella","fontSize":"Dimensione carattere","indent":"Rientra","redo":"Ripristina","strikethrough":"Barrato","justifyFull":"Giustifica","justifyCenter":"Allinea al centro","hiliteColor":"Colore sfondo","deleteTable":"Elimina tabella","outdent":"Rimuovi rientro","cut":"Taglia","plainFormatBlock":"Stile paragrafo","toggleDir":"Inverti direzione","bold":"Grassetto","systemShortcutFF":"L'azione \"${0}\" è disponibile solo in Mozilla Firefox tramite tasti di scelta rapida. Utilizzare ${1}.","justifyRight":"Allinea a destra","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"超極小","2":"極小","formatBlock":"フォーマット","monospaced":"monospace","3":"小","4":"標準","5":"大","6":"特大","7":"超特大","fantasy":"fantasy","serif":"serif","p":"段落","pre":"事前フォーマット済み","sans-serif":"sans-serif","fontName":"フォント","h1":"見出し","h2":"副見出し","h3":"副見出しの副見出し","fontSize":"サイズ","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"設定","text":"説明:","insertImageTitle":"イメージ・プロパティー","url":"URL:","createLinkTitle":"リンク・プロパティー"})

View file

@ -0,0 +1 @@
({"removeFormat":"形式の除去","copy":"コピー","paste":"貼り付け","selectAll":"すべて選択","insertOrderedList":"番号付きリスト","insertTable":"テーブルの挿入/編集","underline":"下線","foreColor":"前景色","htmlToggle":"HTML ソース","formatBlock":"段落スタイル","insertHorizontalRule":"水平罫線","delete":"削除","insertUnorderedList":"黒丸付きリスト","tableProp":"テーブル・プロパティー","insertImage":"イメージの挿入","superscript":"上付き文字","subscript":"下付き文字","createLink":"リンクの作成","undo":"元に戻す","italic":"イタリック","fontName":"フォント名","justifyLeft":"左揃え","unlink":"リンクの除去","toggleTableBorder":"テーブル・ボーダーの切り替え","fontSize":"フォント・サイズ","indent":"インデント","redo":"やり直し","strikethrough":"取り消し線","justifyFull":"両端揃え","justifyCenter":"中央揃え","hiliteColor":"背景色","deleteTable":"テーブルの削除","outdent":"アウトデント","cut":"切り取り","plainFormatBlock":"段落スタイル","toggleDir":"方向の切り替え","bold":"太字","systemShortcutFF":"\"${0}\" アクションは、キーボード・ショートカットを使用して Mozilla Firefox でのみ使用できます。${1} を使用してください。","justifyRight":"右揃え","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"가장 작게","2":"조금 작게","formatBlock":"서식","monospaced":"monospaced","3":"작게","4":"중간","5":"크게","6":"조금 크게","7":"가장 크게","fantasy":"fantasy","serif":"serif","p":"단락","pre":"서식이 지정됨","sans-serif":"sans-serif","fontName":"글꼴","h1":"제목","h2":"부제목","h3":"하위 부제목","fontSize":"크기","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"설정","text":"설명:","insertImageTitle":"이미지 등록 정보","url":"URL:","createLinkTitle":"링크 등록 정보"})

View file

@ -0,0 +1 @@
({"removeFormat":"형식 제거","copy":"복사","paste":"붙여넣기","selectAll":"모두 선택","insertOrderedList":"번호 목록","insertTable":"테이블 삽입/편집","underline":"밑줄","foreColor":"전경색","htmlToggle":"HTML 소스","formatBlock":"단락 양식","insertHorizontalRule":"수평 자","delete":"삭제","insertUnorderedList":"글머리표 목록","tableProp":"테이블 특성","insertImage":"이미지 삽입","superscript":"위첨자","subscript":"아래첨자","createLink":"링크 작성","undo":"실행 취소","italic":"이탤릭체","fontName":"글꼴 이름","justifyLeft":"왼쪽 맞춤","unlink":"링크 제거","toggleTableBorder":"토글 테이블 경계","fontSize":"글꼴 크기","indent":"들여쓰기","redo":"다시 실행","strikethrough":"취소선","justifyFull":"양쪽 맞춤","justifyCenter":"가운데 맞춤","hiliteColor":"배경색","deleteTable":"테이블 삭제","outdent":"내어쓰기","cut":"잘라내기","plainFormatBlock":"단락 양식","toggleDir":"토글 방향","bold":"굵은체","systemShortcutFF":"\"${0}\" 조치는 키보드 바로 가기를 사용하는 Mozilla Firefox에서만 사용 가능합니다. ${1} 사용.","justifyRight":"오른쪽 맞춤","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-liten","2":"x-liten","formatBlock":"Format","monospaced":"ikke-proporsjonal","3":"liten","4":"middels","5":"stor","6":"x-stor","7":"xx-stor","fantasy":"fantasi","serif":"serif","p":"Avsnitt","pre":"Forhåndsformatert","sans-serif":"sans-serif","fontName":"Skrift","h1":"Overskrift","h2":"Undertittel","h3":"Under-undertittel","fontSize":"Størrelse","cursive":"kursiv","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Definer","text":"Beskrivelse:","insertImageTitle":"Bildeegenskaper","url":"URL:","createLinkTitle":"Koblingsegenskaper"})

View file

@ -0,0 +1 @@
({"removeFormat":"Fjern format","copy":"Kopier","paste":"Lim inn","selectAll":"Velg alle","insertOrderedList":"Nummerert liste","insertTable":"Sett inn/rediger tabell","underline":"Understreking","foreColor":"Forgrunnsfarge","htmlToggle":"HTML-kilde","formatBlock":"Avsnittsstil","insertHorizontalRule":"Vannrett strek","delete":"Slett","insertUnorderedList":"Punktliste","tableProp":"Tabellegenskap","insertImage":"Sett inn bilde","superscript":"Hevet skrift","subscript":"Senket skrift","createLink":"Opprett kobling","undo":"Angre","italic":"Kursiv","fontName":"Skriftnavn","justifyLeft":"Venstrejuster","unlink":"Fjern kobling","toggleTableBorder":"Bytt tabellkant","fontSize":"Skriftstørrelse","indent":"Innrykk","redo":"Gjør om","strikethrough":"Gjennomstreking","justifyFull":"Juster","justifyCenter":"Midtstill","hiliteColor":"Bakgrunnsfarge","deleteTable":"Slett tabell","outdent":"Fjern innrykk","cut":"Klipp ut","plainFormatBlock":"Avsnittsstil","toggleDir":"Bytt retning","bold":"Fet","systemShortcutFF":"Handlingen \"${0}\" er bare tilgjengelig i Mozilla Firefox ved hjelp av en tastatursnarvei. Bruk ${1}.","justifyRight":"Høyrejuster","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-klein","2":"x-klein","formatBlock":"Opmaak","monospaced":"monospaced","3":"klein","4":"gemiddeld","5":"groot","6":"x-groot","7":"xx-groot","fantasy":"fantasy","serif":"serif","p":"Alinea","pre":"Vooraf opgemaakt","sans-serif":"sans-serif","fontName":"Lettertype","h1":"Kop","h2":"Subkop","h3":"Sub-subkop","fontSize":"Grootte","cursive":"cursief","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Instellen","text":"Beschrijving:","insertImageTitle":"Afbeeldingseigenschappen","url":"URL:","createLinkTitle":"Linkeigenschappen"})

View file

@ -0,0 +1 @@
({"removeFormat":"Opmaak verwijderen","copy":"Kopiëren","paste":"Plakken","selectAll":"Alles selecteren","insertOrderedList":"Genummerde lijst","insertTable":"Tabel invoegen/bewerken","underline":"Onderstrepen","foreColor":"Voorgrondkleur","htmlToggle":"HTML-bron","formatBlock":"Alineastijl","insertHorizontalRule":"Horizontale liniaal","delete":"Wissen","insertUnorderedList":"Lijst met opsommingstekens","tableProp":"Tabeleigenschap","insertImage":"Afbeelding invoegen","superscript":"Superscript","subscript":"Subscript","createLink":"Link maken","undo":"Ongedaan maken","italic":"Cursief","fontName":"Lettertype","justifyLeft":"Links uitlijnen","unlink":"Link verwijderen","toggleTableBorder":"Tabelkader wijzigen","ctrlKey":"Ctrl+${0}","fontSize":"Lettergrootte","indent":"Inspringen","redo":"Opnieuw","strikethrough":"Doorhalen","justifyFull":"Uitvullen","justifyCenter":"Centreren","hiliteColor":"Achtergrondkleur","deleteTable":"Tabel wissen","outdent":"Uitspringen","cut":"Knippen","plainFormatBlock":"Alineastijl","toggleDir":"Schrijfrichting wijzigen","bold":"Vet","systemShortcutFF":"De actie \"${0}\" is alleen beschikbaar in Mozilla Firefox via een sneltoestcombinatie. Gebruik ${1}.","justifyRight":"Rechts uitlijnen","appleKey":"⌘${0}"})

View file

@ -0,0 +1 @@
({"1":"najmniejsza","2":"mniejsza","formatBlock":"Format","monospaced":"stałej szerokości","3":"mała","4":"średnia","5":"duża","6":"większa","7":"największa","fantasy":"fantazyjna","serif":"szeryfowa","p":"Akapit","pre":"Wstępnie sformatowane","sans-serif":"bezszeryfowa","fontName":"Czcionka","h1":"Nagłówek","h2":"Nagłówek 2-go poziomu","h3":"Nagłówek 3-go poziomu","fontSize":"Wielkość","cursive":"kursywa","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Ustaw","text":"Opis:","insertImageTitle":"Właściwości obrazu","url":"Adres URL:","createLinkTitle":"Właściwości odsyłacza"})

View file

@ -0,0 +1 @@
({"removeFormat":"Usuń formatowanie","copy":"Kopiuj","paste":"Wklej","selectAll":"Wybierz wszystko","insertOrderedList":"Lista numerowana","insertTable":"Wstaw/edytuj tabelę","underline":"Podkreślenie","foreColor":"Kolor pierwszego planu","htmlToggle":"Źródło HTML","formatBlock":"Styl akapitu","insertHorizontalRule":"Linia pozioma","delete":"Usuń","insertUnorderedList":"Lista wypunktowana","tableProp":"Właściwość tabeli","insertImage":"Wstaw obraz","superscript":"Indeks górny","subscript":"Indeks dolny","createLink":"Utwórz odsyłacz","undo":"Cofnij","italic":"Kursywa","fontName":"Nazwa czcionki","justifyLeft":"Wyrównaj do lewej","unlink":"Usuń odsyłacz","toggleTableBorder":"Przełącz ramkę tabeli","fontSize":"Wielkość czcionki","indent":"Wcięcie","redo":"Przywróć","strikethrough":"Przekreślenie","justifyFull":"Wyrównaj do lewej i prawej","justifyCenter":"Wyrównaj do środka","hiliteColor":"Kolor tła","deleteTable":"Usuń tabelę","outdent":"Usuń wcięcie","cut":"Wytnij","plainFormatBlock":"Styl akapitu","toggleDir":"Przełącz kierunek","bold":"Pogrubienie","systemShortcutFF":"Działanie ${0} jest dostępne w przeglądarce Mozilla Firefox wyłącznie za pomocą skrótu klawiaturowego. Użyj ${1}.","justifyRight":"Wyrównaj do prawej","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xxs","2":"xs","formatBlock":"Formato","monospaced":"monospaced","3":"small","4":"medium","5":"large","6":"xl","7":"xxl","fantasy":"fantasy","serif":"serif","p":"Parágrafo","pre":"Pré-formatado","sans-serif":"sans-serif","fontName":"Tipo de letra","h1":"Título","h2":"Sub-título","h3":"Sub-subtítulo","fontSize":"Tamanho","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Definir","text":"Descrição:","insertImageTitle":"Propriedades da imagem","url":"URL:","createLinkTitle":"Propriedade da ligação"})

View file

@ -0,0 +1 @@
({"removeFormat":"Remover formato","copy":"Copiar","paste":"Colar","selectAll":"Seleccionar tudo","insertOrderedList":"Lista numerada","insertTable":"Inserir/Editar tabela","underline":"Sublinhado","foreColor":"Cor de primeiro plano","htmlToggle":"Origem HTML","formatBlock":"Estilo de parágrafo","insertHorizontalRule":"Régua horizontal","delete":"Eliminar","insertUnorderedList":"Lista marcada","tableProp":"Propriedades da tabela","insertImage":"Inserir imagem","superscript":"Superior à linha","subscript":"Inferior à linha","createLink":"Criar ligação","undo":"Anular","italic":"Itálico","fontName":"Nome do tipo de letra","justifyLeft":"Alinhar à esquerda","unlink":"Remover ligação","toggleTableBorder":"Alternar limite da tabela","fontSize":"Tamanho do tipo de letra","indent":"Indentar","redo":"Repetir","strikethrough":"Rasurado","justifyFull":"Justificar","justifyCenter":"Alinhar ao centro","hiliteColor":"Cor de segundo plano","deleteTable":"Eliminar tabela","outdent":"Recuar","cut":"Cortar","plainFormatBlock":"Estilo de parágrafo","toggleDir":"Alternar direcção","bold":"Negrito","systemShortcutFF":"A acção \"${0}\" apenas está disponível no Mozilla Firefox utilizando um atalho de teclado. Utilize ${1}.","justifyRight":"Alinhar à direita","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-small","2":"x-small","formatBlock":"Formato","monospaced":"monospaced","3":"small","4":"medium","5":"large","6":"x-large","7":"xx-large","fantasy":"fantasy","serif":"serif","p":"Parágrafo","pre":"Pré-formatado","sans-serif":"sans-serif","fontName":"Fonte","h1":"Título","h2":"Subtítulo","h3":"Sub-subtítulo","fontSize":"Tamanho","cursive":"cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Definir","text":"Descrição:","insertImageTitle":"Propriedades de Imagem","url":"URL:","createLinkTitle":"Propriedades de Link"})

View file

@ -0,0 +1 @@
({"removeFormat":"Remover Formato","copy":"Copiar","paste":"Colar","selectAll":"Selecionar Todos","insertOrderedList":"Lista Numerada","insertTable":"Inserir/Editar Tabela","underline":"Sublinhado","foreColor":"Cor do Primeiro Plano","htmlToggle":"Origem HTML","formatBlock":"Estilo de Parágrafo","insertHorizontalRule":"Régua Horizontal","delete":"Excluir ","insertUnorderedList":"Lista com Marcadores","tableProp":"Propriedade da Tabela","insertImage":"Inserir Imagem","superscript":"Sobrescrito","subscript":"Subscrito","createLink":"Criar Link","undo":"Desfazer","italic":"Itálico","fontName":"Nome da Fonte","justifyLeft":"Alinhar pela Esquerda","unlink":"Remover Link","toggleTableBorder":"Alternar Moldura da Tabela","fontSize":"Tamanho da Fonte","indent":"Recuar","redo":"Refazer","strikethrough":"Tachado","justifyFull":"Justificar","justifyCenter":"Alinhar pelo Centro","hiliteColor":"Cor de segundo plano","deleteTable":"Excluir Tabela","outdent":"Não-chanfrado","cut":"Recortar","plainFormatBlock":"Estilo de Parágrafo","toggleDir":"Alternar Direção","bold":"Negrito","systemShortcutFF":"A ação \"${0}\" está disponível apenas no Mozilla Firefox utilizando um atalho do teclado. Utilize ${1}.","justifyRight":"Alinhar pela Direita","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"самый маленький","2":"очень маленький","formatBlock":"Формат","monospaced":"непропорциональный","3":"маленький","4":"средний","5":"большой","6":"очень большой","7":"самый большой","fantasy":"артистический","serif":"с засечками","p":"Абзац","pre":"Заранее отформатированный","sans-serif":"без засечек","fontName":"Шрифт","h1":"Заголовок","h2":"Подзаголовок","h3":"Вложенный подзаголовок","fontSize":"Размер","cursive":"курсив","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Задать","text":"Описание:","insertImageTitle":"Свойства изображения","url":"URL:","createLinkTitle":"Свойства ссылки"})

View file

@ -0,0 +1 @@
({"removeFormat":"Удалить формат","copy":"Копировать","paste":"Вставить","selectAll":"Выбрать все","insertOrderedList":"Нумерованный список","insertTable":"Вставить/изменить таблицу","underline":"Подчеркивание","foreColor":"Цвет текста","htmlToggle":"Код HTML","formatBlock":"Стиль абзаца","insertHorizontalRule":"Горизонтальная линейка","delete":"Удалить","insertUnorderedList":"Список с маркерами","tableProp":"Свойства таблицы","insertImage":"Вставить изображение","superscript":"Верхний индекс","subscript":"Нижний индекс","createLink":"Создать ссылку","undo":"Отменить","italic":"Курсив","fontName":"Название шрифта","justifyLeft":"По левому краю","unlink":"Удалить ссылку","toggleTableBorder":"Переключить рамку таблицы","fontSize":"Размер шрифта","indent":"Отступ","redo":"Повторить","strikethrough":"Перечеркивание","justifyFull":"По ширине","justifyCenter":"По центру","hiliteColor":"Цвет фона","deleteTable":"Удалить таблицу","outdent":"Втяжка","cut":"Вырезать","plainFormatBlock":"Стиль абзаца","toggleDir":"Изменить направление","bold":"Полужирный","systemShortcutFF":"Действие \"${0}\" доступно в Mozilla Firefox только через сочетание клавиш. Используйте ${1}.","justifyRight":"По правому краю","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"mycket, mycket litet","2":"mycket litet","formatBlock":"Format","monospaced":"fast teckenavstånd","3":"litet","4":"medelstort","5":"stort","6":"extra stort","7":"extra extra stort","fantasy":"fantasy","serif":"serif","p":"Stycke","pre":"Förformaterat","sans-serif":"sans-serif","fontName":"Teckensnitt","h1":"Rubrik","h2":"Underrubrik","h3":"Underunderrubrik","fontSize":"Storlek","cursive":"kursivt","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Ange","text":"Beskrivning:","insertImageTitle":"Bildegenskaper","url":"URL-adress:","createLinkTitle":"Länkegenskaper"})

View file

@ -0,0 +1 @@
({"removeFormat":"Ta bort format","copy":"Kopiera","paste":"Klistra in","selectAll":"Markera allt","insertOrderedList":"Numrerad lista","insertTable":"Infoga/redigera tabell","underline":"Understrykning","foreColor":"Förgrundsfärg","htmlToggle":"HTML-källkod","formatBlock":"Styckeformat","insertHorizontalRule":"Horisontell linjal","delete":"Ta bort","insertUnorderedList":"Punktlista","tableProp":"Tabellegenskap","insertImage":"Infoga bild","superscript":"Upphöjt","subscript":"Nedsänkt","createLink":"Skapa länk","undo":"Ångra","italic":"Kursiv","fontName":"Teckensnittsnamn","justifyLeft":"Vänsterjustera","unlink":"Ta bort länk","toggleTableBorder":"Aktivera/avaktivera tabellram","ctrlKey":"Ctrl+${0}","fontSize":"Teckenstorlek","indent":"Indrag","redo":"Gör om","strikethrough":"Genomstruken","justifyFull":"Marginaljustera","justifyCenter":"Centrera","hiliteColor":"Bakgrundsfärg","deleteTable":"Ta bort tabell","outdent":"Utdrag","cut":"Klipp ut","plainFormatBlock":"Styckeformat","toggleDir":"Växla riktning","bold":"Fetstil","systemShortcutFF":"Åtgärden \"${0}\" är endast tillgänglig i Mozilla Firefox med hjälp av ett kortkommando. Använd ${1}.","justifyRight":"Högerjustera","appleKey":"⌘${0}"})

View file

@ -0,0 +1 @@
({"1":"xx-küçük","2":"x-küçük","formatBlock":"Biçim","monospaced":"eşaralıklı","3":"küçük","4":"orta","5":"büyük","6":"x-büyük","7":"xx-büyük","fantasy":"fantazi","serif":"serif","p":"Paragraf","pre":"Önceden Biçimlendirilmiş","sans-serif":"sans-serif","fontName":"Yazı Tipi","h1":"Başlık","h2":"Alt Başlık","h3":"Alt Alt Başlık","fontSize":"Boyut","cursive":"el yazısı","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"Ayarla","text":"Açıklama:","insertImageTitle":"Resim Özellikleri","url":"URL:","createLinkTitle":"Bağlantı Özellikleri"})

View file

@ -0,0 +1 @@
({"removeFormat":"Biçimi Kaldır","copy":"Kopyala","paste":"Yapıştır","selectAll":"Tümünü Seç","insertOrderedList":"Numaralı Liste","insertTable":"Tablo Ekle/Düzenle","underline":"Altı Çizili","foreColor":"Ön Plan Rengi","htmlToggle":"HTML Kaynağı","formatBlock":"Paragraf Stili","insertHorizontalRule":"Yatay Kural","delete":"Sil","insertUnorderedList":"Madde İşaretli Liste","tableProp":"Tablo Özelliği","insertImage":"Resim Ekle","superscript":"Üst Simge","subscript":"Alt Simge","createLink":"Bağlantı Oluştur","undo":"Geri Al","italic":"İtalik","fontName":"Yazı Tipi Adı","justifyLeft":"Sola Hizala","unlink":"Bağlantıyı Kaldır","toggleTableBorder":"Tablo Kenarlığını Göster/Gizle","fontSize":"Yazı Tipi Boyutu","indent":"Girinti","redo":"Yinele","strikethrough":"Üstü Çizili","justifyFull":"Yasla","justifyCenter":"Ortaya Hizala","hiliteColor":"Arka Plan Rengi","deleteTable":"Tabloyu Sil","outdent":ıkıntı","cut":"Kes","plainFormatBlock":"Paragraf Stili","toggleDir":"Yönü Değiştir","bold":"Kalın","systemShortcutFF":"\"${0}\" işlemi yalnızca Mozilla Firefox'ta bir klavye kısayoluyla birlikte kullanılabilir. ${1} işlemini kullanın.","justifyRight":"Sağa Hizala","appleKey":"⌘${0}","ctrlKey":"ctrl+${0}"})

View file

@ -0,0 +1 @@
({"1":"最小","2":"較小","formatBlock":"格式","monospaced":"單距","3":"小","4":"中","5":"大","6":"較大","7":"最大","fantasy":"Fantasy","serif":"新細明體","p":"段落","pre":"預先格式化","sans-serif":"新細明體","fontName":"字型","h1":"標題","h2":"子標題","h3":"次子標題","fontSize":"大小","cursive":"Cursive","monospace":"monospace"})

View file

@ -0,0 +1 @@
({"set":"設定","text":"說明:","insertImageTitle":"影像檔內容","url":"URL","createLinkTitle":"鏈結內容"})

Some files were not shown because too many files have changed in this diff Show more