forked from mirrors/gecko-dev
		
	 63227cf68b
			
		
	
	
		63227cf68b
		
	
	
	
	
		
			
			--HG-- rename : browser/components/places/Makefile.in => browser/components/tabview/Makefile.in rename : browser/base/content/tabview/content.js => browser/components/tabview/content.js rename : browser/base/content/tabview/drag.js => browser/components/tabview/drag.js rename : browser/base/content/tabview/groupitems.js => browser/components/tabview/groupitems.js rename : browser/base/content/tabview/iq.js => browser/components/tabview/iq.js rename : browser/base/content/tabview/items.js => browser/components/tabview/items.js rename : browser/base/content/tabview/modules/utils.jsm => browser/components/tabview/modules/utils.jsm rename : browser/base/content/tabview/search.js => browser/components/tabview/search.js rename : browser/base/content/tabview/storage.js => browser/components/tabview/storage.js rename : browser/base/content/tabview/storagePolicy.js => browser/components/tabview/storagePolicy.js rename : browser/base/content/tabview/tabitems.js => browser/components/tabview/tabitems.js rename : browser/base/content/tabview/tabview.css => browser/components/tabview/tabview.css rename : browser/base/content/tabview/tabview.html => browser/components/tabview/tabview.html rename : browser/base/content/tabview/tabview.js => browser/components/tabview/tabview.js rename : browser/base/content/test/tabview/Makefile.in => browser/components/tabview/test/Makefile.in rename : browser/base/content/test/tabview/browser_tabview_alltabs.js => browser/components/tabview/test/browser_tabview_alltabs.js rename : browser/base/content/test/tabview/browser_tabview_apptabs.js => browser/components/tabview/test/browser_tabview_apptabs.js rename : browser/base/content/test/tabview/browser_tabview_bug580412.js => browser/components/tabview/test/browser_tabview_bug580412.js rename : browser/base/content/test/tabview/browser_tabview_bug586553.js => browser/components/tabview/test/browser_tabview_bug586553.js rename : browser/base/content/test/tabview/browser_tabview_bug587043.js => browser/components/tabview/test/browser_tabview_bug587043.js rename : browser/base/content/test/tabview/browser_tabview_bug587231.js => browser/components/tabview/test/browser_tabview_bug587231.js rename : browser/base/content/test/tabview/browser_tabview_bug587276.js => browser/components/tabview/test/browser_tabview_bug587276.js rename : browser/base/content/test/tabview/browser_tabview_bug587351.js => browser/components/tabview/test/browser_tabview_bug587351.js rename : browser/base/content/test/tabview/browser_tabview_bug587503.js => browser/components/tabview/test/browser_tabview_bug587503.js rename : browser/base/content/test/tabview/browser_tabview_bug587990.js => browser/components/tabview/test/browser_tabview_bug587990.js rename : browser/base/content/test/tabview/browser_tabview_bug588265.js => browser/components/tabview/test/browser_tabview_bug588265.js rename : browser/base/content/test/tabview/browser_tabview_bug589324.js => browser/components/tabview/test/browser_tabview_bug589324.js rename : browser/base/content/test/tabview/browser_tabview_bug590606.js => browser/components/tabview/test/browser_tabview_bug590606.js rename : browser/base/content/test/tabview/browser_tabview_bug591706.js => browser/components/tabview/test/browser_tabview_bug591706.js rename : browser/base/content/test/tabview/browser_tabview_bug593283.js => browser/components/tabview/test/browser_tabview_bug593283.js rename : browser/base/content/test/tabview/browser_tabview_bug594958.js => browser/components/tabview/test/browser_tabview_bug594958.js rename : browser/base/content/test/tabview/browser_tabview_bug595191.js => browser/components/tabview/test/browser_tabview_bug595191.js rename : browser/base/content/test/tabview/browser_tabview_bug595436.js => browser/components/tabview/test/browser_tabview_bug595436.js rename : browser/base/content/test/tabview/browser_tabview_bug595518.js => browser/components/tabview/test/browser_tabview_bug595518.js rename : browser/base/content/test/tabview/browser_tabview_bug595521.js => browser/components/tabview/test/browser_tabview_bug595521.js rename : browser/base/content/test/tabview/browser_tabview_bug595560.js => browser/components/tabview/test/browser_tabview_bug595560.js rename : browser/base/content/test/tabview/browser_tabview_bug595601.js => browser/components/tabview/test/browser_tabview_bug595601.js rename : browser/base/content/test/tabview/browser_tabview_bug595804.js => browser/components/tabview/test/browser_tabview_bug595804.js rename : browser/base/content/test/tabview/browser_tabview_bug595930.js => browser/components/tabview/test/browser_tabview_bug595930.js rename : browser/base/content/test/tabview/browser_tabview_bug595943.js => browser/components/tabview/test/browser_tabview_bug595943.js rename : browser/base/content/test/tabview/browser_tabview_bug595965.js => browser/components/tabview/test/browser_tabview_bug595965.js rename : browser/base/content/test/tabview/browser_tabview_bug596781.js => browser/components/tabview/test/browser_tabview_bug596781.js rename : browser/base/content/test/tabview/browser_tabview_bug597248.js => browser/components/tabview/test/browser_tabview_bug597248.js rename : browser/base/content/test/tabview/browser_tabview_bug597360.js => browser/components/tabview/test/browser_tabview_bug597360.js rename : browser/base/content/test/tabview/browser_tabview_bug597399.js => browser/components/tabview/test/browser_tabview_bug597399.js rename : browser/base/content/test/tabview/browser_tabview_bug597980.js => browser/components/tabview/test/browser_tabview_bug597980.js rename : browser/base/content/test/tabview/browser_tabview_bug598375.js => browser/components/tabview/test/browser_tabview_bug598375.js rename : browser/base/content/test/tabview/browser_tabview_bug598600.js => browser/components/tabview/test/browser_tabview_bug598600.js rename : browser/base/content/test/tabview/browser_tabview_bug599048.js => browser/components/tabview/test/browser_tabview_bug599048.js rename : browser/base/content/test/tabview/browser_tabview_bug599626.js => browser/components/tabview/test/browser_tabview_bug599626.js rename : browser/base/content/test/tabview/browser_tabview_bug600645.js => browser/components/tabview/test/browser_tabview_bug600645.js rename : browser/base/content/test/tabview/browser_tabview_bug600812.js => browser/components/tabview/test/browser_tabview_bug600812.js rename : browser/base/content/test/tabview/browser_tabview_bug602432.js => browser/components/tabview/test/browser_tabview_bug602432.js rename : browser/base/content/test/tabview/browser_tabview_bug604098.js => browser/components/tabview/test/browser_tabview_bug604098.js rename : browser/base/content/test/tabview/browser_tabview_bug606657.js => browser/components/tabview/test/browser_tabview_bug606657.js rename : browser/base/content/test/tabview/browser_tabview_bug606905.js => browser/components/tabview/test/browser_tabview_bug606905.js rename : browser/base/content/test/tabview/browser_tabview_bug607108.js => browser/components/tabview/test/browser_tabview_bug607108.js rename : browser/base/content/test/tabview/browser_tabview_bug608037.js => browser/components/tabview/test/browser_tabview_bug608037.js rename : browser/base/content/test/tabview/browser_tabview_bug608158.js => browser/components/tabview/test/browser_tabview_bug608158.js rename : browser/base/content/test/tabview/browser_tabview_bug608184.js => browser/components/tabview/test/browser_tabview_bug608184.js rename : browser/base/content/test/tabview/browser_tabview_bug608405.js => browser/components/tabview/test/browser_tabview_bug608405.js rename : browser/base/content/test/tabview/browser_tabview_bug610208.js => browser/components/tabview/test/browser_tabview_bug610208.js rename : browser/base/content/test/tabview/browser_tabview_bug610242.js => browser/components/tabview/test/browser_tabview_bug610242.js rename : browser/base/content/test/tabview/browser_tabview_bug612470.js => browser/components/tabview/test/browser_tabview_bug612470.js rename : browser/base/content/test/tabview/browser_tabview_bug613541.js => browser/components/tabview/test/browser_tabview_bug613541.js rename : browser/base/content/test/tabview/browser_tabview_bug616729.js => browser/components/tabview/test/browser_tabview_bug616729.js rename : browser/base/content/test/tabview/browser_tabview_bug616967.js => browser/components/tabview/test/browser_tabview_bug616967.js rename : browser/base/content/test/tabview/browser_tabview_bug618816.js => browser/components/tabview/test/browser_tabview_bug618816.js rename : browser/base/content/test/tabview/browser_tabview_bug618828.js => browser/components/tabview/test/browser_tabview_bug618828.js rename : browser/base/content/test/tabview/browser_tabview_bug619937.js => browser/components/tabview/test/browser_tabview_bug619937.js rename : browser/base/content/test/tabview/browser_tabview_bug622835.js => browser/components/tabview/test/browser_tabview_bug622835.js rename : browser/base/content/test/tabview/browser_tabview_bug623768.js => browser/components/tabview/test/browser_tabview_bug623768.js rename : browser/base/content/test/tabview/browser_tabview_bug624265.js => browser/components/tabview/test/browser_tabview_bug624265.js rename : browser/base/content/test/tabview/browser_tabview_bug624692.js => browser/components/tabview/test/browser_tabview_bug624692.js rename : browser/base/content/test/tabview/browser_tabview_bug624727.js => browser/components/tabview/test/browser_tabview_bug624727.js rename : browser/base/content/test/tabview/browser_tabview_bug624847.js => browser/components/tabview/test/browser_tabview_bug624847.js rename : browser/base/content/test/tabview/browser_tabview_bug624931.js => browser/components/tabview/test/browser_tabview_bug624931.js rename : browser/base/content/test/tabview/browser_tabview_bug624953.js => browser/components/tabview/test/browser_tabview_bug624953.js rename : browser/base/content/test/tabview/browser_tabview_bug625195.js => browser/components/tabview/test/browser_tabview_bug625195.js rename : browser/base/content/test/tabview/browser_tabview_bug625269.js => browser/components/tabview/test/browser_tabview_bug625269.js rename : browser/base/content/test/tabview/browser_tabview_bug625424.js => browser/components/tabview/test/browser_tabview_bug625424.js rename : browser/base/content/test/tabview/browser_tabview_bug625955.js => browser/components/tabview/test/browser_tabview_bug625955.js rename : browser/base/content/test/tabview/browser_tabview_bug626368.js => browser/components/tabview/test/browser_tabview_bug626368.js rename : browser/base/content/test/tabview/browser_tabview_bug626455.js => browser/components/tabview/test/browser_tabview_bug626455.js rename : browser/base/content/test/tabview/browser_tabview_bug626525.js => browser/components/tabview/test/browser_tabview_bug626525.js rename : browser/base/content/test/tabview/browser_tabview_bug626791.js => browser/components/tabview/test/browser_tabview_bug626791.js rename : browser/base/content/test/tabview/browser_tabview_bug627288.js => browser/components/tabview/test/browser_tabview_bug627288.js rename : browser/base/content/test/tabview/browser_tabview_bug627736.js => browser/components/tabview/test/browser_tabview_bug627736.js rename : browser/base/content/test/tabview/browser_tabview_bug628061.js => browser/components/tabview/test/browser_tabview_bug628061.js rename : browser/base/content/test/tabview/browser_tabview_bug628165.js => browser/components/tabview/test/browser_tabview_bug628165.js rename : browser/base/content/test/tabview/browser_tabview_bug628270.js => browser/components/tabview/test/browser_tabview_bug628270.js rename : browser/base/content/test/tabview/browser_tabview_bug628887.js => browser/components/tabview/test/browser_tabview_bug628887.js rename : browser/base/content/test/tabview/browser_tabview_bug629189.js => browser/components/tabview/test/browser_tabview_bug629189.js rename : browser/base/content/test/tabview/browser_tabview_bug629195.js => browser/components/tabview/test/browser_tabview_bug629195.js rename : browser/base/content/test/tabview/browser_tabview_bug630102.js => browser/components/tabview/test/browser_tabview_bug630102.js rename : browser/base/content/test/tabview/browser_tabview_bug630157.js => browser/components/tabview/test/browser_tabview_bug630157.js rename : browser/base/content/test/tabview/browser_tabview_bug631662.js => browser/components/tabview/test/browser_tabview_bug631662.js rename : browser/base/content/test/tabview/browser_tabview_bug631752.js => browser/components/tabview/test/browser_tabview_bug631752.js rename : browser/base/content/test/tabview/browser_tabview_bug633190.js => browser/components/tabview/test/browser_tabview_bug633190.js rename : browser/base/content/test/tabview/browser_tabview_bug633788.js => browser/components/tabview/test/browser_tabview_bug633788.js rename : browser/base/content/test/tabview/browser_tabview_bug634077.js => browser/components/tabview/test/browser_tabview_bug634077.js rename : browser/base/content/test/tabview/browser_tabview_bug634085.js => browser/components/tabview/test/browser_tabview_bug634085.js rename : browser/base/content/test/tabview/browser_tabview_bug634672.js => browser/components/tabview/test/browser_tabview_bug634672.js rename : browser/base/content/test/tabview/browser_tabview_bug635696.js => browser/components/tabview/test/browser_tabview_bug635696.js rename : browser/base/content/test/tabview/browser_tabview_bug637840.js => browser/components/tabview/test/browser_tabview_bug637840.js rename : browser/base/content/test/tabview/browser_tabview_bug640765.js => browser/components/tabview/test/browser_tabview_bug640765.js rename : browser/base/content/test/tabview/browser_tabview_bug641802.js => browser/components/tabview/test/browser_tabview_bug641802.js rename : browser/base/content/test/tabview/browser_tabview_bug642793.js => browser/components/tabview/test/browser_tabview_bug642793.js rename : browser/base/content/test/tabview/browser_tabview_bug643392.js => browser/components/tabview/test/browser_tabview_bug643392.js rename : browser/base/content/test/tabview/browser_tabview_bug644097.js => browser/components/tabview/test/browser_tabview_bug644097.js rename : browser/base/content/test/tabview/browser_tabview_bug648882.js => browser/components/tabview/test/browser_tabview_bug648882.js rename : browser/base/content/test/tabview/browser_tabview_bug649006.js => browser/components/tabview/test/browser_tabview_bug649006.js rename : browser/base/content/test/tabview/browser_tabview_bug649307.js => browser/components/tabview/test/browser_tabview_bug649307.js rename : browser/base/content/test/tabview/browser_tabview_bug649319.js => browser/components/tabview/test/browser_tabview_bug649319.js rename : browser/base/content/test/tabview/browser_tabview_bug650280.js => browser/components/tabview/test/browser_tabview_bug650280.js rename : browser/base/content/test/tabview/browser_tabview_bug650573.js => browser/components/tabview/test/browser_tabview_bug650573.js rename : browser/base/content/test/tabview/browser_tabview_bug651311.js => browser/components/tabview/test/browser_tabview_bug651311.js rename : browser/base/content/test/tabview/browser_tabview_bug654295.js => browser/components/tabview/test/browser_tabview_bug654295.js rename : browser/base/content/test/tabview/browser_tabview_bug654721.js => browser/components/tabview/test/browser_tabview_bug654721.js rename : browser/base/content/test/tabview/browser_tabview_bug654941.js => browser/components/tabview/test/browser_tabview_bug654941.js rename : browser/base/content/test/tabview/browser_tabview_bug655269.js => browser/components/tabview/test/browser_tabview_bug655269.js rename : browser/base/content/test/tabview/browser_tabview_bug656778.js => browser/components/tabview/test/browser_tabview_bug656778.js rename : browser/base/content/test/tabview/browser_tabview_bug656913.js => browser/components/tabview/test/browser_tabview_bug656913.js rename : browser/base/content/test/tabview/browser_tabview_bug662266.js => browser/components/tabview/test/browser_tabview_bug662266.js rename : browser/base/content/test/tabview/browser_tabview_bug663421.js => browser/components/tabview/test/browser_tabview_bug663421.js rename : browser/base/content/test/tabview/browser_tabview_bug665502.js => browser/components/tabview/test/browser_tabview_bug665502.js rename : browser/base/content/test/tabview/browser_tabview_bug669694.js => browser/components/tabview/test/browser_tabview_bug669694.js rename : browser/base/content/test/tabview/browser_tabview_bug673196.js => browser/components/tabview/test/browser_tabview_bug673196.js rename : browser/base/content/test/tabview/browser_tabview_bug673729.js => browser/components/tabview/test/browser_tabview_bug673729.js rename : browser/base/content/test/tabview/browser_tabview_bug677310.js => browser/components/tabview/test/browser_tabview_bug677310.js rename : browser/base/content/test/tabview/browser_tabview_bug679853.js => browser/components/tabview/test/browser_tabview_bug679853.js rename : browser/base/content/test/tabview/browser_tabview_bug681599.js => browser/components/tabview/test/browser_tabview_bug681599.js rename : browser/base/content/test/tabview/browser_tabview_bug685476.js => browser/components/tabview/test/browser_tabview_bug685476.js rename : browser/base/content/test/tabview/browser_tabview_bug685692.js => browser/components/tabview/test/browser_tabview_bug685692.js rename : browser/base/content/test/tabview/browser_tabview_bug686654.js => browser/components/tabview/test/browser_tabview_bug686654.js rename : browser/base/content/test/tabview/browser_tabview_click_group.js => browser/components/tabview/test/browser_tabview_click_group.js rename : browser/base/content/test/tabview/browser_tabview_dragdrop.js => browser/components/tabview/test/browser_tabview_dragdrop.js rename : browser/base/content/test/tabview/browser_tabview_exit_button.js => browser/components/tabview/test/browser_tabview_exit_button.js rename : browser/base/content/test/tabview/browser_tabview_expander.js => browser/components/tabview/test/browser_tabview_expander.js rename : browser/base/content/test/tabview/browser_tabview_firstrun_pref.js => browser/components/tabview/test/browser_tabview_firstrun_pref.js rename : browser/base/content/test/tabview/browser_tabview_group.js => browser/components/tabview/test/browser_tabview_group.js rename : browser/base/content/test/tabview/browser_tabview_launch.js => browser/components/tabview/test/browser_tabview_launch.js rename : browser/base/content/test/tabview/browser_tabview_layout.js => browser/components/tabview/test/browser_tabview_layout.js rename : browser/base/content/test/tabview/browser_tabview_multiwindow_search.js => browser/components/tabview/test/browser_tabview_multiwindow_search.js rename : browser/base/content/test/tabview/browser_tabview_privatebrowsing.js => browser/components/tabview/test/browser_tabview_privatebrowsing.js rename : browser/base/content/test/tabview/browser_tabview_rtl.js => browser/components/tabview/test/browser_tabview_rtl.js rename : browser/base/content/test/tabview/browser_tabview_search.js => browser/components/tabview/test/browser_tabview_search.js rename : browser/base/content/test/tabview/browser_tabview_snapping.js => browser/components/tabview/test/browser_tabview_snapping.js rename : browser/base/content/test/tabview/browser_tabview_startup_transitions.js => browser/components/tabview/test/browser_tabview_startup_transitions.js rename : browser/base/content/test/tabview/browser_tabview_storage_policy.js => browser/components/tabview/test/browser_tabview_storage_policy.js rename : browser/base/content/test/tabview/browser_tabview_thumbnail_storage.js => browser/components/tabview/test/browser_tabview_thumbnail_storage.js rename : browser/base/content/test/tabview/browser_tabview_undo_group.js => browser/components/tabview/test/browser_tabview_undo_group.js rename : browser/base/content/test/tabview/dummy_page.html => browser/components/tabview/test/dummy_page.html rename : browser/base/content/test/tabview/head.js => browser/components/tabview/test/head.js rename : browser/base/content/test/tabview/search1.html => browser/components/tabview/test/search1.html rename : browser/base/content/test/tabview/search2.html => browser/components/tabview/test/search2.html rename : browser/base/content/test/tabview/test_bug600645.html => browser/components/tabview/test/test_bug600645.html rename : browser/base/content/test/tabview/test_bug644097.html => browser/components/tabview/test/test_bug644097.html rename : browser/base/content/tabview/thumbnailStorage.js => browser/components/tabview/thumbnailStorage.js rename : browser/base/content/tabview/trench.js => browser/components/tabview/trench.js rename : browser/base/content/tabview/ui.js => browser/components/tabview/ui.js
		
			
				
	
	
		
			1118 lines
		
	
	
	
		
			36 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1118 lines
		
	
	
	
		
			36 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* ***** BEGIN LICENSE BLOCK *****
 | |
|  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 | |
|  *
 | |
|  * The contents of this file are subject to the Mozilla Public License Version
 | |
|  * 1.1 (the "License"); you may not use this file except in compliance with
 | |
|  * the License. You may obtain a copy of the License at
 | |
|  * http://www.mozilla.org/MPL/
 | |
|  *
 | |
|  * Software distributed under the License is distributed on an "AS IS" basis,
 | |
|  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 | |
|  * for the specific language governing rights and limitations under the
 | |
|  * License.
 | |
|  *
 | |
|  * The Original Code is items.js.
 | |
|  *
 | |
|  * The Initial Developer of the Original Code is
 | |
|  * the Mozilla Foundation.
 | |
|  * Portions created by the Initial Developer are Copyright (C) 2010
 | |
|  * the Initial Developer. All Rights Reserved.
 | |
|  *
 | |
|  * Contributor(s):
 | |
|  * Ian Gilman <ian@iangilman.com>
 | |
|  * Aza Raskin <aza@mozilla.com>
 | |
|  * Michael Yoshitaka Erlewine <mitcho@mitcho.com>
 | |
|  * Sean Dunn <seanedunn@yahoo.com>
 | |
|  * Tim Taubert <tim.taubert@gmx.de>
 | |
|  *
 | |
|  * Alternatively, the contents of this file may be used under the terms of
 | |
|  * either the GNU General Public License Version 2 or later (the "GPL"), or
 | |
|  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 | |
|  * in which case the provisions of the GPL or the LGPL are applicable instead
 | |
|  * of those above. If you wish to allow use of your version of this file only
 | |
|  * under the terms of either the GPL or the LGPL, and not to allow others to
 | |
|  * use your version of this file under the terms of the MPL, indicate your
 | |
|  * decision by deleting the provisions above and replace them with the notice
 | |
|  * and other provisions required by the GPL or the LGPL. If you do not delete
 | |
|  * the provisions above, a recipient may use your version of this file under
 | |
|  * the terms of any one of the MPL, the GPL or the LGPL.
 | |
|  *
 | |
|  * ***** END LICENSE BLOCK ***** */
 | |
| 
 | |
| // **********
 | |
| // Title: items.js
 | |
| 
 | |
| // ##########
 | |
| // Class: Item
 | |
| // Superclass for all visible objects (<TabItem>s and <GroupItem>s).
 | |
| //
 | |
| // If you subclass, in addition to the things Item provides, you need to also provide these methods:
 | |
| //   setBounds - function(rect, immediately, options)
 | |
| //   setZ - function(value)
 | |
| //   close - function()
 | |
| //   save - function()
 | |
| //
 | |
| // Subclasses of Item must also provide the <Subscribable> interface.
 | |
| //
 | |
| // ... and this property:
 | |
| //   defaultSize - a Point
 | |
| //
 | |
| // Make sure to call _init() from your subclass's constructor.
 | |
| function Item() {
 | |
|   // Variable: isAnItem
 | |
|   // Always true for Items
 | |
|   this.isAnItem = true;
 | |
| 
 | |
|   // Variable: bounds
 | |
|   // The position and size of this Item, represented as a <Rect>.
 | |
|   // This should never be modified without using setBounds()
 | |
|   this.bounds = null;
 | |
| 
 | |
|   // Variable: zIndex
 | |
|   // The z-index for this item.
 | |
|   this.zIndex = 0;
 | |
| 
 | |
|   // Variable: container
 | |
|   // The outermost DOM element that describes this item on screen.
 | |
|   this.container = null;
 | |
| 
 | |
|   // Variable: parent
 | |
|   // The groupItem that this item is a child of
 | |
|   this.parent = null;
 | |
| 
 | |
|   // Variable: userSize
 | |
|   // A <Point> that describes the last size specifically chosen by the user.
 | |
|   // Used by unsquish.
 | |
|   this.userSize = null;
 | |
| 
 | |
|   // Variable: dragOptions
 | |
|   // Used by <draggable>
 | |
|   //
 | |
|   // Possible properties:
 | |
|   //   cancelClass - A space-delimited list of classes that should cancel a drag
 | |
|   //   start - A function to be called when a drag starts
 | |
|   //   drag - A function to be called each time the mouse moves during drag
 | |
|   //   stop - A function to be called when the drag is done
 | |
|   this.dragOptions = null;
 | |
| 
 | |
|   // Variable: dropOptions
 | |
|   // Used by <draggable> if the item is set to droppable.
 | |
|   //
 | |
|   // Possible properties:
 | |
|   //   accept - A function to determine if a particular item should be accepted for dropping
 | |
|   //   over - A function to be called when an item is over this item
 | |
|   //   out - A function to be called when an item leaves this item
 | |
|   //   drop - A function to be called when an item is dropped in this item
 | |
|   this.dropOptions = null;
 | |
| 
 | |
|   // Variable: resizeOptions
 | |
|   // Used by <resizable>
 | |
|   //
 | |
|   // Possible properties:
 | |
|   //   minWidth - Minimum width allowable during resize
 | |
|   //   minHeight - Minimum height allowable during resize
 | |
|   //   aspectRatio - true if we should respect aspect ratio; default false
 | |
|   //   start - A function to be called when resizing starts
 | |
|   //   resize - A function to be called each time the mouse moves during resize
 | |
|   //   stop - A function to be called when the resize is done
 | |
|   this.resizeOptions = null;
 | |
| 
 | |
|   // Variable: isDragging
 | |
|   // Boolean for whether the item is currently being dragged or not.
 | |
|   this.isDragging = false;
 | |
| };
 | |
| 
 | |
| Item.prototype = {
 | |
|   // ----------
 | |
|   // Function: _init
 | |
|   // Initializes the object. To be called from the subclass's intialization function.
 | |
|   //
 | |
|   // Parameters:
 | |
|   //   container - the outermost DOM element that describes this item onscreen.
 | |
|   _init: function Item__init(container) {
 | |
|     Utils.assert(typeof this.addSubscriber == 'function' && 
 | |
|         typeof this.removeSubscriber == 'function' && 
 | |
|         typeof this._sendToSubscribers == 'function',
 | |
|         'Subclass must implement the Subscribable interface');
 | |
|     Utils.assert(Utils.isDOMElement(container), 'container must be a DOM element');
 | |
|     Utils.assert(typeof this.setBounds == 'function', 'Subclass must provide setBounds');
 | |
|     Utils.assert(typeof this.setZ == 'function', 'Subclass must provide setZ');
 | |
|     Utils.assert(typeof this.close == 'function', 'Subclass must provide close');
 | |
|     Utils.assert(typeof this.save == 'function', 'Subclass must provide save');
 | |
|     Utils.assert(Utils.isPoint(this.defaultSize), 'Subclass must provide defaultSize');
 | |
|     Utils.assert(Utils.isRect(this.bounds), 'Subclass must provide bounds');
 | |
| 
 | |
|     this.container = container;
 | |
|     this.$container = iQ(container);
 | |
| 
 | |
|     iQ(this.container).data('item', this);
 | |
| 
 | |
|     // ___ drag
 | |
|     this.dragOptions = {
 | |
|       cancelClass: 'close stackExpander',
 | |
|       start: function(e, ui) {
 | |
|         UI.setActive(this);
 | |
|         if (this.isAGroupItem)
 | |
|           this._unfreezeItemSize();
 | |
|         // if we start dragging a tab within a group, start with dropSpace on.
 | |
|         else if (this.parent != null)
 | |
|           this.parent._dropSpaceActive = true;
 | |
|         drag.info = new Drag(this, e);
 | |
|       },
 | |
|       drag: function(e) {
 | |
|         drag.info.drag(e);
 | |
|       },
 | |
|       stop: function() {
 | |
|         drag.info.stop();
 | |
| 
 | |
|         if (!this.isAGroupItem && !this.parent) {
 | |
|           new GroupItem([drag.info.$el], {focusTitle: true});
 | |
|           gTabView.firstUseExperienced = true;
 | |
|         }
 | |
| 
 | |
|         drag.info = null;
 | |
|       },
 | |
|       // The minimum the mouse must move after mouseDown in order to move an 
 | |
|       // item
 | |
|       minDragDistance: 3
 | |
|     };
 | |
| 
 | |
|     // ___ drop
 | |
|     this.dropOptions = {
 | |
|       over: function() {},
 | |
|       out: function() {
 | |
|         let groupItem = drag.info.item.parent;
 | |
|         if (groupItem)
 | |
|           groupItem.remove(drag.info.$el, {dontClose: true});
 | |
|         iQ(this.container).removeClass("acceptsDrop");
 | |
|       },
 | |
|       drop: function(event) {
 | |
|         iQ(this.container).removeClass("acceptsDrop");
 | |
|       },
 | |
|       // Function: dropAcceptFunction
 | |
|       // Given a DOM element, returns true if it should accept tabs being dropped on it.
 | |
|       // Private to this file.
 | |
|       accept: function dropAcceptFunction(item) {
 | |
|         return (item && item.isATabItem && (!item.parent || !item.parent.expanded));
 | |
|       }
 | |
|     };
 | |
| 
 | |
|     // ___ resize
 | |
|     var self = this;
 | |
|     this.resizeOptions = {
 | |
|       aspectRatio: self.keepProportional,
 | |
|       minWidth: 90,
 | |
|       minHeight: 90,
 | |
|       start: function(e,ui) {
 | |
|         UI.setActive(this);
 | |
|         resize.info = new Drag(this, e);
 | |
|       },
 | |
|       resize: function(e,ui) {
 | |
|         resize.info.snap(UI.rtl ? 'topright' : 'topleft', false, self.keepProportional);
 | |
|       },
 | |
|       stop: function() {
 | |
|         self.setUserSize();
 | |
|         self.pushAway();
 | |
|         resize.info.stop();
 | |
|         resize.info = null;
 | |
|       }
 | |
|     };
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: getBounds
 | |
|   // Returns a copy of the Item's bounds as a <Rect>.
 | |
|   getBounds: function Item_getBounds() {
 | |
|     Utils.assert(Utils.isRect(this.bounds), 'this.bounds should be a rect');
 | |
|     return new Rect(this.bounds);
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: overlapsWithOtherItems
 | |
|   // Returns true if this Item overlaps with any other Item on the screen.
 | |
|   overlapsWithOtherItems: function Item_overlapsWithOtherItems() {
 | |
|     var self = this;
 | |
|     var items = Items.getTopLevelItems();
 | |
|     var bounds = this.getBounds();
 | |
|     return items.some(function(item) {
 | |
|       if (item == self) // can't overlap with yourself.
 | |
|         return false;
 | |
|       var myBounds = item.getBounds();
 | |
|       return myBounds.intersects(bounds);
 | |
|     } );
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: setPosition
 | |
|   // Moves the Item to the specified location.
 | |
|   //
 | |
|   // Parameters:
 | |
|   //   left - the new left coordinate relative to the window
 | |
|   //   top - the new top coordinate relative to the window
 | |
|   //   immediately - if false or omitted, animates to the new position;
 | |
|   //   otherwise goes there immediately
 | |
|   setPosition: function Item_setPosition(left, top, immediately) {
 | |
|     Utils.assert(Utils.isRect(this.bounds), 'this.bounds');
 | |
|     this.setBounds(new Rect(left, top, this.bounds.width, this.bounds.height), immediately);
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: setSize
 | |
|   // Resizes the Item to the specified size.
 | |
|   //
 | |
|   // Parameters:
 | |
|   //   width - the new width in pixels
 | |
|   //   height - the new height in pixels
 | |
|   //   immediately - if false or omitted, animates to the new size;
 | |
|   //   otherwise resizes immediately
 | |
|   setSize: function Item_setSize(width, height, immediately) {
 | |
|     Utils.assert(Utils.isRect(this.bounds), 'this.bounds');
 | |
|     this.setBounds(new Rect(this.bounds.left, this.bounds.top, width, height), immediately);
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: setUserSize
 | |
|   // Remembers the current size as one the user has chosen.
 | |
|   setUserSize: function Item_setUserSize() {
 | |
|     Utils.assert(Utils.isRect(this.bounds), 'this.bounds');
 | |
|     this.userSize = new Point(this.bounds.width, this.bounds.height);
 | |
|     this.save();
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: getZ
 | |
|   // Returns the zIndex of the Item.
 | |
|   getZ: function Item_getZ() {
 | |
|     return this.zIndex;
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: setRotation
 | |
|   // Rotates the object to the given number of degrees.
 | |
|   setRotation: function Item_setRotation(degrees) {
 | |
|     var value = degrees ? "rotate(%deg)".replace(/%/, degrees) : null;
 | |
|     iQ(this.container).css({"-moz-transform": value});
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: setParent
 | |
|   // Sets the receiver's parent to the given <Item>.
 | |
|   setParent: function Item_setParent(parent) {
 | |
|     this.parent = parent;
 | |
|     this.removeTrenches();
 | |
|     this.save();
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: pushAway
 | |
|   // Pushes all other items away so none overlap this Item.
 | |
|   //
 | |
|   // Parameters:
 | |
|   //  immediately - boolean for doing the pushAway without animation
 | |
|   pushAway: function Item_pushAway(immediately) {
 | |
|     var items = Items.getTopLevelItems();
 | |
| 
 | |
|     // we need at least two top-level items to push something away
 | |
|     if (items.length < 2)
 | |
|       return;
 | |
| 
 | |
|     var buffer = Math.floor(Items.defaultGutter / 2);
 | |
| 
 | |
|     // setup each Item's pushAwayData attribute:
 | |
|     items.forEach(function pushAway_setupPushAwayData(item) {
 | |
|       var data = {};
 | |
|       data.bounds = item.getBounds();
 | |
|       data.startBounds = new Rect(data.bounds);
 | |
|       // Infinity = (as yet) unaffected
 | |
|       data.generation = Infinity;
 | |
|       item.pushAwayData = data;
 | |
|     });
 | |
| 
 | |
|     // The first item is a 0-generation pushed item. It all starts here.
 | |
|     var itemsToPush = [this];
 | |
|     this.pushAwayData.generation = 0;
 | |
| 
 | |
|     var pushOne = function Item_pushAway_pushOne(baseItem) {
 | |
|       // the baseItem is an n-generation pushed item. (n could be 0)
 | |
|       var baseData = baseItem.pushAwayData;
 | |
|       var bb = new Rect(baseData.bounds);
 | |
| 
 | |
|       // make the bounds larger, adding a +buffer margin to each side.
 | |
|       bb.inset(-buffer, -buffer);
 | |
|       // bbc = center of the base's bounds
 | |
|       var bbc = bb.center();
 | |
| 
 | |
|       items.forEach(function Item_pushAway_pushOne_pushEach(item) {
 | |
|         if (item == baseItem)
 | |
|           return;
 | |
| 
 | |
|         var data = item.pushAwayData;
 | |
|         // if the item under consideration has already been pushed, or has a lower
 | |
|         // "generation" (and thus an implictly greater placement priority) then don't move it.
 | |
|         if (data.generation <= baseData.generation)
 | |
|           return;
 | |
| 
 | |
|         // box = this item's current bounds, with a +buffer margin.
 | |
|         var bounds = data.bounds;
 | |
|         var box = new Rect(bounds);
 | |
|         box.inset(-buffer, -buffer);
 | |
| 
 | |
|         // if the item under consideration overlaps with the base item...
 | |
|         if (box.intersects(bb)) {
 | |
| 
 | |
|           // Let's push it a little.
 | |
| 
 | |
|           // First, decide in which direction and how far to push. This is the offset.
 | |
|           var offset = new Point();
 | |
|           // center = the current item's center.
 | |
|           var center = box.center();
 | |
| 
 | |
|           // Consider the relationship between the current item (box) + the base item.
 | |
|           // If it's more vertically stacked than "side by side"...
 | |
|           if (Math.abs(center.x - bbc.x) < Math.abs(center.y - bbc.y)) {
 | |
|             // push vertically.
 | |
|             if (center.y > bbc.y)
 | |
|               offset.y = bb.bottom - box.top;
 | |
|             else
 | |
|               offset.y = bb.top - box.bottom;
 | |
|           } else { // if they're more "side by side" than stacked vertically...
 | |
|             // push horizontally.
 | |
|             if (center.x > bbc.x)
 | |
|               offset.x = bb.right - box.left;
 | |
|             else
 | |
|               offset.x = bb.left - box.right;
 | |
|           }
 | |
| 
 | |
|           // Actually push the Item.
 | |
|           bounds.offset(offset);
 | |
| 
 | |
|           // This item now becomes an (n+1)-generation pushed item.
 | |
|           data.generation = baseData.generation + 1;
 | |
|           // keep track of who pushed this item.
 | |
|           data.pusher = baseItem;
 | |
|           // add this item to the queue, so that it, in turn, can push some other things.
 | |
|           itemsToPush.push(item);
 | |
|         }
 | |
|       });
 | |
|     };
 | |
| 
 | |
|     // push each of the itemsToPush, one at a time.
 | |
|     // itemsToPush starts with just [this], but pushOne can add more items to the stack.
 | |
|     // Maximally, this could run through all Items on the screen.
 | |
|     while (itemsToPush.length)
 | |
|       pushOne(itemsToPush.shift());
 | |
| 
 | |
|     // ___ Squish!
 | |
|     var pageBounds = Items.getSafeWindowBounds();
 | |
|     items.forEach(function Item_pushAway_squish(item) {
 | |
|       var data = item.pushAwayData;
 | |
|       if (data.generation == 0)
 | |
|         return;
 | |
| 
 | |
|       let apply = function Item_pushAway_squish_apply(item, posStep, posStep2, sizeStep) {
 | |
|         var data = item.pushAwayData;
 | |
|         if (data.generation == 0)
 | |
|           return;
 | |
| 
 | |
|         var bounds = data.bounds;
 | |
|         bounds.width -= sizeStep.x;
 | |
|         bounds.height -= sizeStep.y;
 | |
|         bounds.left += posStep.x;
 | |
|         bounds.top += posStep.y;
 | |
| 
 | |
|         let validSize;
 | |
|         if (item.isAGroupItem) {
 | |
|           validSize = GroupItems.calcValidSize(
 | |
|             new Point(bounds.width, bounds.height));
 | |
|           bounds.width = validSize.x;
 | |
|           bounds.height = validSize.y;
 | |
|         } else {
 | |
|           if (sizeStep.y > sizeStep.x) {
 | |
|             validSize = TabItems.calcValidSize(new Point(-1, bounds.height));
 | |
|             bounds.left += (bounds.width - validSize.x) / 2;
 | |
|             bounds.width = validSize.x;
 | |
|           } else {
 | |
|             validSize = TabItems.calcValidSize(new Point(bounds.width, -1));
 | |
|             bounds.top += (bounds.height - validSize.y) / 2;
 | |
|             bounds.height = validSize.y;        
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         var pusher = data.pusher;
 | |
|         if (pusher) {
 | |
|           var newPosStep = new Point(posStep.x + posStep2.x, posStep.y + posStep2.y);
 | |
|           apply(pusher, newPosStep, posStep2, sizeStep);
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       var bounds = data.bounds;
 | |
|       var posStep = new Point();
 | |
|       var posStep2 = new Point();
 | |
|       var sizeStep = new Point();
 | |
| 
 | |
|       if (bounds.left < pageBounds.left) {
 | |
|         posStep.x = pageBounds.left - bounds.left;
 | |
|         sizeStep.x = posStep.x / data.generation;
 | |
|         posStep2.x = -sizeStep.x;
 | |
|       } else if (bounds.right > pageBounds.right) { // this may be less of a problem post-601534
 | |
|         posStep.x = pageBounds.right - bounds.right;
 | |
|         sizeStep.x = -posStep.x / data.generation;
 | |
|         posStep.x += sizeStep.x;
 | |
|         posStep2.x = sizeStep.x;
 | |
|       }
 | |
| 
 | |
|       if (bounds.top < pageBounds.top) {
 | |
|         posStep.y = pageBounds.top - bounds.top;
 | |
|         sizeStep.y = posStep.y / data.generation;
 | |
|         posStep2.y = -sizeStep.y;
 | |
|       } else if (bounds.bottom > pageBounds.bottom) { // this may be less of a problem post-601534
 | |
|         posStep.y = pageBounds.bottom - bounds.bottom;
 | |
|         sizeStep.y = -posStep.y / data.generation;
 | |
|         posStep.y += sizeStep.y;
 | |
|         posStep2.y = sizeStep.y;
 | |
|       }
 | |
| 
 | |
|       if (posStep.x || posStep.y || sizeStep.x || sizeStep.y)
 | |
|         apply(item, posStep, posStep2, sizeStep);        
 | |
|     });
 | |
| 
 | |
|     // ___ Unsquish
 | |
|     var pairs = [];
 | |
|     items.forEach(function Item_pushAway_setupUnsquish(item) {
 | |
|       var data = item.pushAwayData;
 | |
|       pairs.push({
 | |
|         item: item,
 | |
|         bounds: data.bounds
 | |
|       });
 | |
|     });
 | |
| 
 | |
|     Items.unsquish(pairs);
 | |
| 
 | |
|     // ___ Apply changes
 | |
|     items.forEach(function Item_pushAway_setBounds(item) {
 | |
|       var data = item.pushAwayData;
 | |
|       var bounds = data.bounds;
 | |
|       if (!bounds.equals(data.startBounds)) {
 | |
|         item.setBounds(bounds, immediately);
 | |
|       }
 | |
|     });
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: setTrenches
 | |
|   // Sets up/moves the trenches for snapping to this item.
 | |
|   setTrenches: function Item_setTrenches(rect) {
 | |
|     if (this.parent !== null)
 | |
|       return;
 | |
| 
 | |
|     if (!this.borderTrenches)
 | |
|       this.borderTrenches = Trenches.registerWithItem(this,"border");
 | |
| 
 | |
|     var bT = this.borderTrenches;
 | |
|     Trenches.getById(bT.left).setWithRect(rect);
 | |
|     Trenches.getById(bT.right).setWithRect(rect);
 | |
|     Trenches.getById(bT.top).setWithRect(rect);
 | |
|     Trenches.getById(bT.bottom).setWithRect(rect);
 | |
| 
 | |
|     if (!this.guideTrenches)
 | |
|       this.guideTrenches = Trenches.registerWithItem(this,"guide");
 | |
| 
 | |
|     var gT = this.guideTrenches;
 | |
|     Trenches.getById(gT.left).setWithRect(rect);
 | |
|     Trenches.getById(gT.right).setWithRect(rect);
 | |
|     Trenches.getById(gT.top).setWithRect(rect);
 | |
|     Trenches.getById(gT.bottom).setWithRect(rect);
 | |
| 
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: removeTrenches
 | |
|   // Removes the trenches for snapping to this item.
 | |
|   removeTrenches: function Item_removeTrenches() {
 | |
|     for (var edge in this.borderTrenches) {
 | |
|       Trenches.unregister(this.borderTrenches[edge]); // unregister can take an array
 | |
|     }
 | |
|     this.borderTrenches = null;
 | |
|     for (var edge in this.guideTrenches) {
 | |
|       Trenches.unregister(this.guideTrenches[edge]); // unregister can take an array
 | |
|     }
 | |
|     this.guideTrenches = null;
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: snap
 | |
|   // The snap function used during groupItem creation via drag-out
 | |
|   //
 | |
|   // Parameters:
 | |
|   //  immediately - bool for having the drag do the final positioning without animation
 | |
|   snap: function Item_snap(immediately) {
 | |
|     // make the snapping work with a wider range!
 | |
|     var defaultRadius = Trenches.defaultRadius;
 | |
|     Trenches.defaultRadius = 2 * defaultRadius; // bump up from 10 to 20!
 | |
| 
 | |
|     var FauxDragInfo = new Drag(this, {});
 | |
|     FauxDragInfo.snap('none', false);
 | |
|     FauxDragInfo.stop(immediately);
 | |
| 
 | |
|     Trenches.defaultRadius = defaultRadius;
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: draggable
 | |
|   // Enables dragging on this item. Note: not to be called multiple times on the same item!
 | |
|   draggable: function Item_draggable() {
 | |
|     try {
 | |
|       Utils.assert(this.dragOptions, 'dragOptions');
 | |
| 
 | |
|       var cancelClasses = [];
 | |
|       if (typeof this.dragOptions.cancelClass == 'string')
 | |
|         cancelClasses = this.dragOptions.cancelClass.split(' ');
 | |
| 
 | |
|       var self = this;
 | |
|       var $container = iQ(this.container);
 | |
|       var startMouse;
 | |
|       var startPos;
 | |
|       var startSent;
 | |
|       var startEvent;
 | |
|       var droppables;
 | |
|       var dropTarget;
 | |
| 
 | |
|       // determine the best drop target based on the current mouse coordinates
 | |
|       let determineBestDropTarget = function (e, box) {
 | |
|         // drop events
 | |
|         var best = {
 | |
|           dropTarget: null,
 | |
|           score: 0
 | |
|         };
 | |
| 
 | |
|         droppables.forEach(function(droppable) {
 | |
|           var intersection = box.intersection(droppable.bounds);
 | |
|           if (intersection && intersection.area() > best.score) {
 | |
|             var possibleDropTarget = droppable.item;
 | |
|             var accept = true;
 | |
|             if (possibleDropTarget != dropTarget) {
 | |
|               var dropOptions = possibleDropTarget.dropOptions;
 | |
|               if (dropOptions && typeof dropOptions.accept == "function")
 | |
|                 accept = dropOptions.accept.apply(possibleDropTarget, [self]);
 | |
|             }
 | |
| 
 | |
|             if (accept) {
 | |
|               best.dropTarget = possibleDropTarget;
 | |
|               best.score = intersection.area();
 | |
|             }
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         return best.dropTarget;
 | |
|       }
 | |
| 
 | |
|       // ___ mousemove
 | |
|       var handleMouseMove = function(e) {
 | |
|         // global drag tracking
 | |
|         drag.lastMoveTime = Date.now();
 | |
| 
 | |
|         // positioning
 | |
|         var mouse = new Point(e.pageX, e.pageY);
 | |
|         if (!startSent) {
 | |
|           if(Math.abs(mouse.x - startMouse.x) > self.dragOptions.minDragDistance ||
 | |
|              Math.abs(mouse.y - startMouse.y) > self.dragOptions.minDragDistance) {
 | |
|             if (typeof self.dragOptions.start == "function")
 | |
|               self.dragOptions.start.apply(self,
 | |
|                   [startEvent, {position: {left: startPos.x, top: startPos.y}}]);
 | |
|             startSent = true;
 | |
|           }
 | |
|         }
 | |
|         if (startSent) {
 | |
|           // drag events
 | |
|           var box = self.getBounds();
 | |
|           box.left = startPos.x + (mouse.x - startMouse.x);
 | |
|           box.top = startPos.y + (mouse.y - startMouse.y);
 | |
|           self.setBounds(box, true);
 | |
| 
 | |
|           if (typeof self.dragOptions.drag == "function")
 | |
|             self.dragOptions.drag.apply(self, [e]);
 | |
| 
 | |
|           let bestDropTarget = determineBestDropTarget(e, box);
 | |
| 
 | |
|           if (bestDropTarget != dropTarget) {
 | |
|             var dropOptions;
 | |
|             if (dropTarget) {
 | |
|               dropOptions = dropTarget.dropOptions;
 | |
|               if (dropOptions && typeof dropOptions.out == "function")
 | |
|                 dropOptions.out.apply(dropTarget, [e]);
 | |
|             }
 | |
| 
 | |
|             dropTarget = bestDropTarget;
 | |
| 
 | |
|             if (dropTarget) {
 | |
|               dropOptions = dropTarget.dropOptions;
 | |
|               if (dropOptions && typeof dropOptions.over == "function")
 | |
|                 dropOptions.over.apply(dropTarget, [e]);
 | |
|             }
 | |
|           }
 | |
|           if (dropTarget) {
 | |
|             dropOptions = dropTarget.dropOptions;
 | |
|             if (dropOptions && typeof dropOptions.move == "function")
 | |
|               dropOptions.move.apply(dropTarget, [e]);
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         e.preventDefault();
 | |
|       };
 | |
| 
 | |
|       // ___ mouseup
 | |
|       var handleMouseUp = function(e) {
 | |
|         iQ(gWindow)
 | |
|           .unbind('mousemove', handleMouseMove)
 | |
|           .unbind('mouseup', handleMouseUp);
 | |
| 
 | |
|         if (startSent && dropTarget) {
 | |
|           var dropOptions = dropTarget.dropOptions;
 | |
|           if (dropOptions && typeof dropOptions.drop == "function")
 | |
|             dropOptions.drop.apply(dropTarget, [e]);
 | |
|         }
 | |
| 
 | |
|         if (startSent && typeof self.dragOptions.stop == "function")
 | |
|           self.dragOptions.stop.apply(self, [e]);
 | |
| 
 | |
|         e.preventDefault();
 | |
|       };
 | |
| 
 | |
|       // ___ mousedown
 | |
|       $container.mousedown(function(e) {
 | |
|         if (!Utils.isLeftClick(e))
 | |
|           return;
 | |
| 
 | |
|         var cancel = false;
 | |
|         var $target = iQ(e.target);
 | |
|         cancelClasses.forEach(function(className) {
 | |
|           if ($target.hasClass(className))
 | |
|             cancel = true;
 | |
|         });
 | |
| 
 | |
|         if (cancel) {
 | |
|           e.preventDefault();
 | |
|           return;
 | |
|         }
 | |
| 
 | |
|         startMouse = new Point(e.pageX, e.pageY);
 | |
|         let bounds = self.getBounds();
 | |
|         startPos = bounds.position();
 | |
|         startEvent = e;
 | |
|         startSent = false;
 | |
| 
 | |
|         droppables = [];
 | |
|         iQ('.iq-droppable').each(function(elem) {
 | |
|           if (elem != self.container) {
 | |
|             var item = Items.item(elem);
 | |
|             droppables.push({
 | |
|               item: item,
 | |
|               bounds: item.getBounds()
 | |
|             });
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         dropTarget = determineBestDropTarget(e, bounds);
 | |
| 
 | |
|         iQ(gWindow)
 | |
|           .mousemove(handleMouseMove)
 | |
|           .mouseup(handleMouseUp);
 | |
| 
 | |
|         e.preventDefault();
 | |
|       });
 | |
|     } catch(e) {
 | |
|       Utils.log(e);
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: droppable
 | |
|   // Enables or disables dropping on this item.
 | |
|   droppable: function Item_droppable(value) {
 | |
|     try {
 | |
|       var $container = iQ(this.container);
 | |
|       if (value) {
 | |
|         Utils.assert(this.dropOptions, 'dropOptions');
 | |
|         $container.addClass('iq-droppable');
 | |
|       } else
 | |
|         $container.removeClass('iq-droppable');
 | |
|     } catch(e) {
 | |
|       Utils.log(e);
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: resizable
 | |
|   // Enables or disables resizing of this item.
 | |
|   resizable: function Item_resizable(value) {
 | |
|     try {
 | |
|       var $container = iQ(this.container);
 | |
|       iQ('.iq-resizable-handle', $container).remove();
 | |
| 
 | |
|       if (!value) {
 | |
|         $container.removeClass('iq-resizable');
 | |
|       } else {
 | |
|         Utils.assert(this.resizeOptions, 'resizeOptions');
 | |
| 
 | |
|         $container.addClass('iq-resizable');
 | |
| 
 | |
|         var self = this;
 | |
|         var startMouse;
 | |
|         var startSize;
 | |
|         var startAspect;
 | |
| 
 | |
|         // ___ mousemove
 | |
|         var handleMouseMove = function(e) {
 | |
|           // global resize tracking
 | |
|           resize.lastMoveTime = Date.now();
 | |
| 
 | |
|           var mouse = new Point(e.pageX, e.pageY);
 | |
|           var box = self.getBounds();
 | |
|           if (UI.rtl) {
 | |
|             var minWidth = (self.resizeOptions.minWidth || 0);
 | |
|             var oldWidth = box.width;
 | |
|             if (minWidth != oldWidth || mouse.x < startMouse.x) {
 | |
|               box.width = Math.max(minWidth, startSize.x - (mouse.x - startMouse.x));
 | |
|               box.left -= box.width - oldWidth;
 | |
|             }
 | |
|           } else {
 | |
|             box.width = Math.max(self.resizeOptions.minWidth || 0, startSize.x + (mouse.x - startMouse.x));
 | |
|           }
 | |
|           box.height = Math.max(self.resizeOptions.minHeight || 0, startSize.y + (mouse.y - startMouse.y));
 | |
| 
 | |
|           if (self.resizeOptions.aspectRatio) {
 | |
|             if (startAspect < 1)
 | |
|               box.height = box.width * startAspect;
 | |
|             else
 | |
|               box.width = box.height / startAspect;
 | |
|           }
 | |
| 
 | |
|           self.setBounds(box, true);
 | |
| 
 | |
|           if (typeof self.resizeOptions.resize == "function")
 | |
|             self.resizeOptions.resize.apply(self, [e]);
 | |
| 
 | |
|           e.preventDefault();
 | |
|           e.stopPropagation();
 | |
|         };
 | |
| 
 | |
|         // ___ mouseup
 | |
|         var handleMouseUp = function(e) {
 | |
|           iQ(gWindow)
 | |
|             .unbind('mousemove', handleMouseMove)
 | |
|             .unbind('mouseup', handleMouseUp);
 | |
| 
 | |
|           if (typeof self.resizeOptions.stop == "function")
 | |
|             self.resizeOptions.stop.apply(self, [e]);
 | |
| 
 | |
|           e.preventDefault();
 | |
|           e.stopPropagation();
 | |
|         };
 | |
| 
 | |
|         // ___ handle + mousedown
 | |
|         iQ('<div>')
 | |
|           .addClass('iq-resizable-handle iq-resizable-se')
 | |
|           .appendTo($container)
 | |
|           .mousedown(function(e) {
 | |
|             if (!Utils.isLeftClick(e))
 | |
|               return;
 | |
| 
 | |
|             startMouse = new Point(e.pageX, e.pageY);
 | |
|             startSize = self.getBounds().size();
 | |
|             startAspect = startSize.y / startSize.x;
 | |
| 
 | |
|             if (typeof self.resizeOptions.start == "function")
 | |
|               self.resizeOptions.start.apply(self, [e]);
 | |
| 
 | |
|             iQ(gWindow)
 | |
|               .mousemove(handleMouseMove)
 | |
|               .mouseup(handleMouseUp);
 | |
| 
 | |
|             e.preventDefault();
 | |
|             e.stopPropagation();
 | |
|           });
 | |
|         }
 | |
|     } catch(e) {
 | |
|       Utils.log(e);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| // ##########
 | |
| // Class: Items
 | |
| // Keeps track of all Items.
 | |
| let Items = {
 | |
|   // ----------
 | |
|   // Function: toString
 | |
|   // Prints [Items] for debug use
 | |
|   toString: function Items_toString() {
 | |
|     return "[Items]";
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Variable: defaultGutter
 | |
|   // How far apart Items should be from each other and from bounds
 | |
|   defaultGutter: 15,
 | |
| 
 | |
|   // ----------
 | |
|   // Function: item
 | |
|   // Given a DOM element representing an Item, returns the Item.
 | |
|   item: function Items_item(el) {
 | |
|     return iQ(el).data('item');
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: getTopLevelItems
 | |
|   // Returns an array of all Items not grouped into groupItems.
 | |
|   getTopLevelItems: function Items_getTopLevelItems() {
 | |
|     var items = [];
 | |
| 
 | |
|     iQ('.tab, .groupItem').each(function(elem) {
 | |
|       var $this = iQ(elem);
 | |
|       var item = $this.data('item');
 | |
|       if (item && !item.parent && !$this.hasClass('phantom'))
 | |
|         items.push(item);
 | |
|     });
 | |
| 
 | |
|     return items;
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: getPageBounds
 | |
|   // Returns a <Rect> defining the area of the page <Item>s should stay within.
 | |
|   getPageBounds: function Items_getPageBounds() {
 | |
|     var width = Math.max(100, window.innerWidth);
 | |
|     var height = Math.max(100, window.innerHeight);
 | |
|     return new Rect(0, 0, width, height);
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: getSafeWindowBounds
 | |
|   // Returns the bounds within which it is safe to place all non-stationary <Item>s.
 | |
|   getSafeWindowBounds: function Items_getSafeWindowBounds() {
 | |
|     // the safe bounds that would keep it "in the window"
 | |
|     var gutter = Items.defaultGutter;
 | |
|     // Here, I've set the top gutter separately, as the top of the window has its own
 | |
|     // extra chrome which makes a large top gutter unnecessary.
 | |
|     // TODO: set top gutter separately, elsewhere.
 | |
|     var topGutter = 5;
 | |
|     return new Rect(gutter, topGutter,
 | |
|         window.innerWidth - 2 * gutter, window.innerHeight - gutter - topGutter);
 | |
| 
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: arrange
 | |
|   // Arranges the given items in a grid within the given bounds,
 | |
|   // maximizing item size but maintaining standard tab aspect ratio for each
 | |
|   //
 | |
|   // Parameters:
 | |
|   //   items - an array of <Item>s. Can be null, in which case we won't
 | |
|   //     actually move anything.
 | |
|   //   bounds - a <Rect> defining the space to arrange within
 | |
|   //   options - an object with various properites (see below)
 | |
|   //
 | |
|   // Possible "options" properties:
 | |
|   //   animate - whether to animate; default: true.
 | |
|   //   z - the z index to set all the items; default: don't change z.
 | |
|   //   return - if set to 'widthAndColumns', it'll return an object with the
 | |
|   //     width of children and the columns.
 | |
|   //   count - overrides the item count for layout purposes;
 | |
|   //     default: the actual item count
 | |
|   //   columns - (int) a preset number of columns to use
 | |
|   //   dropPos - a <Point> which should have a one-tab space left open, used
 | |
|   //             when a tab is dragged over.
 | |
|   //
 | |
|   // Returns:
 | |
|   //   By default, an object with three properties: `rects`, the list of <Rect>s,
 | |
|   //   `dropIndex`, the index which a dragged tab should have if dropped
 | |
|   //   (null if no `dropPos` was specified), and the number of columns (`columns`).
 | |
|   //   If the `return` option is set to 'widthAndColumns', an object with the
 | |
|   //   width value of the child items (`childWidth`) and the number of columns
 | |
|   //   (`columns`) is returned.
 | |
|   arrange: function Items_arrange(items, bounds, options) {
 | |
|     if (!options)
 | |
|       options = {};
 | |
|     var animate = "animate" in options ? options.animate : true;
 | |
|     var immediately = !animate;
 | |
| 
 | |
|     var rects = [];
 | |
| 
 | |
|     var count = options.count || (items ? items.length : 0);
 | |
|     if (options.addTab)
 | |
|       count++;
 | |
|     if (!count) {
 | |
|       let dropIndex = (Utils.isPoint(options.dropPos)) ? 0 : null;
 | |
|       return {rects: rects, dropIndex: dropIndex};
 | |
|     }
 | |
| 
 | |
|     var columns = options.columns || 1;
 | |
|     // We'll assume for the time being that all the items have the same styling
 | |
|     // and that the margin is the same width around.
 | |
|     var itemMargin = items && items.length ?
 | |
|                        parseInt(iQ(items[0].container).css('margin-left')) : 0;
 | |
|     var padding = itemMargin * 2;
 | |
|     var rows;
 | |
|     var tabWidth;
 | |
|     var tabHeight;
 | |
|     var totalHeight;
 | |
| 
 | |
|     function figure() {
 | |
|       rows = Math.ceil(count / columns);
 | |
|       let validSize = TabItems.calcValidSize(
 | |
|         new Point((bounds.width - (padding * columns)) / columns, -1),
 | |
|         options);
 | |
|       tabWidth = validSize.x;
 | |
|       tabHeight = validSize.y;
 | |
| 
 | |
|       totalHeight = (tabHeight * rows) + (padding * rows);    
 | |
|     }
 | |
| 
 | |
|     figure();
 | |
| 
 | |
|     while (rows > 1 && totalHeight > bounds.height) {
 | |
|       columns++;
 | |
|       figure();
 | |
|     }
 | |
| 
 | |
|     if (rows == 1) {
 | |
|       let validSize = TabItems.calcValidSize(new Point(tabWidth,
 | |
|         bounds.height - 2 * itemMargin), options);
 | |
|       tabWidth = validSize.x;
 | |
|       tabHeight = validSize.y;
 | |
|     }
 | |
|     
 | |
|     if (options.return == 'widthAndColumns')
 | |
|       return {childWidth: tabWidth, columns: columns};
 | |
| 
 | |
|     let initialOffset = 0;
 | |
|     if (UI.rtl) {
 | |
|       initialOffset = bounds.width - tabWidth - padding;
 | |
|     }
 | |
|     var box = new Rect(bounds.left + initialOffset, bounds.top, tabWidth, tabHeight);
 | |
| 
 | |
|     var column = 0;
 | |
| 
 | |
|     var dropIndex = false;
 | |
|     var dropRect = false;
 | |
|     if (Utils.isPoint(options.dropPos))
 | |
|       dropRect = new Rect(options.dropPos.x, options.dropPos.y, 1, 1);
 | |
|     for (let a = 0; a < count; a++) {
 | |
|       // If we had a dropPos, see if this is where we should place it
 | |
|       if (dropRect) {
 | |
|         let activeBox = new Rect(box);
 | |
|         activeBox.inset(-itemMargin - 1, -itemMargin - 1);
 | |
|         // if the designated position (dropRect) is within the active box,
 | |
|         // this is where, if we drop the tab being dragged, it should land!
 | |
|         if (activeBox.contains(dropRect))
 | |
|           dropIndex = a;
 | |
|       }
 | |
|       
 | |
|       // record the box.
 | |
|       rects.push(new Rect(box));
 | |
| 
 | |
|       box.left += (UI.rtl ? -1 : 1) * (box.width + padding);
 | |
|       column++;
 | |
|       if (column == columns) {
 | |
|         box.left = bounds.left + initialOffset;
 | |
|         box.top += box.height + padding;
 | |
|         column = 0;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return {rects: rects, dropIndex: dropIndex, columns: columns};
 | |
|   },
 | |
| 
 | |
|   // ----------
 | |
|   // Function: unsquish
 | |
|   // Checks to see which items can now be unsquished.
 | |
|   //
 | |
|   // Parameters:
 | |
|   //   pairs - an array of objects, each with two properties: item and bounds. The bounds are
 | |
|   //     modified as appropriate, but the items are not changed. If pairs is null, the
 | |
|   //     operation is performed directly on all of the top level items.
 | |
|   //   ignore - an <Item> to not include in calculations (because it's about to be closed, for instance)
 | |
|   unsquish: function Items_unsquish(pairs, ignore) {
 | |
|     var pairsProvided = (pairs ? true : false);
 | |
|     if (!pairsProvided) {
 | |
|       var items = Items.getTopLevelItems();
 | |
|       pairs = [];
 | |
|       items.forEach(function(item) {
 | |
|         pairs.push({
 | |
|           item: item,
 | |
|           bounds: item.getBounds()
 | |
|         });
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     var pageBounds = Items.getSafeWindowBounds();
 | |
|     pairs.forEach(function(pair) {
 | |
|       var item = pair.item;
 | |
|       if (item == ignore)
 | |
|         return;
 | |
| 
 | |
|       var bounds = pair.bounds;
 | |
|       var newBounds = new Rect(bounds);
 | |
| 
 | |
|       var newSize;
 | |
|       if (Utils.isPoint(item.userSize))
 | |
|         newSize = new Point(item.userSize);
 | |
|       else if (item.isAGroupItem)
 | |
|         newSize = GroupItems.calcValidSize(
 | |
|           new Point(GroupItems.minGroupWidth, -1));
 | |
|       else
 | |
|         newSize = TabItems.calcValidSize(
 | |
|           new Point(TabItems.tabWidth, -1));
 | |
| 
 | |
|       if (item.isAGroupItem) {
 | |
|           newBounds.width = Math.max(newBounds.width, newSize.x);
 | |
|           newBounds.height = Math.max(newBounds.height, newSize.y);
 | |
|       } else {
 | |
|         if (bounds.width < newSize.x) {
 | |
|           newBounds.width = newSize.x;
 | |
|           newBounds.height = newSize.y;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       newBounds.left -= (newBounds.width - bounds.width) / 2;
 | |
|       newBounds.top -= (newBounds.height - bounds.height) / 2;
 | |
| 
 | |
|       var offset = new Point();
 | |
|       if (newBounds.left < pageBounds.left)
 | |
|         offset.x = pageBounds.left - newBounds.left;
 | |
|       else if (newBounds.right > pageBounds.right)
 | |
|         offset.x = pageBounds.right - newBounds.right;
 | |
| 
 | |
|       if (newBounds.top < pageBounds.top)
 | |
|         offset.y = pageBounds.top - newBounds.top;
 | |
|       else if (newBounds.bottom > pageBounds.bottom)
 | |
|         offset.y = pageBounds.bottom - newBounds.bottom;
 | |
| 
 | |
|       newBounds.offset(offset);
 | |
| 
 | |
|       if (!bounds.equals(newBounds)) {
 | |
|         var blocked = false;
 | |
|         pairs.forEach(function(pair2) {
 | |
|           if (pair2 == pair || pair2.item == ignore)
 | |
|             return;
 | |
| 
 | |
|           var bounds2 = pair2.bounds;
 | |
|           if (bounds2.intersects(newBounds))
 | |
|             blocked = true;
 | |
|           return;
 | |
|         });
 | |
| 
 | |
|         if (!blocked) {
 | |
|           pair.bounds.copy(newBounds);
 | |
|         }
 | |
|       }
 | |
|       return;
 | |
|     });
 | |
| 
 | |
|     if (!pairsProvided) {
 | |
|       pairs.forEach(function(pair) {
 | |
|         pair.item.setBounds(pair.bounds);
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| };
 |