1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/xpcom",
  5     "firebug/lib/object",
  6     "firebug/lib/locale",
  7     "firebug/lib/domplate",
  8     "firebug/lib/dom",
  9     "firebug/lib/options",
 10     "firebug/lib/persist",
 11     "firebug/lib/string",
 12     "firebug/lib/http",
 13     "firebug/lib/css",
 14     "firebug/lib/events",
 15     "firebug/cookies/baseObserver",
 16     "firebug/cookies/menuUtils",
 17 ],
 18 function(Xpcom, Obj, Locale, Domplate, Dom, Options, Persist, Str, Http, Css, Events,
 19     BaseObserver, MenuUtils) {
 20 
 21 // ********************************************************************************************* //
 22 // Resizable column helper (helper for Templates.CookieTable)
 23 
 24 var HeaderResizer =
 25 {
 26     resizing: false,
 27     currColumn: null,
 28     startX: 0,
 29     startWidth: 0,
 30     lastMouseUp: 0,
 31 
 32     onMouseClick: function(event)
 33     {
 34         if (!Events.isLeftClick(event))
 35             return;
 36 
 37         // Avoid click event for sorting, if the resizing has been just finished.
 38         var rightNow = now();
 39         if ((rightNow - this.lastMouseUp) < 1000)
 40             Events.cancelEvent(event);
 41     },
 42 
 43     onMouseDown: function(event)
 44     {
 45         if (!Events.isLeftClick(event))
 46             return;
 47 
 48         var target = event.target;
 49         if (!Css.hasClass(target, "cookieHeaderCellBox"))
 50             return;
 51 
 52         var header = Dom.getAncestorByClass(target, "cookieHeaderRow");
 53         if (!header)
 54             return;
 55 
 56         if (!this.isBetweenColumns(event))
 57             return;
 58 
 59         this.onStartResizing(event);
 60 
 61         Events.cancelEvent(event);
 62     },
 63 
 64     onMouseMove: function(event)
 65     {
 66         if (this.resizing)
 67         {
 68             if (Css.hasClass(target, "cookieHeaderCellBox"))
 69                 target.style.cursor = "e-resize";
 70 
 71             this.onResizing(event);
 72             return;
 73         }
 74 
 75         var target = event.target;
 76         if (!Css.hasClass(target, "cookieHeaderCellBox"))
 77             return;
 78 
 79         if (target)
 80             target.style.cursor = "";
 81 
 82         if (!this.isBetweenColumns(event))
 83             return;
 84 
 85         // Update cursor if the mouse is located between two columns.
 86         target.style.cursor = "e-resize";
 87     },
 88 
 89     onMouseUp: function(event)
 90     {
 91         if (!this.resizing)
 92             return;
 93 
 94         this.lastMouseUp = now();
 95 
 96         this.onEndResizing(event);
 97         Events.cancelEvent(event);
 98     },
 99 
100     onMouseOut: function(event)
101     {
102         if (!this.resizing)
103             return;
104 
105         if (FBTrace.DBG_COOKIES)
106         {
107             FBTrace.sysout("cookies.Mouse out, target: " + event.target.localName +
108                 ", " + event.target.className);
109             FBTrace.sysout("      explicitOriginalTarget: " + event.explicitOriginalTarget.localName +
110                 ", " + event.explicitOriginalTarget.className);
111         }
112 
113         var target = event.target;
114         if (target == event.explicitOriginalTarget)
115             this.onEndResizing(event);
116 
117         Events.cancelEvent(event);
118     },
119 
120     isBetweenColumns: function(event)
121     {
122         var target = event.target;
123         var x = event.clientX;
124         var y = event.clientY;
125 
126         var column = Dom.getAncestorByClass(target, "cookieHeaderCell");
127         var offset = Dom.getClientOffset(column);
128         var size = Dom.getOffsetSize(column);
129 
130         if (column.previousSibling)
131         {
132             if (x < offset.x + 4)
133                 return 1;   // Mouse is close to the left side of the column (target).
134         }
135 
136         if (column.nextSibling)
137         {
138             if (x > offset.x + size.width - 6)
139                 return 2;  // Mouse is close to the right side.
140         }
141 
142         return 0;
143     },
144 
145     onStartResizing: function(event)
146     {
147         var location = this.isBetweenColumns(event);
148         if (!location)
149             return;
150 
151         var target = event.target;
152 
153         this.resizing = true;
154         this.startX = event.clientX;
155 
156         // Currently resizing column.
157         var column = Dom.getAncestorByClass(target, "cookieHeaderCell");
158         this.currColumn = (location == 1) ? column.previousSibling : column;
159 
160         // Last column width.
161         var size = Dom.getOffsetSize(this.currColumn);
162         this.startWidth = size.width;
163 
164         if (FBTrace.DBG_COOKIES)
165         {
166             var colId = this.currColumn.getAttribute("id");
167             FBTrace.sysout("cookies.Start resizing column (id): " + colId +
168                 ", start width: " + this.startWidth);
169         }
170     },
171 
172     onResizing: function(event)
173     {
174         if (!this.resizing)
175             return;
176 
177         var newWidth = this.startWidth + (event.clientX - this.startX);
178         this.currColumn.style.width = newWidth + "px";
179 
180         if (FBTrace.DBG_COOKIES)
181         {
182             var colId = this.currColumn.getAttribute("id");
183             FBTrace.sysout("cookies.Resizing column (id): " + colId +
184                 ", new width: " + newWidth);
185         }
186     },
187 
188     onEndResizing: function(event)
189     {
190         if (!this.resizing)
191             return;
192 
193         this.resizing = false;
194 
195         var newWidth = this.startWidth + (event.clientX - this.startX);
196         this.currColumn.style.width = newWidth + "px";
197 
198         // Store width into the preferences.
199         var colId = this.currColumn.getAttribute("id");
200         if (colId)
201         {
202             // Use directly nsIPrefBranch interface as the pref
203             // doesn't have to exist yet.
204             Options.setPref(Firebug.prefDomain, ".cookies." + colId + ".width", newWidth);
205         }
206 
207         if (FBTrace.DBG_COOKIES)
208         {
209             var colId = this.currColumn.getAttribute("id");
210             FBTrace.sysout("cookies.End resizing column (id): " + colId +
211                 ", new width: " + newWidth);
212         }
213     }
214 };
215 
216 // ********************************************************************************************* //
217 // Time Helpers
218 
219 function now()
220 {
221     return (new Date()).getTime();
222 }
223 
224 // ********************************************************************************************* //
225 
226 return HeaderResizer;
227 
228 // ********************************************************************************************* //
229 });
230 
231