├── Changes ├── LICENSE ├── README.md ├── docs ├── README.md ├── css │ ├── bootstrap-responsive.css │ ├── bootstrap.css │ ├── bootstrap.min.css │ └── site.css ├── examples │ ├── examples.css │ ├── images │ │ └── world-map.jpg │ ├── jquery.js │ ├── methods.html │ └── options.html ├── img │ ├── glyphicons-halflings-white.png │ ├── glyphicons-halflings.png │ ├── star.png │ └── try-dragging.png ├── index.html ├── jquery.event.ue.js ├── jquery.udraggable.js └── js │ ├── bootstrap.js │ └── bootstrap.min.js ├── jquery.udraggable.js └── udraggable.jquery.json /Changes: -------------------------------------------------------------------------------- 1 | Change log for jquery.udraggable plugin. 2 | 3 | For full commit history see: 4 | 5 | https://github.com/grantm/jquery-udraggable/commits/master 6 | 7 | 0.3.0 2015-03-10 8 | * patch from Lukas Dietrich to allow normalisePosition() to be overridden 9 | 10 | 0.3.0 2014-01-23 11 | * new methods: destroy, disable, enable 12 | * throw an exception if unsupported method called 13 | 14 | 0.2.0 2013-09-06 15 | * "parent" containment now refers to positioning parent - offsetParent() 16 | * element position now normalised to top & left if right or bottom 17 | * redraws now synced via requestAnimationFrame 18 | * new "getStartPosition" and "positionElement" options 19 | * new "handle" option 20 | 21 | 0.1.0 2013-08-29 22 | * initial release 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | 3 | This software is dual-licensed under the MIT and GPL (version 3.0 or later) 4 | licenses as published here: 5 | 6 | * http://opensource.org/licenses/MIT 7 | * http://opensource.org/licenses/GPL-3.0 8 | 9 | ------------------------------------------------------------------------------- 10 | 11 | THE MIT LICENSE 12 | 13 | Copyright (c) 2010-2013 Grant McLean 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of 16 | this software and associated documentation files (the "Software"), to deal in 17 | the Software without restriction, including without limitation the rights to 18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 19 | of the Software, and to permit persons to whom the Software is furnished to do 20 | so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | 33 | ------------------------------------------------------------------------------- 34 | 35 | GNU GENERAL PUBLIC LICENSE 36 | Version 3, 29 June 2007 37 | 38 | Copyright (c) 2010-2013 Grant McLean 39 | Everyone is permitted to copy and distribute verbatim copies 40 | of this license document, but changing it is not allowed. 41 | 42 | Preamble 43 | 44 | The GNU General Public License is a free, copyleft license for 45 | software and other kinds of works. 46 | 47 | The licenses for most software and other practical works are designed 48 | to take away your freedom to share and change the works. By contrast, 49 | the GNU General Public License is intended to guarantee your freedom to 50 | share and change all versions of a program--to make sure it remains free 51 | software for all its users. We, the Free Software Foundation, use the 52 | GNU General Public License for most of our software; it applies also to 53 | any other work released this way by its authors. You can apply it to 54 | your programs, too. 55 | 56 | When we speak of free software, we are referring to freedom, not 57 | price. Our General Public Licenses are designed to make sure that you 58 | have the freedom to distribute copies of free software (and charge for 59 | them if you wish), that you receive source code or can get it if you 60 | want it, that you can change the software or use pieces of it in new 61 | free programs, and that you know you can do these things. 62 | 63 | To protect your rights, we need to prevent others from denying you 64 | these rights or asking you to surrender the rights. Therefore, you have 65 | certain responsibilities if you distribute copies of the software, or if 66 | you modify it: responsibilities to respect the freedom of others. 67 | 68 | For example, if you distribute copies of such a program, whether 69 | gratis or for a fee, you must pass on to the recipients the same 70 | freedoms that you received. You must make sure that they, too, receive 71 | or can get the source code. And you must show them these terms so they 72 | know their rights. 73 | 74 | Developers that use the GNU GPL protect your rights with two steps: 75 | (1) assert copyright on the software, and (2) offer you this License 76 | giving you legal permission to copy, distribute and/or modify it. 77 | 78 | For the developers' and authors' protection, the GPL clearly explains 79 | that there is no warranty for this free software. For both users' and 80 | authors' sake, the GPL requires that modified versions be marked as 81 | changed, so that their problems will not be attributed erroneously to 82 | authors of previous versions. 83 | 84 | Some devices are designed to deny users access to install or run 85 | modified versions of the software inside them, although the manufacturer 86 | can do so. This is fundamentally incompatible with the aim of 87 | protecting users' freedom to change the software. The systematic 88 | pattern of such abuse occurs in the area of products for individuals to 89 | use, which is precisely where it is most unacceptable. Therefore, we 90 | have designed this version of the GPL to prohibit the practice for those 91 | products. If such problems arise substantially in other domains, we 92 | stand ready to extend this provision to those domains in future versions 93 | of the GPL, as needed to protect the freedom of users. 94 | 95 | Finally, every program is threatened constantly by software patents. 96 | States should not allow patents to restrict development and use of 97 | software on general-purpose computers, but in those that do, we wish to 98 | avoid the special danger that patents applied to a free program could 99 | make it effectively proprietary. To prevent this, the GPL assures that 100 | patents cannot be used to render the program non-free. 101 | 102 | The precise terms and conditions for copying, distribution and 103 | modification follow. 104 | 105 | TERMS AND CONDITIONS 106 | 107 | 0. Definitions. 108 | 109 | "This License" refers to version 3 of the GNU General Public License. 110 | 111 | "Copyright" also means copyright-like laws that apply to other kinds of 112 | works, such as semiconductor masks. 113 | 114 | "The Program" refers to any copyrightable work licensed under this 115 | License. Each licensee is addressed as "you". "Licensees" and 116 | "recipients" may be individuals or organizations. 117 | 118 | To "modify" a work means to copy from or adapt all or part of the work 119 | in a fashion requiring copyright permission, other than the making of an 120 | exact copy. The resulting work is called a "modified version" of the 121 | earlier work or a work "based on" the earlier work. 122 | 123 | A "covered work" means either the unmodified Program or a work based 124 | on the Program. 125 | 126 | To "propagate" a work means to do anything with it that, without 127 | permission, would make you directly or secondarily liable for 128 | infringement under applicable copyright law, except executing it on a 129 | computer or modifying a private copy. Propagation includes copying, 130 | distribution (with or without modification), making available to the 131 | public, and in some countries other activities as well. 132 | 133 | To "convey" a work means any kind of propagation that enables other 134 | parties to make or receive copies. Mere interaction with a user through 135 | a computer network, with no transfer of a copy, is not conveying. 136 | 137 | An interactive user interface displays "Appropriate Legal Notices" 138 | to the extent that it includes a convenient and prominently visible 139 | feature that (1) displays an appropriate copyright notice, and (2) 140 | tells the user that there is no warranty for the work (except to the 141 | extent that warranties are provided), that licensees may convey the 142 | work under this License, and how to view a copy of this License. If 143 | the interface presents a list of user commands or options, such as a 144 | menu, a prominent item in the list meets this criterion. 145 | 146 | 1. Source Code. 147 | 148 | The "source code" for a work means the preferred form of the work 149 | for making modifications to it. "Object code" means any non-source 150 | form of a work. 151 | 152 | A "Standard Interface" means an interface that either is an official 153 | standard defined by a recognized standards body, or, in the case of 154 | interfaces specified for a particular programming language, one that 155 | is widely used among developers working in that language. 156 | 157 | The "System Libraries" of an executable work include anything, other 158 | than the work as a whole, that (a) is included in the normal form of 159 | packaging a Major Component, but which is not part of that Major 160 | Component, and (b) serves only to enable use of the work with that 161 | Major Component, or to implement a Standard Interface for which an 162 | implementation is available to the public in source code form. A 163 | "Major Component", in this context, means a major essential component 164 | (kernel, window system, and so on) of the specific operating system 165 | (if any) on which the executable work runs, or a compiler used to 166 | produce the work, or an object code interpreter used to run it. 167 | 168 | The "Corresponding Source" for a work in object code form means all 169 | the source code needed to generate, install, and (for an executable 170 | work) run the object code and to modify the work, including scripts to 171 | control those activities. However, it does not include the work's 172 | System Libraries, or general-purpose tools or generally available free 173 | programs which are used unmodified in performing those activities but 174 | which are not part of the work. For example, Corresponding Source 175 | includes interface definition files associated with source files for 176 | the work, and the source code for shared libraries and dynamically 177 | linked subprograms that the work is specifically designed to require, 178 | such as by intimate data communication or control flow between those 179 | subprograms and other parts of the work. 180 | 181 | The Corresponding Source need not include anything that users 182 | can regenerate automatically from other parts of the Corresponding 183 | Source. 184 | 185 | The Corresponding Source for a work in source code form is that 186 | same work. 187 | 188 | 2. Basic Permissions. 189 | 190 | All rights granted under this License are granted for the term of 191 | copyright on the Program, and are irrevocable provided the stated 192 | conditions are met. This License explicitly affirms your unlimited 193 | permission to run the unmodified Program. The output from running a 194 | covered work is covered by this License only if the output, given its 195 | content, constitutes a covered work. This License acknowledges your 196 | rights of fair use or other equivalent, as provided by copyright law. 197 | 198 | You may make, run and propagate covered works that you do not 199 | convey, without conditions so long as your license otherwise remains 200 | in force. You may convey covered works to others for the sole purpose 201 | of having them make modifications exclusively for you, or provide you 202 | with facilities for running those works, provided that you comply with 203 | the terms of this License in conveying all material for which you do 204 | not control copyright. Those thus making or running the covered works 205 | for you must do so exclusively on your behalf, under your direction 206 | and control, on terms that prohibit them from making any copies of 207 | your copyrighted material outside their relationship with you. 208 | 209 | Conveying under any other circumstances is permitted solely under 210 | the conditions stated below. Sublicensing is not allowed; section 10 211 | makes it unnecessary. 212 | 213 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 214 | 215 | No covered work shall be deemed part of an effective technological 216 | measure under any applicable law fulfilling obligations under article 217 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 218 | similar laws prohibiting or restricting circumvention of such 219 | measures. 220 | 221 | When you convey a covered work, you waive any legal power to forbid 222 | circumvention of technological measures to the extent such circumvention 223 | is effected by exercising rights under this License with respect to 224 | the covered work, and you disclaim any intention to limit operation or 225 | modification of the work as a means of enforcing, against the work's 226 | users, your or third parties' legal rights to forbid circumvention of 227 | technological measures. 228 | 229 | 4. Conveying Verbatim Copies. 230 | 231 | You may convey verbatim copies of the Program's source code as you 232 | receive it, in any medium, provided that you conspicuously and 233 | appropriately publish on each copy an appropriate copyright notice; 234 | keep intact all notices stating that this License and any 235 | non-permissive terms added in accord with section 7 apply to the code; 236 | keep intact all notices of the absence of any warranty; and give all 237 | recipients a copy of this License along with the Program. 238 | 239 | You may charge any price or no price for each copy that you convey, 240 | and you may offer support or warranty protection for a fee. 241 | 242 | 5. Conveying Modified Source Versions. 243 | 244 | You may convey a work based on the Program, or the modifications to 245 | produce it from the Program, in the form of source code under the 246 | terms of section 4, provided that you also meet all of these conditions: 247 | 248 | a) The work must carry prominent notices stating that you modified 249 | it, and giving a relevant date. 250 | 251 | b) The work must carry prominent notices stating that it is 252 | released under this License and any conditions added under section 253 | 7. This requirement modifies the requirement in section 4 to 254 | "keep intact all notices". 255 | 256 | c) You must license the entire work, as a whole, under this 257 | License to anyone who comes into possession of a copy. This 258 | License will therefore apply, along with any applicable section 7 259 | additional terms, to the whole of the work, and all its parts, 260 | regardless of how they are packaged. This License gives no 261 | permission to license the work in any other way, but it does not 262 | invalidate such permission if you have separately received it. 263 | 264 | d) If the work has interactive user interfaces, each must display 265 | Appropriate Legal Notices; however, if the Program has interactive 266 | interfaces that do not display Appropriate Legal Notices, your 267 | work need not make them do so. 268 | 269 | A compilation of a covered work with other separate and independent 270 | works, which are not by their nature extensions of the covered work, 271 | and which are not combined with it such as to form a larger program, 272 | in or on a volume of a storage or distribution medium, is called an 273 | "aggregate" if the compilation and its resulting copyright are not 274 | used to limit the access or legal rights of the compilation's users 275 | beyond what the individual works permit. Inclusion of a covered work 276 | in an aggregate does not cause this License to apply to the other 277 | parts of the aggregate. 278 | 279 | 6. Conveying Non-Source Forms. 280 | 281 | You may convey a covered work in object code form under the terms 282 | of sections 4 and 5, provided that you also convey the 283 | machine-readable Corresponding Source under the terms of this License, 284 | in one of these ways: 285 | 286 | a) Convey the object code in, or embodied in, a physical product 287 | (including a physical distribution medium), accompanied by the 288 | Corresponding Source fixed on a durable physical medium 289 | customarily used for software interchange. 290 | 291 | b) Convey the object code in, or embodied in, a physical product 292 | (including a physical distribution medium), accompanied by a 293 | written offer, valid for at least three years and valid for as 294 | long as you offer spare parts or customer support for that product 295 | model, to give anyone who possesses the object code either (1) a 296 | copy of the Corresponding Source for all the software in the 297 | product that is covered by this License, on a durable physical 298 | medium customarily used for software interchange, for a price no 299 | more than your reasonable cost of physically performing this 300 | conveying of source, or (2) access to copy the 301 | Corresponding Source from a network server at no charge. 302 | 303 | c) Convey individual copies of the object code with a copy of the 304 | written offer to provide the Corresponding Source. This 305 | alternative is allowed only occasionally and noncommercially, and 306 | only if you received the object code with such an offer, in accord 307 | with subsection 6b. 308 | 309 | d) Convey the object code by offering access from a designated 310 | place (gratis or for a charge), and offer equivalent access to the 311 | Corresponding Source in the same way through the same place at no 312 | further charge. You need not require recipients to copy the 313 | Corresponding Source along with the object code. If the place to 314 | copy the object code is a network server, the Corresponding Source 315 | may be on a different server (operated by you or a third party) 316 | that supports equivalent copying facilities, provided you maintain 317 | clear directions next to the object code saying where to find the 318 | Corresponding Source. Regardless of what server hosts the 319 | Corresponding Source, you remain obligated to ensure that it is 320 | available for as long as needed to satisfy these requirements. 321 | 322 | e) Convey the object code using peer-to-peer transmission, provided 323 | you inform other peers where the object code and Corresponding 324 | Source of the work are being offered to the general public at no 325 | charge under subsection 6d. 326 | 327 | A separable portion of the object code, whose source code is excluded 328 | from the Corresponding Source as a System Library, need not be 329 | included in conveying the object code work. 330 | 331 | A "User Product" is either (1) a "consumer product", which means any 332 | tangible personal property which is normally used for personal, family, 333 | or household purposes, or (2) anything designed or sold for incorporation 334 | into a dwelling. In determining whether a product is a consumer product, 335 | doubtful cases shall be resolved in favor of coverage. For a particular 336 | product received by a particular user, "normally used" refers to a 337 | typical or common use of that class of product, regardless of the status 338 | of the particular user or of the way in which the particular user 339 | actually uses, or expects or is expected to use, the product. A product 340 | is a consumer product regardless of whether the product has substantial 341 | commercial, industrial or non-consumer uses, unless such uses represent 342 | the only significant mode of use of the product. 343 | 344 | "Installation Information" for a User Product means any methods, 345 | procedures, authorization keys, or other information required to install 346 | and execute modified versions of a covered work in that User Product from 347 | a modified version of its Corresponding Source. The information must 348 | suffice to ensure that the continued functioning of the modified object 349 | code is in no case prevented or interfered with solely because 350 | modification has been made. 351 | 352 | If you convey an object code work under this section in, or with, or 353 | specifically for use in, a User Product, and the conveying occurs as 354 | part of a transaction in which the right of possession and use of the 355 | User Product is transferred to the recipient in perpetuity or for a 356 | fixed term (regardless of how the transaction is characterized), the 357 | Corresponding Source conveyed under this section must be accompanied 358 | by the Installation Information. But this requirement does not apply 359 | if neither you nor any third party retains the ability to install 360 | modified object code on the User Product (for example, the work has 361 | been installed in ROM). 362 | 363 | The requirement to provide Installation Information does not include a 364 | requirement to continue to provide support service, warranty, or updates 365 | for a work that has been modified or installed by the recipient, or for 366 | the User Product in which it has been modified or installed. Access to a 367 | network may be denied when the modification itself materially and 368 | adversely affects the operation of the network or violates the rules and 369 | protocols for communication across the network. 370 | 371 | Corresponding Source conveyed, and Installation Information provided, 372 | in accord with this section must be in a format that is publicly 373 | documented (and with an implementation available to the public in 374 | source code form), and must require no special password or key for 375 | unpacking, reading or copying. 376 | 377 | 7. Additional Terms. 378 | 379 | "Additional permissions" are terms that supplement the terms of this 380 | License by making exceptions from one or more of its conditions. 381 | Additional permissions that are applicable to the entire Program shall 382 | be treated as though they were included in this License, to the extent 383 | that they are valid under applicable law. If additional permissions 384 | apply only to part of the Program, that part may be used separately 385 | under those permissions, but the entire Program remains governed by 386 | this License without regard to the additional permissions. 387 | 388 | When you convey a copy of a covered work, you may at your option 389 | remove any additional permissions from that copy, or from any part of 390 | it. (Additional permissions may be written to require their own 391 | removal in certain cases when you modify the work.) You may place 392 | additional permissions on material, added by you to a covered work, 393 | for which you have or can give appropriate copyright permission. 394 | 395 | Notwithstanding any other provision of this License, for material you 396 | add to a covered work, you may (if authorized by the copyright holders of 397 | that material) supplement the terms of this License with terms: 398 | 399 | a) Disclaiming warranty or limiting liability differently from the 400 | terms of sections 15 and 16 of this License; or 401 | 402 | b) Requiring preservation of specified reasonable legal notices or 403 | author attributions in that material or in the Appropriate Legal 404 | Notices displayed by works containing it; or 405 | 406 | c) Prohibiting misrepresentation of the origin of that material, or 407 | requiring that modified versions of such material be marked in 408 | reasonable ways as different from the original version; or 409 | 410 | d) Limiting the use for publicity purposes of names of licensors or 411 | authors of the material; or 412 | 413 | e) Declining to grant rights under trademark law for use of some 414 | trade names, trademarks, or service marks; or 415 | 416 | f) Requiring indemnification of licensors and authors of that 417 | material by anyone who conveys the material (or modified versions of 418 | it) with contractual assumptions of liability to the recipient, for 419 | any liability that these contractual assumptions directly impose on 420 | those licensors and authors. 421 | 422 | All other non-permissive additional terms are considered "further 423 | restrictions" within the meaning of section 10. If the Program as you 424 | received it, or any part of it, contains a notice stating that it is 425 | governed by this License along with a term that is a further 426 | restriction, you may remove that term. If a license document contains 427 | a further restriction but permits relicensing or conveying under this 428 | License, you may add to a covered work material governed by the terms 429 | of that license document, provided that the further restriction does 430 | not survive such relicensing or conveying. 431 | 432 | If you add terms to a covered work in accord with this section, you 433 | must place, in the relevant source files, a statement of the 434 | additional terms that apply to those files, or a notice indicating 435 | where to find the applicable terms. 436 | 437 | Additional terms, permissive or non-permissive, may be stated in the 438 | form of a separately written license, or stated as exceptions; 439 | the above requirements apply either way. 440 | 441 | 8. Termination. 442 | 443 | You may not propagate or modify a covered work except as expressly 444 | provided under this License. Any attempt otherwise to propagate or 445 | modify it is void, and will automatically terminate your rights under 446 | this License (including any patent licenses granted under the third 447 | paragraph of section 11). 448 | 449 | However, if you cease all violation of this License, then your 450 | license from a particular copyright holder is reinstated (a) 451 | provisionally, unless and until the copyright holder explicitly and 452 | finally terminates your license, and (b) permanently, if the copyright 453 | holder fails to notify you of the violation by some reasonable means 454 | prior to 60 days after the cessation. 455 | 456 | Moreover, your license from a particular copyright holder is 457 | reinstated permanently if the copyright holder notifies you of the 458 | violation by some reasonable means, this is the first time you have 459 | received notice of violation of this License (for any work) from that 460 | copyright holder, and you cure the violation prior to 30 days after 461 | your receipt of the notice. 462 | 463 | Termination of your rights under this section does not terminate the 464 | licenses of parties who have received copies or rights from you under 465 | this License. If your rights have been terminated and not permanently 466 | reinstated, you do not qualify to receive new licenses for the same 467 | material under section 10. 468 | 469 | 9. Acceptance Not Required for Having Copies. 470 | 471 | You are not required to accept this License in order to receive or 472 | run a copy of the Program. Ancillary propagation of a covered work 473 | occurring solely as a consequence of using peer-to-peer transmission 474 | to receive a copy likewise does not require acceptance. However, 475 | nothing other than this License grants you permission to propagate or 476 | modify any covered work. These actions infringe copyright if you do 477 | not accept this License. Therefore, by modifying or propagating a 478 | covered work, you indicate your acceptance of this License to do so. 479 | 480 | 10. Automatic Licensing of Downstream Recipients. 481 | 482 | Each time you convey a covered work, the recipient automatically 483 | receives a license from the original licensors, to run, modify and 484 | propagate that work, subject to this License. You are not responsible 485 | for enforcing compliance by third parties with this License. 486 | 487 | An "entity transaction" is a transaction transferring control of an 488 | organization, or substantially all assets of one, or subdividing an 489 | organization, or merging organizations. If propagation of a covered 490 | work results from an entity transaction, each party to that 491 | transaction who receives a copy of the work also receives whatever 492 | licenses to the work the party's predecessor in interest had or could 493 | give under the previous paragraph, plus a right to possession of the 494 | Corresponding Source of the work from the predecessor in interest, if 495 | the predecessor has it or can get it with reasonable efforts. 496 | 497 | You may not impose any further restrictions on the exercise of the 498 | rights granted or affirmed under this License. For example, you may 499 | not impose a license fee, royalty, or other charge for exercise of 500 | rights granted under this License, and you may not initiate litigation 501 | (including a cross-claim or counterclaim in a lawsuit) alleging that 502 | any patent claim is infringed by making, using, selling, offering for 503 | sale, or importing the Program or any portion of it. 504 | 505 | 11. Patents. 506 | 507 | A "contributor" is a copyright holder who authorizes use under this 508 | License of the Program or a work on which the Program is based. The 509 | work thus licensed is called the contributor's "contributor version". 510 | 511 | A contributor's "essential patent claims" are all patent claims 512 | owned or controlled by the contributor, whether already acquired or 513 | hereafter acquired, that would be infringed by some manner, permitted 514 | by this License, of making, using, or selling its contributor version, 515 | but do not include claims that would be infringed only as a 516 | consequence of further modification of the contributor version. For 517 | purposes of this definition, "control" includes the right to grant 518 | patent sublicenses in a manner consistent with the requirements of 519 | this License. 520 | 521 | Each contributor grants you a non-exclusive, worldwide, royalty-free 522 | patent license under the contributor's essential patent claims, to 523 | make, use, sell, offer for sale, import and otherwise run, modify and 524 | propagate the contents of its contributor version. 525 | 526 | In the following three paragraphs, a "patent license" is any express 527 | agreement or commitment, however denominated, not to enforce a patent 528 | (such as an express permission to practice a patent or covenant not to 529 | sue for patent infringement). To "grant" such a patent license to a 530 | party means to make such an agreement or commitment not to enforce a 531 | patent against the party. 532 | 533 | If you convey a covered work, knowingly relying on a patent license, 534 | and the Corresponding Source of the work is not available for anyone 535 | to copy, free of charge and under the terms of this License, through a 536 | publicly available network server or other readily accessible means, 537 | then you must either (1) cause the Corresponding Source to be so 538 | available, or (2) arrange to deprive yourself of the benefit of the 539 | patent license for this particular work, or (3) arrange, in a manner 540 | consistent with the requirements of this License, to extend the patent 541 | license to downstream recipients. "Knowingly relying" means you have 542 | actual knowledge that, but for the patent license, your conveying the 543 | covered work in a country, or your recipient's use of the covered work 544 | in a country, would infringe one or more identifiable patents in that 545 | country that you have reason to believe are valid. 546 | 547 | If, pursuant to or in connection with a single transaction or 548 | arrangement, you convey, or propagate by procuring conveyance of, a 549 | covered work, and grant a patent license to some of the parties 550 | receiving the covered work authorizing them to use, propagate, modify 551 | or convey a specific copy of the covered work, then the patent license 552 | you grant is automatically extended to all recipients of the covered 553 | work and works based on it. 554 | 555 | A patent license is "discriminatory" if it does not include within 556 | the scope of its coverage, prohibits the exercise of, or is 557 | conditioned on the non-exercise of one or more of the rights that are 558 | specifically granted under this License. You may not convey a covered 559 | work if you are a party to an arrangement with a third party that is 560 | in the business of distributing software, under which you make payment 561 | to the third party based on the extent of your activity of conveying 562 | the work, and under which the third party grants, to any of the 563 | parties who would receive the covered work from you, a discriminatory 564 | patent license (a) in connection with copies of the covered work 565 | conveyed by you (or copies made from those copies), or (b) primarily 566 | for and in connection with specific products or compilations that 567 | contain the covered work, unless you entered into that arrangement, 568 | or that patent license was granted, prior to 28 March 2007. 569 | 570 | Nothing in this License shall be construed as excluding or limiting 571 | any implied license or other defenses to infringement that may 572 | otherwise be available to you under applicable patent law. 573 | 574 | 12. No Surrender of Others' Freedom. 575 | 576 | If conditions are imposed on you (whether by court order, agreement or 577 | otherwise) that contradict the conditions of this License, they do not 578 | excuse you from the conditions of this License. If you cannot convey a 579 | covered work so as to satisfy simultaneously your obligations under this 580 | License and any other pertinent obligations, then as a consequence you may 581 | not convey it at all. For example, if you agree to terms that obligate you 582 | to collect a royalty for further conveying from those to whom you convey 583 | the Program, the only way you could satisfy both those terms and this 584 | License would be to refrain entirely from conveying the Program. 585 | 586 | 13. Use with the GNU Affero General Public License. 587 | 588 | Notwithstanding any other provision of this License, you have 589 | permission to link or combine any covered work with a work licensed 590 | under version 3 of the GNU Affero General Public License into a single 591 | combined work, and to convey the resulting work. The terms of this 592 | License will continue to apply to the part which is the covered work, 593 | but the special requirements of the GNU Affero General Public License, 594 | section 13, concerning interaction through a network will apply to the 595 | combination as such. 596 | 597 | 14. Revised Versions of this License. 598 | 599 | The Free Software Foundation may publish revised and/or new versions of 600 | the GNU General Public License from time to time. Such new versions will 601 | be similar in spirit to the present version, but may differ in detail to 602 | address new problems or concerns. 603 | 604 | Each version is given a distinguishing version number. If the 605 | Program specifies that a certain numbered version of the GNU General 606 | Public License "or any later version" applies to it, you have the 607 | option of following the terms and conditions either of that numbered 608 | version or of any later version published by the Free Software 609 | Foundation. If the Program does not specify a version number of the 610 | GNU General Public License, you may choose any version ever published 611 | by the Free Software Foundation. 612 | 613 | If the Program specifies that a proxy can decide which future 614 | versions of the GNU General Public License can be used, that proxy's 615 | public statement of acceptance of a version permanently authorizes you 616 | to choose that version for the Program. 617 | 618 | Later license versions may give you additional or different 619 | permissions. However, no additional obligations are imposed on any 620 | author or copyright holder as a result of your choosing to follow a 621 | later version. 622 | 623 | 15. Disclaimer of Warranty. 624 | 625 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 626 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 627 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 628 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 629 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 630 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 631 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 632 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 633 | 634 | 16. Limitation of Liability. 635 | 636 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 637 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 638 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 639 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 640 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 641 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 642 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 643 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 644 | SUCH DAMAGES. 645 | 646 | 17. Interpretation of Sections 15 and 16. 647 | 648 | If the disclaimer of warranty and limitation of liability provided 649 | above cannot be given local legal effect according to their terms, 650 | reviewing courts shall apply local law that most closely approximates 651 | an absolute waiver of all civil liability in connection with the 652 | Program, unless a warranty or assumption of liability accompanies a 653 | copy of the Program in return for a fee. 654 | 655 | END OF TERMS AND CONDITIONS 656 | 657 | How to Apply These Terms to Your New Programs 658 | 659 | If you develop a new program, and you want it to be of the greatest 660 | possible use to the public, the best way to achieve this is to make it 661 | free software which everyone can redistribute and change under these terms. 662 | 663 | To do so, attach the following notices to the program. It is safest 664 | to attach them to the start of each source file to most effectively 665 | state the exclusion of warranty; and each file should have at least 666 | the "copyright" line and a pointer to where the full notice is found. 667 | 668 | 669 | Copyright (C) 670 | 671 | This program is free software: you can redistribute it and/or modify 672 | it under the terms of the GNU General Public License as published by 673 | the Free Software Foundation, either version 3 of the License, or 674 | (at your option) any later version. 675 | 676 | This program is distributed in the hope that it will be useful, 677 | but WITHOUT ANY WARRANTY; without even the implied warranty of 678 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 679 | GNU General Public License for more details. 680 | 681 | You should have received a copy of the GNU General Public License 682 | along with this program. If not, see . 683 | 684 | Also add information on how to contact you by electronic and paper mail. 685 | 686 | If the program does terminal interaction, make it output a short 687 | notice like this when it starts in an interactive mode: 688 | 689 | Copyright (C) 690 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 691 | This is free software, and you are welcome to redistribute it 692 | under certain conditions; type `show c' for details. 693 | 694 | The hypothetical commands `show w' and `show c' should show the appropriate 695 | parts of the General Public License. Of course, your program's commands 696 | might be different; for a GUI interface, you would use an "about box". 697 | 698 | You should also get your employer (if you work as a programmer) or school, 699 | if any, to sign a "copyright disclaimer" for the program, if necessary. 700 | For more information on this, and how to apply and follow the GNU GPL, see 701 | . 702 | 703 | The GNU General Public License does not permit incorporating your program 704 | into proprietary programs. If your program is a subroutine library, you 705 | may consider it more useful to permit linking proprietary applications with 706 | the library. If this is what you want to do, use the GNU Lesser General 707 | Public License instead of this License. But first, please read 708 | . 709 | 710 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jquery-udraggable 2 | ================= 3 | 4 | jQuery plugin to make elements draggable by mouse or touch. 5 | 6 | See the [documentation page](http://grantm.github.com/jquery-udraggable/) 7 | for examples and reference documentation. 8 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Visit http://grantm.github.com/jquery-udraggable/ to view this documentation 2 | in your browser. 3 | 4 | -------------------------------------------------------------------------------- /docs/css/bootstrap-responsive.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .clearfix { 12 | *zoom: 1; 13 | } 14 | 15 | .clearfix:before, 16 | .clearfix:after { 17 | display: table; 18 | line-height: 0; 19 | content: ""; 20 | } 21 | 22 | .clearfix:after { 23 | clear: both; 24 | } 25 | 26 | .hide-text { 27 | font: 0/0 a; 28 | color: transparent; 29 | text-shadow: none; 30 | background-color: transparent; 31 | border: 0; 32 | } 33 | 34 | .input-block-level { 35 | display: block; 36 | width: 100%; 37 | min-height: 30px; 38 | -webkit-box-sizing: border-box; 39 | -moz-box-sizing: border-box; 40 | box-sizing: border-box; 41 | } 42 | 43 | @-ms-viewport { 44 | width: device-width; 45 | } 46 | 47 | .hidden { 48 | display: none; 49 | visibility: hidden; 50 | } 51 | 52 | .visible-phone { 53 | display: none !important; 54 | } 55 | 56 | .visible-tablet { 57 | display: none !important; 58 | } 59 | 60 | .hidden-desktop { 61 | display: none !important; 62 | } 63 | 64 | .visible-desktop { 65 | display: inherit !important; 66 | } 67 | 68 | @media (min-width: 768px) and (max-width: 979px) { 69 | .hidden-desktop { 70 | display: inherit !important; 71 | } 72 | .visible-desktop { 73 | display: none !important ; 74 | } 75 | .visible-tablet { 76 | display: inherit !important; 77 | } 78 | .hidden-tablet { 79 | display: none !important; 80 | } 81 | } 82 | 83 | @media (max-width: 767px) { 84 | .hidden-desktop { 85 | display: inherit !important; 86 | } 87 | .visible-desktop { 88 | display: none !important; 89 | } 90 | .visible-phone { 91 | display: inherit !important; 92 | } 93 | .hidden-phone { 94 | display: none !important; 95 | } 96 | } 97 | 98 | .visible-print { 99 | display: none !important; 100 | } 101 | 102 | @media print { 103 | .visible-print { 104 | display: inherit !important; 105 | } 106 | .hidden-print { 107 | display: none !important; 108 | } 109 | } 110 | 111 | @media (min-width: 1200px) { 112 | .row { 113 | margin-left: -30px; 114 | *zoom: 1; 115 | } 116 | .row:before, 117 | .row:after { 118 | display: table; 119 | line-height: 0; 120 | content: ""; 121 | } 122 | .row:after { 123 | clear: both; 124 | } 125 | [class*="span"] { 126 | float: left; 127 | min-height: 1px; 128 | margin-left: 30px; 129 | } 130 | .container, 131 | .navbar-static-top .container, 132 | .navbar-fixed-top .container, 133 | .navbar-fixed-bottom .container { 134 | width: 1170px; 135 | } 136 | .span12 { 137 | width: 1170px; 138 | } 139 | .span11 { 140 | width: 1070px; 141 | } 142 | .span10 { 143 | width: 970px; 144 | } 145 | .span9 { 146 | width: 870px; 147 | } 148 | .span8 { 149 | width: 770px; 150 | } 151 | .span7 { 152 | width: 670px; 153 | } 154 | .span6 { 155 | width: 570px; 156 | } 157 | .span5 { 158 | width: 470px; 159 | } 160 | .span4 { 161 | width: 370px; 162 | } 163 | .span3 { 164 | width: 270px; 165 | } 166 | .span2 { 167 | width: 170px; 168 | } 169 | .span1 { 170 | width: 70px; 171 | } 172 | .offset12 { 173 | margin-left: 1230px; 174 | } 175 | .offset11 { 176 | margin-left: 1130px; 177 | } 178 | .offset10 { 179 | margin-left: 1030px; 180 | } 181 | .offset9 { 182 | margin-left: 930px; 183 | } 184 | .offset8 { 185 | margin-left: 830px; 186 | } 187 | .offset7 { 188 | margin-left: 730px; 189 | } 190 | .offset6 { 191 | margin-left: 630px; 192 | } 193 | .offset5 { 194 | margin-left: 530px; 195 | } 196 | .offset4 { 197 | margin-left: 430px; 198 | } 199 | .offset3 { 200 | margin-left: 330px; 201 | } 202 | .offset2 { 203 | margin-left: 230px; 204 | } 205 | .offset1 { 206 | margin-left: 130px; 207 | } 208 | .row-fluid { 209 | width: 100%; 210 | *zoom: 1; 211 | } 212 | .row-fluid:before, 213 | .row-fluid:after { 214 | display: table; 215 | line-height: 0; 216 | content: ""; 217 | } 218 | .row-fluid:after { 219 | clear: both; 220 | } 221 | .row-fluid [class*="span"] { 222 | display: block; 223 | float: left; 224 | width: 100%; 225 | min-height: 30px; 226 | margin-left: 2.564102564102564%; 227 | *margin-left: 2.5109110747408616%; 228 | -webkit-box-sizing: border-box; 229 | -moz-box-sizing: border-box; 230 | box-sizing: border-box; 231 | } 232 | .row-fluid [class*="span"]:first-child { 233 | margin-left: 0; 234 | } 235 | .row-fluid .controls-row [class*="span"] + [class*="span"] { 236 | margin-left: 2.564102564102564%; 237 | } 238 | .row-fluid .span12 { 239 | width: 100%; 240 | *width: 99.94680851063829%; 241 | } 242 | .row-fluid .span11 { 243 | width: 91.45299145299145%; 244 | *width: 91.39979996362975%; 245 | } 246 | .row-fluid .span10 { 247 | width: 82.90598290598291%; 248 | *width: 82.8527914166212%; 249 | } 250 | .row-fluid .span9 { 251 | width: 74.35897435897436%; 252 | *width: 74.30578286961266%; 253 | } 254 | .row-fluid .span8 { 255 | width: 65.81196581196582%; 256 | *width: 65.75877432260411%; 257 | } 258 | .row-fluid .span7 { 259 | width: 57.26495726495726%; 260 | *width: 57.21176577559556%; 261 | } 262 | .row-fluid .span6 { 263 | width: 48.717948717948715%; 264 | *width: 48.664757228587014%; 265 | } 266 | .row-fluid .span5 { 267 | width: 40.17094017094017%; 268 | *width: 40.11774868157847%; 269 | } 270 | .row-fluid .span4 { 271 | width: 31.623931623931625%; 272 | *width: 31.570740134569924%; 273 | } 274 | .row-fluid .span3 { 275 | width: 23.076923076923077%; 276 | *width: 23.023731587561375%; 277 | } 278 | .row-fluid .span2 { 279 | width: 14.52991452991453%; 280 | *width: 14.476723040552828%; 281 | } 282 | .row-fluid .span1 { 283 | width: 5.982905982905983%; 284 | *width: 5.929714493544281%; 285 | } 286 | .row-fluid .offset12 { 287 | margin-left: 105.12820512820512%; 288 | *margin-left: 105.02182214948171%; 289 | } 290 | .row-fluid .offset12:first-child { 291 | margin-left: 102.56410256410257%; 292 | *margin-left: 102.45771958537915%; 293 | } 294 | .row-fluid .offset11 { 295 | margin-left: 96.58119658119658%; 296 | *margin-left: 96.47481360247316%; 297 | } 298 | .row-fluid .offset11:first-child { 299 | margin-left: 94.01709401709402%; 300 | *margin-left: 93.91071103837061%; 301 | } 302 | .row-fluid .offset10 { 303 | margin-left: 88.03418803418803%; 304 | *margin-left: 87.92780505546462%; 305 | } 306 | .row-fluid .offset10:first-child { 307 | margin-left: 85.47008547008548%; 308 | *margin-left: 85.36370249136206%; 309 | } 310 | .row-fluid .offset9 { 311 | margin-left: 79.48717948717949%; 312 | *margin-left: 79.38079650845607%; 313 | } 314 | .row-fluid .offset9:first-child { 315 | margin-left: 76.92307692307693%; 316 | *margin-left: 76.81669394435352%; 317 | } 318 | .row-fluid .offset8 { 319 | margin-left: 70.94017094017094%; 320 | *margin-left: 70.83378796144753%; 321 | } 322 | .row-fluid .offset8:first-child { 323 | margin-left: 68.37606837606839%; 324 | *margin-left: 68.26968539734497%; 325 | } 326 | .row-fluid .offset7 { 327 | margin-left: 62.393162393162385%; 328 | *margin-left: 62.28677941443899%; 329 | } 330 | .row-fluid .offset7:first-child { 331 | margin-left: 59.82905982905982%; 332 | *margin-left: 59.72267685033642%; 333 | } 334 | .row-fluid .offset6 { 335 | margin-left: 53.84615384615384%; 336 | *margin-left: 53.739770867430444%; 337 | } 338 | .row-fluid .offset6:first-child { 339 | margin-left: 51.28205128205128%; 340 | *margin-left: 51.175668303327875%; 341 | } 342 | .row-fluid .offset5 { 343 | margin-left: 45.299145299145295%; 344 | *margin-left: 45.1927623204219%; 345 | } 346 | .row-fluid .offset5:first-child { 347 | margin-left: 42.73504273504273%; 348 | *margin-left: 42.62865975631933%; 349 | } 350 | .row-fluid .offset4 { 351 | margin-left: 36.75213675213675%; 352 | *margin-left: 36.645753773413354%; 353 | } 354 | .row-fluid .offset4:first-child { 355 | margin-left: 34.18803418803419%; 356 | *margin-left: 34.081651209310785%; 357 | } 358 | .row-fluid .offset3 { 359 | margin-left: 28.205128205128204%; 360 | *margin-left: 28.0987452264048%; 361 | } 362 | .row-fluid .offset3:first-child { 363 | margin-left: 25.641025641025642%; 364 | *margin-left: 25.53464266230224%; 365 | } 366 | .row-fluid .offset2 { 367 | margin-left: 19.65811965811966%; 368 | *margin-left: 19.551736679396257%; 369 | } 370 | .row-fluid .offset2:first-child { 371 | margin-left: 17.094017094017094%; 372 | *margin-left: 16.98763411529369%; 373 | } 374 | .row-fluid .offset1 { 375 | margin-left: 11.11111111111111%; 376 | *margin-left: 11.004728132387708%; 377 | } 378 | .row-fluid .offset1:first-child { 379 | margin-left: 8.547008547008547%; 380 | *margin-left: 8.440625568285142%; 381 | } 382 | input, 383 | textarea, 384 | .uneditable-input { 385 | margin-left: 0; 386 | } 387 | .controls-row [class*="span"] + [class*="span"] { 388 | margin-left: 30px; 389 | } 390 | input.span12, 391 | textarea.span12, 392 | .uneditable-input.span12 { 393 | width: 1156px; 394 | } 395 | input.span11, 396 | textarea.span11, 397 | .uneditable-input.span11 { 398 | width: 1056px; 399 | } 400 | input.span10, 401 | textarea.span10, 402 | .uneditable-input.span10 { 403 | width: 956px; 404 | } 405 | input.span9, 406 | textarea.span9, 407 | .uneditable-input.span9 { 408 | width: 856px; 409 | } 410 | input.span8, 411 | textarea.span8, 412 | .uneditable-input.span8 { 413 | width: 756px; 414 | } 415 | input.span7, 416 | textarea.span7, 417 | .uneditable-input.span7 { 418 | width: 656px; 419 | } 420 | input.span6, 421 | textarea.span6, 422 | .uneditable-input.span6 { 423 | width: 556px; 424 | } 425 | input.span5, 426 | textarea.span5, 427 | .uneditable-input.span5 { 428 | width: 456px; 429 | } 430 | input.span4, 431 | textarea.span4, 432 | .uneditable-input.span4 { 433 | width: 356px; 434 | } 435 | input.span3, 436 | textarea.span3, 437 | .uneditable-input.span3 { 438 | width: 256px; 439 | } 440 | input.span2, 441 | textarea.span2, 442 | .uneditable-input.span2 { 443 | width: 156px; 444 | } 445 | input.span1, 446 | textarea.span1, 447 | .uneditable-input.span1 { 448 | width: 56px; 449 | } 450 | .thumbnails { 451 | margin-left: -30px; 452 | } 453 | .thumbnails > li { 454 | margin-left: 30px; 455 | } 456 | .row-fluid .thumbnails { 457 | margin-left: 0; 458 | } 459 | } 460 | 461 | @media (min-width: 768px) and (max-width: 979px) { 462 | .row { 463 | margin-left: -20px; 464 | *zoom: 1; 465 | } 466 | .row:before, 467 | .row:after { 468 | display: table; 469 | line-height: 0; 470 | content: ""; 471 | } 472 | .row:after { 473 | clear: both; 474 | } 475 | [class*="span"] { 476 | float: left; 477 | min-height: 1px; 478 | margin-left: 20px; 479 | } 480 | .container, 481 | .navbar-static-top .container, 482 | .navbar-fixed-top .container, 483 | .navbar-fixed-bottom .container { 484 | width: 724px; 485 | } 486 | .span12 { 487 | width: 724px; 488 | } 489 | .span11 { 490 | width: 662px; 491 | } 492 | .span10 { 493 | width: 600px; 494 | } 495 | .span9 { 496 | width: 538px; 497 | } 498 | .span8 { 499 | width: 476px; 500 | } 501 | .span7 { 502 | width: 414px; 503 | } 504 | .span6 { 505 | width: 352px; 506 | } 507 | .span5 { 508 | width: 290px; 509 | } 510 | .span4 { 511 | width: 228px; 512 | } 513 | .span3 { 514 | width: 166px; 515 | } 516 | .span2 { 517 | width: 104px; 518 | } 519 | .span1 { 520 | width: 42px; 521 | } 522 | .offset12 { 523 | margin-left: 764px; 524 | } 525 | .offset11 { 526 | margin-left: 702px; 527 | } 528 | .offset10 { 529 | margin-left: 640px; 530 | } 531 | .offset9 { 532 | margin-left: 578px; 533 | } 534 | .offset8 { 535 | margin-left: 516px; 536 | } 537 | .offset7 { 538 | margin-left: 454px; 539 | } 540 | .offset6 { 541 | margin-left: 392px; 542 | } 543 | .offset5 { 544 | margin-left: 330px; 545 | } 546 | .offset4 { 547 | margin-left: 268px; 548 | } 549 | .offset3 { 550 | margin-left: 206px; 551 | } 552 | .offset2 { 553 | margin-left: 144px; 554 | } 555 | .offset1 { 556 | margin-left: 82px; 557 | } 558 | .row-fluid { 559 | width: 100%; 560 | *zoom: 1; 561 | } 562 | .row-fluid:before, 563 | .row-fluid:after { 564 | display: table; 565 | line-height: 0; 566 | content: ""; 567 | } 568 | .row-fluid:after { 569 | clear: both; 570 | } 571 | .row-fluid [class*="span"] { 572 | display: block; 573 | float: left; 574 | width: 100%; 575 | min-height: 30px; 576 | margin-left: 2.7624309392265194%; 577 | *margin-left: 2.709239449864817%; 578 | -webkit-box-sizing: border-box; 579 | -moz-box-sizing: border-box; 580 | box-sizing: border-box; 581 | } 582 | .row-fluid [class*="span"]:first-child { 583 | margin-left: 0; 584 | } 585 | .row-fluid .controls-row [class*="span"] + [class*="span"] { 586 | margin-left: 2.7624309392265194%; 587 | } 588 | .row-fluid .span12 { 589 | width: 100%; 590 | *width: 99.94680851063829%; 591 | } 592 | .row-fluid .span11 { 593 | width: 91.43646408839778%; 594 | *width: 91.38327259903608%; 595 | } 596 | .row-fluid .span10 { 597 | width: 82.87292817679558%; 598 | *width: 82.81973668743387%; 599 | } 600 | .row-fluid .span9 { 601 | width: 74.30939226519337%; 602 | *width: 74.25620077583166%; 603 | } 604 | .row-fluid .span8 { 605 | width: 65.74585635359117%; 606 | *width: 65.69266486422946%; 607 | } 608 | .row-fluid .span7 { 609 | width: 57.18232044198895%; 610 | *width: 57.12912895262725%; 611 | } 612 | .row-fluid .span6 { 613 | width: 48.61878453038674%; 614 | *width: 48.56559304102504%; 615 | } 616 | .row-fluid .span5 { 617 | width: 40.05524861878453%; 618 | *width: 40.00205712942283%; 619 | } 620 | .row-fluid .span4 { 621 | width: 31.491712707182323%; 622 | *width: 31.43852121782062%; 623 | } 624 | .row-fluid .span3 { 625 | width: 22.92817679558011%; 626 | *width: 22.87498530621841%; 627 | } 628 | .row-fluid .span2 { 629 | width: 14.3646408839779%; 630 | *width: 14.311449394616199%; 631 | } 632 | .row-fluid .span1 { 633 | width: 5.801104972375691%; 634 | *width: 5.747913483013988%; 635 | } 636 | .row-fluid .offset12 { 637 | margin-left: 105.52486187845304%; 638 | *margin-left: 105.41847889972962%; 639 | } 640 | .row-fluid .offset12:first-child { 641 | margin-left: 102.76243093922652%; 642 | *margin-left: 102.6560479605031%; 643 | } 644 | .row-fluid .offset11 { 645 | margin-left: 96.96132596685082%; 646 | *margin-left: 96.8549429881274%; 647 | } 648 | .row-fluid .offset11:first-child { 649 | margin-left: 94.1988950276243%; 650 | *margin-left: 94.09251204890089%; 651 | } 652 | .row-fluid .offset10 { 653 | margin-left: 88.39779005524862%; 654 | *margin-left: 88.2914070765252%; 655 | } 656 | .row-fluid .offset10:first-child { 657 | margin-left: 85.6353591160221%; 658 | *margin-left: 85.52897613729868%; 659 | } 660 | .row-fluid .offset9 { 661 | margin-left: 79.8342541436464%; 662 | *margin-left: 79.72787116492299%; 663 | } 664 | .row-fluid .offset9:first-child { 665 | margin-left: 77.07182320441989%; 666 | *margin-left: 76.96544022569647%; 667 | } 668 | .row-fluid .offset8 { 669 | margin-left: 71.2707182320442%; 670 | *margin-left: 71.16433525332079%; 671 | } 672 | .row-fluid .offset8:first-child { 673 | margin-left: 68.50828729281768%; 674 | *margin-left: 68.40190431409427%; 675 | } 676 | .row-fluid .offset7 { 677 | margin-left: 62.70718232044199%; 678 | *margin-left: 62.600799341718584%; 679 | } 680 | .row-fluid .offset7:first-child { 681 | margin-left: 59.94475138121547%; 682 | *margin-left: 59.838368402492065%; 683 | } 684 | .row-fluid .offset6 { 685 | margin-left: 54.14364640883978%; 686 | *margin-left: 54.037263430116376%; 687 | } 688 | .row-fluid .offset6:first-child { 689 | margin-left: 51.38121546961326%; 690 | *margin-left: 51.27483249088986%; 691 | } 692 | .row-fluid .offset5 { 693 | margin-left: 45.58011049723757%; 694 | *margin-left: 45.47372751851417%; 695 | } 696 | .row-fluid .offset5:first-child { 697 | margin-left: 42.81767955801105%; 698 | *margin-left: 42.71129657928765%; 699 | } 700 | .row-fluid .offset4 { 701 | margin-left: 37.01657458563536%; 702 | *margin-left: 36.91019160691196%; 703 | } 704 | .row-fluid .offset4:first-child { 705 | margin-left: 34.25414364640884%; 706 | *margin-left: 34.14776066768544%; 707 | } 708 | .row-fluid .offset3 { 709 | margin-left: 28.45303867403315%; 710 | *margin-left: 28.346655695309746%; 711 | } 712 | .row-fluid .offset3:first-child { 713 | margin-left: 25.69060773480663%; 714 | *margin-left: 25.584224756083227%; 715 | } 716 | .row-fluid .offset2 { 717 | margin-left: 19.88950276243094%; 718 | *margin-left: 19.783119783707537%; 719 | } 720 | .row-fluid .offset2:first-child { 721 | margin-left: 17.12707182320442%; 722 | *margin-left: 17.02068884448102%; 723 | } 724 | .row-fluid .offset1 { 725 | margin-left: 11.32596685082873%; 726 | *margin-left: 11.219583872105325%; 727 | } 728 | .row-fluid .offset1:first-child { 729 | margin-left: 8.56353591160221%; 730 | *margin-left: 8.457152932878806%; 731 | } 732 | input, 733 | textarea, 734 | .uneditable-input { 735 | margin-left: 0; 736 | } 737 | .controls-row [class*="span"] + [class*="span"] { 738 | margin-left: 20px; 739 | } 740 | input.span12, 741 | textarea.span12, 742 | .uneditable-input.span12 { 743 | width: 710px; 744 | } 745 | input.span11, 746 | textarea.span11, 747 | .uneditable-input.span11 { 748 | width: 648px; 749 | } 750 | input.span10, 751 | textarea.span10, 752 | .uneditable-input.span10 { 753 | width: 586px; 754 | } 755 | input.span9, 756 | textarea.span9, 757 | .uneditable-input.span9 { 758 | width: 524px; 759 | } 760 | input.span8, 761 | textarea.span8, 762 | .uneditable-input.span8 { 763 | width: 462px; 764 | } 765 | input.span7, 766 | textarea.span7, 767 | .uneditable-input.span7 { 768 | width: 400px; 769 | } 770 | input.span6, 771 | textarea.span6, 772 | .uneditable-input.span6 { 773 | width: 338px; 774 | } 775 | input.span5, 776 | textarea.span5, 777 | .uneditable-input.span5 { 778 | width: 276px; 779 | } 780 | input.span4, 781 | textarea.span4, 782 | .uneditable-input.span4 { 783 | width: 214px; 784 | } 785 | input.span3, 786 | textarea.span3, 787 | .uneditable-input.span3 { 788 | width: 152px; 789 | } 790 | input.span2, 791 | textarea.span2, 792 | .uneditable-input.span2 { 793 | width: 90px; 794 | } 795 | input.span1, 796 | textarea.span1, 797 | .uneditable-input.span1 { 798 | width: 28px; 799 | } 800 | } 801 | 802 | @media (max-width: 767px) { 803 | body { 804 | padding-right: 20px; 805 | padding-left: 20px; 806 | } 807 | .navbar-fixed-top, 808 | .navbar-fixed-bottom, 809 | .navbar-static-top { 810 | margin-right: -20px; 811 | margin-left: -20px; 812 | } 813 | .container-fluid { 814 | padding: 0; 815 | } 816 | .dl-horizontal dt { 817 | float: none; 818 | width: auto; 819 | clear: none; 820 | text-align: left; 821 | } 822 | .dl-horizontal dd { 823 | margin-left: 0; 824 | } 825 | .container { 826 | width: auto; 827 | } 828 | .row-fluid { 829 | width: 100%; 830 | } 831 | .row, 832 | .thumbnails { 833 | margin-left: 0; 834 | } 835 | .thumbnails > li { 836 | float: none; 837 | margin-left: 0; 838 | } 839 | [class*="span"], 840 | .uneditable-input[class*="span"], 841 | .row-fluid [class*="span"] { 842 | display: block; 843 | float: none; 844 | width: 100%; 845 | margin-left: 0; 846 | -webkit-box-sizing: border-box; 847 | -moz-box-sizing: border-box; 848 | box-sizing: border-box; 849 | } 850 | .span12, 851 | .row-fluid .span12 { 852 | width: 100%; 853 | -webkit-box-sizing: border-box; 854 | -moz-box-sizing: border-box; 855 | box-sizing: border-box; 856 | } 857 | .row-fluid [class*="offset"]:first-child { 858 | margin-left: 0; 859 | } 860 | .input-large, 861 | .input-xlarge, 862 | .input-xxlarge, 863 | input[class*="span"], 864 | select[class*="span"], 865 | textarea[class*="span"], 866 | .uneditable-input { 867 | display: block; 868 | width: 100%; 869 | min-height: 30px; 870 | -webkit-box-sizing: border-box; 871 | -moz-box-sizing: border-box; 872 | box-sizing: border-box; 873 | } 874 | .input-prepend input, 875 | .input-append input, 876 | .input-prepend input[class*="span"], 877 | .input-append input[class*="span"] { 878 | display: inline-block; 879 | width: auto; 880 | } 881 | .controls-row [class*="span"] + [class*="span"] { 882 | margin-left: 0; 883 | } 884 | .modal { 885 | position: fixed; 886 | top: 20px; 887 | right: 20px; 888 | left: 20px; 889 | width: auto; 890 | margin: 0; 891 | } 892 | .modal.fade { 893 | top: -100px; 894 | } 895 | .modal.fade.in { 896 | top: 20px; 897 | } 898 | } 899 | 900 | @media (max-width: 480px) { 901 | .nav-collapse { 902 | -webkit-transform: translate3d(0, 0, 0); 903 | } 904 | .page-header h1 small { 905 | display: block; 906 | line-height: 20px; 907 | } 908 | input[type="checkbox"], 909 | input[type="radio"] { 910 | border: 1px solid #ccc; 911 | } 912 | .form-horizontal .control-label { 913 | float: none; 914 | width: auto; 915 | padding-top: 0; 916 | text-align: left; 917 | } 918 | .form-horizontal .controls { 919 | margin-left: 0; 920 | } 921 | .form-horizontal .control-list { 922 | padding-top: 0; 923 | } 924 | .form-horizontal .form-actions { 925 | padding-right: 10px; 926 | padding-left: 10px; 927 | } 928 | .media .pull-left, 929 | .media .pull-right { 930 | display: block; 931 | float: none; 932 | margin-bottom: 10px; 933 | } 934 | .media-object { 935 | margin-right: 0; 936 | margin-left: 0; 937 | } 938 | .modal { 939 | top: 10px; 940 | right: 10px; 941 | left: 10px; 942 | } 943 | .modal-header .close { 944 | padding: 10px; 945 | margin: -10px; 946 | } 947 | .carousel-caption { 948 | position: static; 949 | } 950 | } 951 | 952 | @media (max-width: 979px) { 953 | body { 954 | padding-top: 0; 955 | } 956 | .navbar-fixed-top, 957 | .navbar-fixed-bottom { 958 | position: static; 959 | } 960 | .navbar-fixed-top { 961 | margin-bottom: 20px; 962 | } 963 | .navbar-fixed-bottom { 964 | margin-top: 20px; 965 | } 966 | .navbar-fixed-top .navbar-inner, 967 | .navbar-fixed-bottom .navbar-inner { 968 | padding: 5px; 969 | } 970 | .navbar .container { 971 | width: auto; 972 | padding: 0; 973 | } 974 | .navbar .brand { 975 | padding-right: 10px; 976 | padding-left: 10px; 977 | margin: 0 0 0 -5px; 978 | } 979 | .nav-collapse { 980 | clear: both; 981 | } 982 | .nav-collapse .nav { 983 | float: none; 984 | margin: 0 0 10px; 985 | } 986 | .nav-collapse .nav > li { 987 | float: none; 988 | } 989 | .nav-collapse .nav > li > a { 990 | margin-bottom: 2px; 991 | } 992 | .nav-collapse .nav > .divider-vertical { 993 | display: none; 994 | } 995 | .nav-collapse .nav .nav-header { 996 | color: #777777; 997 | text-shadow: none; 998 | } 999 | .nav-collapse .nav > li > a, 1000 | .nav-collapse .dropdown-menu a { 1001 | padding: 9px 15px; 1002 | font-weight: bold; 1003 | color: #777777; 1004 | -webkit-border-radius: 3px; 1005 | -moz-border-radius: 3px; 1006 | border-radius: 3px; 1007 | } 1008 | .nav-collapse .btn { 1009 | padding: 4px 10px 4px; 1010 | font-weight: normal; 1011 | -webkit-border-radius: 4px; 1012 | -moz-border-radius: 4px; 1013 | border-radius: 4px; 1014 | } 1015 | .nav-collapse .dropdown-menu li + li a { 1016 | margin-bottom: 2px; 1017 | } 1018 | .nav-collapse .nav > li > a:hover, 1019 | .nav-collapse .nav > li > a:focus, 1020 | .nav-collapse .dropdown-menu a:hover, 1021 | .nav-collapse .dropdown-menu a:focus { 1022 | background-color: #f2f2f2; 1023 | } 1024 | .navbar-inverse .nav-collapse .nav > li > a, 1025 | .navbar-inverse .nav-collapse .dropdown-menu a { 1026 | color: #999999; 1027 | } 1028 | .navbar-inverse .nav-collapse .nav > li > a:hover, 1029 | .navbar-inverse .nav-collapse .nav > li > a:focus, 1030 | .navbar-inverse .nav-collapse .dropdown-menu a:hover, 1031 | .navbar-inverse .nav-collapse .dropdown-menu a:focus { 1032 | background-color: #111111; 1033 | } 1034 | .nav-collapse.in .btn-group { 1035 | padding: 0; 1036 | margin-top: 5px; 1037 | } 1038 | .nav-collapse .dropdown-menu { 1039 | position: static; 1040 | top: auto; 1041 | left: auto; 1042 | display: none; 1043 | float: none; 1044 | max-width: none; 1045 | padding: 0; 1046 | margin: 0 15px; 1047 | background-color: transparent; 1048 | border: none; 1049 | -webkit-border-radius: 0; 1050 | -moz-border-radius: 0; 1051 | border-radius: 0; 1052 | -webkit-box-shadow: none; 1053 | -moz-box-shadow: none; 1054 | box-shadow: none; 1055 | } 1056 | .nav-collapse .open > .dropdown-menu { 1057 | display: block; 1058 | } 1059 | .nav-collapse .dropdown-menu:before, 1060 | .nav-collapse .dropdown-menu:after { 1061 | display: none; 1062 | } 1063 | .nav-collapse .dropdown-menu .divider { 1064 | display: none; 1065 | } 1066 | .nav-collapse .nav > li > .dropdown-menu:before, 1067 | .nav-collapse .nav > li > .dropdown-menu:after { 1068 | display: none; 1069 | } 1070 | .nav-collapse .navbar-form, 1071 | .nav-collapse .navbar-search { 1072 | float: none; 1073 | padding: 10px 15px; 1074 | margin: 10px 0; 1075 | border-top: 1px solid #f2f2f2; 1076 | border-bottom: 1px solid #f2f2f2; 1077 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 1078 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 1079 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 1080 | } 1081 | .navbar-inverse .nav-collapse .navbar-form, 1082 | .navbar-inverse .nav-collapse .navbar-search { 1083 | border-top-color: #111111; 1084 | border-bottom-color: #111111; 1085 | } 1086 | .navbar .nav-collapse .nav.pull-right { 1087 | float: none; 1088 | margin-left: 0; 1089 | } 1090 | .nav-collapse, 1091 | .nav-collapse.collapse { 1092 | height: 0; 1093 | overflow: hidden; 1094 | } 1095 | .navbar .btn-navbar { 1096 | display: block; 1097 | } 1098 | .navbar-static .navbar-inner { 1099 | padding-right: 10px; 1100 | padding-left: 10px; 1101 | } 1102 | } 1103 | 1104 | @media (min-width: 980px) { 1105 | .nav-collapse.collapse { 1106 | height: auto !important; 1107 | overflow: visible !important; 1108 | } 1109 | } 1110 | -------------------------------------------------------------------------------- /docs/css/site.css: -------------------------------------------------------------------------------- 1 | 2 | div.hero-unit { 3 | margin-top: 30px; 4 | } 5 | 6 | div.hero-unit h1 { 7 | margin-top: 0; 8 | margin-bottom: 12px; 9 | } 10 | 11 | div.hero-unit p { 12 | font-height: 18px; 13 | line-height: 27px; 14 | } 15 | 16 | body h1 { 17 | margin-top: 40px; 18 | } 19 | 20 | body h2 { 21 | margin-top: 30px; 22 | } 23 | 24 | div.row-fluid #demo-titles { 25 | float: right; 26 | } 27 | 28 | dl dd { 29 | margin: 0 0 12px 36px; 30 | } 31 | 32 | p.example-link { 33 | margin: 0 0 0 0; 34 | float: right; 35 | font-size: 90%; 36 | line-height: 1; 37 | } 38 | 39 | #sample1 { 40 | position: relative; 41 | padding: 30px; 42 | } 43 | 44 | #try-drag { 45 | position: absolute; 46 | left: 295px; 47 | top: 5px; 48 | width: 256px; 49 | height: 74px; 50 | background-image: url(../img/try-dragging.png) 51 | } 52 | 53 | #star { 54 | position: absolute; 55 | left: 295px; 56 | top: 10px; 57 | width: 60px; 58 | height: 60px; 59 | background-image: url(../img/star.png) 60 | } 61 | 62 | -------------------------------------------------------------------------------- /docs/examples/examples.css: -------------------------------------------------------------------------------- 1 | 2 | body { 3 | font-family: sans-serif; 4 | color: #333333; 5 | padding: 1em 1em 5em 1em; 6 | } 7 | 8 | p { 9 | line-height: 1.3; 10 | } 11 | 12 | blockquote { 13 | font-family: serif; 14 | font-style: italic; 15 | font-size: 110%; 16 | max-width: 50em; 17 | margin-right: 5em; 18 | } 19 | 20 | pre.code { 21 | margin: 2em 1em 2em 0; 22 | padding: 1.3em; 23 | border: 1px solid #aaaaaa; 24 | background-color: #f7f7f7; 25 | border-radius: 3px; 26 | } 27 | 28 | table.options-list { 29 | border-collapse: collapse; 30 | } 31 | 32 | table.options-list th { 33 | padding: 1.4em 2em 0.4em 0; 34 | border-bottom: 1px solid #aaaaaa; 35 | } 36 | 37 | table.options-list td { 38 | border-bottom: 1px solid #aaaaaa; 39 | padding: 1em; 40 | } 41 | 42 | table.options-list td:first-child { 43 | vertical-align: top; 44 | max-width: 40em; 45 | border-right: 1px solid #aaaaaa; 46 | } 47 | 48 | .arena { 49 | position: relative; 50 | width: 300px; 51 | height: 240px; 52 | background-color: #ffffee; 53 | border: 1px solid #cccccc; 54 | border-radius: 4px; 55 | } 56 | 57 | #drag1, 58 | #drag2, 59 | #drag3, 60 | #drag4, 61 | #drag14, 62 | #drag15, 63 | #drag16, 64 | #drag17, 65 | #drag18, 66 | #drag19, 67 | .sub-drag { 68 | position: absolute; 69 | top: 105px; 70 | left: 135px; 71 | width: 26px; 72 | height: 26px; 73 | border: 2px solid #6666cc; 74 | background-color: #ccccff; 75 | border-radius: 4px; 76 | } 77 | 78 | #drag4 { 79 | top: 0; 80 | left: 0; 81 | } 82 | 83 | .blk-red { 84 | position: absolute; 85 | width: 26px; 86 | height: 26px; 87 | border: 2px solid #cc6666; 88 | background-color: #ffcccc; 89 | border-radius: 4px; 90 | } 91 | 92 | .blk-green { 93 | position: absolute; 94 | width: 26px; 95 | height: 26px; 96 | border: 2px solid #66cc66; 97 | background-color: #ccffcc; 98 | border-radius: 4px; 99 | } 100 | 101 | #drag5 { top: 33px; left: 125px; } 102 | #drag6 { top: 180px; left: 77px; } 103 | #drag7 { top: 110px; left: 16px; } 104 | #drag8 { top: 79px; left: 270px; } 105 | #drag9 { top: 150px; left: 230px; } 106 | #drag10 { top: 7px; left: 169px; } 107 | 108 | #map-container { 109 | overflow: hidden; 110 | border: 1px solid #777777; 111 | } 112 | 113 | #map { 114 | position: absolute; 115 | left: -460px; 116 | top: -60px; 117 | width: 1280px; 118 | height: 635px; 119 | background-image: url(images/world-map.jpg); 120 | } 121 | 122 | #drag11 { 123 | position: absolute; 124 | border: 4px solid #339933; 125 | border-radius: 4px; 126 | width: 150px; 127 | height: 120px; 128 | top: 30px; 129 | left: 60px; 130 | } 131 | #drag12 { top: 60px; left: 30px; } 132 | #drag13 { top: 30px; left: 90px; } 133 | 134 | #drag14.udraggable-dragging { 135 | border: 2px solid #cc6666; 136 | background-color: #ffcccc; 137 | box-shadow: 1px 1px 3px 3px rgba(100, 100, 100, 0.3); 138 | } 139 | 140 | #status-bar { 141 | position: absolute; 142 | bottom: 0; 143 | width: 100%; 144 | height: 24px; 145 | font-size: 16px; 146 | line-height: 1.4; 147 | background-color: #666666; 148 | color: #cccccc; 149 | } 150 | 151 | #status-bar .value { 152 | color: #ffffff; 153 | } 154 | 155 | #status-bar span { 156 | position: absolute; 157 | bottom: 1px; 158 | } 159 | 160 | #lbl-mode { left: 10px; } 161 | #stat-mode { left: 63px; } 162 | #lbl-x { left: 165px; } 163 | #stat-x { left: 185px; } 164 | #lbl-y { left: 237px; } 165 | #stat-y { left: 257px; } 166 | 167 | #dialog { 168 | position: absolute; 169 | top: 30px; 170 | left: 50px; 171 | width: 200px; 172 | padding: 2px; 173 | background-color: #dddddd; 174 | font-family: sans-serif; 175 | font-size: 12px; 176 | border: 3px outset #dddddd; 177 | } 178 | 179 | #dialog h1 { 180 | background-color: #0000aa; 181 | color: #eeeeee; 182 | margin: 0 0 10px 0; 183 | padding: 3px; 184 | text-align: center; 185 | font-size: 14px; 186 | font-weight: bold; 187 | border: 1px inset #0000aa; 188 | cursor: move; 189 | } 190 | 191 | #dialog label { 192 | display: inline-block; 193 | width: 85px; 194 | padding: 0 0 0 2px; 195 | } 196 | 197 | #dialog input.text { 198 | width: 95px; 199 | padding: 1px 2px; 200 | margin: 1px 0; 201 | } 202 | 203 | #dialog select { 204 | width: 104px; 205 | padding: 1px 0px; 206 | } 207 | 208 | #dialog button { 209 | float: right; 210 | } 211 | 212 | .dice { 213 | position: absolute; 214 | width: 72px; 215 | height: 72px; 216 | background-color: #cc0000; 217 | border-radius: 10px; 218 | } 219 | 220 | .dot { 221 | position: absolute; 222 | width: 12px; 223 | height: 12px; 224 | background-color: #eeeeee; 225 | border-radius: 6px; 226 | } 227 | 228 | .dot1 { top: 12px; left: 14px; } 229 | .dot2 { top: 12px; left: 46px; } 230 | .dot3 { top: 30px; left: 14px; } 231 | .dot4 { top: 30px; left: 46px; } 232 | .dot5 { top: 48px; left: 14px; } 233 | .dot6 { top: 48px; left: 46px; } 234 | .dice1 { top: 20px; left: 10px; } 235 | .dice2 { top: 60px; left: 150px; } 236 | 237 | #destroy-btn { 238 | width: 80px; 239 | position: absolute; 240 | bottom: 6px; 241 | left: 110px; 242 | } 243 | 244 | #disable-btn, 245 | #sml-grid-btn, 246 | #zone-red-btn { 247 | width: 80px; 248 | position: absolute; 249 | bottom: 6px; 250 | left: 45px; 251 | } 252 | 253 | #enable-btn, 254 | #big-grid-btn, 255 | #zone-blue-btn { 256 | width: 80px; 257 | position: absolute; 258 | bottom: 6px; 259 | left: 175px; 260 | } 261 | 262 | #zone-red { 263 | position: absolute; 264 | width: 120px; 265 | height: 150px; 266 | left: 89px; 267 | top: 29px; 268 | background-color: #ff6666; 269 | border: 1px solid #881111; 270 | opacity: 0.4; 271 | border-radius: 4px; 272 | } 273 | 274 | #zone-blue { 275 | position: absolute; 276 | width: 240px; 277 | height: 80px; 278 | left: 29px; 279 | top: 59px; 280 | background-color: #6666ff; 281 | border: 1px solid #111188; 282 | opacity: 0.4; 283 | border-radius: 4px; 284 | } 285 | 286 | -------------------------------------------------------------------------------- /docs/examples/images/world-map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grantm/jquery-udraggable/060b2bc04798ac204b2f7881249837c20b0a3fd1/docs/examples/images/world-map.jpg -------------------------------------------------------------------------------- /docs/examples/methods.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery.udraggable: Methods 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

jQuery.udraggable: Methods

14 | 15 |

This is a demo page for the jquery.udraggable.js plugin:

16 | 17 |
“This plugin provides an API similar to jQueryUI's draggable but 18 | with support for unified mouse and touch events. It builds on Michael S. 19 | Mikowski's jquery.event.ue unified event plugin.”
20 | 21 |

The following examples illustrate the use of various methods to 22 | change the udraggable behaviour after the initial setup.

23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 43 | 49 | 50 | 51 | 52 | 68 | 75 | 76 | 77 | 78 | 98 | 105 | 106 | 107 | 108 | 127 | 136 | 137 | 138 |
DescriptionExample
33 |

You can call the destroy method 34 | to completely remove the udraggable behaviour from the target element.

35 |
$('#drag16').udraggable({
 36 |     containment: 'parent'
 37 | });
 38 | 
 39 | $('#destroy-btn').click(function () {
 40 |     $('#drag16').udraggable('destroy');
 41 | });
42 |
44 |
45 |
46 | 47 |
48 |
53 |

You can call the disable and 54 | enable methods to temporarily disable the udraggable 55 | behaviour and later enable it again.

56 |
$('#drag17').udraggable({
 57 |     containment: 'parent'
 58 | });
 59 | 
 60 | $('#disable-btn').click(function () {
 61 |     $('#drag17').udraggable('disable');
 62 | });
 63 | 
 64 | $('#enable-btn').click(function () {
 65 |     $('#drag17').udraggable('enable');
 66 | });
67 |
69 |
70 |
71 | 72 | 73 |
74 |
79 |

You can call the option method 80 | to set a new value for an option after the udraggable 81 | behaviour has been initialised.

82 |
$('#drag18').udraggable({
 83 |     containment: 'parent'
 84 | });
 85 | 
 86 | $('#sml-grid-btn').click(function () {
 87 |     $('#drag18').udraggable('option', {
 88 |         grid: [10, 10]
 89 |     });
 90 | });
 91 | 
 92 | $('#big-grid-btn').click(function () {
 93 |     $('#drag18').udraggable('option', {
 94 |         grid: [30, 30]
 95 |     });
 96 | });
97 |
99 |
100 |
101 | 102 | 103 |
104 |
109 |

This example also calls the option 110 | method - in this case to alter the 'containment' setting.

111 |
$('#drag19').udraggable({
112 |     containment: 'parent'
113 | });
114 | 
115 | $('#zone-red-btn').click(function () {
116 |     $('#drag19').udraggable('option', {
117 |         containment: [90, 30, 180, 150]
118 |     });
119 | });
120 | 
121 | $('#zone-blue-btn').click(function () {
122 |     $('#drag19').udraggable('option', {
123 |         containment: [30, 60, 240, 110]
124 |     });
125 | });
126 |
128 |
129 |
130 |
131 |
132 | 133 | 134 |
135 |
139 | 140 |

[Home]

141 | 142 |
143 | 144 |

Copyright © 2013-2014 Grant McLean

145 | 146 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/examples/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery.udraggable: Options 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

jQuery.udraggable: Options

14 | 15 |

This is a demo page for the jquery.udraggable.js plugin:

16 | 17 |
“This plugin provides an API similar to jQueryUI's draggable but 18 | with support for unified mouse and touch events. It builds on Michael S. 19 | Mikowski's jquery.event.ue unified event plugin.”
20 | 21 |

The following examples illustrate the use of various options.

22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 40 | 41 | 42 | 43 | 50 | 55 | 56 | 57 | 58 | 67 | 72 | 73 | 74 | 75 | 83 | 88 | 89 | 90 | 91 | 106 | 116 | 117 | 118 | 119 | 127 | 134 | 135 | 136 | 137 | 148 | 156 | 157 | 158 | 159 | 184 | 197 | 198 | 199 | 200 | 225 | 231 | 232 | 233 | 234 | 243 | 263 | 264 | 265 | 266 | 275 | 295 | 296 | 297 |
DescriptionExample
32 |

Default behaviour.

33 |
$('#drag1').udraggable();
34 |
36 |
37 |
38 |
39 |
44 |

Constrain drag to within parent 45 | element.

46 |
$('#drag2').udraggable({
 47 |     containment: 'parent'
 48 | });
49 |
51 |
52 |
53 |
54 |
59 |

Constrain drag to a specified 60 | rectangular area.

61 |
$('#drag3').udraggable({
 62 |     containment: [ 40, 40, 180, 170]
 63 | });
64 |

Note: the coordinates constrain the possible positions of the 65 | top left corner of the draggable element

66 |
68 |
69 |
70 |
71 |
76 |

Constrain position of dragged item to 77 | a 30px by 30px grid.

78 |
$('#drag4').udraggable({
 79 |     containment: [ 0, 0, 270, 210],
 80 |     grid:        [ 30, 30 ]
 81 | });
82 |
84 |
85 |
86 |
87 |
92 |

Apply draggable behaviour to multiple 93 | elements at one time. Red elements can only be dragged on the "y" 94 | axis (up and down). Green elements can only be dragged on the "x" 95 | axis (left and right).

96 |
$('.blk-red').udraggable({
 97 |     containment: 'parent',
 98 |     axis:        'y'
 99 | });
100 | 
101 | $('.blk-green').udraggable({
102 |     containment: 'parent',
103 |     axis:        'x'
104 | });
105 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
120 |

Constrain drag to a rectangular area larger 121 | than the containing element. The parent element uses the 122 | "overflow: hidden" style to apply a clipping region.

123 |
$('#map').udraggable({
124 |     containment: [ -960, -395, 0, 0]
125 | });
126 |
128 |
129 |
130 |
131 | 133 |
138 |

It is of course possible to drag an 139 | element that contains draggable elements.

140 |
$('#drag11').udraggable({
141 |     containment: 'parent'
142 | });
143 | 
144 | $('.sub-drag').udraggable({
145 |     containment: 'parent'
146 | });
147 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
160 |

The 'start', 'stop' and 'drag' options 161 | allow you to monitor the progress of a drag through callback functions. 162 | The item being dragged will also have the "udraggable-dragging" 163 | class applied to it automatically - you can use CSS to take advantage 164 | of this.

165 |

This example also sets the distance threshold. The 166 | drag operation will not start until the pointer has been moved at 167 | least 15px after the initial touchstart / mousedown.

168 |
$('#drag14').udraggable({
169 |     distance: 15,
170 |     containment: 'parent',
171 |     start: function () {
172 |       $('#stat-mode').text('Dragging');
173 |     },
174 |     stop: function () {
175 |       $('#stat-mode').text('Idle');
176 |     },
177 |     drag: function (e, ui) {
178 |       var pos = ui.position
179 |       $('#stat-x').text(pos.left);
180 |       $('#stat-y').text(pos.top);
181 |     }
182 | });
183 |
185 |
186 |
187 |
188 | Mode: 189 | Idle 190 | X: 191 | 105 192 | Y: 193 | 135 194 |
195 |
196 |
201 |

You can override the 202 | positionElement function used to adjust the position of 203 | the dragged element. This example uses CSS transforms rather than the 204 | default left, top.

205 |
$('#drag15').udraggable({
206 |     containment: 'parent',
207 |     positionElement: function ($el, dragging, x, y) {
208 |         if (dragging) {
209 |             $el.css({
210 |                 left: 'auto',
211 |                 top: 'auto',
212 |                 transform: 'translate(' + x + 'px,' + y + 'px)'
213 |             });
214 |         }
215 |         else {
216 |             $el.css({
217 |                 left: x,
218 |                 top: y,
219 |                 transform: 'none'
220 |             });
221 |         }
222 |     }
223 | });
224 |
226 |
227 |
228 |
229 |
230 |
235 |

This example defines a drag handle. Although 236 | the whole panel can be dragged, you can only drag it by the blue title 237 | bar.

238 |
$('#dialog').udraggable({
239 |     containment: 'parent',
240 |     handle:      'h1'
241 | });
242 |
244 |
245 |
246 |

Personal Details

247 |
248 | 249 | 250 | 251 | 252 | 253 | 257 |
258 | 259 |
260 |
261 |
262 |
267 |

The handle selector can reference multiple 268 | 'drag handle' elements. In this somewhat silly example the dice can be 269 | dragged but only by the dots.

270 |
$('.dice').udraggable({
271 |     containment: 'parent',
272 |     handle:      '.dot'
273 | });
274 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
298 | 299 |

[Home]

300 | 301 |
302 | 303 |

Copyright © 2013-2014 Grant McLean

304 | 305 | 391 | 392 | 393 | 394 | -------------------------------------------------------------------------------- /docs/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grantm/jquery-udraggable/060b2bc04798ac204b2f7881249837c20b0a3fd1/docs/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /docs/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grantm/jquery-udraggable/060b2bc04798ac204b2f7881249837c20b0a3fd1/docs/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /docs/img/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grantm/jquery-udraggable/060b2bc04798ac204b2f7881249837c20b0a3fd1/docs/img/star.png -------------------------------------------------------------------------------- /docs/img/try-dragging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grantm/jquery-udraggable/060b2bc04798ac204b2f7881249837c20b0a3fd1/docs/img/try-dragging.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery udraggable Plugin 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 | 16 |
17 |

jquery.udraggable.js

18 | 19 |

This plugin provides an API similar to jQueryUI's draggable but with 21 | support for unified mouse and touch events. It builds on Michael S. 22 | Mikowski's jquery.event.ue 24 | unified event plugin.

25 | 26 |
27 | Zip 28 | Tar 29 | Git 30 |
31 |
32 | 33 |
34 |
35 | 47 | 48 |

Introduction

49 | 50 |

The udraggable plugin allows you to make elements 51 | draggable with a single line of code and to use a declarative syntax 52 | to define the constraints of the dragging behaviour.

53 | 54 |
$('#star').udraggable({});
55 | 56 |

See the examples page for more 57 | complex scenarios.

58 | 59 |

The plugin is dual-licensed under the MIT and GPL licences.

60 | 61 |

Caveats

62 | 63 |

This plugin is much simpler and therefore much less capable than 64 | jQueryUI's draggable widget. It aims to provide a minimum useful 65 | subset rather than attempting to clone the full range of behaviours 66 | supported by jQueryUI. However some of the limitations can be 67 | worked around quite simply.

68 | 69 |

Positioning: The plugin will give best results 70 | when the draggable elements and their parent container elements are 71 | both positioned using either absolute or 72 | relative positioning.

73 | 74 |

Scrolling: Dragging (or 'swiping') is used to 75 | scroll on touch devices. This can lead to conflict when some user 76 | interactions are intended to scroll and some are intended to drag 77 | specific elements. The jquery.event.ue plugin effectively disables 78 | scrolling on touch devices. This can work fine if the web 79 | application fills the full screen and uses touch/mouse events to 80 | adjust element positioning to achieve scrolling. This page and the 81 | associated example pages use an experimental modified version of the 83 | plugin which supports both scrolling and dragging (test by dragging 84 | the star above).

85 | 86 |

Auto-scrolling: If you drag an element outside 87 | the current viewport, the jQueryUI draggable can automatically 88 | scroll the page to bring the element back into view. This plugin 89 | does not support auto-scrolling. You can use the drag 90 | option to supply your own function to adjust the scroll position.

91 | 92 |

Selection: When dragging an element, the 93 | click-drag-release sequence can have the side-effect of selecting 94 | text in the vicinity. To avoid the visual flash, you can set the 95 | CSS property "user-select: none". Alternatively, the 96 | experimental version of the jquery.event.ue plugin (linked above) 97 | also seems to fix this issue.

98 | 99 |

Reference Documentation

100 | 101 |
102 | 103 |
104 |

Options

105 | 119 |
120 | 121 |
122 |

Methods

123 | 129 |
130 | 131 |
132 | 133 |

Options

134 | 135 |

When the udraggable function is called, you can 136 | provide option name/value pairs as an object literal like this:

137 | 138 |
$(selector).udraggable({opt1: value1, opt2: value2});
139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 152 | 153 | 154 | 155 | 156 | 170 | 171 | 172 | 173 | 179 | 180 | 181 | 182 | 183 | 190 | 191 | 192 | 193 | 194 | 201 | 202 | 203 | 204 | 205 | 215 | 216 | 217 | 218 | 219 | 224 | 225 | 226 | 227 | 228 | 233 | 234 | 235 | 236 | 237 | 244 | 245 | 246 | 247 | 248 | 266 | 267 | 268 | 269 | 270 | 278 | 279 | 280 | 281 | 282 | 288 | 289 | 290 |
NameDescription
axis 149 |

A string value: either "x" or "y". 150 | The drag operation will be constrained to the specified axis.

151 |
containment 157 |

This option is used to specify an area within which the drag 158 | operation should be contained. Acceptable values are 159 | the string "parent" or an array of pixel offset 160 | values defining a rectangle: [left, top, right, bottom].

161 |

"parent" refers to the 'offset parent' - the 162 | closest ancestor element that is positioned.

163 | 164 |

The draggable element is assumed to be positioned relative 165 | to its offset parent element (see "caveats" above) and if the 166 | array of offsets is used, the values are relative to the 167 | offset parent.

Note: it does make sense in 168 | some circumstances for the 'top' and 'left' values to be 169 | negative numbers.

delay 174 |

A delay value in milliseconds before the drag operation 175 | will commence. This is one way to reduce the chance of a drag 176 | operation being triggered accidentally by tapping or clicking 177 | on an element (see also distance).

178 |
drag 184 |

This option allows you to specify a callback function 185 | that will be invoked as the element is dragged. The function 186 | will be passed an event object and a ui 187 | object. Your function will be called after the 188 | position of the element has been adjusted.

189 |
distance 195 |

A distance value in pixels that the pointer must be moved 196 | before the drag operation will commence. This is one way to 197 | reduce the chance of a drag operation being triggered 198 | accidentally by tapping or clicking on an element (see also 199 | delay).

200 |
getStartPosition 206 |

You can use this option to replace the code that calculates 207 | the initial position of the element before the drag begins. 208 | The default implementation simply reads the top 209 | and left CSS properties.

210 |

The function you provide will be passed the target element 211 | in a jQuery wrapper.

212 |

Note: this option is not supported by the jQueryUI 213 | draggable.

214 |
grid 220 |

An array of two integers ([x, y]) specifying 221 | the pixel size of a grid that should be used to constrain the 222 | drag and give it a snap-to-grid behaviour.

223 |
handle 229 |

Optional selector for a child element to be used as a drag 230 | handle. A drag will not start unless the initial mousedown / 231 | touchstart event occurs on the selected element(s).

232 |
longPress 238 |

Specify a boolean true value if the drag 239 | should require a "long press" to start (i.e. press and hold 240 | before starting the drag).

241 |

Note: this option is not supported by the jQueryUI 242 | draggable.

243 |
positionElement 249 |

You can use this option to replace the code that positions 250 | the element at each step of the drag. The default 251 | implementation positions the element by adjusting its 252 | top and left CSS properties.

253 |

The function you provide will be passed 4 arguments:

254 |
    255 |
  • $el — the element to be positioned 256 | (jQuery wrapped)
  • 257 |
  • dragging — boolean indicating whether a 258 | drag is in process, this value will be false for the final 259 | update in a drag
  • 260 |
  • x — the new x (left) position
  • 261 |
  • y — the new y (top) position
  • 262 |
263 |

Note: this option is not supported by the jQueryUI 264 | draggable.

265 |
start 271 |

This option allows you to specify a callback function that 272 | will be called once when the drag operation begins (i.e.: after 273 | the delay and/or distance constraints 274 | have been met. The function will be passed an event 275 | object and a ui 276 | object.

277 |
stop 283 |

This option allows you to specify a callback function that 284 | will be called once when the drag operation completes. The function 285 | will be passed an event object and a ui 286 | object.

287 |
291 | 292 |

When the callback functions (start, drag, 293 | stop) are called, they will be passed two arguments. The 294 | first is an event object as provided by jquery.event.ue and the second 295 | is an object containing the following properties:

296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 312 | 313 | 314 | 315 | 317 | 318 | 319 | 320 | 322 | 323 | 324 |
PropertyDescription
helpera jQuery object containing the dragged element
offsetan object specifying the current top 311 | and left offsets of the dragged element.
originalPositionan object specifying the top and left 316 | offsets of the dragged element before the drag operation began.
positionan object specifying the current top 321 | and left offsets of the dragged element.
325 | 326 |

Methods

327 | 328 |

After the widget has been initialised, you can reference it 329 | again using the same selector and call a method like this:

330 | 331 |
$(selector).udraggable('method-name', args);
332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 349 | 350 | 351 | 352 | 353 | 361 | 362 | 363 | 364 | 365 | 372 | 373 | 374 | 375 | 376 | 394 | 395 | 396 |
NameDescription
destroy 343 | 344 |

This method will completely remove the 345 | udraggable behaviour from the target 346 | element. The element position will be left unchanged.

347 | 348 |
disable 354 | 355 |

This method will temporarily disable the 356 | udraggable behaviour on the target element. A 357 | later call to the enable method will restore the 358 | behaviour with the original options.

359 | 360 |
enable 366 | 367 |

This method will restore the udraggable 368 | behaviour on a target element that was turned off with the 369 | disable method.

370 | 371 |
option 377 | 378 |

This method allows you to get or set option values after 379 | the udraggable behaviour has been applied to an 380 | object.

381 | 382 |

If called with no arguments, the current option names and 383 | values will be returned as an object.

384 | 385 |

If called with two arguments, the first is assumed to be 386 | the name of the option you wish to change and the second is 387 | the new value for that option.

388 | 389 |

If called with a single argument, it is assumed to be an 390 | object containing all the names and values of options you 391 | wish to change.

392 | 393 |
397 | 398 | 399 |

Examples

400 | 401 |
402 | 403 |
Example 1 - Options
404 | 405 |
Various examples demonstrating a range of different option 406 | settings to change drag constraints.
407 | 408 |
Example 2 - Methods
409 | 410 |
Examples demonstrating method calls to alter the 411 | udraggable behaviour after initial setup.
412 | 413 |
Example 3 - TKS-Web
414 | 415 |
The TKS-Web application is a web-based timesheeting system 416 | that uses jquery.udraggable.js to facilitate dragging and 417 | resizing activities on a calendar-style week view.
418 | 419 |
420 | 421 | 422 |
423 | 424 |

Copyright © 2013-2017 Grant McLean

425 | 426 |
427 |
428 | 429 |
430 |
431 | 432 |
433 | 434 | 435 | 436 | 437 | 438 | 453 | 454 | 455 | 456 | -------------------------------------------------------------------------------- /docs/jquery.event.ue.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Jquery plugin for unified mouse and touch events 3 | * 4 | * Copyright (c) 2013 Michael S. Mikowski 5 | * (mike[dot]mikowski[at]gmail[dotcom]) 6 | * 7 | * Dual licensed under the MIT or GPL Version 2 8 | * http://jquery.org/license 9 | * 10 | * Versions 11 | * 0.3.0 - Initial jQuery plugin site release 12 | * - Replaced scrollwheel zoom with drag motion. 13 | * This resolved a conflict with scrollable areas. 14 | * 0.3.1 - Change for jQuery plugins site 15 | * 0.3.2 - Updated to jQuery 1.9.1. 16 | * Confirmed 1.7.0-1.9.1 compatibility. 17 | * 0.4.2 - Updated documentation 18 | * 0.4.3 - Removed fatal execption possibility if originalEvent 19 | * is not defined on event object 20 | * 21 | */ 22 | 23 | /*jslint browser : true, continue : true, 24 | devel : true, indent : 2, maxerr : 50, 25 | newcap : true, plusplus : true, regexp : true, 26 | sloppy : true, vars : true, white : true 27 | */ 28 | /*global jQuery, sl */ 29 | 30 | (function ( $ ) { 31 | //---------------- BEGIN MODULE SCOPE VARIABLES -------------- 32 | var 33 | $Special = $.event.special, // shortcut for special event 34 | motionMapMap = {}, // map of pointer motions by cursor 35 | isMoveBound = false, // flag if move handlers bound 36 | pxPinchZoom = -1, // distance between pinch-zoom points 37 | optionKey = 'ue_bound', // data key for storing options 38 | doDisableMouse = false, // flag to discard mouse input 39 | defaultOptMap = { // Default option hash 40 | bound_ns_map : {}, // namspace hash e.g. bound_ns_map.utap.fred 41 | wheel_ratio : 15, // multiplier for mousewheel delta 42 | px_radius : 3, // 'distance' dragged before dragstart 43 | ignore_class : ':input', // 'not' suppress matching elements 44 | tap_time : 200, // millisecond max time to consider tap 45 | held_tap_time : 300 // millisecond min time to consider taphold 46 | }, 47 | callbackList = [], // global callback stack 48 | zoomMouseNum = 1, // multiplier for mouse zoom 49 | zoomTouchNum = 4, // multiplier for touch zoom 50 | 51 | boundList, Ue, 52 | motionDragId, motionHeldId, motionDzoomId, 53 | motion1ZoomId, motion2ZoomId, 54 | 55 | checkMatchVal, removeListVal, pushUniqVal, makeListPlus, 56 | fnHeld, fnMotionStart, fnMotionMove, 57 | fnMotionEnd, onMouse, onTouch, 58 | onMousewheel 59 | ; 60 | //----------------- END MODULE SCOPE VARIABLES --------------- 61 | 62 | //------------------- BEGIN UTILITY METHODS ------------------ 63 | // Begin utiltity /makeListPlus/ 64 | // Returns an array with much desired methods: 65 | // * remove_val(value) : remove element that matches 66 | // the provided value. Returns number of elements 67 | // removed. 68 | // * match_val(value) : shows if a value exists 69 | // * push_uniq(value) : pushes a value onto the stack 70 | // iff it does not already exist there 71 | // Note: the reason I need this is to compare objects to 72 | // objects (perhaps jQuery has something similar?) 73 | checkMatchVal = function ( data ) { 74 | var match_count = 0, idx; 75 | for ( idx = this.length; idx; 0 ) { 76 | if ( this[--idx] === data ) { match_count++; } 77 | } 78 | return match_count; 79 | }; 80 | removeListVal = function ( data ) { 81 | var removed_count = 0, idx; 82 | for ( idx = this.length; idx; 0 ) { 83 | if ( this[--idx] === data ) { 84 | this.splice(idx, 1); 85 | removed_count++; 86 | idx++; 87 | } 88 | } 89 | return removed_count; 90 | }; 91 | pushUniqVal = function ( data ) { 92 | if ( checkMatchVal.call(this, data ) ) { return false; } 93 | this.push( data ); 94 | return true; 95 | }; 96 | // primary utility 97 | makeListPlus = function ( input_list ) { 98 | if ( input_list && $.isArray(input_list) ) { 99 | if ( input_list.remove_val ) { 100 | console.warn( 'The array appears to already have listPlus capabilities' ); 101 | return input_list; 102 | } 103 | } 104 | else { 105 | input_list = []; 106 | } 107 | input_list.remove_val = removeListVal; 108 | input_list.match_val = checkMatchVal; 109 | input_list.push_uniq = pushUniqVal; 110 | 111 | return input_list; 112 | }; 113 | // End utility /makeListPlus/ 114 | //-------------------- END UTILITY METHODS ------------------- 115 | 116 | //--------------- BEGIN JQUERY SPECIAL EVENTS ---------------- 117 | // Unique array for bound objects 118 | boundList = makeListPlus(); 119 | 120 | // Begin define special event handlers 121 | Ue = { 122 | setup : function( data, a_names, fn_bind ) { 123 | var 124 | this_el = this, 125 | $to_bind = $(this_el), 126 | seen_map = {}, 127 | option_map, idx, namespace_key, ue_namespace_code, namespace_list 128 | ; 129 | 130 | // if previous related event bound do not rebind, but do add to 131 | // type of event bound to this element, if not already noted 132 | if ( $.data( this, optionKey ) ) { return; } 133 | 134 | option_map = {}; 135 | $.extend( true, option_map, defaultOptMap ); 136 | $.data( this_el, optionKey, option_map ); 137 | 138 | namespace_list = makeListPlus(a_names.slice(0)); 139 | if ( ! namespace_list.length 140 | || namespace_list[0] === "" 141 | ) { namespace_list = ["000"]; } 142 | 143 | NSPACE_00: 144 | for ( idx = 0; idx < namespace_list.length; idx++ ) { 145 | namespace_key = namespace_list[idx]; 146 | 147 | if ( ! namespace_key ) { continue NSPACE_00; } 148 | if ( seen_map.hasOwnProperty(namespace_key) ) { continue NSPACE_00; } 149 | 150 | seen_map[namespace_key] = true; 151 | 152 | ue_namespace_code = '.__ue' + namespace_key; 153 | 154 | $to_bind.bind( 'mousedown' + ue_namespace_code, onMouse ); 155 | $to_bind.bind( 'touchstart' + ue_namespace_code, onTouch ); 156 | $to_bind.bind( 'mousewheel' + ue_namespace_code, onMousewheel ); 157 | } 158 | 159 | boundList.push_uniq( this_el ); // record as bound element 160 | 161 | if ( ! isMoveBound ) { 162 | // console.log('first element bound - adding global binds'); 163 | $(document).bind( 'mousemove.__ue', onMouse ); 164 | $(document).bind( 'touchmove.__ue', onTouch ); 165 | $(document).bind( 'mouseup.__ue' , onMouse ); 166 | $(document).bind( 'touchend.__ue' , onTouch ); 167 | $(document).bind( 'touchcancel.__ue', onTouch ); 168 | isMoveBound = true; 169 | } 170 | }, 171 | 172 | // arg_map.type = string - name of event to bind 173 | // arg_map.data = poly - whatever (optional) data was passed when binding 174 | // arg_map.namespace = string - A sorted, dot-delimited list of namespaces 175 | // specified when binding the event 176 | // arg_map.handler = fn - the event handler the developer wishes to be bound 177 | // to the event. This function should be called whenever the event 178 | // is triggered 179 | // arg_map.guid = number - unique ID for event handler, provided by jQuery 180 | // arg_map.selector = string - selector used by 'delegate' or 'live' jQuery 181 | // methods. Only available when these methods are used. 182 | // 183 | // this - the element to which the event handler is being bound 184 | // this always executes immediate after setup (if first binding) 185 | add : function ( arg_map ) { 186 | var 187 | this_el = this, 188 | option_map = $.data( this_el, optionKey ), 189 | namespace_str = arg_map.namespace, 190 | event_type = arg_map.type, 191 | bound_ns_map, namespace_list, idx, namespace_key 192 | ; 193 | if ( ! option_map ) { return; } 194 | 195 | bound_ns_map = option_map.bound_ns_map; 196 | 197 | if ( ! bound_ns_map[event_type] ) { 198 | // this indicates a non-namespaced entry 199 | bound_ns_map[event_type] = {}; 200 | } 201 | 202 | if ( ! namespace_str ) { return; } 203 | 204 | namespace_list = namespace_str.split('.'); 205 | 206 | for ( idx = 0; idx < namespace_list.length; idx++ ) { 207 | namespace_key = namespace_list[idx]; 208 | bound_ns_map[event_type][namespace_key] = true; 209 | } 210 | }, 211 | 212 | remove : function ( arg_map ) { 213 | var 214 | elem_bound = this, 215 | option_map = $.data( elem_bound, optionKey ), 216 | bound_ns_map = option_map.bound_ns_map, 217 | event_type = arg_map.type, 218 | namespace_str = arg_map.namespace, 219 | namespace_list, idx, namespace_key 220 | ; 221 | 222 | if ( ! bound_ns_map[event_type] ) { return; } 223 | 224 | // No namespace(s) provided: 225 | // Remove complete record for custom event type (e.g. utap) 226 | if ( ! namespace_str ) { 227 | delete bound_ns_map[event_type]; 228 | return; 229 | } 230 | 231 | // Namespace(s) provided: 232 | // Remove namespace flags from each custom event typei (e.g. utap) 233 | // record. If all claimed namespaces are removed, remove 234 | // complete record. 235 | namespace_list = namespace_str.split('.'); 236 | 237 | for ( idx = 0; idx < namespace_list.length; idx++ ) { 238 | namespace_key = namespace_list[idx]; 239 | if (bound_ns_map[event_type][namespace_key]) { 240 | delete bound_ns_map[event_type][namespace_key]; 241 | } 242 | } 243 | 244 | if ( $.isEmptyObject( bound_ns_map[event_type] ) ) { 245 | delete bound_ns_map[event_type]; 246 | } 247 | }, 248 | 249 | teardown : function( a_names ) { 250 | var 251 | elem_bound = this, 252 | $bound = $(elem_bound), 253 | option_map = $.data( elem_bound, optionKey ), 254 | bound_ns_map = option_map.bound_ns_map, 255 | idx, namespace_key, ue_namespace_code, namespace_list 256 | ; 257 | 258 | // do not tear down if related handlers are still bound 259 | if ( ! $.isEmptyObject( bound_ns_map ) ) { return; } 260 | 261 | namespace_list = makeListPlus(a_names); 262 | namespace_list.push_uniq('000'); 263 | 264 | NSPACE_01: 265 | for ( idx = 0; idx < namespace_list.length; idx++ ) { 266 | namespace_key = namespace_list[idx]; 267 | 268 | if ( ! namespace_key ) { continue NSPACE_01; } 269 | 270 | ue_namespace_code = '.__ue' + namespace_key; 271 | $bound.unbind( 'mousedown' + ue_namespace_code ); 272 | $bound.unbind( 'touchstart' + ue_namespace_code ); 273 | $bound.unbind( 'mousewheel' + ue_namespace_code ); 274 | } 275 | 276 | $.removeData( elem_bound, optionKey ); 277 | 278 | // Unbind document events only after last element element is removed 279 | boundList.remove_val(this); 280 | if ( boundList.length === 0 ) { 281 | // console.log('last bound element removed - removing global binds'); 282 | $(document).unbind( 'mousemove.__ue'); 283 | $(document).unbind( 'touchmove.__ue'); 284 | $(document).unbind( 'mouseup.__ue'); 285 | $(document).unbind( 'touchend.__ue'); 286 | $(document).unbind( 'touchcancel.__ue'); 287 | isMoveBound = false; 288 | } 289 | } 290 | }; 291 | // End define special event handlers 292 | //--------------- BEGIN JQUERY SPECIAL EVENTS ---------------- 293 | 294 | //------------------ BEGIN MOTION CONTROLS ------------------- 295 | // Begin motion control /fnHeld/ 296 | fnHeld = function ( arg_map ) { 297 | var 298 | timestamp = +new Date(), 299 | motion_id = arg_map.motion_id, 300 | motion_map = arg_map.motion_map, 301 | bound_ns_map = arg_map.bound_ns_map, 302 | event_ue 303 | ; 304 | 305 | delete motion_map.idto_tapheld; 306 | 307 | if ( ! motion_map.do_allow_tap ) { return; } 308 | 309 | motion_map.px_end_x = motion_map.px_start_x; 310 | motion_map.px_end_y = motion_map.px_start_y; 311 | motion_map.ms_timestop = timestamp; 312 | motion_map.ms_elapsed = timestamp - motion_map.ms_timestart; 313 | 314 | if ( bound_ns_map.uheld ) { 315 | event_ue = $.Event('uheld'); 316 | $.extend( event_ue, motion_map ); 317 | $(motion_map.elem_bound).trigger(event_ue); 318 | } 319 | 320 | // remove tracking, as we want no futher action on this motion 321 | if ( bound_ns_map.uheldstart ) { 322 | event_ue = $.Event('uheldstart'); 323 | $.extend( event_ue, motion_map ); 324 | $(motion_map.elem_bound).trigger(event_ue); 325 | motionHeldId = motion_id; 326 | } 327 | else { 328 | delete motionMapMap[motion_id]; 329 | } 330 | }; 331 | // End motion control /fnHeld/ 332 | 333 | 334 | // Begin motion control /fnMotionStart/ 335 | fnMotionStart = function ( arg_map ) { 336 | var 337 | motion_id = arg_map.motion_id, 338 | event_src = arg_map.event_src, 339 | request_dzoom = arg_map.request_dzoom, 340 | 341 | option_map = $.data( arg_map.elem, optionKey ), 342 | bound_ns_map = option_map.bound_ns_map, 343 | $target = $(event_src.target ), 344 | do_zoomstart = false, 345 | motion_map, cb_map, do_allow_tap, event_ue 346 | ; 347 | 348 | // this should never happen, but it does 349 | if ( motionMapMap[ motion_id ] ) { return; } 350 | 351 | if ( request_dzoom && ! bound_ns_map.uzoomstart ) { return; } 352 | 353 | // :input selector includes text areas 354 | if ( $target.is( option_map.ignore_class ) ) { return; } 355 | 356 | do_allow_tap = bound_ns_map.utap 357 | || bound_ns_map.uheld || bound_ns_map.uheldstart 358 | ? true : false; 359 | 360 | cb_map = callbackList.pop(); 361 | 362 | while ( cb_map ) { 363 | if ( $target.is( cb_map.selector_str ) 364 | || $( arg_map.elem ).is( cb_map.selector_str ) 365 | ) { 366 | if ( cb_map.callback_match ) { 367 | cb_map.callback_match( arg_map ); 368 | } 369 | } 370 | else { 371 | if ( cb_map.callback_nomatch ) { 372 | cb_map.callback_nomatch( arg_map ); 373 | } 374 | } 375 | cb_map = callbackList.pop(); 376 | } 377 | 378 | motion_map = { 379 | do_allow_tap : do_allow_tap, 380 | elem_bound : arg_map.elem, 381 | elem_target : event_src.target, 382 | ms_elapsed : 0, 383 | ms_timestart : event_src.timeStamp, 384 | ms_timestop : undefined, 385 | option_map : option_map, 386 | orig_target : event_src.target, 387 | px_current_x : event_src.clientX, 388 | px_current_y : event_src.clientY, 389 | px_end_x : undefined, 390 | px_end_y : undefined, 391 | px_start_x : event_src.clientX, 392 | px_start_y : event_src.clientY, 393 | timeStamp : event_src.timeStamp 394 | }; 395 | 396 | motionMapMap[ motion_id ] = motion_map; 397 | 398 | if ( bound_ns_map.uzoomstart ) { 399 | if ( request_dzoom ) { 400 | motionDzoomId = motion_id; 401 | } 402 | else if ( ! motion1ZoomId ) { 403 | motion1ZoomId = motion_id; 404 | } 405 | else if ( ! motion2ZoomId ) { 406 | motion2ZoomId = motion_id; 407 | event_ue = $.Event('uzoomstart'); 408 | do_zoomstart = true; 409 | } 410 | 411 | if ( do_zoomstart ) { 412 | event_ue = $.Event( 'uzoomstart' ); 413 | motion_map.px_delta_zoom = 0; 414 | $.extend( event_ue, motion_map ); 415 | $(motion_map.elem_bound).trigger(event_ue); 416 | return; 417 | } 418 | } 419 | 420 | if ( bound_ns_map.uheld || bound_ns_map.uheldstart ) { 421 | motion_map.idto_tapheld = setTimeout( 422 | function() { 423 | fnHeld({ 424 | motion_id : motion_id, 425 | motion_map : motion_map, 426 | bound_ns_map : bound_ns_map 427 | }); 428 | }, 429 | option_map.held_tap_time 430 | ); 431 | } 432 | }; 433 | // End motion control /fnMotionStart/ 434 | 435 | // Begin motion control /fnMotionMove/ 436 | fnMotionMove = function ( arg_map ) { 437 | var 438 | motion_id = arg_map.motion_id, 439 | event_src = arg_map.event_src, 440 | do_zoommove = false, 441 | motion_map, option_map, bound_ns_map, 442 | event_ue, px_pinch_zoom, px_delta_zoom, 443 | mzoom1_map, mzoom2_map 444 | ; 445 | 446 | if ( ! motionMapMap[motion_id] ) { return; } 447 | 448 | motion_map = motionMapMap[motion_id]; 449 | option_map = motion_map.option_map; 450 | bound_ns_map = option_map.bound_ns_map; 451 | 452 | motion_map.timeStamp = event_src.timeStamp; 453 | motion_map.elem_target = event_src.target; 454 | motion_map.ms_elapsed = event_src.timeStamp - motion_map.ms_timestart; 455 | 456 | motion_map.px_delta_x = event_src.clientX - motion_map.px_current_x; 457 | motion_map.px_delta_y = event_src.clientY - motion_map.px_current_y; 458 | 459 | motion_map.px_current_x = event_src.clientX; 460 | motion_map.px_current_y = event_src.clientY; 461 | 462 | // native event object override 463 | motion_map.timeStamp = event_src.timeStamp; 464 | 465 | // disallow tap if outside of zone or time elapsed 466 | // we use this for other events, so we do it every time 467 | if ( motion_map.do_allow_tap ) { 468 | if ( Math.abs(motion_map.px_delta_x) > option_map.px_radius 469 | || Math.abs(motion_map.pd_delta_y) > option_map.px_radius 470 | || motion_map.ms_elapsed > option_map.tap_time 471 | ) { motion_map.do_allow_tap = false; } 472 | } 473 | 474 | if ( motion1ZoomId && motion2ZoomId 475 | && ( motion_id === motion1ZoomId 476 | || motion_id === motion2ZoomId 477 | )) { 478 | motionMapMap[motion_id] = motion_map; 479 | mzoom1_map = motionMapMap[motion1ZoomId]; 480 | mzoom2_map = motionMapMap[motion2ZoomId]; 481 | 482 | px_pinch_zoom = Math.floor( 483 | Math.sqrt( 484 | Math.pow((mzoom1_map.px_current_x - mzoom2_map.px_current_x),2) 485 | + Math.pow((mzoom1_map.px_current_y - mzoom2_map.px_current_y),2) 486 | ) +0.5 487 | ); 488 | 489 | if ( pxPinchZoom === -1 ) { px_delta_zoom = 0; } 490 | else { px_delta_zoom = ( px_pinch_zoom - pxPinchZoom ) * zoomTouchNum;} 491 | 492 | // save value for next iteration delta comparison 493 | pxPinchZoom = px_pinch_zoom; 494 | do_zoommove = true; 495 | } 496 | else if ( motionDzoomId === motion_id ) { 497 | if ( bound_ns_map.uzoommove ) { 498 | px_delta_zoom = motion_map.px_delta_y * zoomMouseNum; 499 | do_zoommove = true; 500 | } 501 | } 502 | 503 | if ( do_zoommove ){ 504 | event_ue = $.Event('uzoommove'); 505 | motion_map.px_delta_zoom = px_delta_zoom; 506 | $.extend( event_ue, motion_map ); 507 | $(motion_map.elem_bound).trigger(event_ue); 508 | return; 509 | } 510 | 511 | if ( motionHeldId === motion_id ) { 512 | if ( bound_ns_map.uheldmove ) { 513 | event_ue = $.Event('uheldmove'); 514 | $.extend( event_ue, motion_map ); 515 | $(motion_map.elem_bound).trigger(event_ue); 516 | event_src.preventDefault(); 517 | } 518 | } 519 | else if ( motionDragId === motion_id ) { 520 | if ( bound_ns_map.udragmove ) { 521 | event_ue = $.Event('udragmove'); 522 | $.extend( event_ue, motion_map ); 523 | $(motion_map.elem_bound).trigger(event_ue); 524 | event_src.preventDefault(); 525 | } 526 | } 527 | 528 | if ( ! motionDragId 529 | && ! motionHeldId 530 | && bound_ns_map.udragstart 531 | && motion_map.do_allow_tap === false 532 | ) { 533 | motionDragId = motion_id; 534 | event_ue = $.Event('udragstart'); 535 | $.extend( event_ue, motion_map ); 536 | $(motion_map.elem_bound).trigger(event_ue); 537 | event_src.preventDefault(); 538 | 539 | if ( motion_map.idto_tapheld ) { 540 | clearTimeout(motion_map.idto_tapheld); 541 | delete motion_map.idto_tapheld; 542 | } 543 | } 544 | }; 545 | // End motion control /fnMotionMove/ 546 | 547 | // Begin motion control /fnMotionEnd/ 548 | fnMotionEnd = function ( arg_map ) { 549 | var 550 | motion_id = arg_map.motion_id, 551 | event_src = arg_map.event_src, 552 | do_zoomend = false, 553 | motion_map, option_map, bound_ns_map, event_ue 554 | ; 555 | 556 | doDisableMouse = false; 557 | 558 | if ( ! motionMapMap[motion_id] ) { return; } 559 | 560 | motion_map = motionMapMap[motion_id]; 561 | option_map = motion_map.option_map; 562 | bound_ns_map = option_map.bound_ns_map; 563 | 564 | motion_map.elem_target = event_src.target; 565 | motion_map.ms_elapsed = event_src.timeStamp - motion_map.ms_timestart; 566 | motion_map.ms_timestop = event_src.timeStamp; 567 | 568 | if ( motion_map.px_current_x ) { 569 | motion_map.px_delta_x = event_src.clientX - motion_map.px_current_x; 570 | motion_map.px_delta_y = event_src.clientY - motion_map.px_current_y; 571 | } 572 | 573 | motion_map.px_current_x = event_src.clientX; 574 | motion_map.px_current_y = event_src.clientY; 575 | 576 | motion_map.px_end_x = event_src.clientX; 577 | motion_map.px_end_y = event_src.clientY; 578 | 579 | // native event object override 580 | motion_map.timeStamp = event_src.timeStamp 581 | ; 582 | 583 | // clear-out any long-hold tap timer 584 | if ( motion_map.idto_tapheld ) { 585 | clearTimeout(motion_map.idto_tapheld); 586 | delete motion_map.idto_tapheld; 587 | } 588 | 589 | // trigger utap 590 | if ( bound_ns_map.utap 591 | && motion_map.ms_elapsed <= option_map.tap_time 592 | && motion_map.do_allow_tap 593 | ) { 594 | event_ue = $.Event('utap'); 595 | $.extend( event_ue, motion_map ); 596 | $(motion_map.elem_bound).trigger(event_ue); 597 | } 598 | 599 | // trigger udragend 600 | if ( motion_id === motionDragId ) { 601 | if ( bound_ns_map.udragend ) { 602 | event_ue = $.Event('udragend'); 603 | $.extend( event_ue, motion_map ); 604 | $(motion_map.elem_bound).trigger(event_ue); 605 | event_src.preventDefault(); 606 | } 607 | motionDragId = undefined; 608 | } 609 | 610 | // trigger heldend 611 | if ( motion_id === motionHeldId ) { 612 | if ( bound_ns_map.uheldend ) { 613 | event_ue = $.Event('uheldend'); 614 | $.extend( event_ue, motion_map ); 615 | $(motion_map.elem_bound).trigger(event_ue); 616 | } 617 | motionHeldId = undefined; 618 | } 619 | 620 | // trigger uzoomend 621 | if ( motion_id === motionDzoomId ) { 622 | do_zoomend = true; 623 | motionDzoomId = undefined; 624 | } 625 | 626 | // cleanup zoom info 627 | else if ( motion_id === motion1ZoomId ) { 628 | if ( motion2ZoomId ) { 629 | motion1ZoomId = motion2ZoomId; 630 | motion2ZoomId = undefined; 631 | do_zoomend = true; 632 | } 633 | else { motion1ZoomId = undefined; } 634 | pxPinchZoom = -1; 635 | } 636 | if ( motion_id === motion2ZoomId ) { 637 | motion2ZoomId = undefined; 638 | pxPinchZoom = -1; 639 | do_zoomend = true; 640 | } 641 | 642 | if ( do_zoomend && bound_ns_map.uzoomend ) { 643 | event_ue = $.Event('uzoomend'); 644 | motion_map.px_delta_zoom = 0; 645 | $.extend( event_ue, motion_map ); 646 | $(motion_map.elem_bound).trigger(event_ue); 647 | } 648 | // remove pointer from consideration 649 | delete motionMapMap[motion_id]; 650 | }; 651 | // End motion control /fnMotionEnd/ 652 | //------------------ END MOTION CONTROLS ------------------- 653 | 654 | //------------------- BEGIN EVENT HANDLERS ------------------- 655 | // Begin event handler /onTouch/ for all touch events. 656 | // We use the 'type' attribute to dispatch to motion control 657 | onTouch = function ( event ) { 658 | var 659 | this_el = this, 660 | timestamp = +new Date(), 661 | o_event = event.originalEvent, 662 | touch_list = o_event ? o_event.changedTouches || [] : [], 663 | touch_count = touch_list.length, 664 | idx, touch_event, motion_id, handler_fn 665 | ; 666 | 667 | doDisableMouse = true; 668 | 669 | event.timeStamp = timestamp; 670 | 671 | switch ( event.type ) { 672 | case 'touchstart' : 673 | handler_fn = fnMotionStart; 674 | event.preventDefault(); 675 | break; 676 | case 'touchmove' : 677 | handler_fn = fnMotionMove; 678 | break; 679 | case 'touchend' : 680 | case 'touchcancel' : handler_fn = fnMotionEnd; break; 681 | default : handler_fn = null; 682 | } 683 | 684 | if ( ! handler_fn ) { return; } 685 | 686 | for ( idx = 0; idx < touch_count; idx++ ) { 687 | touch_event = touch_list[idx]; 688 | 689 | motion_id = 'touch' + String(touch_event.identifier); 690 | 691 | event.clientX = touch_event.clientX; 692 | event.clientY = touch_event.clientY; 693 | handler_fn({ 694 | elem : this_el, 695 | motion_id : motion_id, 696 | event_src : event 697 | }); 698 | } 699 | }; 700 | // End event handler /onTouch/ 701 | 702 | 703 | // Begin event handler /onMouse/ for all mouse events 704 | // We use the 'type' attribute to dispatch to motion control 705 | onMouse = function ( event ) { 706 | var 707 | this_el = this, 708 | motion_id = 'mouse' + String(event.button), 709 | request_dzoom = false, 710 | handler_fn 711 | ; 712 | 713 | if ( doDisableMouse ) { 714 | event.stopImmediatePropagation(); 715 | return; 716 | } 717 | 718 | if ( event.shiftKey ) { request_dzoom = true; } 719 | 720 | // skip left or middle clicks 721 | if ( event.type !== 'mousemove' ) { 722 | if ( event.button !== 0 ) { return true; } 723 | } 724 | 725 | switch ( event.type ) { 726 | case 'mousedown' : 727 | handler_fn = fnMotionStart; 728 | event.preventDefault(); 729 | break; 730 | case 'mouseup' : 731 | handler_fn = fnMotionEnd; 732 | break; 733 | case 'mousemove' : 734 | handler_fn = fnMotionMove; 735 | break; 736 | default: 737 | handler_fn = null; 738 | } 739 | 740 | if ( ! handler_fn ) { return; } 741 | 742 | handler_fn({ 743 | elem : this_el, 744 | event_src : event, 745 | request_dzoom : request_dzoom, 746 | motion_id : motion_id 747 | }); 748 | }; 749 | // End event handler /onMouse/ 750 | //-------------------- END EVENT HANDLERS -------------------- 751 | 752 | 753 | // Export special events through jQuery API 754 | $Special.ue 755 | = $Special.utap = $Special.uheld 756 | = $Special.uzoomstart = $Special.uzoommove = $Special.uzoomend 757 | = $Special.udragstart = $Special.udragmove = $Special.udragend 758 | = $Special.uheldstart = $Special.uheldmove = $Special.uheldend 759 | = Ue 760 | ; 761 | $.ueSetGlobalCb = function ( selector_str, callback_match, callback_nomatch ) { 762 | callbackList.push( { 763 | selector_str : selector_str || '', 764 | callback_match : callback_match || null, 765 | callback_nomatch : callback_nomatch || null 766 | }); 767 | }; 768 | 769 | }(jQuery)); 770 | -------------------------------------------------------------------------------- /docs/jquery.udraggable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery udraggable plugin v0.3.0 3 | * Copyright (c) 2013-2014 Grant McLean (grant@mclean.net.nz) 4 | * 5 | * Homepage: https://github.com/grantm/jquery-udraggable 6 | * 7 | * Dual licensed under the MIT and GPL (v2.0 or later) licenses: 8 | * http://opensource.org/licenses/MIT 9 | * http://opensource.org/licenses/GPL-2.0 10 | * 11 | * This library requires Michael S. Mikowski's unified mouse and touch 12 | * event plugin: https://github.com/mmikowski/jquery.event.ue 13 | * 14 | */ 15 | 16 | (function($) { 17 | "use strict"; 18 | 19 | var floor = Math.floor; 20 | var min = Math.min; 21 | var max = Math.max; 22 | 23 | window.requestAnimationFrame = window.requestAnimationFrame || function(work) { 24 | return setTimeout(work, 10); 25 | }; 26 | 27 | window.cancelAnimationFrame = window.cancelAnimationFrame || function(id) { 28 | return clearTimeout(id); 29 | }; 30 | 31 | 32 | // Constructor function 33 | 34 | var UDraggable = function (el, options) { 35 | var that = this; 36 | this.el = el; 37 | this.$el = $(el); 38 | this.options = $.extend({}, $.fn.udraggable.defaults, options); 39 | this.positionElement = this.options.positionElement || this.positionElement; 40 | this.getStartPosition = this.options.getStartPosition || this.getStartPosition; 41 | this.updatePositionFrameHandler = function() { 42 | delete that.queuedUpdate; 43 | var pos = that.ui.position; 44 | that.positionElement(that.$el, that.started, pos.left, pos.top); 45 | if (that.options.dragUpdate) { 46 | that.options.dragUpdate.apply(that.el, [that.ui]); 47 | } 48 | }; 49 | this.queuePositionUpdate = function() { 50 | if (!that.queuedUpdate) { 51 | that.queuedUpdate = window.requestAnimationFrame(that.updatePositionFrameHandler); 52 | } 53 | }; 54 | this.init(); 55 | }; 56 | 57 | UDraggable.prototype = { 58 | 59 | constructor: UDraggable, 60 | 61 | init: function() { 62 | var that = this; 63 | this.disabled = false; 64 | this.started = false; 65 | this.normalisePosition(); 66 | var $target = this.options.handle ? 67 | this.$el.find( this.options.handle ) : 68 | this.$el; 69 | if (this.options.longPress) { 70 | $target 71 | .on('uheldstart.udraggable', function(e) { that.start(e); }) 72 | .on('uheldmove.udraggable', function(e) { that.move(e); }) 73 | .on('uheldend.udraggable', function(e) { that.end(e); }); 74 | } 75 | else { 76 | $target 77 | .on('udragstart.udraggable', function(e) { that.start(e); }) 78 | .on('udragmove.udraggable', function(e) { that.move(e); }) 79 | .on('udragend.udraggable', function(e) { that.end(e); }); 80 | } 81 | }, 82 | 83 | destroy: function() { 84 | var $target = this.options.handle ? 85 | this.$el.find( this.options.handle ) : 86 | this.$el; 87 | $target.off('.udraggable'); 88 | this.$el.removeData('udraggable'); 89 | }, 90 | 91 | disable: function() { 92 | this.disabled = true; 93 | }, 94 | 95 | enable: function() { 96 | this.disabled = false; 97 | }, 98 | 99 | option: function() { 100 | var name; 101 | if (arguments.length === 0) { 102 | return this.options; 103 | } 104 | if (arguments.length === 2) { 105 | this.options[ arguments[0] ] = arguments[1]; 106 | return; 107 | } 108 | if (arguments.length === 1) { 109 | if (typeof arguments[0] === 'string') { 110 | return this.options[ arguments[0] ]; 111 | } 112 | if (typeof arguments[0] === 'object') { 113 | for(name in arguments[0]) { 114 | if (arguments[0].hasOwnProperty(name)) { 115 | this.options[name] = arguments[0][name]; 116 | } 117 | } 118 | } 119 | } 120 | if (this.options.containment) { 121 | this._initContainment(); 122 | } 123 | }, 124 | 125 | normalisePosition: function() { 126 | var pos = this.$el.position(); 127 | this.$el.css({ 128 | position: 'absolute', 129 | top: pos.top, 130 | left: pos.left, 131 | right: 'auto', 132 | bottom: 'auto' 133 | }); 134 | }, 135 | 136 | start: function(e) { 137 | if (this.disabled) { 138 | return; 139 | } 140 | var start = this.getStartPosition(this.$el); 141 | this._initContainment(); 142 | this.ui = { 143 | helper: this.$el, 144 | offset: { top: start.y, left: start.x}, 145 | originalPosition: { top: start.y, left: start.x}, 146 | position: { top: start.y, left: start.x}, 147 | }; 148 | if (this.options.longPress) { 149 | this._start(e); 150 | } 151 | return this._stopPropagation(e); 152 | }, 153 | 154 | move: function(e) { 155 | if (this.disabled || (!this.started && !this._start(e))) { 156 | return; 157 | } 158 | var delta_x = e.px_current_x - e.px_start_x; 159 | var delta_y = e.px_current_y - e.px_start_y; 160 | var axis = this.options.axis; 161 | if (axis && axis === "x") { 162 | delta_y = 0; 163 | } 164 | if (axis && axis === "y") { 165 | delta_x = 0; 166 | } 167 | var cur = { 168 | left: this.ui.originalPosition.left, 169 | top: this.ui.originalPosition.top 170 | }; 171 | if (!axis || (axis === "x")) { 172 | cur.left += delta_x; 173 | } 174 | if (!axis || (axis === "y")) { 175 | cur.top += delta_y; 176 | } 177 | this._applyGrid(cur); 178 | this._applyContainment(cur); 179 | var pos = this.ui.position; 180 | if ((cur.top !== pos.top) || (cur.left !== pos.left)) { 181 | this.ui.position.left = cur.left; 182 | this.ui.position.top = cur.top; 183 | this.ui.offset.left = cur.left; 184 | this.ui.offset.top = cur.top; 185 | if (this.options.drag) { 186 | this.options.drag.apply(this.el, [e, this.ui]); 187 | } 188 | this.queuePositionUpdate(); 189 | } 190 | return this._stopPropagation(e); 191 | }, 192 | 193 | end: function(e) { 194 | if (this.started || this._start(e)) { 195 | this.$el.removeClass("udraggable-dragging"); 196 | this.started = false; 197 | if (this.queuedUpdate) { 198 | window.cancelAnimationFrame(this.queuedUpdate); 199 | } 200 | this.updatePositionFrameHandler(); 201 | if (this.options.stop) { 202 | this.options.stop.apply(this.el, [e, this.ui]); 203 | } 204 | } 205 | return this._stopPropagation(e); 206 | }, 207 | 208 | // helper methods 209 | 210 | _stopPropagation: function(e) { 211 | e.stopPropagation(); 212 | e.preventDefault(); 213 | return false; 214 | }, 215 | 216 | _start: function(e) { 217 | if (!this._mouseDistanceMet(e) || !this._mouseDelayMet(e)) { 218 | return; 219 | } 220 | this.started = true; 221 | this.queuePositionUpdate(); 222 | if (this.options.start) { 223 | this.options.start.apply(this.el, [e, this.ui]); 224 | } 225 | this.$el.addClass("udraggable-dragging"); 226 | return true; 227 | }, 228 | 229 | _mouseDistanceMet: function(e) { 230 | return max( 231 | Math.abs(e.px_start_x - e.px_current_x), 232 | Math.abs(e.px_start_y - e.px_current_y) 233 | ) >= this.options.distance; 234 | }, 235 | 236 | _mouseDelayMet: function(e) { 237 | return e.ms_elapsed > this.options.delay; 238 | }, 239 | 240 | _initContainment: function() { 241 | var o = this.options; 242 | var $c, ce; 243 | 244 | if (!o.containment) { 245 | this.containment = null; 246 | return; 247 | } 248 | 249 | if (o.containment.constructor === Array) { 250 | this.containment = o.containment; 251 | return; 252 | } 253 | 254 | if (o.containment === "parent") { 255 | o.containment = this.$el.offsetParent(); 256 | } 257 | 258 | $c = $( o.containment ); 259 | ce = $c[ 0 ]; 260 | if (!ce) { 261 | return; 262 | } 263 | 264 | this.containment = [ 265 | 0, 266 | 0, 267 | $c.innerWidth() - this.$el.outerWidth(), 268 | $c.innerHeight() - this.$el.outerHeight(), 269 | ]; 270 | }, 271 | 272 | _applyGrid: function(cur) { 273 | if (this.options.grid) { 274 | var gx = this.options.grid[0]; 275 | var gy = this.options.grid[1]; 276 | cur.left = floor( (cur.left + gx / 2) / gx ) * gx; 277 | cur.top = floor( (cur.top + gy / 2) / gy ) * gy; 278 | } 279 | }, 280 | 281 | _applyContainment: function(cur) { 282 | var cont = this.containment; 283 | if (cont) { 284 | cur.left = min( max(cur.left, cont[0]), cont[2] ); 285 | cur.top = min( max(cur.top, cont[1]), cont[3] ); 286 | } 287 | }, 288 | 289 | getStartPosition: function($el) { 290 | return { 291 | x: parseInt($el.css('left'), 10) || 0, 292 | y: parseInt($el.css('top'), 10) || 0 293 | }; 294 | }, 295 | 296 | positionElement: function($el, dragging, left, top) { 297 | $el.css({ left: left, top: top }); 298 | } 299 | 300 | }; 301 | 302 | 303 | // jQuery plugin function 304 | 305 | $.fn.udraggable = function(option) { 306 | var args = Array.prototype.slice.call(arguments, 1); 307 | var results = []; 308 | this.each(function () { 309 | var $this = $(this); 310 | var data = $this.data('udraggable'); 311 | if (!data) { 312 | data = new UDraggable(this, option); 313 | $this.data('udraggable', data); 314 | } 315 | if (typeof option === 'string') { // option is a method - call it 316 | if(typeof data[option] !== 'function') { 317 | throw "jquery.udraggable has no '" + option + "' method"; 318 | } 319 | var result = data[option].apply(data, args); 320 | if (result !== undefined) { 321 | results.push( result ); 322 | } 323 | } 324 | }); 325 | return results.length > 0 ? results[0] : this; 326 | }; 327 | 328 | $.fn.udraggable.defaults = { 329 | axis: null, 330 | delay: 0, 331 | distance: 0, 332 | longPress: false, 333 | // callbacks 334 | drag: null, 335 | start: null, 336 | stop: null 337 | }; 338 | 339 | 340 | })(jQuery); 341 | 342 | -------------------------------------------------------------------------------- /docs/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bootstrap.js by @fat & @mdo 3 | * plugins: bootstrap-transition.js, bootstrap-modal.js, bootstrap-dropdown.js, bootstrap-scrollspy.js, bootstrap-tab.js, bootstrap-tooltip.js, bootstrap-popover.js, bootstrap-affix.js, bootstrap-alert.js, bootstrap-button.js, bootstrap-collapse.js, bootstrap-carousel.js, bootstrap-typeahead.js 4 | * Copyright 2012 Twitter, Inc. 5 | * http://www.apache.org/licenses/LICENSE-2.0.txt 6 | */ 7 | !function(a){a(function(){a.support.transition=function(){var a=function(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},c;for(c in b)if(a.style[c]!==undefined)return b[c]}();return a&&{end:a}}()})}(window.jQuery),!function(a){var b=function(b,c){this.options=c,this.$element=a(b).delegate('[data-dismiss="modal"]',"click.dismiss.modal",a.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};b.prototype={constructor:b,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var b=this,c=a.Event("show");this.$element.trigger(c);if(this.isShown||c.isDefaultPrevented())return;a("body").addClass("modal-open"),this.isShown=!0,this.escape(),this.backdrop(function(){var c=a.support.transition&&b.$element.hasClass("fade");b.$element.parent().length||b.$element.appendTo(document.body),b.$element.show(),c&&b.$element[0].offsetWidth,b.$element.addClass("in").attr("aria-hidden",!1).focus(),b.enforceFocus(),c?b.$element.one(a.support.transition.end,function(){b.$element.trigger("shown")}):b.$element.trigger("shown")})},hide:function(b){b&&b.preventDefault();var c=this;b=a.Event("hide"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,a("body").removeClass("modal-open"),this.escape(),a(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),a.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var b=this;a(document).on("focusin.modal",function(a){b.$element[0]!==a.target&&!b.$element.has(a.target).length&&b.$element.focus()})},escape:function(){var a=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(b){b.which==27&&a.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var b=this,c=setTimeout(function(){b.$element.off(a.support.transition.end),b.hideModal()},500);this.$element.one(a.support.transition.end,function(){clearTimeout(c),b.hideModal()})},hideModal:function(a){this.$element.hide().trigger("hidden"),this.backdrop()},removeBackdrop:function(){this.$backdrop.remove(),this.$backdrop=null},backdrop:function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('