Eliminate duplicated platform-specific code in ScrollingTreeStickyNode
[WebKit-https.git] / Websites / webkit.org / demos / calendar / Utilities.js
1 // Element extension --------------------------------------------------------------
2
3 Element.prototype.removeStyleClass = function(className) 
4 {
5     // Test for the simple case before using a RegExp.
6     if (this.className === className) {
7         this.className = "";
8         return;
9     }
10
11     var regex = new RegExp("(^|\\s+)" + className.escapeForRegExp() + "($|\\s+)");
12     if (regex.test(this.className))
13         this.className = this.className.replace(regex, " ");
14 }
15
16 Element.prototype.addStyleClass = function(className) 
17 {
18     if (className && !this.hasStyleClass(className))
19         this.className += (this.className.length ? " " + className : className);
20 }
21
22 Element.prototype.hasStyleClass = function(className) 
23 {
24     if (!className)
25         return false;
26     // Test for the simple case before using a RegExp.
27     if (this.className === className)
28         return true;
29     var regex = new RegExp("(^|\\s)" + className.escapeForRegExp() + "($|\\s)");
30     return regex.test(this.className);
31 }
32
33 Element.prototype.removeChildren = function()
34 {
35     while (this.firstChild) 
36         this.removeChild(this.firstChild);        
37 }
38
39 Element.prototype.findParentOfTagName = function(tagName)
40 {
41     var parent = this;
42     while (parent) {
43         if (parent.tagName == tagName)
44             return parent;
45         parent = parent.parentNode;
46     }
47     return null;
48 }
49
50 Element.prototype.__defineGetter__("totalOffsetLeft", function()
51 {
52     var total = 0;
53     for (var element = this; element; element = element.offsetParent)
54         total += element.offsetLeft;
55     return total;
56 });
57
58 Element.prototype.__defineGetter__("totalOffsetTop", function()
59 {
60     var total = 0;
61     for (var element = this; element; element = element.offsetParent)
62         total += element.offsetTop;
63     return total;
64 });
65
66 // String extension ------------------------------------------------------
67
68 String.prototype.hasSubstring = function(string, caseInsensitive)
69 {
70     if (!caseInsensitive)
71         return this.indexOf(string) !== -1;
72     return this.match(new RegExp(string.escapeForRegExp(), "i"));
73 }
74
75 String.prototype.escapeCharacters = function(chars)
76 {
77     var foundChar = false;
78     for (var i = 0; i < chars.length; ++i) {
79         if (this.indexOf(chars.charAt(i)) !== -1) {
80             foundChar = true;
81             break;
82         }
83     }
84
85     if (!foundChar)
86         return this;
87
88     var result = "";
89     for (var i = 0; i < this.length; ++i) {
90         if (chars.indexOf(this.charAt(i)) !== -1)
91             result += "\\";
92         result += this.charAt(i);
93     }
94
95     return result;
96 }
97
98 String.prototype.escapeForRegExp = function()
99 {
100     return this.escapeCharacters("^[]{}()\\.$*+?|");
101 }
102
103 // Number extension ------------------------------------------------------
104
105 Number.constrain = function(num, min, max)
106 {
107     if (num < min)
108         num = min;
109     else if (num > max)
110         num = max;
111     return num;
112 }
113
114 // Date extension --------------------------------------------------------
115
116 Date.prototype.isToday = function()
117 {
118     var today = new Date();
119     return (today.getFullYear() == this.getFullYear() && today.getMonth() == this.getMonth() && today.getDate() == this.getDate());    
120 }
121
122 Date.prototype.roundToHour = function() {
123     if (this.getMinutes() == 0)
124         return; // Already rounded to the hour
125     if (this.getHours() < 23)
126         this.setHours(this.getHours() + 1);
127     this.setMinutes(0);
128 }
129
130 Date.dayDateFromTime = function(time) {
131     var date = new Date(time);
132     date.setHours(0, 0, 0, 0);
133     return date;
134 }