New build scripts

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2007-03-04 19:05:34 +00:00
parent 04f9a2e7bc
commit 838e7d5381
845 changed files with 121780 additions and 183 deletions

View File

@@ -0,0 +1,15 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [ "dojo.html.common",
"dojo.html.style" ]
});
dojo.provide("dojo.html.*");

View File

@@ -0,0 +1,35 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.html.style");
dojo.provide("dojo.html.color");
dojo.require("dojo.gfx.color");
dojo.require("dojo.lang.common");
dojo.html.getBackgroundColor = function(/* HTMLElement */node){
// summary
// returns the background color of the passed node as a 32-bit color (RGBA)
node = dojo.byId(node);
var color;
do{
color = dojo.html.getStyle(node, "background-color");
// Safari doesn't say "transparent"
if(color.toLowerCase() == "rgba(0, 0, 0, 0)") { color = "transparent"; }
if(node == document.getElementsByTagName("body")[0]) { node = null; break; }
node = node.parentNode;
}while(node && dojo.lang.inArray(["transparent", ""], color));
if(color == "transparent"){
color = [255, 255, 255, 0];
}else{
color = dojo.gfx.color.extractRGB(color);
}
return color; // array
}

View File

@@ -0,0 +1,230 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.common");
dojo.require("dojo.lang.common");
dojo.require("dojo.dom");
dojo.lang.mixin(dojo.html, dojo.dom);
dojo.html.body = function(){
dojo.deprecated("dojo.html.body() moved to dojo.body()", "0.5");
return dojo.body();
}
// FIXME: we are going to assume that we can throw any and every rendering
// engine into the IE 5.x box model. In Mozilla, we do this w/ CSS.
// Need to investigate for KHTML and Opera
dojo.html.getEventTarget = function(/* DOMEvent */evt){
// summary
// Returns the target of an event
if(!evt) { evt = dojo.global().event || {} };
var t = (evt.srcElement ? evt.srcElement : (evt.target ? evt.target : null));
while((t)&&(t.nodeType!=1)){ t = t.parentNode; }
return t; // HTMLElement
}
dojo.html.getViewport = function(){
// summary
// Returns the dimensions of the viewable area of a browser window
var _window = dojo.global();
var _document = dojo.doc();
var w = 0;
var h = 0;
if(dojo.render.html.mozilla){
// mozilla
w = _document.documentElement.clientWidth;
h = _window.innerHeight;
}else if(!dojo.render.html.opera && _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.render.html.opera && dojo.exists(_document, "documentElement.clientWidth")){
// IE6 Strict
var w2 = _document.documentElement.clientWidth;
// this lets us account for scrollbars
if(!w || w2 && w2 < w) {
w = w2;
}
h = _document.documentElement.clientHeight;
} else if (dojo.body().clientWidth){
// IE, Opera
w = dojo.body().clientWidth;
h = dojo.body().clientHeight;
}
return { width: w, height: h }; // object
}
dojo.html.getScroll = function(){
// summary
// Returns the scroll position of the document
var _window = dojo.global();
var _document = dojo.doc();
var top = _window.pageYOffset || _document.documentElement.scrollTop || dojo.body().scrollTop || 0;
var left = _window.pageXOffset || _document.documentElement.scrollLeft || dojo.body().scrollLeft || 0;
return {
top: top,
left: left,
offset:{ x: left, y: top } // note the change, NOT an Array with added properties.
}; // object
}
dojo.html.getParentByType = function(/* HTMLElement */node, /* string */type) {
// summary
// Returns the first ancestor of node with tagName type.
var _document = dojo.doc();
var parent = dojo.byId(node);
type = type.toLowerCase();
while((parent)&&(parent.nodeName.toLowerCase()!=type)){
if(parent==(_document["body"]||_document["documentElement"])){
return null;
}
parent = parent.parentNode;
}
return parent; // HTMLElement
}
dojo.html.getAttribute = function(/* HTMLElement */node, /* string */attr){
// summary
// Returns the value of attribute attr from node.
node = dojo.byId(node);
// FIXME: need to add support for attr-specific accessors
if((!node)||(!node.getAttribute)){
// if(attr !== 'nwType'){
// alert("getAttr of '" + attr + "' with bad node");
// }
return null;
}
var ta = typeof attr == 'string' ? attr : new String(attr);
// first try the approach most likely to succeed
var v = node.getAttribute(ta.toUpperCase());
if((v)&&(typeof v == 'string')&&(v!="")){
return v; // string
}
// try returning the attributes value, if we couldn't get it as a string
if(v && v.value){
return v.value; // string
}
// this should work on Opera 7, but it's a little on the crashy side
if((node.getAttributeNode)&&(node.getAttributeNode(ta))){
return (node.getAttributeNode(ta)).value; // string
}else if(node.getAttribute(ta)){
return node.getAttribute(ta); // string
}else if(node.getAttribute(ta.toLowerCase())){
return node.getAttribute(ta.toLowerCase()); // string
}
return null; // string
}
dojo.html.hasAttribute = function(/* HTMLElement */node, /* string */attr){
// summary
// Determines whether or not the specified node carries a value for the attribute in question.
return dojo.html.getAttribute(dojo.byId(node), attr) ? true : false; // boolean
}
dojo.html.getCursorPosition = function(/* DOMEvent */e){
// summary
// Returns the mouse position relative to the document (not the viewport).
// For example, if you have a document that is 10000px tall,
// but your browser window is only 100px tall,
// if you scroll to the bottom of the document and call this function it
// will return {x: 0, y: 10000}
// NOTE: for events delivered via dojo.event.connect() and/or dojoAttachEvent (for widgets),
// you can just access evt.pageX and evt.pageY, rather than calling this function.
e = e || dojo.global().event;
var cursor = {x:0, y:0};
if(e.pageX || e.pageY){
cursor.x = e.pageX;
cursor.y = e.pageY;
}else{
var de = dojo.doc().documentElement;
var db = dojo.body();
cursor.x = e.clientX + ((de||db)["scrollLeft"]) - ((de||db)["clientLeft"]);
cursor.y = e.clientY + ((de||db)["scrollTop"]) - ((de||db)["clientTop"]);
}
return cursor; // object
}
dojo.html.isTag = function(/* HTMLElement */node) {
// summary
// Like dojo.dom.isTag, except case-insensitive
node = dojo.byId(node);
if(node && node.tagName) {
for (var i=1; i<arguments.length; i++){
if (node.tagName.toLowerCase()==String(arguments[i]).toLowerCase()){
return String(arguments[i]).toLowerCase(); // string
}
}
}
return ""; // string
}
//define dojo.html.createExternalElement for IE to workaround the annoying activation "feature" in new IE
//details: http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/overview/activating_activex.asp
if(dojo.render.html.ie && !dojo.render.html.ie70){
//only define createExternalElement for IE in none https to avoid "mixed content" warning dialog
if(window.location.href.substr(0,6).toLowerCase() != "https:"){
(function(){
// FIXME: this seems not to work correctly on IE 7!!
//The trick is to define a function in a script.src property:
// <script src="javascript:'function createExternalElement(){...}'"></script>,
//which will be treated as an external javascript file in IE
var xscript = dojo.doc().createElement('script');
xscript.src = "javascript:'dojo.html.createExternalElement=function(doc, tag){ return doc.createElement(tag); }'";
dojo.doc().getElementsByTagName("head")[0].appendChild(xscript);
})();
}
}else{
//for other browsers, simply use document.createElement
//is enough
dojo.html.createExternalElement = function(/* HTMLDocument */doc, /* string */tag){
// summary
// Creates an element in the HTML document, here for ActiveX activation workaround.
return doc.createElement(tag); // HTMLElement
}
}
dojo.html._callDeprecated = function(inFunc, replFunc, args, argName, retValue){
dojo.deprecated("dojo.html." + inFunc,
"replaced by dojo.html." + replFunc + "(" + (argName ? "node, {"+ argName + ": " + argName + "}" : "" ) + ")" + (retValue ? "." + retValue : ""), "0.5");
var newArgs = [];
if(argName){ var argsIn = {}; argsIn[argName] = args[1]; newArgs.push(args[0]); newArgs.push(argsIn); }
else { newArgs = args }
var ret = dojo.html[replFunc].apply(dojo.html, args);
if(retValue){ return ret[retValue]; }
else { return ret; }
}
dojo.html.getViewportWidth = function(){
return dojo.html._callDeprecated("getViewportWidth", "getViewport", arguments, null, "width");
}
dojo.html.getViewportHeight = function(){
return dojo.html._callDeprecated("getViewportHeight", "getViewport", arguments, null, "height");
}
dojo.html.getViewportSize = function(){
return dojo.html._callDeprecated("getViewportSize", "getViewport", arguments);
}
dojo.html.getScrollTop = function(){
return dojo.html._callDeprecated("getScrollTop", "getScroll", arguments, null, "top");
}
dojo.html.getScrollLeft = function(){
return dojo.html._callDeprecated("getScrollLeft", "getScroll", arguments, null, "left");
}
dojo.html.getScrollOffset = function(){
return dojo.html._callDeprecated("getScrollOffset", "getScroll", arguments, null, "offset");
}

View File

@@ -0,0 +1,196 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.display");
dojo.require("dojo.html.style");
dojo.html._toggle = function(node, tester, setter){
node = dojo.byId(node);
setter(node, !tester(node));
return tester(node);
}
dojo.html.show = function(/* HTMLElement */node){
// summary
// Show the passed element by reverting display property set by dojo.html.hide
node = dojo.byId(node);
if(dojo.html.getStyleProperty(node, 'display')=='none'){
dojo.html.setStyle(node, 'display', (node.dojoDisplayCache||''));
node.dojoDisplayCache = undefined; // cannot use delete on a node in IE6
}
}
dojo.html.hide = function(/* HTMLElement */node){
// summary
// Hide the passed element by setting display:none
node = dojo.byId(node);
if(typeof node["dojoDisplayCache"] == "undefined"){ // it could == '', so we cannot say !node.dojoDisplayCount
var d = dojo.html.getStyleProperty(node, 'display')
if(d!='none'){
node.dojoDisplayCache = d;
}
}
dojo.html.setStyle(node, 'display', 'none');
}
dojo.html.setShowing = function(/* HTMLElement */node, /* boolean? */showing){
// summary
// Calls show() if showing is true, hide() otherwise
dojo.html[(showing ? 'show' : 'hide')](node);
}
dojo.html.isShowing = function(/* HTMLElement */node){
// summary
// Returns whether the element is displayed or not.
// FIXME: returns true if node is bad, isHidden would be easier to make correct
return (dojo.html.getStyleProperty(node, 'display') != 'none'); // boolean
}
dojo.html.toggleShowing = function(/* HTMLElement */node){
// summary
// Call setShowing() on node with the complement of isShowing(), then return the new value of isShowing()
return dojo.html._toggle(node, dojo.html.isShowing, dojo.html.setShowing); // boolean
}
// Simple mapping of tag names to display values
// FIXME: simplistic
dojo.html.displayMap = { tr: '', td: '', th: '', img: 'inline', span: 'inline', input: 'inline', button: 'inline' };
dojo.html.suggestDisplayByTagName = function(/* HTMLElement */node){
// summary
// Suggest a value for the display property that will show 'node' based on it's tag
node = dojo.byId(node);
if(node && node.tagName){
var tag = node.tagName.toLowerCase();
return (tag in dojo.html.displayMap ? dojo.html.displayMap[tag] : 'block'); // string
}
}
dojo.html.setDisplay = function(/* HTMLElement */node, /* string */display){
// summary
// Sets the value of style.display to value of 'display' parameter if it is a string.
// Otherwise, if 'display' is false, set style.display to 'none'.
// Finally, set 'display' to a suggested display value based on the node's tag
dojo.html.setStyle(node, 'display', ((display instanceof String || typeof display == "string") ? display : (display ? dojo.html.suggestDisplayByTagName(node) : 'none')));
}
dojo.html.isDisplayed = function(/* HTMLElement */node){
// summary
// Is true if the the computed display style for node is not 'none'
// FIXME: returns true if node is bad, isNotDisplayed would be easier to make correct
return (dojo.html.getComputedStyle(node, 'display') != 'none'); // boolean
}
dojo.html.toggleDisplay = function(/* HTMLElement */node){
// summary
// Call setDisplay() on node with the complement of isDisplayed(), then
// return the new value of isDisplayed()
return dojo.html._toggle(node, dojo.html.isDisplayed, dojo.html.setDisplay); // boolean
}
dojo.html.setVisibility = function(/* HTMLElement */node, /* string */visibility){
// summary
// Sets the value of style.visibility to value of 'visibility' parameter if it is a string.
// Otherwise, if 'visibility' is false, set style.visibility to 'hidden'. Finally, set style.visibility to 'visible'.
dojo.html.setStyle(node, 'visibility', ((visibility instanceof String || typeof visibility == "string") ? visibility : (visibility ? 'visible' : 'hidden')));
}
dojo.html.isVisible = function(/* HTMLElement */node){
// summary
// Returns true if the the computed visibility style for node is not 'hidden'
// FIXME: returns true if node is bad, isInvisible would be easier to make correct
return (dojo.html.getComputedStyle(node, 'visibility') != 'hidden'); // boolean
}
dojo.html.toggleVisibility = function(node){
// summary
// Call setVisibility() on node with the complement of isVisible(), then return the new value of isVisible()
return dojo.html._toggle(node, dojo.html.isVisible, dojo.html.setVisibility); // boolean
}
dojo.html.setOpacity = function(/* HTMLElement */node, /* float */opacity, /* boolean? */dontFixOpacity){
// summary
// Sets the opacity of node in a cross-browser way.
// float between 0.0 (transparent) and 1.0 (opaque)
node = dojo.byId(node);
var h = dojo.render.html;
if(!dontFixOpacity){
if( opacity >= 1.0){
if(h.ie){
dojo.html.clearOpacity(node);
return;
}else{
opacity = 0.999999;
}
}else if( opacity < 0.0){ opacity = 0; }
}
if(h.ie){
if(node.nodeName.toLowerCase() == "tr"){
// FIXME: is this too naive? will we get more than we want?
var tds = node.getElementsByTagName("td");
for(var x=0; x<tds.length; x++){
tds[x].style.filter = "Alpha(Opacity="+opacity*100+")";
}
}
node.style.filter = "Alpha(Opacity="+opacity*100+")";
}else if(h.moz){
node.style.opacity = opacity; // ffox 1.0 directly supports "opacity"
node.style.MozOpacity = opacity;
}else if(h.safari){
node.style.opacity = opacity; // 1.3 directly supports "opacity"
node.style.KhtmlOpacity = opacity;
}else{
node.style.opacity = opacity;
}
}
dojo.html.clearOpacity = function(/* HTMLElement */node){
// summary
// Clears any opacity setting on the passed element.
node = dojo.byId(node);
var ns = node.style;
var h = dojo.render.html;
if(h.ie){
try {
if( node.filters && node.filters.alpha ){
ns.filter = ""; // FIXME: may get rid of other filter effects
}
} catch(e) {
/*
* IE7 gives error if node.filters not set;
* don't know why or how to workaround (other than this)
*/
}
}else if(h.moz){
ns.opacity = 1;
ns.MozOpacity = 1;
}else if(h.safari){
ns.opacity = 1;
ns.KhtmlOpacity = 1;
}else{
ns.opacity = 1;
}
}
dojo.html.getOpacity = function(/* HTMLElement */node){
// summary
// Returns the opacity of the passed element
node = dojo.byId(node);
var h = dojo.render.html;
if(h.ie){
var opac = (node.filters && node.filters.alpha &&
typeof node.filters.alpha.opacity == "number"
? node.filters.alpha.opacity : 100) / 100;
}else{
var opac = node.style.opacity || node.style.MozOpacity ||
node.style.KhtmlOpacity || 1;
}
return opac >= 0.999999 ? 1.0 : Number(opac); // float
}

View File

@@ -0,0 +1,128 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.iframe");
dojo.require("dojo.html.util");
// thanks burstlib!
dojo.html.iframeContentWindow = function(/* HTMLIFrameElement */iframe_el) {
// summary
// returns the window reference of the passed iframe
var win = dojo.html.getDocumentWindow(dojo.html.iframeContentDocument(iframe_el)) ||
// Moz. TODO: is this available when defaultView isn't?
dojo.html.iframeContentDocument(iframe_el).__parent__ ||
(iframe_el.name && document.frames[iframe_el.name]) || null;
return win; // Window
}
dojo.html.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)&&(document.frames[iframe_el.name])&&(document.frames[iframe_el.name].document))
|| null;
return doc; // HTMLDocument
}
dojo.html.BackgroundIframe = function(/* HTMLElement */node) {
// summary
// For IE z-index schenanigans
// Two possible uses:
// 1. new dojo.html.BackgroundIframe(node)
// Makes a background iframe as a child of node, that fills area (and position) of node
// 2. new dojo.html.BackgroundIframe()
// Attaches frame to dojo.body(). User must call size() to set size.
if(dojo.render.html.ie55 || dojo.render.html.ie60) {
var html="<iframe src='javascript:false'"
+ " style='position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;"
+ "z-index: -1; filter:Alpha(Opacity=\"0\");' "
+ ">";
this.iframe = dojo.doc().createElement(html);
this.iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
if(node){
node.appendChild(this.iframe);
this.domNode=node;
}else{
dojo.body().appendChild(this.iframe);
this.iframe.style.display="none";
}
}
}
dojo.lang.extend(dojo.html.BackgroundIframe, {
iframe: null,
onResized: function(){
// summary
// Resize event handler.
// TODO: this function shouldn't be necessary but setting width=height=100% doesn't work!
if(this.iframe && this.domNode && this.domNode.parentNode){ // No parentElement if onResized() timeout event occurs on a removed domnode
var outer = dojo.html.getMarginBox(this.domNode);
if (outer.width == 0 || outer.height == 0 ){
dojo.lang.setTimeout(this, this.onResized, 100);
return;
}
this.iframe.style.width = outer.width + "px";
this.iframe.style.height = outer.height + "px";
}
},
size: function(/* HTMLElement */node) {
// summary:
// Call this function if the iframe is connected to dojo.body()
// rather than the node being shadowed
// (TODO: erase)
if(!this.iframe){ return; }
var coords = dojo.html.toCoordinateObject(node, true, dojo.html.boxSizing.BORDER_BOX);
with(this.iframe.style){
width = coords.width + "px";
height = coords.height + "px";
left = coords.left + "px";
top = coords.top + "px";
}
},
setZIndex: function(/* HTMLElement */node){
// summary
// Sets the z-index of the background iframe.
if(!this.iframe){ return; }
if(dojo.dom.isNode(node)){
this.iframe.style.zIndex = dojo.html.getStyle(node, "z-index") - 1;
}else if(!isNaN(node)){
this.iframe.style.zIndex = node;
}
},
show: function(){
// summary:
// show the iframe
if(this.iframe){
this.iframe.style.display = "block";
}
},
hide: function(){
// summary:
// hide the iframe
if(this.iframe){
this.iframe.style.display = "none";
}
},
remove: function(){
// summary:
// remove the iframe
if(this.iframe){
dojo.html.removeNode(this.iframe, true);
delete this.iframe;
this.iframe=null;
}
}
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

View File

@@ -0,0 +1,487 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.layout");
dojo.require("dojo.html.common");
dojo.require("dojo.html.style");
dojo.require("dojo.html.display");
dojo.html.sumAncestorProperties = function(/* HTMLElement */node, /* string */prop){
// summary
// Returns the sum of the passed property on all ancestors of node.
node = dojo.byId(node);
if(!node){ return 0; } // FIXME: throw an error?
var retVal = 0;
while(node){
if(dojo.html.getComputedStyle(node, 'position') == 'fixed'){
return 0;
}
var val = node[prop];
if(val){
retVal += val - 0;
if(node==dojo.body()){ break; }// opera and khtml #body & #html has the same values, we only need one value
}
node = node.parentNode;
}
return retVal; // integer
}
dojo.html.setStyleAttributes = function(/* HTMLElement */node, /* string */attributes) {
// summary
// allows a dev to pass a string similar to what you'd pass in style="", and apply it to a node.
node = dojo.byId(node);
var splittedAttribs=attributes.replace(/(;)?\s*$/, "").split(";");
for(var i=0; i<splittedAttribs.length; i++){
var nameValue=splittedAttribs[i].split(":");
var name=nameValue[0].replace(/\s*$/, "").replace(/^\s*/, "").toLowerCase();
var value=nameValue[1].replace(/\s*$/, "").replace(/^\s*/, "");
switch(name){
case "opacity":
dojo.html.setOpacity(node, value);
break;
case "content-height":
dojo.html.setContentBox(node, {height: value});
break;
case "content-width":
dojo.html.setContentBox(node, {width: value});
break;
case "outer-height":
dojo.html.setMarginBox(node, {height: value});
break;
case "outer-width":
dojo.html.setMarginBox(node, {width: value});
break;
default:
node.style[dojo.html.toCamelCase(name)]=value;
}
}
}
dojo.html.boxSizing = {
MARGIN_BOX: "margin-box",
BORDER_BOX: "border-box",
PADDING_BOX: "padding-box",
CONTENT_BOX: "content-box"
};
dojo.html.getAbsolutePosition = dojo.html.abs = function(/* HTMLElement */node, /* boolean? */includeScroll, /* string? */boxType){
// summary
// Gets the absolute position of the passed element based on the document itself.
node = dojo.byId(node, node.ownerDocument);
var ret = {
x: 0,
y: 0
};
var bs = dojo.html.boxSizing;
if(!boxType) { boxType = bs.CONTENT_BOX; }
var nativeBoxType = 2; //BORDER box
var targetBoxType;
switch(boxType){
case bs.MARGIN_BOX:
targetBoxType = 3;
break;
case bs.BORDER_BOX:
targetBoxType = 2;
break;
case bs.PADDING_BOX:
default:
targetBoxType = 1;
break;
case bs.CONTENT_BOX:
targetBoxType = 0;
break;
}
var h = dojo.render.html;
var db = document["body"]||document["documentElement"];
if(h.ie){
with(node.getBoundingClientRect()){
ret.x = left-2;
ret.y = top-2;
}
}else if(document.getBoxObjectFor){
// mozilla
nativeBoxType = 1; //getBoxObjectFor return padding box coordinate
try{
var bo = document.getBoxObjectFor(node);
ret.x = bo.x - dojo.html.sumAncestorProperties(node, "scrollLeft");
ret.y = bo.y - dojo.html.sumAncestorProperties(node, "scrollTop");
}catch(e){
// squelch
}
}else{
if(node["offsetParent"]){
var endNode;
// in Safari, if the node is an absolutely positioned child of
// the body and the body has a margin the offset of the child
// and the body contain the body's margins, so we need to end
// at the body
if( (h.safari)&&
(node.style.getPropertyValue("position") == "absolute")&&
(node.parentNode == db)){
endNode = db;
}else{
endNode = db.parentNode;
}
//TODO: set correct nativeBoxType for safari/konqueror
if(node.parentNode != db){
var nd = node;
if(dojo.render.html.opera){ nd = db; }
ret.x -= dojo.html.sumAncestorProperties(nd, "scrollLeft");
ret.y -= dojo.html.sumAncestorProperties(nd, "scrollTop");
}
var curnode = node;
do{
var n = curnode["offsetLeft"];
//FIXME: ugly hack to workaround the submenu in
//popupmenu2 does not shown up correctly in opera.
//Someone have a better workaround?
if(!h.opera || n>0){
ret.x += isNaN(n) ? 0 : n;
}
var m = curnode["offsetTop"];
ret.y += isNaN(m) ? 0 : m;
curnode = curnode.offsetParent;
}while((curnode != endNode)&&(curnode != null));
}else if(node["x"]&&node["y"]){
ret.x += isNaN(node.x) ? 0 : node.x;
ret.y += isNaN(node.y) ? 0 : node.y;
}
}
// account for document scrolling!
if(includeScroll){
var scroll = dojo.html.getScroll();
ret.y += scroll.top;
ret.x += scroll.left;
}
var extentFuncArray=[dojo.html.getPaddingExtent, dojo.html.getBorderExtent, dojo.html.getMarginExtent];
if(nativeBoxType > targetBoxType){
for(var i=targetBoxType;i<nativeBoxType;++i){
ret.y += extentFuncArray[i](node, 'top');
ret.x += extentFuncArray[i](node, 'left');
}
}else if(nativeBoxType < targetBoxType){
for(var i=targetBoxType;i>nativeBoxType;--i){
ret.y -= extentFuncArray[i-1](node, 'top');
ret.x -= extentFuncArray[i-1](node, 'left');
}
}
ret.top = ret.y;
ret.left = ret.x;
return ret; // object
}
dojo.html.isPositionAbsolute = function(/* HTMLElement */node){
// summary
// Returns true if the element is absolutely positioned.
return (dojo.html.getComputedStyle(node, 'position') == 'absolute'); // boolean
}
dojo.html._sumPixelValues = function(/* HTMLElement */node, selectors, autoIsZero){
var total = 0;
for(var x=0; x<selectors.length; x++){
total += dojo.html.getPixelValue(node, selectors[x], autoIsZero);
}
return total;
}
dojo.html.getMargin = function(/* HTMLElement */node){
// summary
// Returns the width and height of the passed node's margin
return {
width: dojo.html._sumPixelValues(node, ["margin-left", "margin-right"], (dojo.html.getComputedStyle(node, 'position') == 'absolute')),
height: dojo.html._sumPixelValues(node, ["margin-top", "margin-bottom"], (dojo.html.getComputedStyle(node, 'position') == 'absolute'))
}; // object
}
dojo.html.getBorder = function(/* HTMLElement */node){
// summary
// Returns the width and height of the passed node's border
return {
width: dojo.html.getBorderExtent(node, 'left') + dojo.html.getBorderExtent(node, 'right'),
height: dojo.html.getBorderExtent(node, 'top') + dojo.html.getBorderExtent(node, 'bottom')
}; // object
}
dojo.html.getBorderExtent = function(/* HTMLElement */node, /* string */side){
// summary
// returns the width of the requested border
return (dojo.html.getStyle(node, 'border-' + side + '-style') == 'none' ? 0 : dojo.html.getPixelValue(node, 'border-' + side + '-width')); // integer
}
dojo.html.getMarginExtent = function(/* HTMLElement */node, /* string */side){
// summary
// returns the width of the requested margin
return dojo.html._sumPixelValues(node, ["margin-" + side], dojo.html.isPositionAbsolute(node)); // integer
}
dojo.html.getPaddingExtent = function(/* HTMLElement */node, /* string */side){
// summary
// Returns the width of the requested padding
return dojo.html._sumPixelValues(node, ["padding-" + side], true); // integer
}
dojo.html.getPadding = function(/* HTMLElement */node){
// summary
// Returns the width and height of the passed node's padding
return {
width: dojo.html._sumPixelValues(node, ["padding-left", "padding-right"], true),
height: dojo.html._sumPixelValues(node, ["padding-top", "padding-bottom"], true)
}; // object
}
dojo.html.getPadBorder = function(/* HTMLElement */node){
// summary
// Returns the width and height of the passed node's padding and border
var pad = dojo.html.getPadding(node);
var border = dojo.html.getBorder(node);
return { width: pad.width + border.width, height: pad.height + border.height }; // object
}
dojo.html.getBoxSizing = function(/* HTMLElement */node){
// summary
// Returns which box model the passed element is working with
var h = dojo.render.html;
var bs = dojo.html.boxSizing;
if(((h.ie)||(h.opera)) && node.nodeName!="IMG"){
var cm = document["compatMode"];
if((cm == "BackCompat")||(cm == "QuirksMode")){
return bs.BORDER_BOX; // string
}else{
return bs.CONTENT_BOX; // string
}
}else{
if(arguments.length == 0){ node = document.documentElement; }
var sizing = dojo.html.getStyle(node, "-moz-box-sizing");
if(!sizing){ sizing = dojo.html.getStyle(node, "box-sizing"); }
return (sizing ? sizing : bs.CONTENT_BOX); // string
}
}
dojo.html.isBorderBox = function(/* HTMLElement */node){
// summary
// returns whether the passed element is using border box sizing or not.
return (dojo.html.getBoxSizing(node) == dojo.html.boxSizing.BORDER_BOX); // boolean
}
dojo.html.getBorderBox = function(/* HTMLElement */node){
// summary
// Returns the dimensions of the passed element based on border-box sizing.
node = dojo.byId(node);
return { width: node.offsetWidth, height: node.offsetHeight }; // object
}
dojo.html.getPaddingBox = function(/* HTMLElement */node){
// summary
// Returns the dimensions of the padding box (see http://www.w3.org/TR/CSS21/box.html)
var box = dojo.html.getBorderBox(node);
var border = dojo.html.getBorder(node);
return {
width: box.width - border.width,
height:box.height - border.height
}; // object
}
dojo.html.getContentBox = function(/* HTMLElement */node){
// summary
// Returns the dimensions of the content box (see http://www.w3.org/TR/CSS21/box.html)
node = dojo.byId(node);
var padborder = dojo.html.getPadBorder(node);
return {
width: node.offsetWidth - padborder.width,
height: node.offsetHeight - padborder.height
}; // object
}
dojo.html.setContentBox = function(/* HTMLElement */node, /* object */args){
// summary
// Sets the dimensions of the passed node according to content sizing.
node = dojo.byId(node);
var width = 0; var height = 0;
var isbb = dojo.html.isBorderBox(node);
var padborder = (isbb ? dojo.html.getPadBorder(node) : { width: 0, height: 0});
var ret = {};
if(typeof args.width != "undefined"){
width = args.width + padborder.width;
ret.width = dojo.html.setPositivePixelValue(node, "width", width);
}
if(typeof args.height != "undefined"){
height = args.height + padborder.height;
ret.height = dojo.html.setPositivePixelValue(node, "height", height);
}
return ret; // object
}
dojo.html.getMarginBox = function(/* HTMLElement */node){
// summary
// returns the dimensions of the passed node including any margins.
var borderbox = dojo.html.getBorderBox(node);
var margin = dojo.html.getMargin(node);
return { width: borderbox.width + margin.width, height: borderbox.height + margin.height }; // object
}
dojo.html.setMarginBox = function(/* HTMLElement */node, /* object */args){
// summary
// Sets the dimensions of the passed node using margin box calcs.
node = dojo.byId(node);
var width = 0; var height = 0;
var isbb = dojo.html.isBorderBox(node);
var padborder = (!isbb ? dojo.html.getPadBorder(node) : { width: 0, height: 0 });
var margin = dojo.html.getMargin(node);
var ret = {};
if(typeof args.width != "undefined"){
width = args.width - padborder.width;
width -= margin.width;
ret.width = dojo.html.setPositivePixelValue(node, "width", width);
}
if(typeof args.height != "undefined"){
height = args.height - padborder.height;
height -= margin.height;
ret.height = dojo.html.setPositivePixelValue(node, "height", height);
}
return ret; // object
}
dojo.html.getElementBox = function(/* HTMLElement */node, /* string */type){
// summary
// return dimesions of a node based on the passed box model type.
var bs = dojo.html.boxSizing;
switch(type){
case bs.MARGIN_BOX:
return dojo.html.getMarginBox(node); // object
case bs.BORDER_BOX:
return dojo.html.getBorderBox(node); // object
case bs.PADDING_BOX:
return dojo.html.getPaddingBox(node); // object
case bs.CONTENT_BOX:
default:
return dojo.html.getContentBox(node); // object
}
}
// in: coordinate array [x,y,w,h] or dom node
// return: coordinate object
dojo.html.toCoordinateObject = dojo.html.toCoordinateArray = function(/* array */coords, /* boolean? */includeScroll, /* string? */boxtype) {
// summary
// Converts an array of coordinates into an object of named arguments.
if(coords instanceof Array || typeof coords == "array"){
dojo.deprecated("dojo.html.toCoordinateArray", "use dojo.html.toCoordinateObject({left: , top: , width: , height: }) instead", "0.5");
// coords is already an array (of format [x,y,w,h]), just return it
while ( coords.length < 4 ) { coords.push(0); }
while ( coords.length > 4 ) { coords.pop(); }
var ret = {
left: coords[0],
top: coords[1],
width: coords[2],
height: coords[3]
};
}else if(!coords.nodeType && !(coords instanceof String || typeof coords == "string") &&
('width' in coords || 'height' in coords || 'left' in coords ||
'x' in coords || 'top' in coords || 'y' in coords)){
// coords is a coordinate object or at least part of one
var ret = {
left: coords.left||coords.x||0,
top: coords.top||coords.y||0,
width: coords.width||0,
height: coords.height||0
};
}else{
// coords is an dom object (or dom object id); return it's coordinates
var node = dojo.byId(coords);
var pos = dojo.html.abs(node, includeScroll, boxtype);
var marginbox = dojo.html.getMarginBox(node);
var ret = {
left: pos.left,
top: pos.top,
width: marginbox.width,
height: marginbox.height
};
}
ret.x = ret.left;
ret.y = ret.top;
return ret; // object
}
dojo.html.setMarginBoxWidth = dojo.html.setOuterWidth = function(node, width){
return dojo.html._callDeprecated("setMarginBoxWidth", "setMarginBox", arguments, "width");
}
dojo.html.setMarginBoxHeight = dojo.html.setOuterHeight = function(){
return dojo.html._callDeprecated("setMarginBoxHeight", "setMarginBox", arguments, "height");
}
dojo.html.getMarginBoxWidth = dojo.html.getOuterWidth = function(){
return dojo.html._callDeprecated("getMarginBoxWidth", "getMarginBox", arguments, null, "width");
}
dojo.html.getMarginBoxHeight = dojo.html.getOuterHeight = function(){
return dojo.html._callDeprecated("getMarginBoxHeight", "getMarginBox", arguments, null, "height");
}
dojo.html.getTotalOffset = function(node, type, includeScroll){
return dojo.html._callDeprecated("getTotalOffset", "getAbsolutePosition", arguments, null, type);
}
dojo.html.getAbsoluteX = function(node, includeScroll){
return dojo.html._callDeprecated("getAbsoluteX", "getAbsolutePosition", arguments, null, "x");
}
dojo.html.getAbsoluteY = function(node, includeScroll){
return dojo.html._callDeprecated("getAbsoluteY", "getAbsolutePosition", arguments, null, "y");
}
dojo.html.totalOffsetLeft = function(node, includeScroll){
return dojo.html._callDeprecated("totalOffsetLeft", "getAbsolutePosition", arguments, null, "left");
}
dojo.html.totalOffsetTop = function(node, includeScroll){
return dojo.html._callDeprecated("totalOffsetTop", "getAbsolutePosition", arguments, null, "top");
}
dojo.html.getMarginWidth = function(node){
return dojo.html._callDeprecated("getMarginWidth", "getMargin", arguments, null, "width");
}
dojo.html.getMarginHeight = function(node){
return dojo.html._callDeprecated("getMarginHeight", "getMargin", arguments, null, "height");
}
dojo.html.getBorderWidth = function(node){
return dojo.html._callDeprecated("getBorderWidth", "getBorder", arguments, null, "width");
}
dojo.html.getBorderHeight = function(node){
return dojo.html._callDeprecated("getBorderHeight", "getBorder", arguments, null, "height");
}
dojo.html.getPaddingWidth = function(node){
return dojo.html._callDeprecated("getPaddingWidth", "getPadding", arguments, null, "width");
}
dojo.html.getPaddingHeight = function(node){
return dojo.html._callDeprecated("getPaddingHeight", "getPadding", arguments, null, "height");
}
dojo.html.getPadBorderWidth = function(node){
return dojo.html._callDeprecated("getPadBorderWidth", "getPadBorder", arguments, null, "width");
}
dojo.html.getPadBorderHeight = function(node){
return dojo.html._callDeprecated("getPadBorderHeight", "getPadBorder", arguments, null, "height");
}
dojo.html.getBorderBoxWidth = dojo.html.getInnerWidth = function(){
return dojo.html._callDeprecated("getBorderBoxWidth", "getBorderBox", arguments, null, "width");
}
dojo.html.getBorderBoxHeight = dojo.html.getInnerHeight = function(){
return dojo.html._callDeprecated("getBorderBoxHeight", "getBorderBox", arguments, null, "height");
}
dojo.html.getContentBoxWidth = dojo.html.getContentWidth = function(){
return dojo.html._callDeprecated("getContentBoxWidth", "getContentBox", arguments, null, "width");
}
dojo.html.getContentBoxHeight = dojo.html.getContentHeight = function(){
return dojo.html._callDeprecated("getContentBoxHeight", "getContentBox", arguments, null, "height");
}
dojo.html.setContentBoxWidth = dojo.html.setContentWidth = function(node, width){
return dojo.html._callDeprecated("setContentBoxWidth", "setContentBox", arguments, "width");
}
dojo.html.setContentBoxHeight = dojo.html.setContentHeight = function(node, height){
return dojo.html._callDeprecated("setContentBoxHeight", "setContentBox", arguments, "height");
}

View File

@@ -0,0 +1,266 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.metrics");
dojo.require("dojo.html.layout");
/* dojo.html.metrics
* Methods to help determine font metrics, including things like
* how much of a string will fit inside a certain width, what size
* something might be if you were to place it in a certain node, etc.
*
* Based partially on a submitted patch by Morris Johns, and work
* done with 13th Parallel and f( m ) (the 13th columns and the
* unreleased f( m ) layout manager.
*/
// derived from Morris John's scrollbar measurer.
dojo.html.getScrollbar=function(){
// summary
// returns the width of a scrollbar.
// set up the test nodes.
var scroll = document.createElement("div");
scroll.style.width="100px";
scroll.style.height="100px";
scroll.style.overflow="scroll";
scroll.style.position="absolute";
scroll.style.top="-300px";
scroll.style.left="0px"
var test = document.createElement("div");
test.style.width="400px";
test.style.height="400px";
scroll.appendChild(test);
dojo.body().appendChild(scroll);
var width=scroll.offsetWidth - scroll.clientWidth;
dojo.body().removeChild(scroll);
scroll.removeChild(test);
scroll=test=null;
// we return an object because we may add additional info in the future.
return { width: width }; // object
};
// derived from Morris John's emResized measurer
dojo.html.getFontMeasurements = function(){
// summary
// Returns an object that has pixel equivilents of standard font size values.
var heights = {
'1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
};
if(dojo.render.html.ie){
// we do a font-size fix if and only if one isn't applied already.
// NOTE: If someone set the fontSize on the HTML Element, this will kill it.
document.documentElement.style.fontSize="100%";
}
// set up the measuring node.
var div=document.createElement("div");
div.style.position="absolute";
div.style.left="-100px";
div.style.top="0";
div.style.width="30px";
div.style.height="1000em";
div.style.border="0";
div.style.margin="0";
div.style.padding="0";
div.style.outline="0";
div.style.lineHeight="1";
div.style.overflow="hidden";
dojo.body().appendChild(div);
// do the measurements.
for(var p in heights){
div.style.fontSize = p;
heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
}
dojo.body().removeChild(div);
div = null;
return heights; // object
};
dojo.html._fontMeasurements = null;
dojo.html.getCachedFontMeasurements = function(recalculate){
if(recalculate || !dojo.html._fontMeasurements){
dojo.html._fontMeasurements = dojo.html.getFontMeasurements();
}
return dojo.html._fontMeasurements;
};
dojo.html.measureFragment = function(/* HTMLElement */node, /* string */html, /* string? */boxType){
// summary
// get the dimensions of passed node if it were populated with passed html.
var clone = node.cloneNode(true);
clone.innerHTML = html;
node.parentNode.appendChild(clone);
var ret = dojo.html.getElementBox(clone, boxType);
node.parentNode.removeChild(clone);
clone=null;
return ret; // object
};
// the following are derived from the 13th Parallel Column script, as
// reinterpreted by trt. http://www.13thparallel.org/archive/column-script
// Original by Dan Pupius and Michael van Ouwerkerk.
dojo.html.getFittedFragment = function(/* HTMLElement */node, /* string */html){
// summary
// Given html, return the fragment that will fit on one line of passed node.
function cl(node){
var element = document.createElement(node.tagName);
element.id = node.id + "-clone";
element.className = node.className;
for (var j = 0; j < node.attributes.length; j++) {
if (node.attributes[j].specified) {
if (node.attributes[j].nodeName.toLowerCase() != "style"
&& node.attributes[j].nodeName.toLowerCase() != "edited"
&& node.attributes[j].nodeName.toLowerCase() != "contenteditable"
&& node.attributes[j].nodeName.toLowerCase() != "id"
&& node.attributes[j].nodeName.toLowerCase() != "class"
){
element.setAttribute(node.attributes[j].nodeName.toLowerCase(), node.attributes[j].nodeValue);
}
}
}
return element;
}
var height = dojo.html.getFontMeasurements()["16px"];
var n=cl(node);
n.style.width=dojo.html.getBorderBox(node).width+"px";
n.style.height=(height+4)+"px";
node.parentNode.appendChild(n);
var rem = dojo.html.fitToElement(n, html);
var ret = n.innerHTML;
n.parentNode.removeChild(n);
return ret;
};
dojo.html.fitToElement = function(/* HTMLElement */node, /* string */html){
// summary
// will fit as much html as possible into node, and return the unused
// portion, with tag corrections.
function cl(node){
var element = document.createElement(node.tagName);
element.id = node.id + "-clone";
element.className = node.className;
for (var j = 0; j < node.attributes.length; j++) {
if (node.attributes[j].specified) {
if (node.attributes[j].nodeName.toLowerCase() != "style"
&& node.attributes[j].nodeName.toLowerCase() != "edited"
&& node.attributes[j].nodeName.toLowerCase() != "contenteditable"
&& node.attributes[j].nodeName.toLowerCase() != "id"
&& node.attributes[j].nodeName.toLowerCase() != "class"
){
element.setAttribute(node.attributes[j].nodeName.toLowerCase(), node.attributes[j].nodeValue);
}
}
}
return element;
}
var clone = cl(node);
node.parentNode.appendChild(clone);
var t=dojo.html.getBorderBox(node);
clone.style.width = t.width+"px";
var singletons = ["br","img", "hr", "input", "!--"];
var chop = ["<BR>","<br>","<br/>","<br />","<p></p>","<P></P>"];
var openTags = [];
var str = html;
var i = 0;
var limit = str.length;
var add = 0;
var doLoop = true;
clone.innerHTML = str;
while (doLoop) {
add = Math.round((limit - i) / 2);
if (add <= 1) doLoop = false;
i += add;
clone.innerHTML = str.substr(0, i);
if (clone.offsetHeight > t.height) {
limit = i;
i -= add;
}
}
if (str.substr(0, i) != str) {
var lastSpace = str.substr(0, i).lastIndexOf(" ");
var lastNewLine = str.substr(0, i).lastIndexOf("\n");
var lastGreater = str.substr(0, i).lastIndexOf(">");
var lastLess = str.substr(0, i).lastIndexOf("<");
if (lastLess <= lastGreater && lastNewLine == i - 1) i = i;
else if (lastSpace != -1 && lastSpace > lastGreater && lastGreater > lastLess) i = lastSpace + 1;
else if (lastLess > lastGreater) i = lastLess;
else if (lastGreater != -1) i = lastGreater + 1;
}
str = str.substr(0, i);
var ret = html.substr(str.length); // get the rest of the passed text.
var doPush = true;
var tags = str.split("<");
tags.shift();
for (var j = 0; j < tags.length; j++) {
tags[j] = tags[j].split(">")[0];
if (tags[j].charAt(tags[j].length - 1) == "/"){ continue; }
if (tags[j].charAt(0) != "/") {
for (var k = 0; k < singletons.length; k++) {
if (tags[j].split(" ")[0].toLowerCase() == singletons[k]){
doPush = false;
}
}
if (doPush){
openTags.push(tags[j]);
}
doPush = true;
} else {
openTags.pop();
}
}
// close any open tags and prepend them to ret as well.
for(var j=0; j<chop.length; j++){
if(ret.charAt(0) == "\n"){ ret = ret.substr(1); }
while(ret.indexOf(chop[j]) == 0){
ret = ret.substr(chop[j].length);
}
}
for(var j=openTags.length-1; j>=0; j--){
if(str.lastIndexOf(openTags[j]) == (str.length-openTags[j].length-1)){
str = str.substring(0, str.lastIndexOf(openTags[j]));
} else {
str += "</"+openTags[j]+">";
}
if(ret.length > 0){
ret = "<"+openTags[j]+">"+ret;
}
}
for(var j=0; j<chop.length; j++){
if(ret.charAt(0) == "\n"){ ret = ret.substr(1); }
while(ret.indexOf(chop[j]) == 0){
ret = ret.substr(chop[j].length);
}
}
// push it into the node and pull the temp one.
node.innerHTML = str;
clone.parentNode.removeChild(clone);
clone = null;
// return the remainder.
return ret; // string
};

View File

@@ -0,0 +1,376 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.html.common");
dojo.provide("dojo.html.selection");
dojo.require("dojo.dom");
dojo.require("dojo.lang.common");
/**
* type of selection
**/
dojo.html.selectionType = {
NONE : 0, //selection is empty
TEXT : 1, //selection contains text (may also contains CONTROL objects)
CONTROL : 2 //only one element is selected (such as img, table etc)
};
dojo.html.clearSelection = function(){
// summary: deselect the current selection to make it empty
var _window = dojo.global();
var _document = dojo.doc();
try{
if(_window["getSelection"]){
if(dojo.render.html.safari){
// pulled from WebCore/ecma/kjs_window.cpp, line 2536
_window.getSelection().collapse();
}else{
_window.getSelection().removeAllRanges();
}
}else if(_document.selection){
if(_document.selection.empty){
_document.selection.empty();
}else if(_document.selection.clear){
_document.selection.clear();
}
}
return true;
}catch(e){
dojo.debug(e);
return false;
}
}
dojo.html.disableSelection = function(/*DomNode*/element){
// summary: disable selection on a node
element = dojo.byId(element)||dojo.body();
var h = dojo.render.html;
if(h.mozilla){
element.style.MozUserSelect = "none";
}else if(h.safari){
element.style.KhtmlUserSelect = "none";
}else if(h.ie){
element.unselectable = "on";
}else{
return false;
}
return true;
}
dojo.html.enableSelection = function(/*DomNode*/element){
// summary: enable selection on a node
element = dojo.byId(element)||dojo.body();
var h = dojo.render.html;
if(h.mozilla){
element.style.MozUserSelect = "";
}else if(h.safari){
element.style.KhtmlUserSelect = "";
}else if(h.ie){
element.unselectable = "off";
}else{
return false;
}
return true;
}
dojo.html.selectElement = function(/*DomNode*/element){
dojo.deprecated("dojo.html.selectElement", "replaced by dojo.html.selection.selectElementChildren", 0.5);
}
dojo.html.selectInputText = function(/*DomNode*/element){
// summary: select all the text in an input element
var _window = dojo.global();
var _document = dojo.doc();
element = dojo.byId(element);
if(_document["selection"] && dojo.body()["createTextRange"]){ // IE
var range = element.createTextRange();
range.moveStart("character", 0);
range.moveEnd("character", element.value.length);
range.select();
}else if(_window["getSelection"]){
var selection = _window.getSelection();
// FIXME: does this work on Safari?
element.setSelectionRange(0, element.value.length);
}
element.focus();
}
dojo.html.isSelectionCollapsed = function(){
dojo.deprecated("dojo.html.isSelectionCollapsed", "replaced by dojo.html.selection.isCollapsed", 0.5);
return dojo.html.selection.isCollapsed();
}
dojo.lang.mixin(dojo.html.selection, {
getType: function() {
// summary: Get the selection type (like document.select.type in IE).
if(dojo.doc()["selection"]){ //IE
return dojo.html.selectionType[dojo.doc().selection.type.toUpperCase()];
}else{
var stype = dojo.html.selectionType.TEXT;
// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
var oSel;
try {oSel = dojo.global().getSelection();}
catch (e) {}
if(oSel && oSel.rangeCount==1){
var oRange = oSel.getRangeAt(0);
if (oRange.startContainer == oRange.endContainer && (oRange.endOffset - oRange.startOffset) == 1
&& oRange.startContainer.nodeType != dojo.dom.TEXT_NODE) {
stype = dojo.html.selectionType.CONTROL;
}
}
return stype;
}
},
isCollapsed: function() {
// summary: return whether the current selection is empty
var _window = dojo.global();
var _document = dojo.doc();
if(_document["selection"]){ // IE
return _document.selection.createRange().text == "";
}else if(_window["getSelection"]){
var selection = _window.getSelection();
if(dojo.lang.isString(selection)){ // Safari
return selection == "";
}else{ // Mozilla/W3
return selection.isCollapsed || selection.toString() == "";
}
}
},
getSelectedElement: function() {
// summary:
// Retrieves the selected element (if any), just in the case that a single
// element (object like and image or a table) is selected.
if ( dojo.html.selection.getType() == dojo.html.selectionType.CONTROL ){
if(dojo.doc()["selection"]){ //IE
var range = dojo.doc().selection.createRange();
if ( range && range.item ){
return dojo.doc().selection.createRange().item(0);
}
}else{
var selection = dojo.global().getSelection();
return selection.anchorNode.childNodes[ selection.anchorOffset ];
}
}
},
getParentElement: function() {
// summary:
// Get the parent element of the current selection
if(dojo.html.selection.getType() == dojo.html.selectionType.CONTROL){
var p = dojo.html.selection.getSelectedElement();
if(p){ return p.parentNode; }
}else{
if(dojo.doc()["selection"]){ //IE
return dojo.doc().selection.createRange().parentElement();
}else{
var selection = dojo.global().getSelection();
if(selection){
var node = selection.anchorNode;
while ( node && node.nodeType != dojo.dom.ELEMENT_NODE ){
node = node.parentNode;
}
return node;
}
}
}
},
getSelectedText: function(){
// summary:
// Return the text (no html tags) included in the current selection or null if no text is selected
if(dojo.doc()["selection"]){ //IE
if(dojo.html.selection.getType() == dojo.html.selectionType.CONTROL){
return null;
}
return dojo.doc().selection.createRange().text;
}else{
var selection = dojo.global().getSelection();
if(selection){
return selection.toString();
}
}
},
getSelectedHtml: function(){
// summary:
// Return the html of the current selection or null if unavailable
if(dojo.doc()["selection"]){ //IE
if(dojo.html.selection.getType() == dojo.html.selectionType.CONTROL){
return null;
}
return dojo.doc().selection.createRange().htmlText;
}else{
var selection = dojo.global().getSelection();
if(selection && selection.rangeCount){
var frag = selection.getRangeAt(0).cloneContents();
var div = document.createElement("div");
div.appendChild(frag);
return div.innerHTML;
}
return null;
}
},
hasAncestorElement: function(/*String*/tagName /* ... */){
// summary:
// Check whether current selection has a parent element which is of type tagName (or one of the other specified tagName)
return (dojo.html.selection.getAncestorElement.apply(this, arguments) != null);
},
getAncestorElement: function(/*String*/tagName /* ... */){
// summary:
// Return the parent element of the current selection which is of type tagName (or one of the other specified tagName)
var node = dojo.html.selection.getSelectedElement() || dojo.html.selection.getParentElement();
while(node /*&& node.tagName.toLowerCase() != 'body'*/){
if(dojo.html.selection.isTag(node, arguments).length>0){
return node;
}
node = node.parentNode;
}
return null;
},
//modified from dojo.html.isTag to take an array as second parameter
isTag: function(/*DomNode*/node, /*Array*/tags) {
if(node && node.tagName) {
for (var i=0; i<tags.length; i++){
if (node.tagName.toLowerCase()==String(tags[i]).toLowerCase()){
return String(tags[i]).toLowerCase();
}
}
}
return "";
},
selectElement: function(/*DomNode*/element) {
// summary: clear previous selection and select element (including all its children)
var _window = dojo.global();
var _document = dojo.doc();
element = dojo.byId(element);
if(_document.selection && dojo.body().createTextRange){ // IE
try{
var range = dojo.body().createControlRange();
range.addElement(element);
range.select();
}catch(e){
dojo.html.selection.selectElementChildren(element);
}
}else if(_window["getSelection"]){
var selection = _window.getSelection();
// FIXME: does this work on Safari?
if(selection["removeAllRanges"]){ // Mozilla
var range = _document.createRange() ;
range.selectNode(element) ;
selection.removeAllRanges() ;
selection.addRange(range) ;
}
}
},
selectElementChildren: function(/*DomNode*/element){
// summary: clear previous selection and select the content of the node (excluding the node itself)
var _window = dojo.global();
var _document = dojo.doc();
element = dojo.byId(element);
if(_document.selection && dojo.body().createTextRange){ // IE
var range = dojo.body().createTextRange();
range.moveToElementText(element);
range.select();
}else if(_window["getSelection"]){
var selection = _window.getSelection();
if(selection["setBaseAndExtent"]){ // Safari
selection.setBaseAndExtent(element, 0, element, element.innerText.length - 1);
} else if(selection["selectAllChildren"]){ // Mozilla
selection.selectAllChildren(element);
}
}
},
getBookmark: function(){
// summary: Retrieves a bookmark that can be used with moveToBookmark to return to the same range
var bookmark;
var _document = dojo.doc();
if(_document["selection"]){ // IE
var range = _document.selection.createRange();
bookmark = range.getBookmark();
}else{
var selection;
try {selection = dojo.global().getSelection();}
catch (e) {}
if(selection){
var range = selection.getRangeAt(0);
bookmark = range.cloneRange();
}else{
dojo.debug("No idea how to store the current selection for this browser!");
}
}
return bookmark;
},
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 = _document.selection.createRange();
range.moveToBookmark(bookmark);
range.select();
}else{ //Moz/W3C
var selection;
try {selection = dojo.global().getSelection();}
catch (e) {}
if(selection && selection['removeAllRanges']){
selection.removeAllRanges() ;
selection.addRange(bookmark) ;
}else{
dojo.debug("No idea how to restore selection for this browser!");
}
}
},
collapse: function(/*Boolean*/beginning) {
// summary: clear current selection
if(dojo.global()['getSelection']){
var selection = dojo.global().getSelection();
if(selection.removeAllRanges){ // Mozilla
if(beginning){
selection.collapseToStart();
}else{
selection.collapseToEnd();
}
}else{ // Safari
// pulled from WebCore/ecma/kjs_window.cpp, line 2536
dojo.global().getSelection().collapse(beginning);
}
}else if(dojo.doc().selection){ // IE
var range = dojo.doc().selection.createRange();
range.collapse(beginning);
range.select();
}
},
remove: function() {
// summary: delete current selection
if(dojo.doc().selection) { //IE
var selection = dojo.doc().selection;
if ( selection.type.toUpperCase() != "NONE" ){
selection.clear();
}
return selection;
}else{
var selection = dojo.global().getSelection();
for ( var i = 0; i < selection.rangeCount; i++ ){
selection.getRangeAt(i).deleteContents();
}
return selection;
}
}
});

View File

@@ -0,0 +1,16 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.shadow");
dojo.require("dojo.lfx.shadow");
dojo.deprecated("dojo.html.shadow has been moved to dojo.lfx.", "0.5");
dojo.html.shadow = dojo.lfx.shadow;

View File

@@ -0,0 +1,587 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.style");
dojo.require("dojo.html.common");
dojo.require("dojo.uri.Uri");
dojo.html.getClass = function(/* HTMLElement */node){
// summary
// Returns the string value of the list of CSS classes currently assigned directly
// to the node in question. Returns an empty string if no class attribute is found;
node = dojo.byId(node);
if(!node){ return ""; }
var cs = "";
if(node.className){
cs = node.className;
}else if(dojo.html.hasAttribute(node, "class")){
cs = dojo.html.getAttribute(node, "class");
}
return cs.replace(/^\s+|\s+$/g, ""); // string
}
dojo.html.getClasses = function(/* HTMLElement */node) {
// summary
// Returns an array of CSS classes currently assigned directly to the node in question.
// Returns an empty array if no classes are found;
var c = dojo.html.getClass(node);
return (c == "") ? [] : c.split(/\s+/g); // array
}
dojo.html.hasClass = function(/* HTMLElement */node, /* string */classname){
// summary
// Returns whether or not the specified classname is a portion of the
// class list currently applied to the node. Does not cover cascaded
// styles, only classes directly applied to the node.
return (new RegExp('(^|\\s+)'+classname+'(\\s+|$)')).test(dojo.html.getClass(node)) // boolean
}
dojo.html.prependClass = function(/* HTMLElement */node, /* string */classStr){
// summary
// Adds the specified class to the beginning of the class list on the
// passed node. This gives the specified class the highest precidence
// when style cascading is calculated for the node. Returns true or
// false; indicating success or failure of the operation, respectively.
classStr += " " + dojo.html.getClass(node);
return dojo.html.setClass(node, classStr); // boolean
}
dojo.html.addClass = function(/* HTMLElement */node, /* string */classStr){
// summary
// Adds the specified class to the end of the class list on the
// passed &node;. Returns &true; or &false; indicating success or failure.
if (dojo.html.hasClass(node, classStr)) {
return false;
}
classStr = (dojo.html.getClass(node) + " " + classStr).replace(/^\s+|\s+$/g,"");
return dojo.html.setClass(node, classStr); // boolean
}
dojo.html.setClass = function(/* HTMLElement */node, /* string */classStr){
// summary
// Clobbers the existing list of classes for the node, replacing it with
// the list given in the 2nd argument. Returns true or false
// indicating success or failure.
node = dojo.byId(node);
var cs = new String(classStr);
try{
if(typeof node.className == "string"){
node.className = cs;
}else if(node.setAttribute){
node.setAttribute("class", classStr);
node.className = cs;
}else{
return false;
}
}catch(e){
dojo.debug("dojo.html.setClass() failed", e);
}
return true;
}
dojo.html.removeClass = function(/* HTMLElement */node, /* string */classStr, /* boolean? */allowPartialMatches){
// summary
// Removes the className from the node;. Returns true or false indicating success or failure.
try{
if (!allowPartialMatches) {
var newcs = dojo.html.getClass(node).replace(new RegExp('(^|\\s+)'+classStr+'(\\s+|$)'), "$1$2");
} else {
var newcs = dojo.html.getClass(node).replace(classStr,'');
}
dojo.html.setClass(node, newcs);
}catch(e){
dojo.debug("dojo.html.removeClass() failed", e);
}
return true; // boolean
}
dojo.html.replaceClass = function(/* HTMLElement */node, /* string */newClass, /* string */oldClass) {
// summary
// Replaces 'oldClass' and adds 'newClass' to node
dojo.html.removeClass(node, oldClass);
dojo.html.addClass(node, newClass);
}
// Enum type for getElementsByClass classMatchType arg:
dojo.html.classMatchType = {
ContainsAll : 0, // all of the classes are part of the node's class (default)
ContainsAny : 1, // any of the classes are part of the node's class
IsOnly : 2 // only all of the classes are part of the node's class
}
dojo.html.getElementsByClass = function(
/* string */classStr,
/* HTMLElement? */parent,
/* string? */nodeType,
/* integer? */classMatchType,
/* boolean? */useNonXpath
){
// summary
// Returns an array of nodes for the given classStr, children of a
// parent, and optionally of a certain nodeType
// FIXME: temporarily set to false because of several dojo tickets related
// to the xpath version not working consistently in firefox.
useNonXpath = false;
var _document = dojo.doc();
parent = dojo.byId(parent) || _document;
var classes = classStr.split(/\s+/g);
var nodes = [];
if( classMatchType != 1 && classMatchType != 2 ) classMatchType = 0; // make it enum
var reClass = new RegExp("(\\s|^)((" + classes.join(")|(") + "))(\\s|$)");
var srtLength = classes.join(" ").length;
var candidateNodes = [];
if(!useNonXpath && _document.evaluate) { // supports dom 3 xpath
var xpath = ".//" + (nodeType || "*") + "[contains(";
if(classMatchType != dojo.html.classMatchType.ContainsAny){
xpath += "concat(' ',@class,' '), ' " +
classes.join(" ') and contains(concat(' ',@class,' '), ' ") +
" ')";
if (classMatchType == 2) {
xpath += " and string-length(@class)="+srtLength+"]";
}else{
xpath += "]";
}
}else{
xpath += "concat(' ',@class,' '), ' " +
classes.join(" ') or contains(concat(' ',@class,' '), ' ") +
" ')]";
}
var xpathResult = _document.evaluate(xpath, parent, null, XPathResult.ANY_TYPE, null);
var result = xpathResult.iterateNext();
while(result){
try{
candidateNodes.push(result);
result = xpathResult.iterateNext();
}catch(e){ break; }
}
return candidateNodes; // NodeList
}else{
if(!nodeType){
nodeType = "*";
}
candidateNodes = parent.getElementsByTagName(nodeType);
var node, i = 0;
outer:
while(node = candidateNodes[i++]){
var nodeClasses = dojo.html.getClasses(node);
if(nodeClasses.length == 0){ continue outer; }
var matches = 0;
for(var j = 0; j < nodeClasses.length; j++){
if(reClass.test(nodeClasses[j])){
if(classMatchType == dojo.html.classMatchType.ContainsAny){
nodes.push(node);
continue outer;
}else{
matches++;
}
}else{
if(classMatchType == dojo.html.classMatchType.IsOnly){
continue outer;
}
}
}
if(matches == classes.length){
if( (classMatchType == dojo.html.classMatchType.IsOnly)&&
(matches == nodeClasses.length)){
nodes.push(node);
}else if(classMatchType == dojo.html.classMatchType.ContainsAll){
nodes.push(node);
}
}
}
return nodes; // NodeList
}
}
dojo.html.getElementsByClassName = dojo.html.getElementsByClass;
dojo.html.toCamelCase = function(/* string */selector){
// summary
// Translates a CSS selector string to a camel-cased one.
var arr = selector.split('-'), cc = arr[0];
for(var i = 1; i < arr.length; i++) {
cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
}
return cc; // string
}
dojo.html.toSelectorCase = function(/* string */selector){
// summary
// Translates a camel cased string to a selector cased one.
return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase(); // string
}
dojo.html.getComputedStyle = function(/* HTMLElement */node, /* string */cssSelector, /* integer? */inValue){
// summary
// Returns the computed style of cssSelector on node.
node = dojo.byId(node);
// cssSelector may actually be in camel case, so force selector version
var cssSelector = dojo.html.toSelectorCase(cssSelector);
var property = dojo.html.toCamelCase(cssSelector);
if(!node || !node.style){
return inValue;
} else if (document.defaultView && dojo.html.isDescendantOf(node, node.ownerDocument)){ // W3, gecko, KHTML
try{
// mozilla segfaults when margin-* and node is removed from doc
// FIXME: need to figure out a if there is quicker workaround
var cs = document.defaultView.getComputedStyle(node, "");
if(cs){
return cs.getPropertyValue(cssSelector); // integer
}
}catch(e){ // reports are that Safari can throw an exception above
if(node.style.getPropertyValue){ // W3
return node.style.getPropertyValue(cssSelector); // integer
} else {
return inValue; // integer
}
}
} else if(node.currentStyle){ // IE
return node.currentStyle[property]; // integer
}
if(node.style.getPropertyValue){ // W3
return node.style.getPropertyValue(cssSelector); // integer
}else{
return inValue; // integer
}
}
dojo.html.getStyleProperty = function(/* HTMLElement */node, /* string */cssSelector){
// summary
// Returns the value of the passed style
node = dojo.byId(node);
return (node && node.style ? node.style[dojo.html.toCamelCase(cssSelector)] : undefined); // string
}
dojo.html.getStyle = function(/* HTMLElement */node, /* string */cssSelector){
// summary
// Returns the computed value of the passed style
var value = dojo.html.getStyleProperty(node, cssSelector);
return (value ? value : dojo.html.getComputedStyle(node, cssSelector)); // string || integer
}
dojo.html.setStyle = function(/* HTMLElement */node, /* string */cssSelector, /* string */value){
// summary
// Set the value of passed style on node
node = dojo.byId(node);
if(node && node.style){
var camelCased = dojo.html.toCamelCase(cssSelector);
node.style[camelCased] = value;
}
}
dojo.html.setStyleText = function (/* HTMLElement */target, /* string */text) {
// summary
// Try to set the entire cssText property of the passed target; equiv of setting style attribute.
try {
target.style.cssText = text;
} catch (e) {
target.setAttribute("style", text);
}
}
dojo.html.copyStyle = function(/* HTMLElement */target, /* HTMLElement */source){
// summary
// work around for opera which doesn't have cssText, and for IE which fails on setAttribute
if(!source.style.cssText){
target.setAttribute("style", source.getAttribute("style"));
}else{
target.style.cssText = source.style.cssText;
}
dojo.html.addClass(target, dojo.html.getClass(source));
}
dojo.html.getUnitValue = function(/* HTMLElement */node, /* string */cssSelector, /* boolean? */autoIsZero){
// summary
// Get the value of passed selector, with the specific units used
var s = dojo.html.getComputedStyle(node, cssSelector);
if((!s)||((s == 'auto')&&(autoIsZero))){
return { value: 0, units: 'px' }; // object
}
// FIXME: is regex inefficient vs. parseInt or some manual test?
var match = s.match(/(\-?[\d.]+)([a-z%]*)/i);
if (!match){return dojo.html.getUnitValue.bad;}
return { value: Number(match[1]), units: match[2].toLowerCase() }; // object
}
dojo.html.getUnitValue.bad = { value: NaN, units: '' };
dojo.html.getPixelValue = function(/* HTMLElement */node, /* string */cssSelector, /* boolean? */autoIsZero){
// summary
// Get the value of passed selector in pixels.
var result = dojo.html.getUnitValue(node, cssSelector, autoIsZero);
// FIXME: there is serious debate as to whether or not this is the right solution
if(isNaN(result.value)){
return 0; // integer
}
// FIXME: code exists for converting other units to px (see Dean Edward's IE7)
// but there are cross-browser complexities
if((result.value)&&(result.units != 'px')){
return NaN; // integer
}
return result.value; // integer
}
dojo.html.setPositivePixelValue = function(/* HTMLElement */node, /* string */selector, /* integer */value){
// summary
// Attempt to set the value of selector on node as a positive pixel value.
if(isNaN(value)){return false;}
node.style[selector] = Math.max(0, value) + 'px';
return true; // boolean
}
dojo.html.styleSheet = null;
// FIXME: this is a really basic stub for adding and removing cssRules, but
// it assumes that you know the index of the cssRule that you want to add
// or remove, making it less than useful. So we need something that can
// search for the selector that you you want to remove.
dojo.html.insertCssRule = function(/* string */selector, /* string */declaration, /* integer? */index) {
// summary
// Attempt to insert declaration as selector on the internal stylesheet; if index try to set it there.
if (!dojo.html.styleSheet) {
if (document.createStyleSheet) { // IE
dojo.html.styleSheet = document.createStyleSheet();
} else if (document.styleSheets[0]) { // rest
// FIXME: should create a new style sheet here
// fall back on an exsiting style sheet
dojo.html.styleSheet = document.styleSheets[0];
} else {
return null; // integer
} // fail
}
if (arguments.length < 3) { // index may == 0
if (dojo.html.styleSheet.cssRules) { // W3
index = dojo.html.styleSheet.cssRules.length;
} else if (dojo.html.styleSheet.rules) { // IE
index = dojo.html.styleSheet.rules.length;
} else {
return null; // integer
} // fail
}
if (dojo.html.styleSheet.insertRule) { // W3
var rule = selector + " { " + declaration + " }";
return dojo.html.styleSheet.insertRule(rule, index); // integer
} else if (dojo.html.styleSheet.addRule) { // IE
return dojo.html.styleSheet.addRule(selector, declaration, index); // integer
} else {
return null; // integer
} // fail
}
dojo.html.removeCssRule = function(/* integer? */index){
// summary
// Attempt to remove the rule at index.
if(!dojo.html.styleSheet){
dojo.debug("no stylesheet defined for removing rules");
return false;
}
if(dojo.render.html.ie){
if(!index){
index = dojo.html.styleSheet.rules.length;
dojo.html.styleSheet.removeRule(index);
}
}else if(document.styleSheets[0]){
if(!index){
index = dojo.html.styleSheet.cssRules.length;
}
dojo.html.styleSheet.deleteRule(index);
}
return true; // boolean
}
dojo.html._insertedCssFiles = []; // cache container needed because IE reformats cssText when added to DOM
dojo.html.insertCssFile = function(/* string */URI, /* HTMLDocument? */doc, /* boolean? */checkDuplicates, /* boolean */fail_ok){
// summary
// calls css by XmlHTTP and inserts it into DOM as <style [widgetType="widgetType"]> *downloaded cssText*</style>
if(!URI){ return; }
if(!doc){ doc = document; }
var cssStr = dojo.hostenv.getText(URI, false, fail_ok);
if(cssStr===null){ return; }
cssStr = dojo.html.fixPathsInCssText(cssStr, URI);
if(checkDuplicates){
var idx = -1, node, ent = dojo.html._insertedCssFiles;
for(var i = 0; i < ent.length; i++){
if((ent[i].doc == doc) && (ent[i].cssText == cssStr)){
idx = i; node = ent[i].nodeRef;
break;
}
}
// make sure we havent deleted our node
if(node){
var styles = doc.getElementsByTagName("style");
for(var i = 0; i < styles.length; i++){
if(styles[i] == node){
return;
}
}
// delete this entry
dojo.html._insertedCssFiles.shift(idx, 1);
}
}
var style = dojo.html.insertCssText(cssStr, doc);
dojo.html._insertedCssFiles.push({'doc': doc, 'cssText': cssStr, 'nodeRef': style});
// insert custom attribute ex dbgHref="../foo.css" usefull when debugging in DOM inspectors, no?
if(style && djConfig.isDebug){
style.setAttribute("dbgHref", URI);
}
return style; // HTMLStyleElement
}
dojo.html.insertCssText = function(/* string */cssStr, /* HTMLDocument? */doc, /* string? */URI){
// summary
// Attempt to insert CSS rules into the document through inserting a style element
// DomNode Style = insertCssText(String ".dojoMenu {color: green;}"[, DomDoc document, dojo.uri.Uri Url ])
if(!cssStr){
return; // HTMLStyleElement
}
if(!doc){ doc = document; }
if(URI){// fix paths in cssStr
cssStr = dojo.html.fixPathsInCssText(cssStr, URI);
}
var style = doc.createElement("style");
style.setAttribute("type", "text/css");
// IE is b0rken enough to require that we add the element to the doc
// before changing it's properties
var head = doc.getElementsByTagName("head")[0];
if(!head){ // must have a head tag
dojo.debug("No head tag in document, aborting styles");
return; // HTMLStyleElement
}else{
head.appendChild(style);
}
if(style.styleSheet){// IE
var setFunc = function(){
try{
style.styleSheet.cssText = cssStr;
}catch(e){ dojo.debug(e); }
};
if(style.styleSheet.disabled){
setTimeout(setFunc, 10);
}else{
setFunc();
}
}else{ // w3c
var cssText = doc.createTextNode(cssStr);
style.appendChild(cssText);
}
return style; // HTMLStyleElement
}
dojo.html.fixPathsInCssText = function(/* string */cssStr, /* string */URI){
// summary
// usage: cssText comes from dojoroot/src/widget/templates/Foobar.css
// it has .dojoFoo { background-image: url(images/bar.png);} then uri should point to dojoroot/src/widget/templates/
if(!cssStr || !URI){ return; }
var match, str = "", url = "", urlChrs = "[\\t\\s\\w\\(\\)\\/\\.\\\\'\"-:#=&?~]+";
var regex = new RegExp('url\\(\\s*('+urlChrs+')\\s*\\)');
var regexProtocol = /(file|https?|ftps?):\/\//;
regexTrim = new RegExp("^[\\s]*(['\"]?)("+urlChrs+")\\1[\\s]*?$");
if(dojo.render.html.ie55 || dojo.render.html.ie60){
var regexIe = new RegExp("AlphaImageLoader\\((.*)src\=['\"]("+urlChrs+")['\"]");
// TODO: need to decide how to handle relative paths and AlphaImageLoader see #1441
// current implementation breaks on build with intern_strings
while(match = regexIe.exec(cssStr)){
url = match[2].replace(regexTrim, "$2");
if(!regexProtocol.exec(url)){
url = (new dojo.uri.Uri(URI, url).toString());
}
str += cssStr.substring(0, match.index) + "AlphaImageLoader(" + match[1] + "src='" + url + "'";
cssStr = cssStr.substr(match.index + match[0].length);
}
cssStr = str + cssStr;
str = "";
}
while(match = regex.exec(cssStr)){
url = match[1].replace(regexTrim, "$2");
if(!regexProtocol.exec(url)){
url = (new dojo.uri.Uri(URI, url).toString());
}
str += cssStr.substring(0, match.index) + "url(" + url + ")";
cssStr = cssStr.substr(match.index + match[0].length);
}
return str + cssStr; // string
}
dojo.html.setActiveStyleSheet = function(/* string */title){
// summary
// Activate style sheet with specified title.
var i = 0, a, els = dojo.doc().getElementsByTagName("link");
while (a = els[i++]) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")){
a.disabled = true;
if (a.getAttribute("title") == title) { a.disabled = false; }
}
}
}
dojo.html.getActiveStyleSheet = function(){
// summary
// return the title of the currently active stylesheet
var i = 0, a, els = dojo.doc().getElementsByTagName("link");
while (a = els[i++]) {
if (a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("title")
&& !a.disabled
){
return a.getAttribute("title"); // string
}
}
return null; // string
}
dojo.html.getPreferredStyleSheet = function(){
// summary
// Return the preferred stylesheet title (i.e. link without alt attribute)
var i = 0, a, els = dojo.doc().getElementsByTagName("link");
while (a = els[i++]) {
if(a.getAttribute("rel").indexOf("style") != -1
&& a.getAttribute("rel").indexOf("alt") == -1
&& a.getAttribute("title")
){
return a.getAttribute("title"); // string
}
}
return null; // string
}
dojo.html.applyBrowserClass = function(/* HTMLElement */node){
// summary
// Applies pre-set class names based on browser & version to the passed node.
// Modified version of Morris' CSS hack.
var drh=dojo.render.html;
var classes = {
dj_ie: drh.ie,
dj_ie55: drh.ie55,
dj_ie6: drh.ie60,
dj_ie7: drh.ie70,
dj_iequirks: drh.ie && drh.quirks,
dj_opera: drh.opera,
dj_opera8: drh.opera && (Math.floor(dojo.render.version)==8),
dj_opera9: drh.opera && (Math.floor(dojo.render.version)==9),
dj_khtml: drh.khtml,
dj_safari: drh.safari,
dj_gecko: drh.mozilla
}; // no dojo unsupported browsers
for(var p in classes){
if(classes[p]){
dojo.html.addClass(node, p);
}
}
};

View File

@@ -0,0 +1,485 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.html.util");
dojo.require("dojo.html.layout");
dojo.html.getElementWindow = function(/* HTMLElement */element){
// summary
// Get the window object where the element is placed in.
return dojo.html.getDocumentWindow( element.ownerDocument ); // Window
}
dojo.html.getDocumentWindow = function(doc){
// summary
// Get window object associated with document doc
// With Safari, there is not wa to retrieve the window from the document, so we must fix it.
if(dojo.render.html.safari && !doc._parentWindow){
/*
This is a Safari specific function that fix the reference to the parent
window from the document object.
*/
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
if(dojo.render.html.ie && 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
}
dojo.html.gravity = function(/* HTMLElement */node, /* DOMEvent */e){
// summary
// Calculates the mouse's direction of gravity relative to the centre
// of the given node.
// <p>
// If you wanted to insert a node into a DOM tree based on the mouse
// position you might use the following code:
// <pre>
// if (gravity(node, e) & gravity.NORTH) { [insert before]; }
// else { [insert after]; }
// </pre>
//
// @param node The node
// @param e The event containing the mouse coordinates
// @return The directions, NORTH or SOUTH and EAST or WEST. These
// are properties of the function.
node = dojo.byId(node);
var mouse = dojo.html.getCursorPosition(e);
with (dojo.html) {
var absolute = getAbsolutePosition(node, true);
var bb = getBorderBox(node);
var nodecenterx = absolute.x + (bb.width / 2);
var nodecentery = absolute.y + (bb.height / 2);
}
with (dojo.html.gravity) {
return ((mouse.x < nodecenterx ? WEST : EAST) | (mouse.y < nodecentery ? NORTH : SOUTH)); // integer
}
}
dojo.html.gravity.NORTH = 1;
dojo.html.gravity.SOUTH = 1 << 1;
dojo.html.gravity.EAST = 1 << 2;
dojo.html.gravity.WEST = 1 << 3;
dojo.html.overElement = function(/* HTMLElement */element, /* DOMEvent */e){
// summary
// Returns whether the mouse is over the passed element.
// Element must be display:block (ie, not a <span>)
element = dojo.byId(element);
var mouse = dojo.html.getCursorPosition(e);
var bb = dojo.html.getBorderBox(element);
var absolute = dojo.html.getAbsolutePosition(element, true, dojo.html.boxSizing.BORDER_BOX);
var top = absolute.y;
var bottom = top + bb.height;
var left = absolute.x;
var right = left + bb.width;
return (mouse.x >= left
&& mouse.x <= right
&& mouse.y >= top
&& mouse.y <= bottom
); // boolean
}
dojo.html.renderedTextContent = function(/* HTMLElement */node){
// summary
// Attempts to return the text as it would be rendered, with the line breaks
// sorted out nicely. Unfinished.
node = dojo.byId(node);
var result = "";
if (node == null) { return result; }
for (var i = 0; i < node.childNodes.length; i++) {
switch (node.childNodes[i].nodeType) {
case 1: // ELEMENT_NODE
case 5: // ENTITY_REFERENCE_NODE
var display = "unknown";
try {
display = dojo.html.getStyle(node.childNodes[i], "display");
} catch(E) {}
switch (display) {
case "block": case "list-item": case "run-in":
case "table": case "table-row-group": case "table-header-group":
case "table-footer-group": case "table-row": case "table-column-group":
case "table-column": case "table-cell": case "table-caption":
// TODO: this shouldn't insert double spaces on aligning blocks
result += "\n";
result += dojo.html.renderedTextContent(node.childNodes[i]);
result += "\n";
break;
case "none": break;
default:
if(node.childNodes[i].tagName && node.childNodes[i].tagName.toLowerCase() == "br") {
result += "\n";
} else {
result += dojo.html.renderedTextContent(node.childNodes[i]);
}
break;
}
break;
case 3: // TEXT_NODE
case 2: // ATTRIBUTE_NODE
case 4: // CDATA_SECTION_NODE
var text = node.childNodes[i].nodeValue;
var textTransform = "unknown";
try {
textTransform = dojo.html.getStyle(node, "text-transform");
} catch(E) {}
switch (textTransform){
case "capitalize":
var words = text.split(' ');
for(var i=0; i<words.length; i++){
words[i] = words[i].charAt(0).toUpperCase() + words[i].substring(1);
}
text = words.join(" ");
break;
case "uppercase": text = text.toUpperCase(); break;
case "lowercase": text = text.toLowerCase(); break;
default: break; // leave as is
}
// TODO: implement
switch (textTransform){
case "nowrap": break;
case "pre-wrap": break;
case "pre-line": break;
case "pre": break; // leave as is
default:
// remove whitespace and collapse first space
text = text.replace(/\s+/, " ");
if (/\s$/.test(result)) { text.replace(/^\s/, ""); }
break;
}
result += text;
break;
default:
break;
}
}
return result; // string
}
dojo.html.createNodesFromText = function(/* string */txt, /* boolean? */trim){
// summary
// Attempts to create a set of nodes based on the structure of the passed text.
if(trim) { txt = txt.replace(/^\s+|\s+$/g, ""); }
var tn = dojo.doc().createElement("div");
// tn.style.display = "none";
tn.style.visibility= "hidden";
dojo.body().appendChild(tn);
var tableType = "none";
if((/^<t[dh][\s\r\n>]/i).test(txt.replace(/^\s+/))) {
txt = "<table><tbody><tr>" + txt + "</tr></tbody></table>";
tableType = "cell";
} else if((/^<tr[\s\r\n>]/i).test(txt.replace(/^\s+/))) {
txt = "<table><tbody>" + txt + "</tbody></table>";
tableType = "row";
} else if((/^<(thead|tbody|tfoot)[\s\r\n>]/i).test(txt.replace(/^\s+/))) {
txt = "<table>" + txt + "</table>";
tableType = "section";
}
tn.innerHTML = txt;
if(tn["normalize"]){
tn.normalize();
}
var parent = null;
switch(tableType) {
case "cell":
parent = tn.getElementsByTagName("tr")[0];
break;
case "row":
parent = tn.getElementsByTagName("tbody")[0];
break;
case "section":
parent = tn.getElementsByTagName("table")[0];
break;
default:
parent = tn;
break;
}
/* this doesn't make much sense, I'm assuming it just meant trim() so wrap was replaced with trim
if(wrap){
var ret = [];
// start hack
var fc = tn.firstChild;
ret[0] = ((fc.nodeValue == " ")||(fc.nodeValue == "\t")) ? fc.nextSibling : fc;
// end hack
// tn.style.display = "none";
dojo.body().removeChild(tn);
return ret;
}
*/
var nodes = [];
for(var x=0; x<parent.childNodes.length; x++){
nodes.push(parent.childNodes[x].cloneNode(true));
}
tn.style.display = "none"; // FIXME: why do we do this?
dojo.html.destroyNode(tn);
return nodes; // array
}
dojo.html.placeOnScreen = function(
/* HTMLElement */node,
/* integer */desiredX,
/* integer */desiredY,
/* integer */padding,
/* boolean? */hasScroll,
/* string? */corners,
/* boolean? */tryOnly
){
// summary
// Keeps 'node' in the visible area of the screen while trying to
// place closest to desiredX, desiredY. The input coordinates are
// expected to be the desired screen position, not accounting for
// scrolling. If you already accounted for scrolling, set 'hasScroll'
// to true. Set padding to either a number or array for [paddingX, paddingY]
// to put some buffer around the element you want to position.
// Set which corner(s) you want to bind to, such as
//
// placeOnScreen(node, desiredX, desiredY, padding, hasScroll, "TR")
// placeOnScreen(node, [desiredX, desiredY], padding, hasScroll, ["TR", "BL"])
//
// The desiredX/desiredY 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.
// By default, corner = ['TL'].
// If tryOnly is set to true, the node will not be moved to the place.
//
// NOTE: node is assumed to be absolutely or relatively positioned.
//
// Alternate call sig:
// placeOnScreen(node, [x, y], padding, hasScroll)
//
// Examples:
// placeOnScreen(node, 100, 200)
// placeOnScreen("myId", [800, 623], 5)
// placeOnScreen(node, 234, 3284, [2, 5], true)
// TODO: make this function have variable call sigs
// kes(node, ptArray, cornerArray, padding, hasScroll)
// kes(node, ptX, ptY, cornerA, cornerB, cornerC, paddingArray, hasScroll)
if(desiredX instanceof Array || typeof desiredX == "array") {
tryOnly = corners;
corners = hasScroll;
hasScroll = padding;
padding = desiredY;
desiredY = desiredX[1];
desiredX = desiredX[0];
}
if(corners instanceof String || typeof corners == "string"){
corners = corners.split(",");
}
if(!isNaN(padding)) {
padding = [Number(padding), Number(padding)];
} else if(!(padding instanceof Array || typeof padding == "array")) {
padding = [0, 0];
}
var scroll = dojo.html.getScroll().offset;
var view = dojo.html.getViewport();
node = dojo.byId(node);
var oldDisplay = node.style.display;
node.style.display="";
var bb = dojo.html.getBorderBox(node);
var w = bb.width;
var h = bb.height;
node.style.display=oldDisplay;
if(!(corners instanceof Array || typeof corners == "array")){
corners = ['TL'];
}
var bestx, besty, bestDistance = Infinity, bestCorner;
for(var cidex=0; cidex<corners.length; ++cidex){
var corner = corners[cidex];
var match = true;
var tryX = desiredX - (corner.charAt(1)=='L' ? 0 : w) + padding[0]*(corner.charAt(1)=='L' ? 1 : -1);
var tryY = desiredY - (corner.charAt(0)=='T' ? 0 : h) + padding[1]*(corner.charAt(0)=='T' ? 1 : -1);
if(hasScroll) {
tryX -= scroll.x;
tryY -= scroll.y;
}
if(tryX < 0){
tryX = 0;
match = false;
}
if(tryY < 0){
tryY = 0;
match = false;
}
var x = tryX + w;
if(x > view.width) {
x = view.width - w;
match = false;
} else {
x = tryX;
}
x = Math.max(padding[0], x) + scroll.x;
var y = tryY + h;
if(y > view.height) {
y = view.height - h;
match = false;
} else {
y = tryY;
}
y = Math.max(padding[1], y) + scroll.y;
if(match){ //perfect match, return now
bestx = x;
besty = y;
bestDistance = 0;
bestCorner = corner;
break;
}else{
//not perfect, find out whether it is better than the saved one
var dist = Math.pow(x-tryX-scroll.x,2)+Math.pow(y-tryY-scroll.y,2);
if(bestDistance > dist){
bestDistance = dist;
bestx = x;
besty = y;
bestCorner = corner;
}
}
}
if(!tryOnly){
node.style.left = bestx + "px";
node.style.top = besty + "px";
}
return { left: bestx, top: besty, x: bestx, y: besty, dist: bestDistance, corner: bestCorner}; // object
}
dojo.html.placeOnScreenPoint = function(node, desiredX, desiredY, padding, hasScroll) {
dojo.deprecated("dojo.html.placeOnScreenPoint", "use dojo.html.placeOnScreen() instead", "0.5");
return dojo.html.placeOnScreen(node, desiredX, desiredY, padding, hasScroll, ['TL', 'TR', 'BL', 'BR']);
}
dojo.html.placeOnScreenAroundElement = function(
/* HTMLElement */node,
/* HTMLElement */aroundNode,
/* integer */padding,
/* string? */aroundType,
/* string? */aroundCorners,
/* boolean? */tryOnly
){
// summary
// Like placeOnScreen, except it accepts aroundNode instead of x,y
// and attempts to place node around it. aroundType (see
// dojo.html.boxSizing in html/layout.js) determines which box of the
// aroundNode should be used to calculate the outer box.
// 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 dojo.html.placeOnScreen)
// aroundCorners: {'TL': 'BL', 'BL': 'TL'}
var best, bestDistance=Infinity;
aroundNode = dojo.byId(aroundNode);
var oldDisplay = aroundNode.style.display;
aroundNode.style.display="";
var mb = dojo.html.getElementBox(aroundNode, aroundType);
var aroundNodeW = mb.width;
var aroundNodeH = mb.height;
var aroundNodePos = dojo.html.getAbsolutePosition(aroundNode, true, aroundType);
aroundNode.style.display=oldDisplay;
for(var nodeCorner in aroundCorners){
var pos, desiredX, desiredY;
var corners = aroundCorners[nodeCorner];
desiredX = aroundNodePos.x + (nodeCorner.charAt(1)=='L' ? 0 : aroundNodeW);
desiredY = aroundNodePos.y + (nodeCorner.charAt(0)=='T' ? 0 : aroundNodeH);
pos = dojo.html.placeOnScreen(node, desiredX, desiredY, padding, true, corners, true);
if(pos.dist == 0){
best = pos;
break;
}else{
//not perfect, find out whether it is better than the saved one
if(bestDistance > pos.dist){
bestDistance = pos.dist;
best = pos;
}
}
}
if(!tryOnly){
node.style.left = best.left + "px";
node.style.top = best.top + "px";
}
return best; // object
}
dojo.html.scrollIntoView = function(/* HTMLElement */node){
// summary
// Scroll the passed node into view, if it is not.
if(!node){ return; }
// 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
// dont like browser sniffs implementations but sometimes you have to use it
if(dojo.render.html.ie){
//only call scrollIntoView if there is a scrollbar for this menu,
//otherwise, scrollIntoView will scroll the window scrollbar
if(dojo.html.getBorderBox(node.parentNode).height <= node.parentNode.scrollHeight){
node.scrollIntoView(false);
}
}else if(dojo.render.html.mozilla){
// IE, mozilla
node.scrollIntoView(false);
}else{
var parent = node.parentNode;
var parentBottom = parent.scrollTop + dojo.html.getBorderBox(parent).height;
var nodeBottom = node.offsetTop + dojo.html.getMarginBox(node).height;
if(parentBottom < nodeBottom){
parent.scrollTop += (nodeBottom - parentBottom);
}else if(parent.scrollTop > node.offsetTop){
parent.scrollTop -= (parent.scrollTop - node.offsetTop);
}
}
}