source: gs3-extensions/overlay-notes/trunk/src/PhotoNotes-1.5.js.orig@ 26826

Last change on this file since 26826 was 26826, checked in by davidb, 9 years ago

Javascript and CSS files that provide overlay/photo notes. Originally developed for the Pei Jones collection

File size: 26.9 KB
Line 
1/*
2Copyright (c) 2006 Dusty Davidson - http://www.dustyd.net
3(portions Copyright (c) 2005 Angus Turnbull http://www.twinhelix.come)
4
5Permission is hereby granted, free of charge, to any person obtaining
6a copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8the rights to use, copy, modify, merge, publish, distribute, sublicense,
9and/or sell copies of the Software, and to permit persons to whom the Software
10is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
20IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21*/
22
23
24
25/*********************************************************/
26/*** Photo Notes Container *******************************/
27/*********************************************************/
28function PhotoNoteContainer(element, config)
29{
30 var props = {
31 element: element,
32 dragresize: null,
33 notes: new Array(),
34 editing: false
35 };
36
37 for (var p in props)
38 {
39 this[p] = (!config || typeof config[p] == 'undefined') ? props[p] : config[p];
40 }
41
42};
43
44PhotoNoteContainer.prototype.DeleteNote = function(note)
45{
46 note.UnSelect();
47
48 /* remove from the DOM */
49 this.element.removeChild(note.gui.ElementRect);
50 this.element.removeChild(note.gui.ElementNote);
51
52 /* remove from the array... */
53 this.notes.remove(note);
54}
55
56PhotoNoteContainer.prototype.AddNote = function(note)
57{
58 if(!this.editing)
59 {
60 /* add the note to the array of notes, and set its container */
61 this.notes[this.notes.length] = note;
62 note.container = this;
63
64 /* add the note to the DOM */
65 this.element.appendChild(note.gui.ElementRect);
66 this.element.appendChild(note.gui.ElementNote);
67 }
68};
69
70/* hide all of the "text" parts of the notes. Primarily called when hovering a note, at which
71 point we want to hide all of the other note texts */
72PhotoNoteContainer.prototype.HideAllNoteTexts = function()
73{
74 for (var i = 0;i<this.notes.length;i++)
75 this.notes[i].HideNoteText();
76};
77
78
79PhotoNoteContainer.prototype.DisableAllNotes = function()
80{
81 for (var i = 0;i<this.notes.length;i++)
82 this.notes[i].DisableNote();
83};
84
85PhotoNoteContainer.prototype.HideAllNotes = function()
86{
87 for (var i = 0;i<this.notes.length;i++)
88 this.notes[i].HideNote();
89};
90
91PhotoNoteContainer.prototype.ShowAllNotes = function()
92{
93 for (var i = 0;i<this.notes.length;i++)
94 this.notes[i].ShowNote();
95};
96
97PhotoNoteContainer.prototype.EnableAllNotes = function()
98{
99 for (var i = 0;i<this.notes.length;i++)
100 this.notes[i].EnableNote();
101};
102
103
104
105/*********************************************************/
106/*** Photo Note ******************************************/
107/*********************************************************/
108function PhotoNote(text,id,rect)
109{
110 var props = {
111 text: text,
112 id: id,
113 rect: rect,
114 selected: false,
115 container: null,
116 dragresize: null,
117 oldRect: null,
118 YOffset: 10,
119 XOffset: 0,
120 onsave: null,
121 ondelete: null,
122 gui: null
123
124 };
125
126 for (var p in props)
127 {
128 this[p] = props[p];
129 }
130
131 this.CreateElements();
132}
133
134PhotoNote.prototype.Select = function()
135{
136 //window.status = 'container: ' + this.container;
137 if(!this.container.editing)
138 {
139 this.ShowNoteText();
140 this.dragresize.select(this.gui.ElementRect);
141 this.selected = true;
142 this.SetEditable(true);
143 }
144}
145
146PhotoNote.prototype.UnSelect = function()
147{
148 this.dragresize.deselect(false);
149 this.selected = false;
150 this.SetEditable(false);
151 this.HideNoteText();
152}
153
154PhotoNote.prototype.Save = function()
155{
156 this.oldRect = null;
157 this.gui.TextTitle.innerHTML = this.gui.TextBox.value;
158 this.text = this.gui.TextBox.value
159 this.UnSelect();
160}
161
162PhotoNote.prototype.Cancel = function()
163{
164 //if the note is still new, then we actually want to delete it, not cancel it..
165 if(this.id < 0)
166 {
167 this.container.DeleteNote(this)
168 }
169 else
170 {
171 //reset the node to it's old position
172 if(this.oldRect != null)
173 {
174 this.rect = this.oldRect;
175 }
176 this.oldRect = null;
177 this.gui.TextBox.value = this.text;
178 this.PositionNote();
179 this.UnSelect();
180 }
181}
182
183PhotoNote.prototype.ShowNoteText = function()
184{
185 if(!this.container.editing)
186 {
187 this.container.HideAllNoteTexts();
188 this.container.DisableAllNotes();
189 this.EnableNote();
190
191 this.gui.ElementNote.style.display='block';
192 if(BrowserDetect.browser == 'Explorer')
193 {
194 this.gui.ElementRect.firstChild.filters.alpha.opacity = '85';
195 this.gui.ElementRect.firstChild.firstChild.filters.alpha.opacity = '85';
196 } else {
197 this.gui.ElementRect.firstChild.firstChild.style.opacity = '.85';
198 this.gui.ElementRect.firstChild.style.opacity = '.85';
199 }
200
201 }
202}
203
204PhotoNote.prototype.DisableNote = function ()
205{
206 this.dragresize.enabled=false;
207}
208
209PhotoNote.prototype.EnableNote = function ()
210{
211 this.dragresize.enabled=true;
212}
213
214PhotoNote.prototype.HideNoteText = function ()
215{
216 this.gui.ElementNote.style.display='none';
217 if(BrowserDetect.browser == 'Explorer')
218 {
219 this.gui.ElementRect.firstChild.firstChild.filters.alpha.opacity = '40';
220 this.gui.ElementRect.firstChild.filters.alpha.opacity = '40';
221 } else {
222 this.gui.ElementRect.firstChild.style.opacity = '0.4';
223 this.gui.ElementRect.firstChild.firstChild.style.opacity = '0.4';
224 }
225}
226
227PhotoNote.prototype.HideNote = function ()
228{
229 this.gui.ElementRect.style.display='none';
230 this.gui.ElementNote.style.display='none';
231}
232
233PhotoNote.prototype.ShowNote = function ()
234{
235 this.gui.ElementRect.style.display='block';
236 this.gui.ElementNote.style.display='none';
237}
238
239PhotoNote.prototype.SetEditable = function(editable)
240{
241 this.container.editing = editable;
242
243 if(editable)
244 {
245 //the first child of the note is the text
246 this.gui.TextTitle.style.display = 'none';
247
248 //the second child is the edit area...
249 this.gui.EditArea.style.display = 'block';
250
251 //if this is a "new" note, then hide the delete button
252 if(this.id <= 0)
253 this.gui.DeleteButton.style.display = 'none';
254 else
255 this.gui.DeleteButton.style.display = 'inline';
256
257 // get the textarea and select the text...
258 this.HighlightTextbox();
259 }
260 else
261 {
262 //the first child of the note is the text
263 this.gui.TextTitle.style.display = 'block';
264
265 //the second child is the edit area...
266 this.gui.EditArea.style.display = 'none';
267 }
268}
269
270PhotoNote.prototype.HighlightTextbox = function ()
271{
272 // get the textarea and select the text...
273 if(this.gui.EditArea.style.display=='block')
274 {
275 var textfield = this.gui.TextBox;
276 setTimeout(function() {
277 try
278 {
279 textfield.focus();
280 textfield.select();
281 }
282 catch(e) {}
283 }, 200);
284 }
285
286}
287
288PhotoNote.prototype.CreateElements = function()
289{
290 this.gui = new PhotoNoteGUI();
291
292 var newArea = document.createElement('div');
293 this.dragresize = new DragResize('dragresize', { allowBlur: false });
294 newArea.className = 'fn-area';
295 newArea.id = 'fn-area-new';
296
297 var newAreaBlack = document.createElement('div');
298 newAreaBlack.className = 'fn-area-blackborder';
299 var newAreaWhite = document.createElement('div');
300 newAreaWhite.className = 'fn-area-whiteborder';
301
302 var currentNote = this;
303
304 var newAreaInner = document.createElement('div');
305 newAreaInner.className = 'fn-area-inner';
306 newAreaWhite.appendChild(newAreaInner);
307
308 //attach mouse events to this element...
309 addEvent(newAreaInner, 'mouseover', function() {
310 currentNote.ShowNoteText();
311 });
312 addEvent(newAreaInner, 'mouseout', function() {
313
314 if(!currentNote.selected)
315 {
316 setTimeout(function () {
317 currentNote.HideNoteText();
318 }, 250);
319
320 }
321 });
322
323 addEvent(newAreaInner, 'mousedown', function() {
324 if(!currentNote.selected)
325 {
326 //window.status = 'mouseDown2!';
327 currentNote.Select();
328 }
329 });
330
331 newAreaBlack.appendChild(newAreaWhite);
332 newArea.appendChild(newAreaBlack);
333
334 // add the notes area
335 var noteArea = document.createElement('div');
336 noteArea.className = 'fn-note';
337
338 var titleArea = document.createElement('div');
339 titleArea.className = 'fn-note-text';
340 var t = document.createTextNode(this.text);
341 titleArea.appendChild(t);
342 noteArea.appendChild(titleArea);
343
344 var editArea = document.createElement('div');
345 editArea.className = 'fn-note-edit';
346
347 var editAreaText = document.createElement('div');
348 editAreaText.className = 'fn-note-edit-text';
349
350 var newTextbox = document.createElement('textarea');
351 newTextbox.value = this.text;
352 editAreaText.appendChild(newTextbox);
353 editArea.appendChild(editAreaText);
354
355 var buttonsDiv = document.createElement('div');
356 var newButtonOK = document.createElement('input');
357 newButtonOK.type='button';
358 newButtonOK.className = 'Butt';
359 newButtonOK.value='SAVE';
360 newButtonOK.onclick = function() {
361 if(currentNote.onsave)
362 {
363 var res = currentNote.onsave(currentNote);
364 if(res > 0)
365 {
366 //window.status = '';
367 currentNote.id = res;
368 currentNote.Save();
369 }
370 else
371 {
372 alert("error saving note");
373 currentNote.Cancel();
374 }
375 }
376 else
377 {
378 alert("onsave must be implemented in order to *actually* save");
379 currentNote.Cancel();
380 }
381 };
382 buttonsDiv.appendChild(newButtonOK);
383
384 var newButtonCancel = document.createElement('input');
385 newButtonCancel.type='button';
386 newButtonCancel.className = 'CancelButt';
387 newButtonCancel.value='CANCEL';
388 newButtonCancel.onclick = function() {
389 currentNote.Cancel();
390
391 };
392 buttonsDiv.appendChild(newButtonCancel);
393
394 var newButtonDelete = document.createElement('input');
395 newButtonDelete.type='button';
396 newButtonDelete.className = 'CancelButt';
397 newButtonDelete.value='DELETE';
398 newButtonDelete.onclick = function() {
399
400 if(currentNote.ondelete)
401 {
402 var res = currentNote.ondelete(currentNote);
403 if(res)
404 {
405 currentNote.container.DeleteNote(currentNote);
406 }
407 else
408 {
409 alert("error deleting note");
410 }
411 }
412 else
413 {
414 alert("ondelete must be implemented in order to *actually* delete");
415 }
416 };
417 buttonsDiv.appendChild(newButtonDelete);
418
419 editArea.appendChild(buttonsDiv);
420 noteArea.appendChild(editArea);
421
422 /********* DRAG & RESIZE EVENTS **********************/
423 this.dragresize.isElement = function(elm)
424 {
425 if(elm.className == 'fn-area')
426 {
427 this.maxRight = currentNote.container.element.offsetWidth;
428 this.maxBottom = currentNote.container.element.offsetHeight - 3;
429 return true;
430 }
431 };
432 this.dragresize.isHandle = function(elm)
433 {
434 if(elm.className == 'fn-area')
435 return true;
436 };
437 this.dragresize.ondragfocus = function()
438 {
439 currentNote.gui.ElementRect.style.cursor = 'move';
440 };
441 this.dragresize.ondragblur = function()
442 {
443 currentNote.gui.ElementRect.style.cursor = 'pointer';
444 };
445 this.dragresize.ondragstart = function()
446 {
447 if(currentNote.oldRect == null)
448 {
449 var r = currentNote.rect;
450 currentNote.oldRect = new PhotoNoteRect(r.left,r.top,r.width,r.height);
451 }
452 };
453 this.dragresize.ondragend = function()
454 {
455 //window.status = 'LKSFDLKJDFSLKJFDLKJ';
456 currentNote.HighlightTextbox();
457 };
458 this.dragresize.ondragmove = function()
459 {
460 currentNote.rect.left = parseInt(this.element.style.left);
461 currentNote.rect.top = parseInt(this.element.style.top);
462 currentNote.rect.width = parseInt(this.element.style.width);
463 currentNote.rect.height = parseInt(this.element.style.height);
464 currentNote.PositionNote();
465 };
466
467 this.dragresize.apply(document);
468
469 /* setup the GUI object */
470 this.gui.ElementRect = newArea;
471 this.gui.ElementNote = noteArea;
472 this.gui.EditArea = editArea;
473 this.gui.TextBox = newTextbox;
474 this.gui.TextTitle = titleArea;
475 this.gui.DeleteButton = newButtonDelete;
476
477 /* position the note text below the note area */
478 this.PositionNote();
479}
480
481PhotoNote.prototype.PositionNote = function()
482{
483 /* outer most box */
484 this.gui.ElementRect.style.left = this.rect.left + 'px';
485 this.gui.ElementRect.style.top = this.rect.top + 'px';
486 this.gui.ElementRect.style.width = this.rect.width + 'px';
487 this.gui.ElementRect.style.height = this.rect.height + 'px';
488
489 // black border
490 this.gui.ElementRect.firstChild.style.width = parseInt(this.gui.ElementRect.style.width) - 2 + 'px';
491 this.gui.ElementRect.firstChild.style.height = parseInt(this.gui.ElementRect.style.height) - 2 + 'px';
492
493 // white border
494 this.gui.ElementRect.firstChild.firstChild.style.width = parseInt(this.gui.ElementRect.style.width) - 4 + 'px';
495 this.gui.ElementRect.firstChild.firstChild.style.height = parseInt(this.gui.ElementRect.style.height) - 4 + 'px';
496
497 // inner box
498 this.gui.ElementRect.firstChild.firstChild.firstChild.style.width = parseInt(this.gui.ElementRect.style.width) - 6 + 'px';
499 this.gui.ElementRect.firstChild.firstChild.firstChild.style.height = parseInt(this.gui.ElementRect.style.height) - 6 + 'px';
500
501 this.gui.ElementNote.style.left = this.rect.left + this.XOffset + 'px';
502 this.gui.ElementNote.style.top = this.rect.top + this.YOffset + this.rect.height + 'px';
503
504}
505
506/*********************************************************/
507/*** Photo Note GUI Object *******************************/
508/*********************************************************/
509function PhotoNoteGUI()
510{
511 this.ElementRect = null;
512
513 // the note text area...
514 this.ElementNote = null;
515 this.TextTitle = null;
516 this.EditArea = null;
517 this.TextBox = null;
518
519 // buttons
520 this.DeleteButton = null;
521}
522
523
524
525/*********************************************************/
526/*** Rectangle *******************************************/
527/*********************************************************/
528function PhotoNoteRect(left,top,width,height)
529{
530 this.left = left;
531 this.top = top;
532 this.width = width;
533 this.height = height;
534}
535
536/* for debugging purposes */
537PhotoNoteRect.prototype.toString = function()
538{
539 return 'left: ' + this.left + ', top: ' + this.top + ', width: ' + this.width + ', height: ' + this.height;
540}
541
542
543// *** Common API Code ***
544// (c) 2005 Angus Turnbull http://www.twinhelix.com
545
546var aeOL = [];
547function addEvent(o, n, f, l)
548{
549 var a = 'addEventListener', h = 'on'+n, b = '', s = '';
550 if (o[a] && !l) return o[a](n, f, false);
551 o._c |= 0;
552 if (o[h])
553 {
554 b = '_f' + o._c++;
555 o[b] = o[h];
556 }
557 s = '_f' + o._c++;
558 o[s] = f;
559 o[h] = function(e)
560 {
561 e = e || window.event;
562 var r = true;
563 if (b) r = o[b](e) != false && r;
564 r = o[s](e) != false && r;
565 return r;
566 };
567 aeOL[aeOL.length] = { o: o, h: h };
568};
569addEvent(window, 'unload', function() {
570 for (var i = 0; i < aeOL.length; i++) with (aeOL[i])
571 {
572 o[h] = null;
573 for (var c = 0; o['_f' + c]; c++) o['_f' + c] = null;
574 }
575});
576
577function cancelEvent(e, c)
578{
579 e.returnValue = false;
580 if (e.preventDefault) e.preventDefault();
581 if (c)
582 {
583 e.cancelBubble = true;
584 if (e.stopPropagation) e.stopPropagation();
585 }
586};
587
588function addLoadEvent(func) {
589 var oldonload = window.onload;
590 if (typeof window.onload != 'function') {
591 window.onload = func;
592 } else {
593 window.onload = function() {
594 oldonload();
595 func();
596 }
597 }
598}
599
600
601/* Extend the Array object with some useful features
602 http://www.ditchnet.org/wp/?p=8
603*/
604
605Array.prototype.clear = function () {
606 this.length = 0;
607};
608
609Array.prototype.remove = function (element) {
610 var result = false;
611 var array = [];
612 for (var i = 0; i < this.length; i++) {
613 if (this[i] == element) {
614 result = true;
615 } else {
616 array.push(this[i]);
617 }
618 }
619 this.clear();
620 for (var i = 0; i < array.length; i++) {
621 this.push(array[i]);
622 }
623 array = null;
624 return result;
625};
626
627
628// *** Drag and Resize Library Code ***
629// (c) 2005 Angus Turnbull http://www.twinhelix.come
630
631function DragResize(myName, config)
632{
633 var props = {
634 myName: myName, // Name of the object.
635 enabled: true, // Global toggle of drag/resize.
636 handles: ['tl', 'tm', 'tr',
637 'ml', 'mr', 'bl', 'bm', 'br'], // Array of drag handles: top/mid/.
638 isElement: null, // Function ref to test for an element.
639 isHandle: null, // Function ref to test for move handle.
640 element: null, // The currently selected element.
641 dragging: null, // Active handle reference of the element.
642 minWidth: 10, minHeight: 10, // Minimum pixel size of elements.
643 minLeft: 0, maxRight: 9999, // Bounding box area.
644 minTop: 0, maxBottom: 9999,
645 zIndex: 1, // The highest Z-Index yet allocated.
646 mouseX: 0, mouseY: 0, // Current mouse position, recorded live.
647 lastMouseX: 0, lastMouseY: 0, // Last processed mouse positions.
648 mOffX: 0, mOffY: 0, // A known offset between position & mouse.
649 elmX: 0, elmY: 0, // Element position.
650 elmW: 0, elmH: 0, // Element size.
651 allowBlur: true, // Whether to allow automatic blur onclick.
652 ondragfocus: null, // Event handler functions.
653 ondragstart: null,
654 ondragmove: null,
655 ondragend: null,
656 ondragblur: null
657 };
658
659 for (var p in props)
660 {
661 this[p] = (typeof config[p] == 'undefined') ? props[p] : config[p];
662 }
663};
664
665DragResize.prototype.apply = function(node)
666{
667 // Adds object event handlers to the specified DOM node.
668
669 var obj = this;
670 addEvent(node, 'mousedown', function(e) { obj.mouseDown(e) } );
671 addEvent(node, 'mousemove', function(e) { obj.mouseMove(e) } );
672 addEvent(node, 'mouseup', function(e) { obj.mouseUp(e) } );
673};
674
675DragResize.prototype.handleSet = function(elm, show) { with (this)
676{
677 // Either creates, shows or hides the resize handles within an element.
678
679 // If we're showing them, and no handles have been created, create 4 new ones.
680 if (!elm._handle_tr)
681 {
682 for (var h = 0; h < handles.length; h++)
683 {
684 // Create 4 news divs, assign each a generic + specific class.
685 var hDiv = document.createElement('div');
686 hDiv.className = myName + ' ' + myName + '-' + handles[h];
687 elm['_handle_' + handles[h]] = elm.appendChild(hDiv);
688 }
689 }
690
691 // We now have handles. Find them all and show/hide.
692 for (var h = 0; h < handles.length; h++)
693 {
694 elm['_handle_' + handles[h]].style.visibility = show ? 'inherit' : 'hidden';
695 }
696}};
697
698
699DragResize.prototype.select = function(newElement) { with (this)
700{
701 // Selects an element for dragging.
702
703 if (!document.getElementById || !enabled) return;
704
705 // Activate and record our new dragging element.
706 if (newElement && (newElement != element) && enabled)
707 {
708 element = newElement;
709 // Elevate it and give it resize handles.
710 element.style.zIndex = ++zIndex;
711 handleSet(element, true);
712 // Record element attributes for mouseMove().
713 elmX = parseInt(element.style.left);
714 elmY = parseInt(element.style.top);
715 elmW = element.offsetWidth;
716 elmH = element.offsetHeight;
717 if (ondragfocus) this.ondragfocus();
718 //window.status = 'start elmX=' + element.className;
719
720 }
721}};
722
723
724DragResize.prototype.deselect = function(keepHandles) { with (this)
725{
726 // Immediately stops dragging an element. If 'keepHandles' is false, this
727 // remove the handles from the element and clears the element flag,
728 // completely resetting the .
729
730 if (!document.getElementById || !enabled) return;
731
732 if (!keepHandles)
733 {
734 if (ondragblur) this.ondragblur();
735 handleSet(element, false);
736 element = null;
737 }
738
739 dragging = null;
740 mOffX = 0;
741 mOffY = 0;
742}};
743
744
745DragResize.prototype.mouseDown = function(e) { with (this)
746{
747 //window.status = 'mouseDown!';
748 // Suitable elements are selected for drag/resize on mousedown.
749 // We also initialise the resize boxes, and drag parameters like mouse position etc.
750 if (!document.getElementById || !enabled) return true;
751
752 var elm = e.target || e.srcElement,
753 newElement = null,
754 newHandle = null,
755 hRE = new RegExp(myName + '-([trmbl]{2})', '');
756
757 while (elm)
758 {
759 // Loop up the DOM looking for matching elements. Remember one if found.
760 if (elm.className)
761 {
762 if (!newHandle && (hRE.test(elm.className) || isHandle(elm))) newHandle = elm;
763 if (isElement(elm)) { newElement = elm; break }
764 }
765 elm = elm.parentNode;
766 }
767
768 // If this isn't on the last dragged element, call deselect(false),
769 // which will hide its handles and clear element.
770 if (element && (element != newElement) && allowBlur) deselect(false);
771
772 // If we have a new matching element, call select().
773 if (newElement && (!element || (newElement == element)))
774 {
775 // Stop mouse selections.
776 cancelEvent(e);
777 select(newElement, newHandle);
778 dragging = newHandle;
779 if (dragging && ondragstart) this.ondragstart();
780 }
781}};
782
783
784DragResize.prototype.mouseMove = function(e) { with (this)
785{
786 // This continually offsets the dragged element by the difference between the
787 // last recorded mouse position (mouseX/Y) and the current mouse position.
788 if (!document.getElementById || !enabled) return true;
789
790 // We always record the current mouse position.
791 mouseX = e.pageX || e.clientX + document.documentElement.scrollLeft;
792 mouseY = e.pageY || e.clientY + document.documentElement.scrollTop;
793 // Record the relative mouse movement, in case we're dragging.
794 // Add any previously stored&ignored offset to the calculations.
795 var diffX = mouseX - lastMouseX + mOffX;
796 var diffY = mouseY - lastMouseY + mOffY;
797 mOffX = mOffY = 0;
798 // Update last processed mouse positions.
799 lastMouseX = mouseX;
800 lastMouseY = mouseY;
801
802 // That's all we do if we're not dragging anything.
803 if (!dragging) return true;
804
805 // Establish which handle is being dragged -- retrieve handle name from className.
806 var hClass = dragging && dragging.className &&
807 dragging.className.match(new RegExp(myName + '-([tmblr]{2})')) ? RegExp.$1 : '';
808
809 // If the hClass is one of the resize handles, resize one or two dimensions.
810 // Bounds checking is the hard bit -- basically for each edge, check that the
811 // element doesn't go under minimum size, and doesn't go beyond its boundary.
812 var rs = 0, dY = diffY, dX = diffX;
813 if (hClass.indexOf('t') >= 0)
814 {
815 rs = 1;
816 if (elmH - dY < minHeight) mOffY = (dY - (diffY = elmH - minHeight));
817 else if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
818 elmY += diffY;
819 elmH -= diffY;
820 }
821 if (hClass.indexOf('b') >= 0)
822 {
823 rs = 1;
824 if (elmH + dY < minHeight) mOffY = (dY - (diffY = minHeight - elmH));
825 else if (elmY + elmH + dY > maxBottom) mOffY = (dY - (diffY = maxBottom - elmY - elmH));
826 elmH += diffY;
827 }
828 if (hClass.indexOf('l') >= 0)
829 {
830 rs = 1;
831 if (elmW - dX < minWidth) mOffX = (dX - (diffX = elmW - minWidth));
832 else if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
833 elmX += diffX;
834 elmW -= diffX;
835 }
836 if (hClass.indexOf('r') >= 0)
837 {
838 rs = 1;
839 if (elmW + dX < minWidth) mOffX = (dX - (diffX = minWidth - elmW));
840 else if (elmX + elmW + dX > maxRight) mOffX = (dX - (diffX = maxRight - elmX - elmW));
841 elmW += diffX;
842 window.status = 'diffX:' + diffX;
843 }
844 // If 'rs' isn't set, we must be dragging the whole element, so move that.
845 if (dragging && !rs)
846 {
847 // Bounds check left-right...
848 if (elmX + dX < minLeft) mOffX = (dX - (diffX = minLeft - elmX));
849 else if (elmX + elmW + dX > maxRight) mOffX = (dX - (diffX = maxRight - elmX - elmW));
850 // ...and up-down.
851 if (elmY + dY < minTop) mOffY = (dY - (diffY = minTop - elmY));
852 else if (elmY + elmH + dY > maxBottom) mOffY = (dY - (diffY = maxBottom - elmY - elmH));
853 //window.status = 'diffX-' + diffX + ' , elmX-' + elmX;
854 elmX += diffX;
855 elmY += diffY;
856 }
857
858 //window.status = 'elmX=' + elmX;
859 // Assign new info back to the element, with minimum dimensions.
860 with (element.style)
861 {
862 left = elmX + 'px';
863 width = elmW + 'px';
864 top = elmY + 'px';
865 height = elmH + 'px';
866 }
867
868 // Evil, dirty, hackish Opera select-as-you-drag fix.
869 if (window.opera && document.documentElement)
870 {
871 var oDF = document.getElementById('op-drag-fix');
872 if (!oDF)
873 {
874 var oDF = document.createElement('input');
875 oDF.id = 'op-drag-fix';
876 oDF.style.display = 'none';
877 document.body.appendChild(oDF);
878 }
879 oDF.focus();
880 }
881
882 if (ondragmove) this.ondragmove();
883
884 // Stop a normal drag event.
885 cancelEvent(e);
886}};
887
888
889DragResize.prototype.mouseUp = function(e) { with (this)
890{
891 // On mouseup, stop dragging, but don't reset handler visibility.
892 if (!document.getElementById || !enabled) return;
893
894 if (ondragend) this.ondragend();
895 deselect(true);
896}};
897
898
899
Note: See TracBrowser for help on using the repository browser.