dragdrop-debug.js 127 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711
  1. /*
  2. Copyright (c) 2009, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.8.0r4
  6. */
  7. /**
  8. * The drag and drop utility provides a framework for building drag and drop
  9. * applications. In addition to enabling drag and drop for specific elements,
  10. * the drag and drop elements are tracked by the manager class, and the
  11. * interactions between the various elements are tracked during the drag and
  12. * the implementing code is notified about these important moments.
  13. * @module dragdrop
  14. * @title Drag and Drop
  15. * @requires yahoo,dom,event
  16. * @namespace YAHOO.util
  17. */
  18. // Only load the library once. Rewriting the manager class would orphan
  19. // existing drag and drop instances.
  20. if (!YAHOO.util.DragDropMgr) {
  21. /**
  22. * DragDropMgr is a singleton that tracks the element interaction for
  23. * all DragDrop items in the window. Generally, you will not call
  24. * this class directly, but it does have helper methods that could
  25. * be useful in your DragDrop implementations.
  26. * @class DragDropMgr
  27. * @static
  28. */
  29. YAHOO.util.DragDropMgr = function() {
  30. var Event = YAHOO.util.Event,
  31. Dom = YAHOO.util.Dom;
  32. return {
  33. /**
  34. * This property is used to turn on global use of the shim element on all DragDrop instances, defaults to false for backcompat. (Use: YAHOO.util.DDM.useShim = true)
  35. * @property useShim
  36. * @type Boolean
  37. * @static
  38. */
  39. useShim: false,
  40. /**
  41. * This property is used to determine if the shim is active over the screen, default false.
  42. * @private
  43. * @property _shimActive
  44. * @type Boolean
  45. * @static
  46. */
  47. _shimActive: false,
  48. /**
  49. * This property is used when useShim is set on a DragDrop object to store the current state of DDM.useShim so it can be reset when a drag operation is done.
  50. * @private
  51. * @property _shimState
  52. * @type Boolean
  53. * @static
  54. */
  55. _shimState: false,
  56. /**
  57. * This property is used when useShim is set to true, it will set the opacity on the shim to .5 for debugging. Use: (YAHOO.util.DDM._debugShim = true;)
  58. * @private
  59. * @property _debugShim
  60. * @type Boolean
  61. * @static
  62. */
  63. _debugShim: false,
  64. /**
  65. * This method will create a shim element (giving it the id of yui-ddm-shim), it also attaches the mousemove and mouseup listeners to it and attaches a scroll listener on the window
  66. * @private
  67. * @method _sizeShim
  68. * @static
  69. */
  70. _createShim: function() {
  71. YAHOO.log('Creating Shim Element', 'info', 'DragDropMgr');
  72. var s = document.createElement('div');
  73. s.id = 'yui-ddm-shim';
  74. if (document.body.firstChild) {
  75. document.body.insertBefore(s, document.body.firstChild);
  76. } else {
  77. document.body.appendChild(s);
  78. }
  79. s.style.display = 'none';
  80. s.style.backgroundColor = 'red';
  81. s.style.position = 'absolute';
  82. s.style.zIndex = '99999';
  83. Dom.setStyle(s, 'opacity', '0');
  84. this._shim = s;
  85. Event.on(s, "mouseup", this.handleMouseUp, this, true);
  86. Event.on(s, "mousemove", this.handleMouseMove, this, true);
  87. Event.on(window, 'scroll', this._sizeShim, this, true);
  88. },
  89. /**
  90. * This method will size the shim, called from activate and on window scroll event
  91. * @private
  92. * @method _sizeShim
  93. * @static
  94. */
  95. _sizeShim: function() {
  96. if (this._shimActive) {
  97. YAHOO.log('Sizing Shim', 'info', 'DragDropMgr');
  98. var s = this._shim;
  99. s.style.height = Dom.getDocumentHeight() + 'px';
  100. s.style.width = Dom.getDocumentWidth() + 'px';
  101. s.style.top = '0';
  102. s.style.left = '0';
  103. }
  104. },
  105. /**
  106. * This method will create the shim element if needed, then show the shim element, size the element and set the _shimActive property to true
  107. * @private
  108. * @method _activateShim
  109. * @static
  110. */
  111. _activateShim: function() {
  112. if (this.useShim) {
  113. YAHOO.log('Activating Shim', 'info', 'DragDropMgr');
  114. if (!this._shim) {
  115. this._createShim();
  116. }
  117. this._shimActive = true;
  118. var s = this._shim,
  119. o = '0';
  120. if (this._debugShim) {
  121. o = '.5';
  122. }
  123. Dom.setStyle(s, 'opacity', o);
  124. this._sizeShim();
  125. s.style.display = 'block';
  126. }
  127. },
  128. /**
  129. * This method will hide the shim element and set the _shimActive property to false
  130. * @private
  131. * @method _deactivateShim
  132. * @static
  133. */
  134. _deactivateShim: function() {
  135. YAHOO.log('Deactivating Shim', 'info', 'DragDropMgr');
  136. this._shim.style.display = 'none';
  137. this._shimActive = false;
  138. },
  139. /**
  140. * The HTML element created to use as a shim over the document to track mouse movements
  141. * @private
  142. * @property _shim
  143. * @type HTMLElement
  144. * @static
  145. */
  146. _shim: null,
  147. /**
  148. * Two dimensional Array of registered DragDrop objects. The first
  149. * dimension is the DragDrop item group, the second the DragDrop
  150. * object.
  151. * @property ids
  152. * @type {string: string}
  153. * @private
  154. * @static
  155. */
  156. ids: {},
  157. /**
  158. * Array of element ids defined as drag handles. Used to determine
  159. * if the element that generated the mousedown event is actually the
  160. * handle and not the html element itself.
  161. * @property handleIds
  162. * @type {string: string}
  163. * @private
  164. * @static
  165. */
  166. handleIds: {},
  167. /**
  168. * the DragDrop object that is currently being dragged
  169. * @property dragCurrent
  170. * @type DragDrop
  171. * @private
  172. * @static
  173. **/
  174. dragCurrent: null,
  175. /**
  176. * the DragDrop object(s) that are being hovered over
  177. * @property dragOvers
  178. * @type Array
  179. * @private
  180. * @static
  181. */
  182. dragOvers: {},
  183. /**
  184. * the X distance between the cursor and the object being dragged
  185. * @property deltaX
  186. * @type int
  187. * @private
  188. * @static
  189. */
  190. deltaX: 0,
  191. /**
  192. * the Y distance between the cursor and the object being dragged
  193. * @property deltaY
  194. * @type int
  195. * @private
  196. * @static
  197. */
  198. deltaY: 0,
  199. /**
  200. * Flag to determine if we should prevent the default behavior of the
  201. * events we define. By default this is true, but this can be set to
  202. * false if you need the default behavior (not recommended)
  203. * @property preventDefault
  204. * @type boolean
  205. * @static
  206. */
  207. preventDefault: true,
  208. /**
  209. * Flag to determine if we should stop the propagation of the events
  210. * we generate. This is true by default but you may want to set it to
  211. * false if the html element contains other features that require the
  212. * mouse click.
  213. * @property stopPropagation
  214. * @type boolean
  215. * @static
  216. */
  217. stopPropagation: true,
  218. /**
  219. * Internal flag that is set to true when drag and drop has been
  220. * initialized
  221. * @property initialized
  222. * @private
  223. * @static
  224. */
  225. initialized: false,
  226. /**
  227. * All drag and drop can be disabled.
  228. * @property locked
  229. * @private
  230. * @static
  231. */
  232. locked: false,
  233. /**
  234. * Provides additional information about the the current set of
  235. * interactions. Can be accessed from the event handlers. It
  236. * contains the following properties:
  237. *
  238. * out: onDragOut interactions
  239. * enter: onDragEnter interactions
  240. * over: onDragOver interactions
  241. * drop: onDragDrop interactions
  242. * point: The location of the cursor
  243. * draggedRegion: The location of dragged element at the time
  244. * of the interaction
  245. * sourceRegion: The location of the source elemtn at the time
  246. * of the interaction
  247. * validDrop: boolean
  248. * @property interactionInfo
  249. * @type object
  250. * @static
  251. */
  252. interactionInfo: null,
  253. /**
  254. * Called the first time an element is registered.
  255. * @method init
  256. * @private
  257. * @static
  258. */
  259. init: function() {
  260. this.initialized = true;
  261. },
  262. /**
  263. * In point mode, drag and drop interaction is defined by the
  264. * location of the cursor during the drag/drop
  265. * @property POINT
  266. * @type int
  267. * @static
  268. * @final
  269. */
  270. POINT: 0,
  271. /**
  272. * In intersect mode, drag and drop interaction is defined by the
  273. * cursor position or the amount of overlap of two or more drag and
  274. * drop objects.
  275. * @property INTERSECT
  276. * @type int
  277. * @static
  278. * @final
  279. */
  280. INTERSECT: 1,
  281. /**
  282. * In intersect mode, drag and drop interaction is defined only by the
  283. * overlap of two or more drag and drop objects.
  284. * @property STRICT_INTERSECT
  285. * @type int
  286. * @static
  287. * @final
  288. */
  289. STRICT_INTERSECT: 2,
  290. /**
  291. * The current drag and drop mode. Default: POINT
  292. * @property mode
  293. * @type int
  294. * @static
  295. */
  296. mode: 0,
  297. /**
  298. * Runs method on all drag and drop objects
  299. * @method _execOnAll
  300. * @private
  301. * @static
  302. */
  303. _execOnAll: function(sMethod, args) {
  304. for (var i in this.ids) {
  305. for (var j in this.ids[i]) {
  306. var oDD = this.ids[i][j];
  307. if (! this.isTypeOfDD(oDD)) {
  308. continue;
  309. }
  310. oDD[sMethod].apply(oDD, args);
  311. }
  312. }
  313. },
  314. /**
  315. * Drag and drop initialization. Sets up the global event handlers
  316. * @method _onLoad
  317. * @private
  318. * @static
  319. */
  320. _onLoad: function() {
  321. this.init();
  322. YAHOO.log("DragDropMgr onload", "info", "DragDropMgr");
  323. Event.on(document, "mouseup", this.handleMouseUp, this, true);
  324. Event.on(document, "mousemove", this.handleMouseMove, this, true);
  325. Event.on(window, "unload", this._onUnload, this, true);
  326. Event.on(window, "resize", this._onResize, this, true);
  327. // Event.on(window, "mouseout", this._test);
  328. },
  329. /**
  330. * Reset constraints on all drag and drop objs
  331. * @method _onResize
  332. * @private
  333. * @static
  334. */
  335. _onResize: function(e) {
  336. YAHOO.log("window resize", "info", "DragDropMgr");
  337. this._execOnAll("resetConstraints", []);
  338. },
  339. /**
  340. * Lock all drag and drop functionality
  341. * @method lock
  342. * @static
  343. */
  344. lock: function() { this.locked = true; },
  345. /**
  346. * Unlock all drag and drop functionality
  347. * @method unlock
  348. * @static
  349. */
  350. unlock: function() { this.locked = false; },
  351. /**
  352. * Is drag and drop locked?
  353. * @method isLocked
  354. * @return {boolean} True if drag and drop is locked, false otherwise.
  355. * @static
  356. */
  357. isLocked: function() { return this.locked; },
  358. /**
  359. * Location cache that is set for all drag drop objects when a drag is
  360. * initiated, cleared when the drag is finished.
  361. * @property locationCache
  362. * @private
  363. * @static
  364. */
  365. locationCache: {},
  366. /**
  367. * Set useCache to false if you want to force object the lookup of each
  368. * drag and drop linked element constantly during a drag.
  369. * @property useCache
  370. * @type boolean
  371. * @static
  372. */
  373. useCache: true,
  374. /**
  375. * The number of pixels that the mouse needs to move after the
  376. * mousedown before the drag is initiated. Default=3;
  377. * @property clickPixelThresh
  378. * @type int
  379. * @static
  380. */
  381. clickPixelThresh: 3,
  382. /**
  383. * The number of milliseconds after the mousedown event to initiate the
  384. * drag if we don't get a mouseup event. Default=1000
  385. * @property clickTimeThresh
  386. * @type int
  387. * @static
  388. */
  389. clickTimeThresh: 1000,
  390. /**
  391. * Flag that indicates that either the drag pixel threshold or the
  392. * mousdown time threshold has been met
  393. * @property dragThreshMet
  394. * @type boolean
  395. * @private
  396. * @static
  397. */
  398. dragThreshMet: false,
  399. /**
  400. * Timeout used for the click time threshold
  401. * @property clickTimeout
  402. * @type Object
  403. * @private
  404. * @static
  405. */
  406. clickTimeout: null,
  407. /**
  408. * The X position of the mousedown event stored for later use when a
  409. * drag threshold is met.
  410. * @property startX
  411. * @type int
  412. * @private
  413. * @static
  414. */
  415. startX: 0,
  416. /**
  417. * The Y position of the mousedown event stored for later use when a
  418. * drag threshold is met.
  419. * @property startY
  420. * @type int
  421. * @private
  422. * @static
  423. */
  424. startY: 0,
  425. /**
  426. * Flag to determine if the drag event was fired from the click timeout and
  427. * not the mouse move threshold.
  428. * @property fromTimeout
  429. * @type boolean
  430. * @private
  431. * @static
  432. */
  433. fromTimeout: false,
  434. /**
  435. * Each DragDrop instance must be registered with the DragDropMgr.
  436. * This is executed in DragDrop.init()
  437. * @method regDragDrop
  438. * @param {DragDrop} oDD the DragDrop object to register
  439. * @param {String} sGroup the name of the group this element belongs to
  440. * @static
  441. */
  442. regDragDrop: function(oDD, sGroup) {
  443. if (!this.initialized) { this.init(); }
  444. if (!this.ids[sGroup]) {
  445. this.ids[sGroup] = {};
  446. }
  447. this.ids[sGroup][oDD.id] = oDD;
  448. },
  449. /**
  450. * Removes the supplied dd instance from the supplied group. Executed
  451. * by DragDrop.removeFromGroup, so don't call this function directly.
  452. * @method removeDDFromGroup
  453. * @private
  454. * @static
  455. */
  456. removeDDFromGroup: function(oDD, sGroup) {
  457. if (!this.ids[sGroup]) {
  458. this.ids[sGroup] = {};
  459. }
  460. var obj = this.ids[sGroup];
  461. if (obj && obj[oDD.id]) {
  462. delete obj[oDD.id];
  463. }
  464. },
  465. /**
  466. * Unregisters a drag and drop item. This is executed in
  467. * DragDrop.unreg, use that method instead of calling this directly.
  468. * @method _remove
  469. * @private
  470. * @static
  471. */
  472. _remove: function(oDD) {
  473. for (var g in oDD.groups) {
  474. if (g) {
  475. var item = this.ids[g];
  476. if (item && item[oDD.id]) {
  477. delete item[oDD.id];
  478. }
  479. }
  480. }
  481. delete this.handleIds[oDD.id];
  482. },
  483. /**
  484. * Each DragDrop handle element must be registered. This is done
  485. * automatically when executing DragDrop.setHandleElId()
  486. * @method regHandle
  487. * @param {String} sDDId the DragDrop id this element is a handle for
  488. * @param {String} sHandleId the id of the element that is the drag
  489. * handle
  490. * @static
  491. */
  492. regHandle: function(sDDId, sHandleId) {
  493. if (!this.handleIds[sDDId]) {
  494. this.handleIds[sDDId] = {};
  495. }
  496. this.handleIds[sDDId][sHandleId] = sHandleId;
  497. },
  498. /**
  499. * Utility function to determine if a given element has been
  500. * registered as a drag drop item.
  501. * @method isDragDrop
  502. * @param {String} id the element id to check
  503. * @return {boolean} true if this element is a DragDrop item,
  504. * false otherwise
  505. * @static
  506. */
  507. isDragDrop: function(id) {
  508. return ( this.getDDById(id) ) ? true : false;
  509. },
  510. /**
  511. * Returns the drag and drop instances that are in all groups the
  512. * passed in instance belongs to.
  513. * @method getRelated
  514. * @param {DragDrop} p_oDD the obj to get related data for
  515. * @param {boolean} bTargetsOnly if true, only return targetable objs
  516. * @return {DragDrop[]} the related instances
  517. * @static
  518. */
  519. getRelated: function(p_oDD, bTargetsOnly) {
  520. var oDDs = [];
  521. for (var i in p_oDD.groups) {
  522. for (var j in this.ids[i]) {
  523. var dd = this.ids[i][j];
  524. if (! this.isTypeOfDD(dd)) {
  525. continue;
  526. }
  527. if (!bTargetsOnly || dd.isTarget) {
  528. oDDs[oDDs.length] = dd;
  529. }
  530. }
  531. }
  532. return oDDs;
  533. },
  534. /**
  535. * Returns true if the specified dd target is a legal target for
  536. * the specifice drag obj
  537. * @method isLegalTarget
  538. * @param {DragDrop} the drag obj
  539. * @param {DragDrop} the target
  540. * @return {boolean} true if the target is a legal target for the
  541. * dd obj
  542. * @static
  543. */
  544. isLegalTarget: function (oDD, oTargetDD) {
  545. var targets = this.getRelated(oDD, true);
  546. for (var i=0, len=targets.length;i<len;++i) {
  547. if (targets[i].id == oTargetDD.id) {
  548. return true;
  549. }
  550. }
  551. return false;
  552. },
  553. /**
  554. * My goal is to be able to transparently determine if an object is
  555. * typeof DragDrop, and the exact subclass of DragDrop. typeof
  556. * returns "object", oDD.constructor.toString() always returns
  557. * "DragDrop" and not the name of the subclass. So for now it just
  558. * evaluates a well-known variable in DragDrop.
  559. * @method isTypeOfDD
  560. * @param {Object} the object to evaluate
  561. * @return {boolean} true if typeof oDD = DragDrop
  562. * @static
  563. */
  564. isTypeOfDD: function (oDD) {
  565. return (oDD && oDD.__ygDragDrop);
  566. },
  567. /**
  568. * Utility function to determine if a given element has been
  569. * registered as a drag drop handle for the given Drag Drop object.
  570. * @method isHandle
  571. * @param {String} id the element id to check
  572. * @return {boolean} true if this element is a DragDrop handle, false
  573. * otherwise
  574. * @static
  575. */
  576. isHandle: function(sDDId, sHandleId) {
  577. return ( this.handleIds[sDDId] &&
  578. this.handleIds[sDDId][sHandleId] );
  579. },
  580. /**
  581. * Returns the DragDrop instance for a given id
  582. * @method getDDById
  583. * @param {String} id the id of the DragDrop object
  584. * @return {DragDrop} the drag drop object, null if it is not found
  585. * @static
  586. */
  587. getDDById: function(id) {
  588. for (var i in this.ids) {
  589. if (this.ids[i][id]) {
  590. return this.ids[i][id];
  591. }
  592. }
  593. return null;
  594. },
  595. /**
  596. * Fired after a registered DragDrop object gets the mousedown event.
  597. * Sets up the events required to track the object being dragged
  598. * @method handleMouseDown
  599. * @param {Event} e the event
  600. * @param oDD the DragDrop object being dragged
  601. * @private
  602. * @static
  603. */
  604. handleMouseDown: function(e, oDD) {
  605. //this._activateShim();
  606. this.currentTarget = YAHOO.util.Event.getTarget(e);
  607. this.dragCurrent = oDD;
  608. var el = oDD.getEl();
  609. // track start position
  610. this.startX = YAHOO.util.Event.getPageX(e);
  611. this.startY = YAHOO.util.Event.getPageY(e);
  612. this.deltaX = this.startX - el.offsetLeft;
  613. this.deltaY = this.startY - el.offsetTop;
  614. this.dragThreshMet = false;
  615. this.clickTimeout = setTimeout(
  616. function() {
  617. var DDM = YAHOO.util.DDM;
  618. DDM.startDrag(DDM.startX, DDM.startY);
  619. DDM.fromTimeout = true;
  620. },
  621. this.clickTimeThresh );
  622. },
  623. /**
  624. * Fired when either the drag pixel threshold or the mousedown hold
  625. * time threshold has been met.
  626. * @method startDrag
  627. * @param x {int} the X position of the original mousedown
  628. * @param y {int} the Y position of the original mousedown
  629. * @static
  630. */
  631. startDrag: function(x, y) {
  632. if (this.dragCurrent && this.dragCurrent.useShim) {
  633. this._shimState = this.useShim;
  634. this.useShim = true;
  635. }
  636. this._activateShim();
  637. YAHOO.log("firing drag start events", "info", "DragDropMgr");
  638. clearTimeout(this.clickTimeout);
  639. var dc = this.dragCurrent;
  640. if (dc && dc.events.b4StartDrag) {
  641. dc.b4StartDrag(x, y);
  642. dc.fireEvent('b4StartDragEvent', { x: x, y: y });
  643. }
  644. if (dc && dc.events.startDrag) {
  645. dc.startDrag(x, y);
  646. dc.fireEvent('startDragEvent', { x: x, y: y });
  647. }
  648. this.dragThreshMet = true;
  649. },
  650. /**
  651. * Internal function to handle the mouseup event. Will be invoked
  652. * from the context of the document.
  653. * @method handleMouseUp
  654. * @param {Event} e the event
  655. * @private
  656. * @static
  657. */
  658. handleMouseUp: function(e) {
  659. if (this.dragCurrent) {
  660. clearTimeout(this.clickTimeout);
  661. if (this.dragThreshMet) {
  662. YAHOO.log("mouseup detected - completing drag", "info", "DragDropMgr");
  663. if (this.fromTimeout) {
  664. YAHOO.log('fromTimeout is true (mouse didn\'t move), call handleMouseMove so we can get the dragOver event', 'info', 'DragDropMgr');
  665. this.fromTimeout = false;
  666. this.handleMouseMove(e);
  667. }
  668. this.fromTimeout = false;
  669. this.fireEvents(e, true);
  670. } else {
  671. YAHOO.log("drag threshold not met", "info", "DragDropMgr");
  672. }
  673. this.stopDrag(e);
  674. this.stopEvent(e);
  675. }
  676. },
  677. /**
  678. * Utility to stop event propagation and event default, if these
  679. * features are turned on.
  680. * @method stopEvent
  681. * @param {Event} e the event as returned by this.getEvent()
  682. * @static
  683. */
  684. stopEvent: function(e) {
  685. if (this.stopPropagation) {
  686. YAHOO.util.Event.stopPropagation(e);
  687. }
  688. if (this.preventDefault) {
  689. YAHOO.util.Event.preventDefault(e);
  690. }
  691. },
  692. /**
  693. * Ends the current drag, cleans up the state, and fires the endDrag
  694. * and mouseUp events. Called internally when a mouseup is detected
  695. * during the drag. Can be fired manually during the drag by passing
  696. * either another event (such as the mousemove event received in onDrag)
  697. * or a fake event with pageX and pageY defined (so that endDrag and
  698. * onMouseUp have usable position data.). Alternatively, pass true
  699. * for the silent parameter so that the endDrag and onMouseUp events
  700. * are skipped (so no event data is needed.)
  701. *
  702. * @method stopDrag
  703. * @param {Event} e the mouseup event, another event (or a fake event)
  704. * with pageX and pageY defined, or nothing if the
  705. * silent parameter is true
  706. * @param {boolean} silent skips the enddrag and mouseup events if true
  707. * @static
  708. */
  709. stopDrag: function(e, silent) {
  710. // YAHOO.log("mouseup - removing event handlers");
  711. var dc = this.dragCurrent;
  712. // Fire the drag end event for the item that was dragged
  713. if (dc && !silent) {
  714. if (this.dragThreshMet) {
  715. YAHOO.log("firing endDrag events", "info", "DragDropMgr");
  716. if (dc.events.b4EndDrag) {
  717. dc.b4EndDrag(e);
  718. dc.fireEvent('b4EndDragEvent', { e: e });
  719. }
  720. if (dc.events.endDrag) {
  721. dc.endDrag(e);
  722. dc.fireEvent('endDragEvent', { e: e });
  723. }
  724. }
  725. if (dc.events.mouseUp) {
  726. YAHOO.log("firing dragdrop onMouseUp event", "info", "DragDropMgr");
  727. dc.onMouseUp(e);
  728. dc.fireEvent('mouseUpEvent', { e: e });
  729. }
  730. }
  731. if (this._shimActive) {
  732. this._deactivateShim();
  733. if (this.dragCurrent && this.dragCurrent.useShim) {
  734. this.useShim = this._shimState;
  735. this._shimState = false;
  736. }
  737. }
  738. this.dragCurrent = null;
  739. this.dragOvers = {};
  740. },
  741. /**
  742. * Internal function to handle the mousemove event. Will be invoked
  743. * from the context of the html element.
  744. *
  745. * @TODO figure out what we can do about mouse events lost when the
  746. * user drags objects beyond the window boundary. Currently we can
  747. * detect this in internet explorer by verifying that the mouse is
  748. * down during the mousemove event. Firefox doesn't give us the
  749. * button state on the mousemove event.
  750. * @method handleMouseMove
  751. * @param {Event} e the event
  752. * @private
  753. * @static
  754. */
  755. handleMouseMove: function(e) {
  756. //YAHOO.log("handlemousemove");
  757. var dc = this.dragCurrent;
  758. if (dc) {
  759. // YAHOO.log("no current drag obj");
  760. // var button = e.which || e.button;
  761. // YAHOO.log("which: " + e.which + ", button: "+ e.button);
  762. // check for IE mouseup outside of page boundary
  763. if (YAHOO.util.Event.isIE && !e.button) {
  764. YAHOO.log("button failure", "info", "DragDropMgr");
  765. this.stopEvent(e);
  766. return this.handleMouseUp(e);
  767. } else {
  768. if (e.clientX < 0 || e.clientY < 0) {
  769. //This will stop the element from leaving the viewport in FF, Opera & Safari
  770. //Not turned on yet
  771. //YAHOO.log("Either clientX or clientY is negative, stop the event.", "info", "DragDropMgr");
  772. //this.stopEvent(e);
  773. //return false;
  774. }
  775. }
  776. if (!this.dragThreshMet) {
  777. var diffX = Math.abs(this.startX - YAHOO.util.Event.getPageX(e));
  778. var diffY = Math.abs(this.startY - YAHOO.util.Event.getPageY(e));
  779. // YAHOO.log("diffX: " + diffX + "diffY: " + diffY);
  780. if (diffX > this.clickPixelThresh ||
  781. diffY > this.clickPixelThresh) {
  782. YAHOO.log("pixel threshold met", "info", "DragDropMgr");
  783. this.startDrag(this.startX, this.startY);
  784. }
  785. }
  786. if (this.dragThreshMet) {
  787. if (dc && dc.events.b4Drag) {
  788. dc.b4Drag(e);
  789. dc.fireEvent('b4DragEvent', { e: e});
  790. }
  791. if (dc && dc.events.drag) {
  792. dc.onDrag(e);
  793. dc.fireEvent('dragEvent', { e: e});
  794. }
  795. if (dc) {
  796. this.fireEvents(e, false);
  797. }
  798. }
  799. this.stopEvent(e);
  800. }
  801. },
  802. /**
  803. * Iterates over all of the DragDrop elements to find ones we are
  804. * hovering over or dropping on
  805. * @method fireEvents
  806. * @param {Event} e the event
  807. * @param {boolean} isDrop is this a drop op or a mouseover op?
  808. * @private
  809. * @static
  810. */
  811. fireEvents: function(e, isDrop) {
  812. var dc = this.dragCurrent;
  813. // If the user did the mouse up outside of the window, we could
  814. // get here even though we have ended the drag.
  815. // If the config option dragOnly is true, bail out and don't fire the events
  816. if (!dc || dc.isLocked() || dc.dragOnly) {
  817. return;
  818. }
  819. var x = YAHOO.util.Event.getPageX(e),
  820. y = YAHOO.util.Event.getPageY(e),
  821. pt = new YAHOO.util.Point(x,y),
  822. pos = dc.getTargetCoord(pt.x, pt.y),
  823. el = dc.getDragEl(),
  824. events = ['out', 'over', 'drop', 'enter'],
  825. curRegion = new YAHOO.util.Region( pos.y,
  826. pos.x + el.offsetWidth,
  827. pos.y + el.offsetHeight,
  828. pos.x ),
  829. oldOvers = [], // cache the previous dragOver array
  830. inGroupsObj = {},
  831. inGroups = [],
  832. data = {
  833. outEvts: [],
  834. overEvts: [],
  835. dropEvts: [],
  836. enterEvts: []
  837. };
  838. // Check to see if the object(s) we were hovering over is no longer
  839. // being hovered over so we can fire the onDragOut event
  840. for (var i in this.dragOvers) {
  841. var ddo = this.dragOvers[i];
  842. if (! this.isTypeOfDD(ddo)) {
  843. continue;
  844. }
  845. if (! this.isOverTarget(pt, ddo, this.mode, curRegion)) {
  846. data.outEvts.push( ddo );
  847. }
  848. oldOvers[i] = true;
  849. delete this.dragOvers[i];
  850. }
  851. for (var sGroup in dc.groups) {
  852. // YAHOO.log("Processing group " + sGroup);
  853. if ("string" != typeof sGroup) {
  854. continue;
  855. }
  856. for (i in this.ids[sGroup]) {
  857. var oDD = this.ids[sGroup][i];
  858. if (! this.isTypeOfDD(oDD)) {
  859. continue;
  860. }
  861. if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
  862. if (this.isOverTarget(pt, oDD, this.mode, curRegion)) {
  863. inGroupsObj[sGroup] = true;
  864. // look for drop interactions
  865. if (isDrop) {
  866. data.dropEvts.push( oDD );
  867. // look for drag enter and drag over interactions
  868. } else {
  869. // initial drag over: dragEnter fires
  870. if (!oldOvers[oDD.id]) {
  871. data.enterEvts.push( oDD );
  872. // subsequent drag overs: dragOver fires
  873. } else {
  874. data.overEvts.push( oDD );
  875. }
  876. this.dragOvers[oDD.id] = oDD;
  877. }
  878. }
  879. }
  880. }
  881. }
  882. this.interactionInfo = {
  883. out: data.outEvts,
  884. enter: data.enterEvts,
  885. over: data.overEvts,
  886. drop: data.dropEvts,
  887. point: pt,
  888. draggedRegion: curRegion,
  889. sourceRegion: this.locationCache[dc.id],
  890. validDrop: isDrop
  891. };
  892. for (var inG in inGroupsObj) {
  893. inGroups.push(inG);
  894. }
  895. // notify about a drop that did not find a target
  896. if (isDrop && !data.dropEvts.length) {
  897. YAHOO.log(dc.id + " dropped, but not on a target", "info", "DragDropMgr");
  898. this.interactionInfo.validDrop = false;
  899. if (dc.events.invalidDrop) {
  900. dc.onInvalidDrop(e);
  901. dc.fireEvent('invalidDropEvent', { e: e });
  902. }
  903. }
  904. for (i = 0; i < events.length; i++) {
  905. var tmp = null;
  906. if (data[events[i] + 'Evts']) {
  907. tmp = data[events[i] + 'Evts'];
  908. }
  909. if (tmp && tmp.length) {
  910. var type = events[i].charAt(0).toUpperCase() + events[i].substr(1),
  911. ev = 'onDrag' + type,
  912. b4 = 'b4Drag' + type,
  913. cev = 'drag' + type + 'Event',
  914. check = 'drag' + type;
  915. if (this.mode) {
  916. YAHOO.log(dc.id + ' ' + ev + ': ' + tmp, "info", "DragDropMgr");
  917. if (dc.events[b4]) {
  918. dc[b4](e, tmp, inGroups);
  919. dc.fireEvent(b4 + 'Event', { event: e, info: tmp, group: inGroups });
  920. }
  921. if (dc.events[check]) {
  922. dc[ev](e, tmp, inGroups);
  923. dc.fireEvent(cev, { event: e, info: tmp, group: inGroups });
  924. }
  925. } else {
  926. for (var b = 0, len = tmp.length; b < len; ++b) {
  927. YAHOO.log(dc.id + ' ' + ev + ': ' + tmp[b].id, "info", "DragDropMgr");
  928. if (dc.events[b4]) {
  929. dc[b4](e, tmp[b].id, inGroups[0]);
  930. dc.fireEvent(b4 + 'Event', { event: e, info: tmp[b].id, group: inGroups[0] });
  931. }
  932. if (dc.events[check]) {
  933. dc[ev](e, tmp[b].id, inGroups[0]);
  934. dc.fireEvent(cev, { event: e, info: tmp[b].id, group: inGroups[0] });
  935. }
  936. }
  937. }
  938. }
  939. }
  940. },
  941. /**
  942. * Helper function for getting the best match from the list of drag
  943. * and drop objects returned by the drag and drop events when we are
  944. * in INTERSECT mode. It returns either the first object that the
  945. * cursor is over, or the object that has the greatest overlap with
  946. * the dragged element.
  947. * @method getBestMatch
  948. * @param {DragDrop[]} dds The array of drag and drop objects
  949. * targeted
  950. * @return {DragDrop} The best single match
  951. * @static
  952. */
  953. getBestMatch: function(dds) {
  954. var winner = null;
  955. var len = dds.length;
  956. if (len == 1) {
  957. winner = dds[0];
  958. } else {
  959. // Loop through the targeted items
  960. for (var i=0; i<len; ++i) {
  961. var dd = dds[i];
  962. // If the cursor is over the object, it wins. If the
  963. // cursor is over multiple matches, the first one we come
  964. // to wins.
  965. if (this.mode == this.INTERSECT && dd.cursorIsOver) {
  966. winner = dd;
  967. break;
  968. // Otherwise the object with the most overlap wins
  969. } else {
  970. if (!winner || !winner.overlap || (dd.overlap &&
  971. winner.overlap.getArea() < dd.overlap.getArea())) {
  972. winner = dd;
  973. }
  974. }
  975. }
  976. }
  977. return winner;
  978. },
  979. /**
  980. * Refreshes the cache of the top-left and bottom-right points of the
  981. * drag and drop objects in the specified group(s). This is in the
  982. * format that is stored in the drag and drop instance, so typical
  983. * usage is:
  984. * <code>
  985. * YAHOO.util.DragDropMgr.refreshCache(ddinstance.groups);
  986. * </code>
  987. * Alternatively:
  988. * <code>
  989. * YAHOO.util.DragDropMgr.refreshCache({group1:true, group2:true});
  990. * </code>
  991. * @TODO this really should be an indexed array. Alternatively this
  992. * method could accept both.
  993. * @method refreshCache
  994. * @param {Object} groups an associative array of groups to refresh
  995. * @static
  996. */
  997. refreshCache: function(groups) {
  998. YAHOO.log("refreshing element location cache", "info", "DragDropMgr");
  999. // refresh everything if group array is not provided
  1000. var g = groups || this.ids;
  1001. for (var sGroup in g) {
  1002. if ("string" != typeof sGroup) {
  1003. continue;
  1004. }
  1005. for (var i in this.ids[sGroup]) {
  1006. var oDD = this.ids[sGroup][i];
  1007. if (this.isTypeOfDD(oDD)) {
  1008. var loc = this.getLocation(oDD);
  1009. if (loc) {
  1010. this.locationCache[oDD.id] = loc;
  1011. } else {
  1012. delete this.locationCache[oDD.id];
  1013. YAHOO.log("Could not get the loc for " + oDD.id, "warn", "DragDropMgr");
  1014. }
  1015. }
  1016. }
  1017. }
  1018. },
  1019. /**
  1020. * This checks to make sure an element exists and is in the DOM. The
  1021. * main purpose is to handle cases where innerHTML is used to remove
  1022. * drag and drop objects from the DOM. IE provides an 'unspecified
  1023. * error' when trying to access the offsetParent of such an element
  1024. * @method verifyEl
  1025. * @param {HTMLElement} el the element to check
  1026. * @return {boolean} true if the element looks usable
  1027. * @static
  1028. */
  1029. verifyEl: function(el) {
  1030. try {
  1031. if (el) {
  1032. var parent = el.offsetParent;
  1033. if (parent) {
  1034. return true;
  1035. }
  1036. }
  1037. } catch(e) {
  1038. YAHOO.log("detected problem with an element", "info", "DragDropMgr");
  1039. }
  1040. return false;
  1041. },
  1042. /**
  1043. * Returns a Region object containing the drag and drop element's position
  1044. * and size, including the padding configured for it
  1045. * @method getLocation
  1046. * @param {DragDrop} oDD the drag and drop object to get the
  1047. * location for
  1048. * @return {YAHOO.util.Region} a Region object representing the total area
  1049. * the element occupies, including any padding
  1050. * the instance is configured for.
  1051. * @static
  1052. */
  1053. getLocation: function(oDD) {
  1054. if (! this.isTypeOfDD(oDD)) {
  1055. YAHOO.log(oDD + " is not a DD obj", "info", "DragDropMgr");
  1056. return null;
  1057. }
  1058. var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
  1059. try {
  1060. pos= YAHOO.util.Dom.getXY(el);
  1061. } catch (e) { }
  1062. if (!pos) {
  1063. YAHOO.log("getXY failed", "info", "DragDropMgr");
  1064. return null;
  1065. }
  1066. x1 = pos[0];
  1067. x2 = x1 + el.offsetWidth;
  1068. y1 = pos[1];
  1069. y2 = y1 + el.offsetHeight;
  1070. t = y1 - oDD.padding[0];
  1071. r = x2 + oDD.padding[1];
  1072. b = y2 + oDD.padding[2];
  1073. l = x1 - oDD.padding[3];
  1074. return new YAHOO.util.Region( t, r, b, l );
  1075. },
  1076. /**
  1077. * Checks the cursor location to see if it over the target
  1078. * @method isOverTarget
  1079. * @param {YAHOO.util.Point} pt The point to evaluate
  1080. * @param {DragDrop} oTarget the DragDrop object we are inspecting
  1081. * @param {boolean} intersect true if we are in intersect mode
  1082. * @param {YAHOO.util.Region} pre-cached location of the dragged element
  1083. * @return {boolean} true if the mouse is over the target
  1084. * @private
  1085. * @static
  1086. */
  1087. isOverTarget: function(pt, oTarget, intersect, curRegion) {
  1088. // use cache if available
  1089. var loc = this.locationCache[oTarget.id];
  1090. if (!loc || !this.useCache) {
  1091. YAHOO.log("cache not populated", "info", "DragDropMgr");
  1092. loc = this.getLocation(oTarget);
  1093. this.locationCache[oTarget.id] = loc;
  1094. YAHOO.log("cache: " + loc, "info", "DragDropMgr");
  1095. }
  1096. if (!loc) {
  1097. YAHOO.log("could not get the location of the element", "info", "DragDropMgr");
  1098. return false;
  1099. }
  1100. //YAHOO.log("loc: " + loc + ", pt: " + pt);
  1101. oTarget.cursorIsOver = loc.contains( pt );
  1102. // DragDrop is using this as a sanity check for the initial mousedown
  1103. // in this case we are done. In POINT mode, if the drag obj has no
  1104. // contraints, we are done. Otherwise we need to evaluate the
  1105. // region the target as occupies to determine if the dragged element
  1106. // overlaps with it.
  1107. var dc = this.dragCurrent;
  1108. if (!dc || (!intersect && !dc.constrainX && !dc.constrainY)) {
  1109. //if (oTarget.cursorIsOver) {
  1110. //YAHOO.log("over " + oTarget + ", " + loc + ", " + pt, "warn");
  1111. //}
  1112. return oTarget.cursorIsOver;
  1113. }
  1114. oTarget.overlap = null;
  1115. // Get the current location of the drag element, this is the
  1116. // location of the mouse event less the delta that represents
  1117. // where the original mousedown happened on the element. We
  1118. // need to consider constraints and ticks as well.
  1119. if (!curRegion) {
  1120. var pos = dc.getTargetCoord(pt.x, pt.y);
  1121. var el = dc.getDragEl();
  1122. curRegion = new YAHOO.util.Region( pos.y,
  1123. pos.x + el.offsetWidth,
  1124. pos.y + el.offsetHeight,
  1125. pos.x );
  1126. }
  1127. var overlap = curRegion.intersect(loc);
  1128. if (overlap) {
  1129. oTarget.overlap = overlap;
  1130. return (intersect) ? true : oTarget.cursorIsOver;
  1131. } else {
  1132. return false;
  1133. }
  1134. },
  1135. /**
  1136. * unload event handler
  1137. * @method _onUnload
  1138. * @private
  1139. * @static
  1140. */
  1141. _onUnload: function(e, me) {
  1142. this.unregAll();
  1143. },
  1144. /**
  1145. * Cleans up the drag and drop events and objects.
  1146. * @method unregAll
  1147. * @private
  1148. * @static
  1149. */
  1150. unregAll: function() {
  1151. YAHOO.log("unregister all", "info", "DragDropMgr");
  1152. if (this.dragCurrent) {
  1153. this.stopDrag();
  1154. this.dragCurrent = null;
  1155. }
  1156. this._execOnAll("unreg", []);
  1157. //for (var i in this.elementCache) {
  1158. //delete this.elementCache[i];
  1159. //}
  1160. //this.elementCache = {};
  1161. this.ids = {};
  1162. },
  1163. /**
  1164. * A cache of DOM elements
  1165. * @property elementCache
  1166. * @private
  1167. * @static
  1168. * @deprecated elements are not cached now
  1169. */
  1170. elementCache: {},
  1171. /**
  1172. * Get the wrapper for the DOM element specified
  1173. * @method getElWrapper
  1174. * @param {String} id the id of the element to get
  1175. * @return {YAHOO.util.DDM.ElementWrapper} the wrapped element
  1176. * @private
  1177. * @deprecated This wrapper isn't that useful
  1178. * @static
  1179. */
  1180. getElWrapper: function(id) {
  1181. var oWrapper = this.elementCache[id];
  1182. if (!oWrapper || !oWrapper.el) {
  1183. oWrapper = this.elementCache[id] =
  1184. new this.ElementWrapper(YAHOO.util.Dom.get(id));
  1185. }
  1186. return oWrapper;
  1187. },
  1188. /**
  1189. * Returns the actual DOM element
  1190. * @method getElement
  1191. * @param {String} id the id of the elment to get
  1192. * @return {Object} The element
  1193. * @deprecated use YAHOO.util.Dom.get instead
  1194. * @static
  1195. */
  1196. getElement: function(id) {
  1197. return YAHOO.util.Dom.get(id);
  1198. },
  1199. /**
  1200. * Returns the style property for the DOM element (i.e.,
  1201. * document.getElById(id).style)
  1202. * @method getCss
  1203. * @param {String} id the id of the elment to get
  1204. * @return {Object} The style property of the element
  1205. * @deprecated use YAHOO.util.Dom instead
  1206. * @static
  1207. */
  1208. getCss: function(id) {
  1209. var el = YAHOO.util.Dom.get(id);
  1210. return (el) ? el.style : null;
  1211. },
  1212. /**
  1213. * Inner class for cached elements
  1214. * @class DragDropMgr.ElementWrapper
  1215. * @for DragDropMgr
  1216. * @private
  1217. * @deprecated
  1218. */
  1219. ElementWrapper: function(el) {
  1220. /**
  1221. * The element
  1222. * @property el
  1223. */
  1224. this.el = el || null;
  1225. /**
  1226. * The element id
  1227. * @property id
  1228. */
  1229. this.id = this.el && el.id;
  1230. /**
  1231. * A reference to the style property
  1232. * @property css
  1233. */
  1234. this.css = this.el && el.style;
  1235. },
  1236. /**
  1237. * Returns the X position of an html element
  1238. * @method getPosX
  1239. * @param el the element for which to get the position
  1240. * @return {int} the X coordinate
  1241. * @for DragDropMgr
  1242. * @deprecated use YAHOO.util.Dom.getX instead
  1243. * @static
  1244. */
  1245. getPosX: function(el) {
  1246. return YAHOO.util.Dom.getX(el);
  1247. },
  1248. /**
  1249. * Returns the Y position of an html element
  1250. * @method getPosY
  1251. * @param el the element for which to get the position
  1252. * @return {int} the Y coordinate
  1253. * @deprecated use YAHOO.util.Dom.getY instead
  1254. * @static
  1255. */
  1256. getPosY: function(el) {
  1257. return YAHOO.util.Dom.getY(el);
  1258. },
  1259. /**
  1260. * Swap two nodes. In IE, we use the native method, for others we
  1261. * emulate the IE behavior
  1262. * @method swapNode
  1263. * @param n1 the first node to swap
  1264. * @param n2 the other node to swap
  1265. * @static
  1266. */
  1267. swapNode: function(n1, n2) {
  1268. if (n1.swapNode) {
  1269. n1.swapNode(n2);
  1270. } else {
  1271. var p = n2.parentNode;
  1272. var s = n2.nextSibling;
  1273. if (s == n1) {
  1274. p.insertBefore(n1, n2);
  1275. } else if (n2 == n1.nextSibling) {
  1276. p.insertBefore(n2, n1);
  1277. } else {
  1278. n1.parentNode.replaceChild(n2, n1);
  1279. p.insertBefore(n1, s);
  1280. }
  1281. }
  1282. },
  1283. /**
  1284. * Returns the current scroll position
  1285. * @method getScroll
  1286. * @private
  1287. * @static
  1288. */
  1289. getScroll: function () {
  1290. var t, l, dde=document.documentElement, db=document.body;
  1291. if (dde && (dde.scrollTop || dde.scrollLeft)) {
  1292. t = dde.scrollTop;
  1293. l = dde.scrollLeft;
  1294. } else if (db) {
  1295. t = db.scrollTop;
  1296. l = db.scrollLeft;
  1297. } else {
  1298. YAHOO.log("could not get scroll property", "info", "DragDropMgr");
  1299. }
  1300. return { top: t, left: l };
  1301. },
  1302. /**
  1303. * Returns the specified element style property
  1304. * @method getStyle
  1305. * @param {HTMLElement} el the element
  1306. * @param {string} styleProp the style property
  1307. * @return {string} The value of the style property
  1308. * @deprecated use YAHOO.util.Dom.getStyle
  1309. * @static
  1310. */
  1311. getStyle: function(el, styleProp) {
  1312. return YAHOO.util.Dom.getStyle(el, styleProp);
  1313. },
  1314. /**
  1315. * Gets the scrollTop
  1316. * @method getScrollTop
  1317. * @return {int} the document's scrollTop
  1318. * @static
  1319. */
  1320. getScrollTop: function () { return this.getScroll().top; },
  1321. /**
  1322. * Gets the scrollLeft
  1323. * @method getScrollLeft
  1324. * @return {int} the document's scrollTop
  1325. * @static
  1326. */
  1327. getScrollLeft: function () { return this.getScroll().left; },
  1328. /**
  1329. * Sets the x/y position of an element to the location of the
  1330. * target element.
  1331. * @method moveToEl
  1332. * @param {HTMLElement} moveEl The element to move
  1333. * @param {HTMLElement} targetEl The position reference element
  1334. * @static
  1335. */
  1336. moveToEl: function (moveEl, targetEl) {
  1337. var aCoord = YAHOO.util.Dom.getXY(targetEl);
  1338. YAHOO.log("moveToEl: " + aCoord, "info", "DragDropMgr");
  1339. YAHOO.util.Dom.setXY(moveEl, aCoord);
  1340. },
  1341. /**
  1342. * Gets the client height
  1343. * @method getClientHeight
  1344. * @return {int} client height in px
  1345. * @deprecated use YAHOO.util.Dom.getViewportHeight instead
  1346. * @static
  1347. */
  1348. getClientHeight: function() {
  1349. return YAHOO.util.Dom.getViewportHeight();
  1350. },
  1351. /**
  1352. * Gets the client width
  1353. * @method getClientWidth
  1354. * @return {int} client width in px
  1355. * @deprecated use YAHOO.util.Dom.getViewportWidth instead
  1356. * @static
  1357. */
  1358. getClientWidth: function() {
  1359. return YAHOO.util.Dom.getViewportWidth();
  1360. },
  1361. /**
  1362. * Numeric array sort function
  1363. * @method numericSort
  1364. * @static
  1365. */
  1366. numericSort: function(a, b) { return (a - b); },
  1367. /**
  1368. * Internal counter
  1369. * @property _timeoutCount
  1370. * @private
  1371. * @static
  1372. */
  1373. _timeoutCount: 0,
  1374. /**
  1375. * Trying to make the load order less important. Without this we get
  1376. * an error if this file is loaded before the Event Utility.
  1377. * @method _addListeners
  1378. * @private
  1379. * @static
  1380. */
  1381. _addListeners: function() {
  1382. var DDM = YAHOO.util.DDM;
  1383. if ( YAHOO.util.Event && document ) {
  1384. DDM._onLoad();
  1385. } else {
  1386. if (DDM._timeoutCount > 2000) {
  1387. YAHOO.log("DragDrop requires the Event Utility", "error", "DragDropMgr");
  1388. } else {
  1389. setTimeout(DDM._addListeners, 10);
  1390. if (document && document.body) {
  1391. DDM._timeoutCount += 1;
  1392. }
  1393. }
  1394. }
  1395. },
  1396. /**
  1397. * Recursively searches the immediate parent and all child nodes for
  1398. * the handle element in order to determine wheter or not it was
  1399. * clicked.
  1400. * @method handleWasClicked
  1401. * @param node the html element to inspect
  1402. * @static
  1403. */
  1404. handleWasClicked: function(node, id) {
  1405. if (this.isHandle(id, node.id)) {
  1406. YAHOO.log("clicked node is a handle", "info", "DragDropMgr");
  1407. return true;
  1408. } else {
  1409. // check to see if this is a text node child of the one we want
  1410. var p = node.parentNode;
  1411. // YAHOO.log("p: " + p);
  1412. while (p) {
  1413. if (this.isHandle(id, p.id)) {
  1414. return true;
  1415. } else {
  1416. YAHOO.log(p.id + " is not a handle", "info", "DragDropMgr");
  1417. p = p.parentNode;
  1418. }
  1419. }
  1420. }
  1421. return false;
  1422. }
  1423. };
  1424. }();
  1425. // shorter alias, save a few bytes
  1426. YAHOO.util.DDM = YAHOO.util.DragDropMgr;
  1427. YAHOO.util.DDM._addListeners();
  1428. }
  1429. (function() {
  1430. var Event=YAHOO.util.Event;
  1431. var Dom=YAHOO.util.Dom;
  1432. /**
  1433. * Defines the interface and base operation of items that that can be
  1434. * dragged or can be drop targets. It was designed to be extended, overriding
  1435. * the event handlers for startDrag, onDrag, onDragOver, onDragOut.
  1436. * Up to three html elements can be associated with a DragDrop instance:
  1437. * <ul>
  1438. * <li>linked element: the element that is passed into the constructor.
  1439. * This is the element which defines the boundaries for interaction with
  1440. * other DragDrop objects.</li>
  1441. * <li>handle element(s): The drag operation only occurs if the element that
  1442. * was clicked matches a handle element. By default this is the linked
  1443. * element, but there are times that you will want only a portion of the
  1444. * linked element to initiate the drag operation, and the setHandleElId()
  1445. * method provides a way to define this.</li>
  1446. * <li>drag element: this represents an the element that would be moved along
  1447. * with the cursor during a drag operation. By default, this is the linked
  1448. * element itself as in {@link YAHOO.util.DD}. setDragElId() lets you define
  1449. * a separate element that would be moved, as in {@link YAHOO.util.DDProxy}
  1450. * </li>
  1451. * </ul>
  1452. * This class should not be instantiated until the onload event to ensure that
  1453. * the associated elements are available.
  1454. * The following would define a DragDrop obj that would interact with any
  1455. * other DragDrop obj in the "group1" group:
  1456. * <pre>
  1457. * dd = new YAHOO.util.DragDrop("div1", "group1");
  1458. * </pre>
  1459. * Since none of the event handlers have been implemented, nothing would
  1460. * actually happen if you were to run the code above. Normally you would
  1461. * override this class or one of the default implementations, but you can
  1462. * also override the methods you want on an instance of the class...
  1463. * <pre>
  1464. * dd.onDragDrop = function(e, id) {
  1465. * &nbsp;&nbsp;alert("dd was dropped on " + id);
  1466. * }
  1467. * </pre>
  1468. * @namespace YAHOO.util
  1469. * @class DragDrop
  1470. * @constructor
  1471. * @param {String} id of the element that is linked to this instance
  1472. * @param {String} sGroup the group of related DragDrop objects
  1473. * @param {object} config an object containing configurable attributes
  1474. * Valid properties for DragDrop:
  1475. * padding, isTarget, maintainOffset, primaryButtonOnly,
  1476. */
  1477. YAHOO.util.DragDrop = function(id, sGroup, config) {
  1478. if (id) {
  1479. this.init(id, sGroup, config);
  1480. }
  1481. };
  1482. YAHOO.util.DragDrop.prototype = {
  1483. /**
  1484. * An Object Literal containing the events that we will be using: mouseDown, b4MouseDown, mouseUp, b4StartDrag, startDrag, b4EndDrag, endDrag, mouseUp, drag, b4Drag, invalidDrop, b4DragOut, dragOut, dragEnter, b4DragOver, dragOver, b4DragDrop, dragDrop
  1485. * By setting any of these to false, then event will not be fired.
  1486. * @property events
  1487. * @type object
  1488. */
  1489. events: null,
  1490. /**
  1491. * @method on
  1492. * @description Shortcut for EventProvider.subscribe, see <a href="YAHOO.util.EventProvider.html#subscribe">YAHOO.util.EventProvider.subscribe</a>
  1493. */
  1494. on: function() {
  1495. this.subscribe.apply(this, arguments);
  1496. },
  1497. /**
  1498. * The id of the element associated with this object. This is what we
  1499. * refer to as the "linked element" because the size and position of
  1500. * this element is used to determine when the drag and drop objects have
  1501. * interacted.
  1502. * @property id
  1503. * @type String
  1504. */
  1505. id: null,
  1506. /**
  1507. * Configuration attributes passed into the constructor
  1508. * @property config
  1509. * @type object
  1510. */
  1511. config: null,
  1512. /**
  1513. * The id of the element that will be dragged. By default this is same
  1514. * as the linked element , but could be changed to another element. Ex:
  1515. * YAHOO.util.DDProxy
  1516. * @property dragElId
  1517. * @type String
  1518. * @private
  1519. */
  1520. dragElId: null,
  1521. /**
  1522. * the id of the element that initiates the drag operation. By default
  1523. * this is the linked element, but could be changed to be a child of this
  1524. * element. This lets us do things like only starting the drag when the
  1525. * header element within the linked html element is clicked.
  1526. * @property handleElId
  1527. * @type String
  1528. * @private
  1529. */
  1530. handleElId: null,
  1531. /**
  1532. * An associative array of HTML tags that will be ignored if clicked.
  1533. * @property invalidHandleTypes
  1534. * @type {string: string}
  1535. */
  1536. invalidHandleTypes: null,
  1537. /**
  1538. * An associative array of ids for elements that will be ignored if clicked
  1539. * @property invalidHandleIds
  1540. * @type {string: string}
  1541. */
  1542. invalidHandleIds: null,
  1543. /**
  1544. * An indexted array of css class names for elements that will be ignored
  1545. * if clicked.
  1546. * @property invalidHandleClasses
  1547. * @type string[]
  1548. */
  1549. invalidHandleClasses: null,
  1550. /**
  1551. * The linked element's absolute X position at the time the drag was
  1552. * started
  1553. * @property startPageX
  1554. * @type int
  1555. * @private
  1556. */
  1557. startPageX: 0,
  1558. /**
  1559. * The linked element's absolute X position at the time the drag was
  1560. * started
  1561. * @property startPageY
  1562. * @type int
  1563. * @private
  1564. */
  1565. startPageY: 0,
  1566. /**
  1567. * The group defines a logical collection of DragDrop objects that are
  1568. * related. Instances only get events when interacting with other
  1569. * DragDrop object in the same group. This lets us define multiple
  1570. * groups using a single DragDrop subclass if we want.
  1571. * @property groups
  1572. * @type {string: string}
  1573. */
  1574. groups: null,
  1575. /**
  1576. * Individual drag/drop instances can be locked. This will prevent
  1577. * onmousedown start drag.
  1578. * @property locked
  1579. * @type boolean
  1580. * @private
  1581. */
  1582. locked: false,
  1583. /**
  1584. * Lock this instance
  1585. * @method lock
  1586. */
  1587. lock: function() { this.locked = true; },
  1588. /**
  1589. * Unlock this instace
  1590. * @method unlock
  1591. */
  1592. unlock: function() { this.locked = false; },
  1593. /**
  1594. * By default, all instances can be a drop target. This can be disabled by
  1595. * setting isTarget to false.
  1596. * @property isTarget
  1597. * @type boolean
  1598. */
  1599. isTarget: true,
  1600. /**
  1601. * The padding configured for this drag and drop object for calculating
  1602. * the drop zone intersection with this object.
  1603. * @property padding
  1604. * @type int[]
  1605. */
  1606. padding: null,
  1607. /**
  1608. * If this flag is true, do not fire drop events. The element is a drag only element (for movement not dropping)
  1609. * @property dragOnly
  1610. * @type Boolean
  1611. */
  1612. dragOnly: false,
  1613. /**
  1614. * If this flag is true, a shim will be placed over the screen/viewable area to track mouse events. Should help with dragging elements over iframes and other controls.
  1615. * @property useShim
  1616. * @type Boolean
  1617. */
  1618. useShim: false,
  1619. /**
  1620. * Cached reference to the linked element
  1621. * @property _domRef
  1622. * @private
  1623. */
  1624. _domRef: null,
  1625. /**
  1626. * Internal typeof flag
  1627. * @property __ygDragDrop
  1628. * @private
  1629. */
  1630. __ygDragDrop: true,
  1631. /**
  1632. * Set to true when horizontal contraints are applied
  1633. * @property constrainX
  1634. * @type boolean
  1635. * @private
  1636. */
  1637. constrainX: false,
  1638. /**
  1639. * Set to true when vertical contraints are applied
  1640. * @property constrainY
  1641. * @type boolean
  1642. * @private
  1643. */
  1644. constrainY: false,
  1645. /**
  1646. * The left constraint
  1647. * @property minX
  1648. * @type int
  1649. * @private
  1650. */
  1651. minX: 0,
  1652. /**
  1653. * The right constraint
  1654. * @property maxX
  1655. * @type int
  1656. * @private
  1657. */
  1658. maxX: 0,
  1659. /**
  1660. * The up constraint
  1661. * @property minY
  1662. * @type int
  1663. * @type int
  1664. * @private
  1665. */
  1666. minY: 0,
  1667. /**
  1668. * The down constraint
  1669. * @property maxY
  1670. * @type int
  1671. * @private
  1672. */
  1673. maxY: 0,
  1674. /**
  1675. * The difference between the click position and the source element's location
  1676. * @property deltaX
  1677. * @type int
  1678. * @private
  1679. */
  1680. deltaX: 0,
  1681. /**
  1682. * The difference between the click position and the source element's location
  1683. * @property deltaY
  1684. * @type int
  1685. * @private
  1686. */
  1687. deltaY: 0,
  1688. /**
  1689. * Maintain offsets when we resetconstraints. Set to true when you want
  1690. * the position of the element relative to its parent to stay the same
  1691. * when the page changes
  1692. *
  1693. * @property maintainOffset
  1694. * @type boolean
  1695. */
  1696. maintainOffset: false,
  1697. /**
  1698. * Array of pixel locations the element will snap to if we specified a
  1699. * horizontal graduation/interval. This array is generated automatically
  1700. * when you define a tick interval.
  1701. * @property xTicks
  1702. * @type int[]
  1703. */
  1704. xTicks: null,
  1705. /**
  1706. * Array of pixel locations the element will snap to if we specified a
  1707. * vertical graduation/interval. This array is generated automatically
  1708. * when you define a tick interval.
  1709. * @property yTicks
  1710. * @type int[]
  1711. */
  1712. yTicks: null,
  1713. /**
  1714. * By default the drag and drop instance will only respond to the primary
  1715. * button click (left button for a right-handed mouse). Set to true to
  1716. * allow drag and drop to start with any mouse click that is propogated
  1717. * by the browser
  1718. * @property primaryButtonOnly
  1719. * @type boolean
  1720. */
  1721. primaryButtonOnly: true,
  1722. /**
  1723. * The availabe property is false until the linked dom element is accessible.
  1724. * @property available
  1725. * @type boolean
  1726. */
  1727. available: false,
  1728. /**
  1729. * By default, drags can only be initiated if the mousedown occurs in the
  1730. * region the linked element is. This is done in part to work around a
  1731. * bug in some browsers that mis-report the mousedown if the previous
  1732. * mouseup happened outside of the window. This property is set to true
  1733. * if outer handles are defined.
  1734. *
  1735. * @property hasOuterHandles
  1736. * @type boolean
  1737. * @default false
  1738. */
  1739. hasOuterHandles: false,
  1740. /**
  1741. * Property that is assigned to a drag and drop object when testing to
  1742. * see if it is being targeted by another dd object. This property
  1743. * can be used in intersect mode to help determine the focus of
  1744. * the mouse interaction. DDM.getBestMatch uses this property first to
  1745. * determine the closest match in INTERSECT mode when multiple targets
  1746. * are part of the same interaction.
  1747. * @property cursorIsOver
  1748. * @type boolean
  1749. */
  1750. cursorIsOver: false,
  1751. /**
  1752. * Property that is assigned to a drag and drop object when testing to
  1753. * see if it is being targeted by another dd object. This is a region
  1754. * that represents the area the draggable element overlaps this target.
  1755. * DDM.getBestMatch uses this property to compare the size of the overlap
  1756. * to that of other targets in order to determine the closest match in
  1757. * INTERSECT mode when multiple targets are part of the same interaction.
  1758. * @property overlap
  1759. * @type YAHOO.util.Region
  1760. */
  1761. overlap: null,
  1762. /**
  1763. * Code that executes immediately before the startDrag event
  1764. * @method b4StartDrag
  1765. * @private
  1766. */
  1767. b4StartDrag: function(x, y) { },
  1768. /**
  1769. * Abstract method called after a drag/drop object is clicked
  1770. * and the drag or mousedown time thresholds have beeen met.
  1771. * @method startDrag
  1772. * @param {int} X click location
  1773. * @param {int} Y click location
  1774. */
  1775. startDrag: function(x, y) { /* override this */ },
  1776. /**
  1777. * Code that executes immediately before the onDrag event
  1778. * @method b4Drag
  1779. * @private
  1780. */
  1781. b4Drag: function(e) { },
  1782. /**
  1783. * Abstract method called during the onMouseMove event while dragging an
  1784. * object.
  1785. * @method onDrag
  1786. * @param {Event} e the mousemove event
  1787. */
  1788. onDrag: function(e) { /* override this */ },
  1789. /**
  1790. * Abstract method called when this element fist begins hovering over
  1791. * another DragDrop obj
  1792. * @method onDragEnter
  1793. * @param {Event} e the mousemove event
  1794. * @param {String|DragDrop[]} id In POINT mode, the element
  1795. * id this is hovering over. In INTERSECT mode, an array of one or more
  1796. * dragdrop items being hovered over.
  1797. */
  1798. onDragEnter: function(e, id) { /* override this */ },
  1799. /**
  1800. * Code that executes immediately before the onDragOver event
  1801. * @method b4DragOver
  1802. * @private
  1803. */
  1804. b4DragOver: function(e) { },
  1805. /**
  1806. * Abstract method called when this element is hovering over another
  1807. * DragDrop obj
  1808. * @method onDragOver
  1809. * @param {Event} e the mousemove event
  1810. * @param {String|DragDrop[]} id In POINT mode, the element
  1811. * id this is hovering over. In INTERSECT mode, an array of dd items
  1812. * being hovered over.
  1813. */
  1814. onDragOver: function(e, id) { /* override this */ },
  1815. /**
  1816. * Code that executes immediately before the onDragOut event
  1817. * @method b4DragOut
  1818. * @private
  1819. */
  1820. b4DragOut: function(e) { },
  1821. /**
  1822. * Abstract method called when we are no longer hovering over an element
  1823. * @method onDragOut
  1824. * @param {Event} e the mousemove event
  1825. * @param {String|DragDrop[]} id In POINT mode, the element
  1826. * id this was hovering over. In INTERSECT mode, an array of dd items
  1827. * that the mouse is no longer over.
  1828. */
  1829. onDragOut: function(e, id) { /* override this */ },
  1830. /**
  1831. * Code that executes immediately before the onDragDrop event
  1832. * @method b4DragDrop
  1833. * @private
  1834. */
  1835. b4DragDrop: function(e) { },
  1836. /**
  1837. * Abstract method called when this item is dropped on another DragDrop
  1838. * obj
  1839. * @method onDragDrop
  1840. * @param {Event} e the mouseup event
  1841. * @param {String|DragDrop[]} id In POINT mode, the element
  1842. * id this was dropped on. In INTERSECT mode, an array of dd items this
  1843. * was dropped on.
  1844. */
  1845. onDragDrop: function(e, id) { /* override this */ },
  1846. /**
  1847. * Abstract method called when this item is dropped on an area with no
  1848. * drop target
  1849. * @method onInvalidDrop
  1850. * @param {Event} e the mouseup event
  1851. */
  1852. onInvalidDrop: function(e) { /* override this */ },
  1853. /**
  1854. * Code that executes immediately before the endDrag event
  1855. * @method b4EndDrag
  1856. * @private
  1857. */
  1858. b4EndDrag: function(e) { },
  1859. /**
  1860. * Fired when we are done dragging the object
  1861. * @method endDrag
  1862. * @param {Event} e the mouseup event
  1863. */
  1864. endDrag: function(e) { /* override this */ },
  1865. /**
  1866. * Code executed immediately before the onMouseDown event
  1867. * @method b4MouseDown
  1868. * @param {Event} e the mousedown event
  1869. * @private
  1870. */
  1871. b4MouseDown: function(e) { },
  1872. /**
  1873. * Event handler that fires when a drag/drop obj gets a mousedown
  1874. * @method onMouseDown
  1875. * @param {Event} e the mousedown event
  1876. */
  1877. onMouseDown: function(e) { /* override this */ },
  1878. /**
  1879. * Event handler that fires when a drag/drop obj gets a mouseup
  1880. * @method onMouseUp
  1881. * @param {Event} e the mouseup event
  1882. */
  1883. onMouseUp: function(e) { /* override this */ },
  1884. /**
  1885. * Override the onAvailable method to do what is needed after the initial
  1886. * position was determined.
  1887. * @method onAvailable
  1888. */
  1889. onAvailable: function () {
  1890. //this.logger.log("onAvailable (base)");
  1891. },
  1892. /**
  1893. * Returns a reference to the linked element
  1894. * @method getEl
  1895. * @return {HTMLElement} the html element
  1896. */
  1897. getEl: function() {
  1898. if (!this._domRef) {
  1899. this._domRef = Dom.get(this.id);
  1900. }
  1901. return this._domRef;
  1902. },
  1903. /**
  1904. * Returns a reference to the actual element to drag. By default this is
  1905. * the same as the html element, but it can be assigned to another
  1906. * element. An example of this can be found in YAHOO.util.DDProxy
  1907. * @method getDragEl
  1908. * @return {HTMLElement} the html element
  1909. */
  1910. getDragEl: function() {
  1911. return Dom.get(this.dragElId);
  1912. },
  1913. /**
  1914. * Sets up the DragDrop object. Must be called in the constructor of any
  1915. * YAHOO.util.DragDrop subclass
  1916. * @method init
  1917. * @param id the id of the linked element
  1918. * @param {String} sGroup the group of related items
  1919. * @param {object} config configuration attributes
  1920. */
  1921. init: function(id, sGroup, config) {
  1922. this.initTarget(id, sGroup, config);
  1923. Event.on(this._domRef || this.id, "mousedown",
  1924. this.handleMouseDown, this, true);
  1925. // Event.on(this.id, "selectstart", Event.preventDefault);
  1926. for (var i in this.events) {
  1927. this.createEvent(i + 'Event');
  1928. }
  1929. },
  1930. /**
  1931. * Initializes Targeting functionality only... the object does not
  1932. * get a mousedown handler.
  1933. * @method initTarget
  1934. * @param id the id of the linked element
  1935. * @param {String} sGroup the group of related items
  1936. * @param {object} config configuration attributes
  1937. */
  1938. initTarget: function(id, sGroup, config) {
  1939. // configuration attributes
  1940. this.config = config || {};
  1941. this.events = {};
  1942. // create a local reference to the drag and drop manager
  1943. this.DDM = YAHOO.util.DDM;
  1944. // initialize the groups object
  1945. this.groups = {};
  1946. // assume that we have an element reference instead of an id if the
  1947. // parameter is not a string
  1948. if (typeof id !== "string") {
  1949. YAHOO.log("id is not a string, assuming it is an HTMLElement");
  1950. this._domRef = id;
  1951. id = Dom.generateId(id);
  1952. }
  1953. // set the id
  1954. this.id = id;
  1955. // add to an interaction group
  1956. this.addToGroup((sGroup) ? sGroup : "default");
  1957. // We don't want to register this as the handle with the manager
  1958. // so we just set the id rather than calling the setter.
  1959. this.handleElId = id;
  1960. Event.onAvailable(id, this.handleOnAvailable, this, true);
  1961. // create a logger instance
  1962. this.logger = (YAHOO.widget.LogWriter) ?
  1963. new YAHOO.widget.LogWriter(this.toString()) : YAHOO;
  1964. // the linked element is the element that gets dragged by default
  1965. this.setDragElId(id);
  1966. // by default, clicked anchors will not start drag operations.
  1967. // @TODO what else should be here? Probably form fields.
  1968. this.invalidHandleTypes = { A: "A" };
  1969. this.invalidHandleIds = {};
  1970. this.invalidHandleClasses = [];
  1971. this.applyConfig();
  1972. },
  1973. /**
  1974. * Applies the configuration parameters that were passed into the constructor.
  1975. * This is supposed to happen at each level through the inheritance chain. So
  1976. * a DDProxy implentation will execute apply config on DDProxy, DD, and
  1977. * DragDrop in order to get all of the parameters that are available in
  1978. * each object.
  1979. * @method applyConfig
  1980. */
  1981. applyConfig: function() {
  1982. this.events = {
  1983. mouseDown: true,
  1984. b4MouseDown: true,
  1985. mouseUp: true,
  1986. b4StartDrag: true,
  1987. startDrag: true,
  1988. b4EndDrag: true,
  1989. endDrag: true,
  1990. drag: true,
  1991. b4Drag: true,
  1992. invalidDrop: true,
  1993. b4DragOut: true,
  1994. dragOut: true,
  1995. dragEnter: true,
  1996. b4DragOver: true,
  1997. dragOver: true,
  1998. b4DragDrop: true,
  1999. dragDrop: true
  2000. };
  2001. if (this.config.events) {
  2002. for (var i in this.config.events) {
  2003. if (this.config.events[i] === false) {
  2004. this.events[i] = false;
  2005. }
  2006. }
  2007. }
  2008. // configurable properties:
  2009. // padding, isTarget, maintainOffset, primaryButtonOnly
  2010. this.padding = this.config.padding || [0, 0, 0, 0];
  2011. this.isTarget = (this.config.isTarget !== false);
  2012. this.maintainOffset = (this.config.maintainOffset);
  2013. this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
  2014. this.dragOnly = ((this.config.dragOnly === true) ? true : false);
  2015. this.useShim = ((this.config.useShim === true) ? true : false);
  2016. },
  2017. /**
  2018. * Executed when the linked element is available
  2019. * @method handleOnAvailable
  2020. * @private
  2021. */
  2022. handleOnAvailable: function() {
  2023. //this.logger.log("handleOnAvailable");
  2024. this.available = true;
  2025. this.resetConstraints();
  2026. this.onAvailable();
  2027. },
  2028. /**
  2029. * Configures the padding for the target zone in px. Effectively expands
  2030. * (or reduces) the virtual object size for targeting calculations.
  2031. * Supports css-style shorthand; if only one parameter is passed, all sides
  2032. * will have that padding, and if only two are passed, the top and bottom
  2033. * will have the first param, the left and right the second.
  2034. * @method setPadding
  2035. * @param {int} iTop Top pad
  2036. * @param {int} iRight Right pad
  2037. * @param {int} iBot Bot pad
  2038. * @param {int} iLeft Left pad
  2039. */
  2040. setPadding: function(iTop, iRight, iBot, iLeft) {
  2041. // this.padding = [iLeft, iRight, iTop, iBot];
  2042. if (!iRight && 0 !== iRight) {
  2043. this.padding = [iTop, iTop, iTop, iTop];
  2044. } else if (!iBot && 0 !== iBot) {
  2045. this.padding = [iTop, iRight, iTop, iRight];
  2046. } else {
  2047. this.padding = [iTop, iRight, iBot, iLeft];
  2048. }
  2049. },
  2050. /**
  2051. * Stores the initial placement of the linked element.
  2052. * @method setInitialPosition
  2053. * @param {int} diffX the X offset, default 0
  2054. * @param {int} diffY the Y offset, default 0
  2055. * @private
  2056. */
  2057. setInitPosition: function(diffX, diffY) {
  2058. var el = this.getEl();
  2059. if (!this.DDM.verifyEl(el)) {
  2060. if (el && el.style && (el.style.display == 'none')) {
  2061. this.logger.log(this.id + " can not get initial position, element style is display: none");
  2062. } else {
  2063. this.logger.log(this.id + " element is broken");
  2064. }
  2065. return;
  2066. }
  2067. var dx = diffX || 0;
  2068. var dy = diffY || 0;
  2069. var p = Dom.getXY( el );
  2070. this.initPageX = p[0] - dx;
  2071. this.initPageY = p[1] - dy;
  2072. this.lastPageX = p[0];
  2073. this.lastPageY = p[1];
  2074. this.logger.log(this.id + " initial position: " + this.initPageX +
  2075. ", " + this.initPageY);
  2076. this.setStartPosition(p);
  2077. },
  2078. /**
  2079. * Sets the start position of the element. This is set when the obj
  2080. * is initialized, the reset when a drag is started.
  2081. * @method setStartPosition
  2082. * @param pos current position (from previous lookup)
  2083. * @private
  2084. */
  2085. setStartPosition: function(pos) {
  2086. var p = pos || Dom.getXY(this.getEl());
  2087. this.deltaSetXY = null;
  2088. this.startPageX = p[0];
  2089. this.startPageY = p[1];
  2090. },
  2091. /**
  2092. * Add this instance to a group of related drag/drop objects. All
  2093. * instances belong to at least one group, and can belong to as many
  2094. * groups as needed.
  2095. * @method addToGroup
  2096. * @param sGroup {string} the name of the group
  2097. */
  2098. addToGroup: function(sGroup) {
  2099. this.groups[sGroup] = true;
  2100. this.DDM.regDragDrop(this, sGroup);
  2101. },
  2102. /**
  2103. * Remove's this instance from the supplied interaction group
  2104. * @method removeFromGroup
  2105. * @param {string} sGroup The group to drop
  2106. */
  2107. removeFromGroup: function(sGroup) {
  2108. this.logger.log("Removing from group: " + sGroup);
  2109. if (this.groups[sGroup]) {
  2110. delete this.groups[sGroup];
  2111. }
  2112. this.DDM.removeDDFromGroup(this, sGroup);
  2113. },
  2114. /**
  2115. * Allows you to specify that an element other than the linked element
  2116. * will be moved with the cursor during a drag
  2117. * @method setDragElId
  2118. * @param id {string} the id of the element that will be used to initiate the drag
  2119. */
  2120. setDragElId: function(id) {
  2121. this.dragElId = id;
  2122. },
  2123. /**
  2124. * Allows you to specify a child of the linked element that should be
  2125. * used to initiate the drag operation. An example of this would be if
  2126. * you have a content div with text and links. Clicking anywhere in the
  2127. * content area would normally start the drag operation. Use this method
  2128. * to specify that an element inside of the content div is the element
  2129. * that starts the drag operation.
  2130. * @method setHandleElId
  2131. * @param id {string} the id of the element that will be used to
  2132. * initiate the drag.
  2133. */
  2134. setHandleElId: function(id) {
  2135. if (typeof id !== "string") {
  2136. YAHOO.log("id is not a string, assuming it is an HTMLElement");
  2137. id = Dom.generateId(id);
  2138. }
  2139. this.handleElId = id;
  2140. this.DDM.regHandle(this.id, id);
  2141. },
  2142. /**
  2143. * Allows you to set an element outside of the linked element as a drag
  2144. * handle
  2145. * @method setOuterHandleElId
  2146. * @param id the id of the element that will be used to initiate the drag
  2147. */
  2148. setOuterHandleElId: function(id) {
  2149. if (typeof id !== "string") {
  2150. YAHOO.log("id is not a string, assuming it is an HTMLElement");
  2151. id = Dom.generateId(id);
  2152. }
  2153. this.logger.log("Adding outer handle event: " + id);
  2154. Event.on(id, "mousedown",
  2155. this.handleMouseDown, this, true);
  2156. this.setHandleElId(id);
  2157. this.hasOuterHandles = true;
  2158. },
  2159. /**
  2160. * Remove all drag and drop hooks for this element
  2161. * @method unreg
  2162. */
  2163. unreg: function() {
  2164. this.logger.log("DragDrop obj cleanup " + this.id);
  2165. Event.removeListener(this.id, "mousedown",
  2166. this.handleMouseDown);
  2167. this._domRef = null;
  2168. this.DDM._remove(this);
  2169. },
  2170. /**
  2171. * Returns true if this instance is locked, or the drag drop mgr is locked
  2172. * (meaning that all drag/drop is disabled on the page.)
  2173. * @method isLocked
  2174. * @return {boolean} true if this obj or all drag/drop is locked, else
  2175. * false
  2176. */
  2177. isLocked: function() {
  2178. return (this.DDM.isLocked() || this.locked);
  2179. },
  2180. /**
  2181. * Fired when this object is clicked
  2182. * @method handleMouseDown
  2183. * @param {Event} e
  2184. * @param {YAHOO.util.DragDrop} oDD the clicked dd object (this dd obj)
  2185. * @private
  2186. */
  2187. handleMouseDown: function(e, oDD) {
  2188. var button = e.which || e.button;
  2189. this.logger.log("button: " + button);
  2190. if (this.primaryButtonOnly && button > 1) {
  2191. this.logger.log("Mousedown was not produced by the primary button");
  2192. return;
  2193. }
  2194. if (this.isLocked()) {
  2195. this.logger.log("Drag and drop is disabled, aborting");
  2196. return;
  2197. }
  2198. this.logger.log("mousedown " + this.id);
  2199. this.logger.log("firing onMouseDown events");
  2200. // firing the mousedown events prior to calculating positions
  2201. var b4Return = this.b4MouseDown(e),
  2202. b4Return2 = true;
  2203. if (this.events.b4MouseDown) {
  2204. b4Return2 = this.fireEvent('b4MouseDownEvent', e);
  2205. }
  2206. var mDownReturn = this.onMouseDown(e),
  2207. mDownReturn2 = true;
  2208. if (this.events.mouseDown) {
  2209. mDownReturn2 = this.fireEvent('mouseDownEvent', e);
  2210. }
  2211. if ((b4Return === false) || (mDownReturn === false) || (b4Return2 === false) || (mDownReturn2 === false)) {
  2212. this.logger.log('b4MouseDown or onMouseDown returned false, exiting drag');
  2213. return;
  2214. }
  2215. this.DDM.refreshCache(this.groups);
  2216. // var self = this;
  2217. // setTimeout( function() { self.DDM.refreshCache(self.groups); }, 0);
  2218. // Only process the event if we really clicked within the linked
  2219. // element. The reason we make this check is that in the case that
  2220. // another element was moved between the clicked element and the
  2221. // cursor in the time between the mousedown and mouseup events. When
  2222. // this happens, the element gets the next mousedown event
  2223. // regardless of where on the screen it happened.
  2224. var pt = new YAHOO.util.Point(Event.getPageX(e), Event.getPageY(e));
  2225. if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
  2226. this.logger.log("Click was not over the element: " + this.id);
  2227. } else {
  2228. if (this.clickValidator(e)) {
  2229. this.logger.log("click was a valid handle");
  2230. // set the initial element position
  2231. this.setStartPosition();
  2232. // start tracking mousemove distance and mousedown time to
  2233. // determine when to start the actual drag
  2234. this.DDM.handleMouseDown(e, this);
  2235. // this mousedown is mine
  2236. this.DDM.stopEvent(e);
  2237. } else {
  2238. this.logger.log("clickValidator returned false, drag not initiated");
  2239. }
  2240. }
  2241. },
  2242. /**
  2243. * @method clickValidator
  2244. * @description Method validates that the clicked element
  2245. * was indeed the handle or a valid child of the handle
  2246. * @param {Event} e
  2247. */
  2248. clickValidator: function(e) {
  2249. var target = YAHOO.util.Event.getTarget(e);
  2250. return ( this.isValidHandleChild(target) &&
  2251. (this.id == this.handleElId ||
  2252. this.DDM.handleWasClicked(target, this.id)) );
  2253. },
  2254. /**
  2255. * Finds the location the element should be placed if we want to move
  2256. * it to where the mouse location less the click offset would place us.
  2257. * @method getTargetCoord
  2258. * @param {int} iPageX the X coordinate of the click
  2259. * @param {int} iPageY the Y coordinate of the click
  2260. * @return an object that contains the coordinates (Object.x and Object.y)
  2261. * @private
  2262. */
  2263. getTargetCoord: function(iPageX, iPageY) {
  2264. // this.logger.log("getTargetCoord: " + iPageX + ", " + iPageY);
  2265. var x = iPageX - this.deltaX;
  2266. var y = iPageY - this.deltaY;
  2267. if (this.constrainX) {
  2268. if (x < this.minX) { x = this.minX; }
  2269. if (x > this.maxX) { x = this.maxX; }
  2270. }
  2271. if (this.constrainY) {
  2272. if (y < this.minY) { y = this.minY; }
  2273. if (y > this.maxY) { y = this.maxY; }
  2274. }
  2275. x = this.getTick(x, this.xTicks);
  2276. y = this.getTick(y, this.yTicks);
  2277. // this.logger.log("getTargetCoord " +
  2278. // " iPageX: " + iPageX +
  2279. // " iPageY: " + iPageY +
  2280. // " x: " + x + ", y: " + y);
  2281. return {x:x, y:y};
  2282. },
  2283. /**
  2284. * Allows you to specify a tag name that should not start a drag operation
  2285. * when clicked. This is designed to facilitate embedding links within a
  2286. * drag handle that do something other than start the drag.
  2287. * @method addInvalidHandleType
  2288. * @param {string} tagName the type of element to exclude
  2289. */
  2290. addInvalidHandleType: function(tagName) {
  2291. var type = tagName.toUpperCase();
  2292. this.invalidHandleTypes[type] = type;
  2293. },
  2294. /**
  2295. * Lets you to specify an element id for a child of a drag handle
  2296. * that should not initiate a drag
  2297. * @method addInvalidHandleId
  2298. * @param {string} id the element id of the element you wish to ignore
  2299. */
  2300. addInvalidHandleId: function(id) {
  2301. if (typeof id !== "string") {
  2302. YAHOO.log("id is not a string, assuming it is an HTMLElement");
  2303. id = Dom.generateId(id);
  2304. }
  2305. this.invalidHandleIds[id] = id;
  2306. },
  2307. /**
  2308. * Lets you specify a css class of elements that will not initiate a drag
  2309. * @method addInvalidHandleClass
  2310. * @param {string} cssClass the class of the elements you wish to ignore
  2311. */
  2312. addInvalidHandleClass: function(cssClass) {
  2313. this.invalidHandleClasses.push(cssClass);
  2314. },
  2315. /**
  2316. * Unsets an excluded tag name set by addInvalidHandleType
  2317. * @method removeInvalidHandleType
  2318. * @param {string} tagName the type of element to unexclude
  2319. */
  2320. removeInvalidHandleType: function(tagName) {
  2321. var type = tagName.toUpperCase();
  2322. // this.invalidHandleTypes[type] = null;
  2323. delete this.invalidHandleTypes[type];
  2324. },
  2325. /**
  2326. * Unsets an invalid handle id
  2327. * @method removeInvalidHandleId
  2328. * @param {string} id the id of the element to re-enable
  2329. */
  2330. removeInvalidHandleId: function(id) {
  2331. if (typeof id !== "string") {
  2332. YAHOO.log("id is not a string, assuming it is an HTMLElement");
  2333. id = Dom.generateId(id);
  2334. }
  2335. delete this.invalidHandleIds[id];
  2336. },
  2337. /**
  2338. * Unsets an invalid css class
  2339. * @method removeInvalidHandleClass
  2340. * @param {string} cssClass the class of the element(s) you wish to
  2341. * re-enable
  2342. */
  2343. removeInvalidHandleClass: function(cssClass) {
  2344. for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
  2345. if (this.invalidHandleClasses[i] == cssClass) {
  2346. delete this.invalidHandleClasses[i];
  2347. }
  2348. }
  2349. },
  2350. /**
  2351. * Checks the tag exclusion list to see if this click should be ignored
  2352. * @method isValidHandleChild
  2353. * @param {HTMLElement} node the HTMLElement to evaluate
  2354. * @return {boolean} true if this is a valid tag type, false if not
  2355. */
  2356. isValidHandleChild: function(node) {
  2357. var valid = true;
  2358. // var n = (node.nodeName == "#text") ? node.parentNode : node;
  2359. var nodeName;
  2360. try {
  2361. nodeName = node.nodeName.toUpperCase();
  2362. } catch(e) {
  2363. nodeName = node.nodeName;
  2364. }
  2365. valid = valid && !this.invalidHandleTypes[nodeName];
  2366. valid = valid && !this.invalidHandleIds[node.id];
  2367. for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
  2368. valid = !Dom.hasClass(node, this.invalidHandleClasses[i]);
  2369. }
  2370. this.logger.log("Valid handle? ... " + valid);
  2371. return valid;
  2372. },
  2373. /**
  2374. * Create the array of horizontal tick marks if an interval was specified
  2375. * in setXConstraint().
  2376. * @method setXTicks
  2377. * @private
  2378. */
  2379. setXTicks: function(iStartX, iTickSize) {
  2380. this.xTicks = [];
  2381. this.xTickSize = iTickSize;
  2382. var tickMap = {};
  2383. for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
  2384. if (!tickMap[i]) {
  2385. this.xTicks[this.xTicks.length] = i;
  2386. tickMap[i] = true;
  2387. }
  2388. }
  2389. for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
  2390. if (!tickMap[i]) {
  2391. this.xTicks[this.xTicks.length] = i;
  2392. tickMap[i] = true;
  2393. }
  2394. }
  2395. this.xTicks.sort(this.DDM.numericSort) ;
  2396. this.logger.log("xTicks: " + this.xTicks.join());
  2397. },
  2398. /**
  2399. * Create the array of vertical tick marks if an interval was specified in
  2400. * setYConstraint().
  2401. * @method setYTicks
  2402. * @private
  2403. */
  2404. setYTicks: function(iStartY, iTickSize) {
  2405. // this.logger.log("setYTicks: " + iStartY + ", " + iTickSize
  2406. // + ", " + this.initPageY + ", " + this.minY + ", " + this.maxY );
  2407. this.yTicks = [];
  2408. this.yTickSize = iTickSize;
  2409. var tickMap = {};
  2410. for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
  2411. if (!tickMap[i]) {
  2412. this.yTicks[this.yTicks.length] = i;
  2413. tickMap[i] = true;
  2414. }
  2415. }
  2416. for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
  2417. if (!tickMap[i]) {
  2418. this.yTicks[this.yTicks.length] = i;
  2419. tickMap[i] = true;
  2420. }
  2421. }
  2422. this.yTicks.sort(this.DDM.numericSort) ;
  2423. this.logger.log("yTicks: " + this.yTicks.join());
  2424. },
  2425. /**
  2426. * By default, the element can be dragged any place on the screen. Use
  2427. * this method to limit the horizontal travel of the element. Pass in
  2428. * 0,0 for the parameters if you want to lock the drag to the y axis.
  2429. * @method setXConstraint
  2430. * @param {int} iLeft the number of pixels the element can move to the left
  2431. * @param {int} iRight the number of pixels the element can move to the
  2432. * right
  2433. * @param {int} iTickSize optional parameter for specifying that the
  2434. * element
  2435. * should move iTickSize pixels at a time.
  2436. */
  2437. setXConstraint: function(iLeft, iRight, iTickSize) {
  2438. this.leftConstraint = parseInt(iLeft, 10);
  2439. this.rightConstraint = parseInt(iRight, 10);
  2440. this.minX = this.initPageX - this.leftConstraint;
  2441. this.maxX = this.initPageX + this.rightConstraint;
  2442. if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
  2443. this.constrainX = true;
  2444. this.logger.log("initPageX:" + this.initPageX + " minX:" + this.minX +
  2445. " maxX:" + this.maxX);
  2446. },
  2447. /**
  2448. * Clears any constraints applied to this instance. Also clears ticks
  2449. * since they can't exist independent of a constraint at this time.
  2450. * @method clearConstraints
  2451. */
  2452. clearConstraints: function() {
  2453. this.logger.log("Clearing constraints");
  2454. this.constrainX = false;
  2455. this.constrainY = false;
  2456. this.clearTicks();
  2457. },
  2458. /**
  2459. * Clears any tick interval defined for this instance
  2460. * @method clearTicks
  2461. */
  2462. clearTicks: function() {
  2463. this.logger.log("Clearing ticks");
  2464. this.xTicks = null;
  2465. this.yTicks = null;
  2466. this.xTickSize = 0;
  2467. this.yTickSize = 0;
  2468. },
  2469. /**
  2470. * By default, the element can be dragged any place on the screen. Set
  2471. * this to limit the vertical travel of the element. Pass in 0,0 for the
  2472. * parameters if you want to lock the drag to the x axis.
  2473. * @method setYConstraint
  2474. * @param {int} iUp the number of pixels the element can move up
  2475. * @param {int} iDown the number of pixels the element can move down
  2476. * @param {int} iTickSize optional parameter for specifying that the
  2477. * element should move iTickSize pixels at a time.
  2478. */
  2479. setYConstraint: function(iUp, iDown, iTickSize) {
  2480. this.logger.log("setYConstraint: " + iUp + "," + iDown + "," + iTickSize);
  2481. this.topConstraint = parseInt(iUp, 10);
  2482. this.bottomConstraint = parseInt(iDown, 10);
  2483. this.minY = this.initPageY - this.topConstraint;
  2484. this.maxY = this.initPageY + this.bottomConstraint;
  2485. if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
  2486. this.constrainY = true;
  2487. this.logger.log("initPageY:" + this.initPageY + " minY:" + this.minY +
  2488. " maxY:" + this.maxY);
  2489. },
  2490. /**
  2491. * resetConstraints must be called if you manually reposition a dd element.
  2492. * @method resetConstraints
  2493. */
  2494. resetConstraints: function() {
  2495. //this.logger.log("resetConstraints");
  2496. // Maintain offsets if necessary
  2497. if (this.initPageX || this.initPageX === 0) {
  2498. //this.logger.log("init pagexy: " + this.initPageX + ", " +
  2499. //this.initPageY);
  2500. //this.logger.log("last pagexy: " + this.lastPageX + ", " +
  2501. //this.lastPageY);
  2502. // figure out how much this thing has moved
  2503. var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
  2504. var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
  2505. this.setInitPosition(dx, dy);
  2506. // This is the first time we have detected the element's position
  2507. } else {
  2508. this.setInitPosition();
  2509. }
  2510. if (this.constrainX) {
  2511. this.setXConstraint( this.leftConstraint,
  2512. this.rightConstraint,
  2513. this.xTickSize );
  2514. }
  2515. if (this.constrainY) {
  2516. this.setYConstraint( this.topConstraint,
  2517. this.bottomConstraint,
  2518. this.yTickSize );
  2519. }
  2520. },
  2521. /**
  2522. * Normally the drag element is moved pixel by pixel, but we can specify
  2523. * that it move a number of pixels at a time. This method resolves the
  2524. * location when we have it set up like this.
  2525. * @method getTick
  2526. * @param {int} val where we want to place the object
  2527. * @param {int[]} tickArray sorted array of valid points
  2528. * @return {int} the closest tick
  2529. * @private
  2530. */
  2531. getTick: function(val, tickArray) {
  2532. if (!tickArray) {
  2533. // If tick interval is not defined, it is effectively 1 pixel,
  2534. // so we return the value passed to us.
  2535. return val;
  2536. } else if (tickArray[0] >= val) {
  2537. // The value is lower than the first tick, so we return the first
  2538. // tick.
  2539. return tickArray[0];
  2540. } else {
  2541. for (var i=0, len=tickArray.length; i<len; ++i) {
  2542. var next = i + 1;
  2543. if (tickArray[next] && tickArray[next] >= val) {
  2544. var diff1 = val - tickArray[i];
  2545. var diff2 = tickArray[next] - val;
  2546. return (diff2 > diff1) ? tickArray[i] : tickArray[next];
  2547. }
  2548. }
  2549. // The value is larger than the last tick, so we return the last
  2550. // tick.
  2551. return tickArray[tickArray.length - 1];
  2552. }
  2553. },
  2554. /**
  2555. * toString method
  2556. * @method toString
  2557. * @return {string} string representation of the dd obj
  2558. */
  2559. toString: function() {
  2560. return ("DragDrop " + this.id);
  2561. }
  2562. };
  2563. YAHOO.augment(YAHOO.util.DragDrop, YAHOO.util.EventProvider);
  2564. /**
  2565. * @event mouseDownEvent
  2566. * @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
  2567. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2568. */
  2569. /**
  2570. * @event b4MouseDownEvent
  2571. * @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
  2572. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2573. */
  2574. /**
  2575. * @event mouseUpEvent
  2576. * @description Fired from inside DragDropMgr when the drag operation is finished.
  2577. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2578. */
  2579. /**
  2580. * @event b4StartDragEvent
  2581. * @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
  2582. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2583. */
  2584. /**
  2585. * @event startDragEvent
  2586. * @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown.
  2587. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2588. */
  2589. /**
  2590. * @event b4EndDragEvent
  2591. * @description Fires before the endDragEvent. Returning false will cancel.
  2592. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2593. */
  2594. /**
  2595. * @event endDragEvent
  2596. * @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
  2597. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2598. */
  2599. /**
  2600. * @event dragEvent
  2601. * @description Occurs every mousemove event while dragging.
  2602. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2603. */
  2604. /**
  2605. * @event b4DragEvent
  2606. * @description Fires before the dragEvent.
  2607. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2608. */
  2609. /**
  2610. * @event invalidDropEvent
  2611. * @description Fires when the dragged objects is dropped in a location that contains no drop targets.
  2612. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2613. */
  2614. /**
  2615. * @event b4DragOutEvent
  2616. * @description Fires before the dragOutEvent
  2617. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2618. */
  2619. /**
  2620. * @event dragOutEvent
  2621. * @description Fires when a dragged object is no longer over an object that had the onDragEnter fire.
  2622. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2623. */
  2624. /**
  2625. * @event dragEnterEvent
  2626. * @description Occurs when the dragged object first interacts with another targettable drag and drop object.
  2627. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2628. */
  2629. /**
  2630. * @event b4DragOverEvent
  2631. * @description Fires before the dragOverEvent.
  2632. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2633. */
  2634. /**
  2635. * @event dragOverEvent
  2636. * @description Fires every mousemove event while over a drag and drop object.
  2637. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2638. */
  2639. /**
  2640. * @event b4DragDropEvent
  2641. * @description Fires before the dragDropEvent
  2642. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2643. */
  2644. /**
  2645. * @event dragDropEvent
  2646. * @description Fires when the dragged objects is dropped on another.
  2647. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2648. */
  2649. })();
  2650. /**
  2651. * A DragDrop implementation where the linked element follows the
  2652. * mouse cursor during a drag.
  2653. * @class DD
  2654. * @extends YAHOO.util.DragDrop
  2655. * @constructor
  2656. * @param {String} id the id of the linked element
  2657. * @param {String} sGroup the group of related DragDrop items
  2658. * @param {object} config an object containing configurable attributes
  2659. * Valid properties for DD:
  2660. * scroll
  2661. */
  2662. YAHOO.util.DD = function(id, sGroup, config) {
  2663. if (id) {
  2664. this.init(id, sGroup, config);
  2665. }
  2666. };
  2667. YAHOO.extend(YAHOO.util.DD, YAHOO.util.DragDrop, {
  2668. /**
  2669. * When set to true, the utility automatically tries to scroll the browser
  2670. * window when a drag and drop element is dragged near the viewport boundary.
  2671. * Defaults to true.
  2672. * @property scroll
  2673. * @type boolean
  2674. */
  2675. scroll: true,
  2676. /**
  2677. * Sets the pointer offset to the distance between the linked element's top
  2678. * left corner and the location the element was clicked
  2679. * @method autoOffset
  2680. * @param {int} iPageX the X coordinate of the click
  2681. * @param {int} iPageY the Y coordinate of the click
  2682. */
  2683. autoOffset: function(iPageX, iPageY) {
  2684. var x = iPageX - this.startPageX;
  2685. var y = iPageY - this.startPageY;
  2686. this.setDelta(x, y);
  2687. // this.logger.log("autoOffset el pos: " + aCoord + ", delta: " + x + "," + y);
  2688. },
  2689. /**
  2690. * Sets the pointer offset. You can call this directly to force the
  2691. * offset to be in a particular location (e.g., pass in 0,0 to set it
  2692. * to the center of the object, as done in YAHOO.widget.Slider)
  2693. * @method setDelta
  2694. * @param {int} iDeltaX the distance from the left
  2695. * @param {int} iDeltaY the distance from the top
  2696. */
  2697. setDelta: function(iDeltaX, iDeltaY) {
  2698. this.deltaX = iDeltaX;
  2699. this.deltaY = iDeltaY;
  2700. this.logger.log("deltaX:" + this.deltaX + ", deltaY:" + this.deltaY);
  2701. },
  2702. /**
  2703. * Sets the drag element to the location of the mousedown or click event,
  2704. * maintaining the cursor location relative to the location on the element
  2705. * that was clicked. Override this if you want to place the element in a
  2706. * location other than where the cursor is.
  2707. * @method setDragElPos
  2708. * @param {int} iPageX the X coordinate of the mousedown or drag event
  2709. * @param {int} iPageY the Y coordinate of the mousedown or drag event
  2710. */
  2711. setDragElPos: function(iPageX, iPageY) {
  2712. // the first time we do this, we are going to check to make sure
  2713. // the element has css positioning
  2714. var el = this.getDragEl();
  2715. this.alignElWithMouse(el, iPageX, iPageY);
  2716. },
  2717. /**
  2718. * Sets the element to the location of the mousedown or click event,
  2719. * maintaining the cursor location relative to the location on the element
  2720. * that was clicked. Override this if you want to place the element in a
  2721. * location other than where the cursor is.
  2722. * @method alignElWithMouse
  2723. * @param {HTMLElement} el the element to move
  2724. * @param {int} iPageX the X coordinate of the mousedown or drag event
  2725. * @param {int} iPageY the Y coordinate of the mousedown or drag event
  2726. */
  2727. alignElWithMouse: function(el, iPageX, iPageY) {
  2728. var oCoord = this.getTargetCoord(iPageX, iPageY);
  2729. // this.logger.log("****alignElWithMouse : " + el.id + ", " + aCoord + ", " + el.style.display);
  2730. if (!this.deltaSetXY) {
  2731. var aCoord = [oCoord.x, oCoord.y];
  2732. YAHOO.util.Dom.setXY(el, aCoord);
  2733. var newLeft = parseInt( YAHOO.util.Dom.getStyle(el, "left"), 10 );
  2734. var newTop = parseInt( YAHOO.util.Dom.getStyle(el, "top" ), 10 );
  2735. this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
  2736. } else {
  2737. YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
  2738. YAHOO.util.Dom.setStyle(el, "top", (oCoord.y + this.deltaSetXY[1]) + "px");
  2739. }
  2740. this.cachePosition(oCoord.x, oCoord.y);
  2741. var self = this;
  2742. setTimeout(function() {
  2743. self.autoScroll.call(self, oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
  2744. }, 0);
  2745. },
  2746. /**
  2747. * Saves the most recent position so that we can reset the constraints and
  2748. * tick marks on-demand. We need to know this so that we can calculate the
  2749. * number of pixels the element is offset from its original position.
  2750. * @method cachePosition
  2751. * @param iPageX the current x position (optional, this just makes it so we
  2752. * don't have to look it up again)
  2753. * @param iPageY the current y position (optional, this just makes it so we
  2754. * don't have to look it up again)
  2755. */
  2756. cachePosition: function(iPageX, iPageY) {
  2757. if (iPageX) {
  2758. this.lastPageX = iPageX;
  2759. this.lastPageY = iPageY;
  2760. } else {
  2761. var aCoord = YAHOO.util.Dom.getXY(this.getEl());
  2762. this.lastPageX = aCoord[0];
  2763. this.lastPageY = aCoord[1];
  2764. }
  2765. },
  2766. /**
  2767. * Auto-scroll the window if the dragged object has been moved beyond the
  2768. * visible window boundary.
  2769. * @method autoScroll
  2770. * @param {int} x the drag element's x position
  2771. * @param {int} y the drag element's y position
  2772. * @param {int} h the height of the drag element
  2773. * @param {int} w the width of the drag element
  2774. * @private
  2775. */
  2776. autoScroll: function(x, y, h, w) {
  2777. if (this.scroll) {
  2778. // The client height
  2779. var clientH = this.DDM.getClientHeight();
  2780. // The client width
  2781. var clientW = this.DDM.getClientWidth();
  2782. // The amt scrolled down
  2783. var st = this.DDM.getScrollTop();
  2784. // The amt scrolled right
  2785. var sl = this.DDM.getScrollLeft();
  2786. // Location of the bottom of the element
  2787. var bot = h + y;
  2788. // Location of the right of the element
  2789. var right = w + x;
  2790. // The distance from the cursor to the bottom of the visible area,
  2791. // adjusted so that we don't scroll if the cursor is beyond the
  2792. // element drag constraints
  2793. var toBot = (clientH + st - y - this.deltaY);
  2794. // The distance from the cursor to the right of the visible area
  2795. var toRight = (clientW + sl - x - this.deltaX);
  2796. // this.logger.log( " x: " + x + " y: " + y + " h: " + h +
  2797. // " clientH: " + clientH + " clientW: " + clientW +
  2798. // " st: " + st + " sl: " + sl + " bot: " + bot +
  2799. // " right: " + right + " toBot: " + toBot + " toRight: " + toRight);
  2800. // How close to the edge the cursor must be before we scroll
  2801. // var thresh = (document.all) ? 100 : 40;
  2802. var thresh = 40;
  2803. // How many pixels to scroll per autoscroll op. This helps to reduce
  2804. // clunky scrolling. IE is more sensitive about this ... it needs this
  2805. // value to be higher.
  2806. var scrAmt = (document.all) ? 80 : 30;
  2807. // Scroll down if we are near the bottom of the visible page and the
  2808. // obj extends below the crease
  2809. if ( bot > clientH && toBot < thresh ) {
  2810. window.scrollTo(sl, st + scrAmt);
  2811. }
  2812. // Scroll up if the window is scrolled down and the top of the object
  2813. // goes above the top border
  2814. if ( y < st && st > 0 && y - st < thresh ) {
  2815. window.scrollTo(sl, st - scrAmt);
  2816. }
  2817. // Scroll right if the obj is beyond the right border and the cursor is
  2818. // near the border.
  2819. if ( right > clientW && toRight < thresh ) {
  2820. window.scrollTo(sl + scrAmt, st);
  2821. }
  2822. // Scroll left if the window has been scrolled to the right and the obj
  2823. // extends past the left border
  2824. if ( x < sl && sl > 0 && x - sl < thresh ) {
  2825. window.scrollTo(sl - scrAmt, st);
  2826. }
  2827. }
  2828. },
  2829. /*
  2830. * Sets up config options specific to this class. Overrides
  2831. * YAHOO.util.DragDrop, but all versions of this method through the
  2832. * inheritance chain are called
  2833. */
  2834. applyConfig: function() {
  2835. YAHOO.util.DD.superclass.applyConfig.call(this);
  2836. this.scroll = (this.config.scroll !== false);
  2837. },
  2838. /*
  2839. * Event that fires prior to the onMouseDown event. Overrides
  2840. * YAHOO.util.DragDrop.
  2841. */
  2842. b4MouseDown: function(e) {
  2843. this.setStartPosition();
  2844. // this.resetConstraints();
  2845. this.autoOffset(YAHOO.util.Event.getPageX(e),
  2846. YAHOO.util.Event.getPageY(e));
  2847. },
  2848. /*
  2849. * Event that fires prior to the onDrag event. Overrides
  2850. * YAHOO.util.DragDrop.
  2851. */
  2852. b4Drag: function(e) {
  2853. this.setDragElPos(YAHOO.util.Event.getPageX(e),
  2854. YAHOO.util.Event.getPageY(e));
  2855. },
  2856. toString: function() {
  2857. return ("DD " + this.id);
  2858. }
  2859. //////////////////////////////////////////////////////////////////////////
  2860. // Debugging ygDragDrop events that can be overridden
  2861. //////////////////////////////////////////////////////////////////////////
  2862. /*
  2863. startDrag: function(x, y) {
  2864. this.logger.log(this.id.toString() + " startDrag");
  2865. },
  2866. onDrag: function(e) {
  2867. this.logger.log(this.id.toString() + " onDrag");
  2868. },
  2869. onDragEnter: function(e, id) {
  2870. this.logger.log(this.id.toString() + " onDragEnter: " + id);
  2871. },
  2872. onDragOver: function(e, id) {
  2873. this.logger.log(this.id.toString() + " onDragOver: " + id);
  2874. },
  2875. onDragOut: function(e, id) {
  2876. this.logger.log(this.id.toString() + " onDragOut: " + id);
  2877. },
  2878. onDragDrop: function(e, id) {
  2879. this.logger.log(this.id.toString() + " onDragDrop: " + id);
  2880. },
  2881. endDrag: function(e) {
  2882. this.logger.log(this.id.toString() + " endDrag");
  2883. }
  2884. */
  2885. /**
  2886. * @event mouseDownEvent
  2887. * @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
  2888. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2889. */
  2890. /**
  2891. * @event b4MouseDownEvent
  2892. * @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
  2893. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2894. */
  2895. /**
  2896. * @event mouseUpEvent
  2897. * @description Fired from inside DragDropMgr when the drag operation is finished.
  2898. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2899. */
  2900. /**
  2901. * @event b4StartDragEvent
  2902. * @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
  2903. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2904. */
  2905. /**
  2906. * @event startDragEvent
  2907. * @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown.
  2908. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2909. */
  2910. /**
  2911. * @event b4EndDragEvent
  2912. * @description Fires before the endDragEvent. Returning false will cancel.
  2913. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2914. */
  2915. /**
  2916. * @event endDragEvent
  2917. * @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
  2918. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2919. */
  2920. /**
  2921. * @event dragEvent
  2922. * @description Occurs every mousemove event while dragging.
  2923. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2924. */
  2925. /**
  2926. * @event b4DragEvent
  2927. * @description Fires before the dragEvent.
  2928. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2929. */
  2930. /**
  2931. * @event invalidDropEvent
  2932. * @description Fires when the dragged objects is dropped in a location that contains no drop targets.
  2933. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2934. */
  2935. /**
  2936. * @event b4DragOutEvent
  2937. * @description Fires before the dragOutEvent
  2938. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2939. */
  2940. /**
  2941. * @event dragOutEvent
  2942. * @description Fires when a dragged object is no longer over an object that had the onDragEnter fire.
  2943. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2944. */
  2945. /**
  2946. * @event dragEnterEvent
  2947. * @description Occurs when the dragged object first interacts with another targettable drag and drop object.
  2948. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2949. */
  2950. /**
  2951. * @event b4DragOverEvent
  2952. * @description Fires before the dragOverEvent.
  2953. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2954. */
  2955. /**
  2956. * @event dragOverEvent
  2957. * @description Fires every mousemove event while over a drag and drop object.
  2958. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2959. */
  2960. /**
  2961. * @event b4DragDropEvent
  2962. * @description Fires before the dragDropEvent
  2963. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2964. */
  2965. /**
  2966. * @event dragDropEvent
  2967. * @description Fires when the dragged objects is dropped on another.
  2968. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  2969. */
  2970. });
  2971. /**
  2972. * A DragDrop implementation that inserts an empty, bordered div into
  2973. * the document that follows the cursor during drag operations. At the time of
  2974. * the click, the frame div is resized to the dimensions of the linked html
  2975. * element, and moved to the exact location of the linked element.
  2976. *
  2977. * References to the "frame" element refer to the single proxy element that
  2978. * was created to be dragged in place of all DDProxy elements on the
  2979. * page.
  2980. *
  2981. * @class DDProxy
  2982. * @extends YAHOO.util.DD
  2983. * @constructor
  2984. * @param {String} id the id of the linked html element
  2985. * @param {String} sGroup the group of related DragDrop objects
  2986. * @param {object} config an object containing configurable attributes
  2987. * Valid properties for DDProxy in addition to those in DragDrop:
  2988. * resizeFrame, centerFrame, dragElId
  2989. */
  2990. YAHOO.util.DDProxy = function(id, sGroup, config) {
  2991. if (id) {
  2992. this.init(id, sGroup, config);
  2993. this.initFrame();
  2994. }
  2995. };
  2996. /**
  2997. * The default drag frame div id
  2998. * @property YAHOO.util.DDProxy.dragElId
  2999. * @type String
  3000. * @static
  3001. */
  3002. YAHOO.util.DDProxy.dragElId = "ygddfdiv";
  3003. YAHOO.extend(YAHOO.util.DDProxy, YAHOO.util.DD, {
  3004. /**
  3005. * By default we resize the drag frame to be the same size as the element
  3006. * we want to drag (this is to get the frame effect). We can turn it off
  3007. * if we want a different behavior.
  3008. * @property resizeFrame
  3009. * @type boolean
  3010. */
  3011. resizeFrame: true,
  3012. /**
  3013. * By default the frame is positioned exactly where the drag element is, so
  3014. * we use the cursor offset provided by YAHOO.util.DD. Another option that works only if
  3015. * you do not have constraints on the obj is to have the drag frame centered
  3016. * around the cursor. Set centerFrame to true for this effect.
  3017. * @property centerFrame
  3018. * @type boolean
  3019. */
  3020. centerFrame: false,
  3021. /**
  3022. * Creates the proxy element if it does not yet exist
  3023. * @method createFrame
  3024. */
  3025. createFrame: function() {
  3026. var self=this, body=document.body;
  3027. if (!body || !body.firstChild) {
  3028. setTimeout( function() { self.createFrame(); }, 50 );
  3029. return;
  3030. }
  3031. var div=this.getDragEl(), Dom=YAHOO.util.Dom;
  3032. if (!div) {
  3033. div = document.createElement("div");
  3034. div.id = this.dragElId;
  3035. var s = div.style;
  3036. s.position = "absolute";
  3037. s.visibility = "hidden";
  3038. s.cursor = "move";
  3039. s.border = "2px solid #aaa";
  3040. s.zIndex = 999;
  3041. s.height = "25px";
  3042. s.width = "25px";
  3043. var _data = document.createElement('div');
  3044. Dom.setStyle(_data, 'height', '100%');
  3045. Dom.setStyle(_data, 'width', '100%');
  3046. /**
  3047. * If the proxy element has no background-color, then it is considered to the "transparent" by Internet Explorer.
  3048. * Since it is "transparent" then the events pass through it to the iframe below.
  3049. * So creating a "fake" div inside the proxy element and giving it a background-color, then setting it to an
  3050. * opacity of 0, it appears to not be there, however IE still thinks that it is so the events never pass through.
  3051. */
  3052. Dom.setStyle(_data, 'background-color', '#ccc');
  3053. Dom.setStyle(_data, 'opacity', '0');
  3054. div.appendChild(_data);
  3055. // appendChild can blow up IE if invoked prior to the window load event
  3056. // while rendering a table. It is possible there are other scenarios
  3057. // that would cause this to happen as well.
  3058. body.insertBefore(div, body.firstChild);
  3059. }
  3060. },
  3061. /**
  3062. * Initialization for the drag frame element. Must be called in the
  3063. * constructor of all subclasses
  3064. * @method initFrame
  3065. */
  3066. initFrame: function() {
  3067. this.createFrame();
  3068. },
  3069. applyConfig: function() {
  3070. //this.logger.log("DDProxy applyConfig");
  3071. YAHOO.util.DDProxy.superclass.applyConfig.call(this);
  3072. this.resizeFrame = (this.config.resizeFrame !== false);
  3073. this.centerFrame = (this.config.centerFrame);
  3074. this.setDragElId(this.config.dragElId || YAHOO.util.DDProxy.dragElId);
  3075. },
  3076. /**
  3077. * Resizes the drag frame to the dimensions of the clicked object, positions
  3078. * it over the object, and finally displays it
  3079. * @method showFrame
  3080. * @param {int} iPageX X click position
  3081. * @param {int} iPageY Y click position
  3082. * @private
  3083. */
  3084. showFrame: function(iPageX, iPageY) {
  3085. var el = this.getEl();
  3086. var dragEl = this.getDragEl();
  3087. var s = dragEl.style;
  3088. this._resizeProxy();
  3089. if (this.centerFrame) {
  3090. this.setDelta( Math.round(parseInt(s.width, 10)/2),
  3091. Math.round(parseInt(s.height, 10)/2) );
  3092. }
  3093. this.setDragElPos(iPageX, iPageY);
  3094. YAHOO.util.Dom.setStyle(dragEl, "visibility", "visible");
  3095. },
  3096. /**
  3097. * The proxy is automatically resized to the dimensions of the linked
  3098. * element when a drag is initiated, unless resizeFrame is set to false
  3099. * @method _resizeProxy
  3100. * @private
  3101. */
  3102. _resizeProxy: function() {
  3103. if (this.resizeFrame) {
  3104. var DOM = YAHOO.util.Dom;
  3105. var el = this.getEl();
  3106. var dragEl = this.getDragEl();
  3107. var bt = parseInt( DOM.getStyle(dragEl, "borderTopWidth" ), 10);
  3108. var br = parseInt( DOM.getStyle(dragEl, "borderRightWidth" ), 10);
  3109. var bb = parseInt( DOM.getStyle(dragEl, "borderBottomWidth" ), 10);
  3110. var bl = parseInt( DOM.getStyle(dragEl, "borderLeftWidth" ), 10);
  3111. if (isNaN(bt)) { bt = 0; }
  3112. if (isNaN(br)) { br = 0; }
  3113. if (isNaN(bb)) { bb = 0; }
  3114. if (isNaN(bl)) { bl = 0; }
  3115. this.logger.log("proxy size: " + bt + " " + br + " " + bb + " " + bl);
  3116. var newWidth = Math.max(0, el.offsetWidth - br - bl);
  3117. var newHeight = Math.max(0, el.offsetHeight - bt - bb);
  3118. this.logger.log("Resizing proxy element");
  3119. DOM.setStyle( dragEl, "width", newWidth + "px" );
  3120. DOM.setStyle( dragEl, "height", newHeight + "px" );
  3121. }
  3122. },
  3123. // overrides YAHOO.util.DragDrop
  3124. b4MouseDown: function(e) {
  3125. this.setStartPosition();
  3126. var x = YAHOO.util.Event.getPageX(e);
  3127. var y = YAHOO.util.Event.getPageY(e);
  3128. this.autoOffset(x, y);
  3129. // This causes the autoscroll code to kick off, which means autoscroll can
  3130. // happen prior to the check for a valid drag handle.
  3131. // this.setDragElPos(x, y);
  3132. },
  3133. // overrides YAHOO.util.DragDrop
  3134. b4StartDrag: function(x, y) {
  3135. // show the drag frame
  3136. this.logger.log("start drag show frame, x: " + x + ", y: " + y);
  3137. this.showFrame(x, y);
  3138. },
  3139. // overrides YAHOO.util.DragDrop
  3140. b4EndDrag: function(e) {
  3141. this.logger.log(this.id + " b4EndDrag");
  3142. YAHOO.util.Dom.setStyle(this.getDragEl(), "visibility", "hidden");
  3143. },
  3144. // overrides YAHOO.util.DragDrop
  3145. // By default we try to move the element to the last location of the frame.
  3146. // This is so that the default behavior mirrors that of YAHOO.util.DD.
  3147. endDrag: function(e) {
  3148. var DOM = YAHOO.util.Dom;
  3149. this.logger.log(this.id + " endDrag");
  3150. var lel = this.getEl();
  3151. var del = this.getDragEl();
  3152. // Show the drag frame briefly so we can get its position
  3153. // del.style.visibility = "";
  3154. DOM.setStyle(del, "visibility", "");
  3155. // Hide the linked element before the move to get around a Safari
  3156. // rendering bug.
  3157. //lel.style.visibility = "hidden";
  3158. DOM.setStyle(lel, "visibility", "hidden");
  3159. YAHOO.util.DDM.moveToEl(lel, del);
  3160. //del.style.visibility = "hidden";
  3161. DOM.setStyle(del, "visibility", "hidden");
  3162. //lel.style.visibility = "";
  3163. DOM.setStyle(lel, "visibility", "");
  3164. },
  3165. toString: function() {
  3166. return ("DDProxy " + this.id);
  3167. }
  3168. /**
  3169. * @event mouseDownEvent
  3170. * @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
  3171. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3172. */
  3173. /**
  3174. * @event b4MouseDownEvent
  3175. * @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
  3176. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3177. */
  3178. /**
  3179. * @event mouseUpEvent
  3180. * @description Fired from inside DragDropMgr when the drag operation is finished.
  3181. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3182. */
  3183. /**
  3184. * @event b4StartDragEvent
  3185. * @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
  3186. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3187. */
  3188. /**
  3189. * @event startDragEvent
  3190. * @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown.
  3191. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3192. */
  3193. /**
  3194. * @event b4EndDragEvent
  3195. * @description Fires before the endDragEvent. Returning false will cancel.
  3196. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3197. */
  3198. /**
  3199. * @event endDragEvent
  3200. * @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
  3201. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3202. */
  3203. /**
  3204. * @event dragEvent
  3205. * @description Occurs every mousemove event while dragging.
  3206. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3207. */
  3208. /**
  3209. * @event b4DragEvent
  3210. * @description Fires before the dragEvent.
  3211. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3212. */
  3213. /**
  3214. * @event invalidDropEvent
  3215. * @description Fires when the dragged objects is dropped in a location that contains no drop targets.
  3216. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3217. */
  3218. /**
  3219. * @event b4DragOutEvent
  3220. * @description Fires before the dragOutEvent
  3221. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3222. */
  3223. /**
  3224. * @event dragOutEvent
  3225. * @description Fires when a dragged object is no longer over an object that had the onDragEnter fire.
  3226. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3227. */
  3228. /**
  3229. * @event dragEnterEvent
  3230. * @description Occurs when the dragged object first interacts with another targettable drag and drop object.
  3231. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3232. */
  3233. /**
  3234. * @event b4DragOverEvent
  3235. * @description Fires before the dragOverEvent.
  3236. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3237. */
  3238. /**
  3239. * @event dragOverEvent
  3240. * @description Fires every mousemove event while over a drag and drop object.
  3241. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3242. */
  3243. /**
  3244. * @event b4DragDropEvent
  3245. * @description Fires before the dragDropEvent
  3246. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3247. */
  3248. /**
  3249. * @event dragDropEvent
  3250. * @description Fires when the dragged objects is dropped on another.
  3251. * @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
  3252. */
  3253. });
  3254. /**
  3255. * A DragDrop implementation that does not move, but can be a drop
  3256. * target. You would get the same result by simply omitting implementation
  3257. * for the event callbacks, but this way we reduce the processing cost of the
  3258. * event listener and the callbacks.
  3259. * @class DDTarget
  3260. * @extends YAHOO.util.DragDrop
  3261. * @constructor
  3262. * @param {String} id the id of the element that is a drop target
  3263. * @param {String} sGroup the group of related DragDrop objects
  3264. * @param {object} config an object containing configurable attributes
  3265. * Valid properties for DDTarget in addition to those in
  3266. * DragDrop:
  3267. * none
  3268. */
  3269. YAHOO.util.DDTarget = function(id, sGroup, config) {
  3270. if (id) {
  3271. this.initTarget(id, sGroup, config);
  3272. }
  3273. };
  3274. // YAHOO.util.DDTarget.prototype = new YAHOO.util.DragDrop();
  3275. YAHOO.extend(YAHOO.util.DDTarget, YAHOO.util.DragDrop, {
  3276. toString: function() {
  3277. return ("DDTarget " + this.id);
  3278. }
  3279. });
  3280. YAHOO.register("dragdrop", YAHOO.util.DragDropMgr, {version: "2.8.0r4", build: "2449"});