imperavi-rails 0.0.3.beta → 0.0.4.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (324) hide show
  1. data/README.md +33 -29
  2. data/app/assets/javascripts/imperavi-rails/imperavi/redactor.js +317 -405
  3. data/app/assets/stylesheets/imperavi-rails/imperavi/redactor.css.scss +1 -1
  4. data/app/views/imperavi_rails/imperavi/image_edit.html.erb +1 -1
  5. data/lib/imperavi-rails/controller_methods.rb +35 -0
  6. data/lib/imperavi-rails/version.rb +1 -1
  7. data/lib/imperavi-rails.rb +9 -3
  8. data/spec/dummy/db/development.sqlite3 +0 -0
  9. data/spec/dummy/log/development.log +12384 -0
  10. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_44_32_721_6.jpg +0 -0
  11. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_44_32_721_6.jpg.meta +4 -0
  12. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_45_23_25_5.jpg +0 -0
  13. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_45_23_25_5.jpg.meta +4 -0
  14. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_45_49_374_15744.jpg +0 -0
  15. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_45_49_374_15744.jpg.meta +3 -0
  16. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_50_20_902_4.jpg +0 -0
  17. data/spec/dummy/public/system/dragonfly/development/2012/02/03/14_50_20_902_4.jpg.meta +4 -0
  18. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_22_15_373_5.jpg +0 -0
  19. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_22_15_373_5.jpg.meta +4 -0
  20. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_22_40_820_5.jpg +0 -0
  21. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_22_40_820_5.jpg.meta +4 -0
  22. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_23_30_325_3.jpg +0 -0
  23. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_23_30_325_3.jpg.meta +4 -0
  24. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_23_57_376_4.jpg +0 -0
  25. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_23_57_376_4.jpg.meta +4 -0
  26. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_26_27_220_5.jpg +0 -0
  27. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_26_27_220_5.jpg.meta +4 -0
  28. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_26_57_55_6.jpg +0 -0
  29. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_26_57_55_6.jpg.meta +4 -0
  30. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_27_58_370_5.jpg +0 -0
  31. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_27_58_370_5.jpg.meta +4 -0
  32. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_29_07_700_5.jpg +0 -0
  33. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_29_07_700_5.jpg.meta +4 -0
  34. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_29_19_327_4.jpg +0 -0
  35. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_29_19_327_4.jpg.meta +4 -0
  36. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_29_53_813_4.jpg +0 -0
  37. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_29_53_813_4.jpg.meta +4 -0
  38. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_30_13_242_5.jpg +0 -0
  39. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_30_13_242_5.jpg.meta +4 -0
  40. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_30_19_927_6.jpg +0 -0
  41. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_30_19_927_6.jpg.meta +4 -0
  42. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_14_355_5.jpg +0 -0
  43. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_14_355_5.jpg.meta +4 -0
  44. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_19_371_1.jpg +0 -0
  45. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_19_371_1.jpg.meta +4 -0
  46. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_28_432_15750.jpg +0 -0
  47. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_28_432_15750.jpg.meta +3 -0
  48. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_39_821_15720.jpg +0 -0
  49. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_39_821_15720.jpg.meta +3 -0
  50. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_47_624_4.jpg +0 -0
  51. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_31_47_624_4.jpg.meta +4 -0
  52. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_33_26_155_5.jpg +0 -0
  53. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_33_26_155_5.jpg.meta +4 -0
  54. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_34_29_787_2_small.jpg +0 -0
  55. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_34_29_787_2_small.jpg.meta +3 -0
  56. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_34_35_450_6.jpg +0 -0
  57. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_34_35_450_6.jpg.meta +4 -0
  58. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_34_41_340_15744.jpg +0 -0
  59. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_34_41_340_15744.jpg.meta +3 -0
  60. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_38_14_325_5.jpg +0 -0
  61. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_38_14_325_5.jpg.meta +4 -0
  62. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_45_06_883_6.jpg +0 -0
  63. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_45_06_883_6.jpg.meta +4 -0
  64. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_45_18_915_6.jpg +0 -0
  65. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_45_18_915_6.jpg.meta +4 -0
  66. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_45_46_86_15744.jpg +0 -0
  67. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_45_46_86_15744.jpg.meta +3 -0
  68. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_47_24_195_3.jpg +0 -0
  69. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_47_24_195_3.jpg.meta +4 -0
  70. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_47_46_83_5.jpg +0 -0
  71. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_47_46_83_5.jpg.meta +4 -0
  72. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_51_18_603_15720.jpg +0 -0
  73. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_51_18_603_15720.jpg.meta +3 -0
  74. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_51_57_666_6.jpg +0 -0
  75. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_51_57_666_6.jpg.meta +4 -0
  76. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_53_25_938_6.jpg +0 -0
  77. data/spec/dummy/public/system/dragonfly/development/2012/02/17/19_53_25_938_6.jpg.meta +4 -0
  78. data/spec/dummy/tmp/cache/assets/CA9/BC0/sprockets%2F85d8b987b980454101a1236fdec2c220 +0 -0
  79. data/spec/dummy/tmp/cache/assets/CBE/FC0/sprockets%2Ff5431a64e341b062b7530132a5c1ea5a +2306 -1667
  80. data/spec/dummy/tmp/cache/assets/CC5/C10/sprockets%2F7c81f5c40dc9b87819488e127f487a04 +447 -369
  81. data/spec/dummy/tmp/cache/assets/CD5/530/sprockets%2F8d4c18bd4851f107c450a2c782301f8b +53 -0
  82. data/spec/dummy/tmp/cache/assets/CD7/EF0/sprockets%2Fc22597dc7c74137ba100f08542fec580 +76 -0
  83. data/spec/dummy/tmp/cache/assets/D09/DB0/sprockets%2F5ad1bbd0a458985447fac962fb121264 +188 -0
  84. data/spec/dummy/tmp/cache/assets/D1A/AB0/sprockets%2F05ea78f209b93ef03f29e933625b7fa5 +305 -1
  85. data/spec/dummy/tmp/cache/assets/D33/480/sprockets%2Fec072121b559132efe7d07cac0e991a5 +106 -0
  86. data/spec/dummy/tmp/cache/assets/D38/5D0/sprockets%2F7913f60d743aeb957af7a0ca5a20059d +0 -0
  87. data/spec/dummy/tmp/cache/assets/D43/830/sprockets%2Fe09848481135db1a4a5c783a7dc94fbd +50 -0
  88. data/spec/dummy/tmp/cache/assets/D59/260/sprockets%2Fd513a46ce8d83f003a733cb306dfe01a +317 -406
  89. data/spec/dummy/tmp/cache/assets/D64/190/sprockets%2Ffdfa1bbf71247a2b9ef0b97732603e02 +0 -0
  90. data/spec/dummy/tmp/cache/assets/D66/200/sprockets%2Fb343cda49d5d41a82c10a8f06d986bd2 +45 -0
  91. data/spec/dummy/tmp/cache/assets/D6B/980/sprockets%2F56c37f49f60073a401fcbd529dcaa74e +222 -0
  92. data/spec/dummy/tmp/cache/assets/D6D/AF0/sprockets%2F5a1aa4e3f7d7008e775019dfef3282cc +97 -0
  93. data/spec/dummy/tmp/cache/assets/D76/560/sprockets%2Fe0c5141697a090ffb74c9412e6dd7fef +50 -0
  94. data/spec/dummy/tmp/cache/assets/D95/E80/sprockets%2F844edf25b78967cbe9cf3e969c37c6c7 +0 -0
  95. data/spec/dummy/tmp/cache/assets/D96/230/sprockets%2F63e1b63e2b03d0bd6aaebd27c9973e91 +248 -1
  96. data/spec/dummy/tmp/cache/assets/D9B/E30/sprockets%2Fd87c8ca46743542cace533cfe91ae1d0 +437 -365
  97. data/spec/dummy/tmp/cache/assets/D9B/FF0/sprockets%2Fd8bbace39747d4af921e0534736baea3 +125 -0
  98. data/spec/dummy/tmp/cache/assets/DA2/970/sprockets%2F0d4ef1d42ee3e36fedcd979b3506525b +881 -1
  99. data/spec/dummy/tmp/cache/assets/DA8/F60/sprockets%2Fbb2cd57d63160c94d622ef9d91ccef68 +5 -5
  100. data/spec/dummy/tmp/cache/assets/DAC/140/sprockets%2F7a814a5598eaaaccf7ab7895f5663ad5 +89 -0
  101. data/spec/dummy/tmp/cache/assets/DB7/F90/sprockets%2Faf8cc6b28a790c7e3bd686e8ab9973c8 +0 -0
  102. data/spec/dummy/tmp/cache/assets/DBB/960/sprockets%2Fe20156d5decfaaea9d1e09f14a100f19 +16 -0
  103. data/spec/dummy/tmp/cache/sass/bc54e898614d486bf9338d646e8cd056915d4779/redactor.css.scssc +0 -0
  104. data/spec/dummy/tmp/dragonfly/cache/body/01/8b80e42551d33aed663f5757b3e4d3789383e6 +2359 -0
  105. data/spec/dummy/tmp/dragonfly/cache/body/02/3133eaaddaa68515039bc51e11b3bca2ad3f23 +986 -0
  106. data/spec/dummy/tmp/dragonfly/cache/body/03/13c061439229cdbd19215cbd1cf0e26441fac2 +713 -0
  107. data/spec/dummy/tmp/dragonfly/cache/body/05/024188cd40feb026eb8ccd15985d890ba9c84e +643 -0
  108. data/spec/dummy/tmp/dragonfly/cache/body/06/e22ab9a18784ce1f20e09401ee38b9672860d9 +697 -0
  109. data/spec/dummy/tmp/dragonfly/cache/body/07/f49938e6a88e40d2d6fd9fc613578396148e1d +1014 -0
  110. data/spec/dummy/tmp/dragonfly/cache/body/08/8e8a8fc07862b6f7f1bb3d065c44a796a1b959 +489 -0
  111. data/spec/dummy/tmp/dragonfly/cache/body/09/7fc6a9593ea7b3a9992dd166cdc87cf0e06afc +2341 -0
  112. data/spec/dummy/tmp/dragonfly/cache/body/09/c8b9529699d7f44fc6e314c992ea222ecf891a +926 -0
  113. data/spec/dummy/tmp/dragonfly/cache/body/0a/eae45805608cdebd81ace3ac272d43ef8c581a +517 -0
  114. data/spec/dummy/tmp/dragonfly/cache/body/0f/33cebc2562a1ba143494c74b572a7f569c398e +0 -0
  115. data/spec/dummy/tmp/dragonfly/cache/body/12/f3e9f5435e64b368b805b0f6e2e5b04763e0e9 +713 -0
  116. data/spec/dummy/tmp/dragonfly/cache/body/13/02bfc481015a6a0abeb3bd17a166b761ba8a47 +626 -0
  117. data/spec/dummy/tmp/dragonfly/cache/body/14/132bf3af2f923b66a62826ebe1dd001f0ba183 +0 -0
  118. data/spec/dummy/tmp/dragonfly/cache/body/16/3001f75355d109f24b59f690f7ba71c2616261 +2343 -0
  119. data/spec/dummy/tmp/dragonfly/cache/body/16/7a17ea4c64e37f9f0aa5e773501ee5131bb2af +552 -0
  120. data/spec/dummy/tmp/dragonfly/cache/body/18/1ddbad5715e03f6bcaeb409ca55a8f1f1c2b76 +1000 -0
  121. data/spec/dummy/tmp/dragonfly/cache/body/18/dc1d281e1b27f8e29a5d3ea3192ee5ab92c8fe +1721 -0
  122. data/spec/dummy/tmp/dragonfly/cache/body/19/244efbcbf0ed096cc80addb39d1139782691e4 +701 -0
  123. data/spec/dummy/tmp/dragonfly/cache/body/1b/09d865c098ccb9e1bb1783281f8f18ab22f49c +1016 -0
  124. data/spec/dummy/tmp/dragonfly/cache/body/1b/5baeb3d8b21ebdd6d60357437ea9b4ddefa49a +537 -0
  125. data/spec/dummy/tmp/dragonfly/cache/body/1b/f3995977d56cd70d334227ffae3858fdb3e1d4 +1011 -0
  126. data/spec/dummy/tmp/dragonfly/cache/body/1c/8c49d20e2ca7ccea3c7124923f2d6ff715400c +538 -0
  127. data/spec/dummy/tmp/dragonfly/cache/body/1e/3ce5b58c37f23053d85f581ff49d15ad1a498a +674 -0
  128. data/spec/dummy/tmp/dragonfly/cache/body/1f/de9c96ae1b545cb125a43f6c81fe6f15851ac7 +546 -0
  129. data/spec/dummy/tmp/dragonfly/cache/body/20/5d43e6adae0bf766e830109660e59dfd97a776 +646 -0
  130. data/spec/dummy/tmp/dragonfly/cache/body/20/9dd05484ee6eca030ee50cf71b912a67089c79 +2339 -0
  131. data/spec/dummy/tmp/dragonfly/cache/body/21/bdc0c588b6d2ddbbcc9b76fe749c38f0ef2f41 +872 -0
  132. data/spec/dummy/tmp/dragonfly/cache/body/22/f0e133e63c81c43643026aa5cbb3712bfa929e +708 -0
  133. data/spec/dummy/tmp/dragonfly/cache/body/24/f7da13054199d224537d7530367474f292c85a +2359 -0
  134. data/spec/dummy/tmp/dragonfly/cache/body/27/0ac007b4441579233e425f3e7a36887eb4298e +986 -0
  135. data/spec/dummy/tmp/dragonfly/cache/body/28/c775213c7f72c870045887887893831bbb9083 +1006 -0
  136. data/spec/dummy/tmp/dragonfly/cache/body/2a/602d5bf47ce3c3e1fbd540f3659acdf8488b84 +2341 -0
  137. data/spec/dummy/tmp/dragonfly/cache/body/2c/79dceb2787a90f7da9a43673db8d1f1922a379 +641 -0
  138. data/spec/dummy/tmp/dragonfly/cache/body/2d/016dc3e8be00f46455041e5187159762a1a72b +535 -0
  139. data/spec/dummy/tmp/dragonfly/cache/body/2d/40a96b71b5c4be6ea5de082c5c468b923df113 +626 -0
  140. data/spec/dummy/tmp/dragonfly/cache/body/2f/2077afd991927df732811e002d532f34a62c86 +0 -0
  141. data/spec/dummy/tmp/dragonfly/cache/body/30/7cdb90b26de71fedb1774d7b7fe630e77cf34f +1011 -0
  142. data/spec/dummy/tmp/dragonfly/cache/body/33/43ee3681542a52fec318884c34cdc6233aec90 +2359 -0
  143. data/spec/dummy/tmp/dragonfly/cache/body/34/d994dfa8a8a2cf1dddcfcb9d7d43839f798a66 +1007 -0
  144. data/spec/dummy/tmp/dragonfly/cache/body/36/1acb61b84bbb2e3b1fe7cb28e1ca0bb2ebc147 +1721 -0
  145. data/spec/dummy/tmp/dragonfly/cache/body/37/0de185ac6803197940a4aca2ee4cb6cd97aa25 +700 -0
  146. data/spec/dummy/tmp/dragonfly/cache/body/39/36d756ac37cbfd7995a8413c5b813623f8c1d6 +496 -0
  147. data/spec/dummy/tmp/dragonfly/cache/body/39/c79f94952d16de5de0ec59089d381ace6e386e +1029 -0
  148. data/spec/dummy/tmp/dragonfly/cache/body/3f/457b87cdc17162db48461cf72c87457ebe753b +1011 -0
  149. data/spec/dummy/tmp/dragonfly/cache/body/40/d745dd4044031ccd76b4f5a8ad46e3c16ea8c0 +915 -0
  150. data/spec/dummy/tmp/dragonfly/cache/body/43/1a5a2dc62c3b453378dad049c48fcf36928f53 +2342 -0
  151. data/spec/dummy/tmp/dragonfly/cache/body/43/abfe6e68d8603f92084533b5f94fb717bc2b02 +700 -0
  152. data/spec/dummy/tmp/dragonfly/cache/body/44/65e89dffc7531e6479a00711d7bf430c56754f +2359 -0
  153. data/spec/dummy/tmp/dragonfly/cache/body/47/1092abd16e44c60537ac674b871481ca6d108e +489 -0
  154. data/spec/dummy/tmp/dragonfly/cache/body/47/befec7e863f30488d1c9a72619411e3c311eea +552 -0
  155. data/spec/dummy/tmp/dragonfly/cache/body/48/4af0743c55ececa9e2b3477a666492914d5a25 +700 -0
  156. data/spec/dummy/tmp/dragonfly/cache/body/48/5935b1ceed38545d44989a5464049018f63ecd +926 -0
  157. data/spec/dummy/tmp/dragonfly/cache/body/4a/db06a6fda9b3fbe12beb6816390a4fd61e4491 +667 -0
  158. data/spec/dummy/tmp/dragonfly/cache/body/4b/088deec20739cb75b3d8e2ca591171b342026d +862 -0
  159. data/spec/dummy/tmp/dragonfly/cache/body/4b/ea67064045b150fdd661d9b25fe1c447df7570 +703 -0
  160. data/spec/dummy/tmp/dragonfly/cache/body/50/8888bca37caef9e8ecf9434f304d1ab2cc820a +538 -0
  161. data/spec/dummy/tmp/dragonfly/cache/body/54/862500a3c1ce6a605de340ded6051d9d6c96dc +880 -0
  162. data/spec/dummy/tmp/dragonfly/cache/body/55/a3a5731c805bf0c5deda35500598030e91caf7 +2358 -0
  163. data/spec/dummy/tmp/dragonfly/cache/body/56/50f6edaa5e2fe07797333404d13fe63360f72c +0 -0
  164. data/spec/dummy/tmp/dragonfly/cache/body/56/dfa139236a6fcecf0fdd13308a17d03666d223 +2361 -0
  165. data/spec/dummy/tmp/dragonfly/cache/body/58/d135dda5118408bf76a2b381ac0d482276ee97 +546 -0
  166. data/spec/dummy/tmp/dragonfly/cache/body/59/0b00b9579bdc8d199e42d68cc83ee72ba6036a +712 -0
  167. data/spec/dummy/tmp/dragonfly/cache/body/59/c6cdda1534cfeb69aed8a295fa36aa0b34d9ac +882 -0
  168. data/spec/dummy/tmp/dragonfly/cache/body/5c/c982746925609ae2ddd24d20e9f96247006dc3 +883 -0
  169. data/spec/dummy/tmp/dragonfly/cache/body/5f/033e3fda7f0149729cdeba2807ccad0ce6ea32 +1016 -0
  170. data/spec/dummy/tmp/dragonfly/cache/body/5f/95bdb3eb07339f50a73c3e2c38d619b2321902 +2361 -0
  171. data/spec/dummy/tmp/dragonfly/cache/body/60/92cdccc969bab02d35b702148409d59276ec8e +703 -0
  172. data/spec/dummy/tmp/dragonfly/cache/body/62/d3974c45b38586ded0f6adefcefeb4e25aea08 +2357 -0
  173. data/spec/dummy/tmp/dragonfly/cache/body/63/9cff6d42d49aaded2e3201d0b311fb0c4d5af5 +872 -0
  174. data/spec/dummy/tmp/dragonfly/cache/body/65/b3251b1348841946320cd8ac140a7a10a07de5 +894 -0
  175. data/spec/dummy/tmp/dragonfly/cache/body/66/59b5c1535bed3649f05f378f9a935a9369a14f +2341 -0
  176. data/spec/dummy/tmp/dragonfly/cache/body/67/8611d272ec29fc5cb7a63a709a12f47da63fbd +538 -0
  177. data/spec/dummy/tmp/dragonfly/cache/body/68/9bc64959e48ba446c2a48a48952d4e6e422bee +2334 -0
  178. data/spec/dummy/tmp/dragonfly/cache/body/6a/0be367e94b672cef188ef8c3261ed63fa59e6d +701 -0
  179. data/spec/dummy/tmp/dragonfly/cache/body/6a/1642bac93ee93e5ca10af933c39f6db9e15508 +0 -0
  180. data/spec/dummy/tmp/dragonfly/cache/body/6a/4558d01c325e63bfe9abe3df6b1255e51a20e6 +703 -0
  181. data/spec/dummy/tmp/dragonfly/cache/body/6b/8df0f17fd3ce7a7e551e91f30909a847a2abee +734 -0
  182. data/spec/dummy/tmp/dragonfly/cache/body/6b/90cf2c21e1934876d420d2524fe5216c5e7bf1 +551 -0
  183. data/spec/dummy/tmp/dragonfly/cache/body/6d/d8a547a0125a1da2df83e6b2f4c36631a1bd2f +538 -0
  184. data/spec/dummy/tmp/dragonfly/cache/body/6e/a8d288ea6931b9277121b209ac32959b717029 +882 -0
  185. data/spec/dummy/tmp/dragonfly/cache/body/6f/b27a907116ff2fa7a668b30d49b65885a09022 +1016 -0
  186. data/spec/dummy/tmp/dragonfly/cache/body/71/01bff740c639a7b8383a5e247ece9552656acb +708 -0
  187. data/spec/dummy/tmp/dragonfly/cache/body/73/7752ee519e2ee8c13b4c9165fb98c19a874843 +882 -0
  188. data/spec/dummy/tmp/dragonfly/cache/body/74/c9b1fca6f96048f555aed33ddb5c5240839f62 +793 -0
  189. data/spec/dummy/tmp/dragonfly/cache/body/75/01f0f946848c6b910634bed2a58e748dd0a4d2 +986 -0
  190. data/spec/dummy/tmp/dragonfly/cache/body/75/15881fe428cd4b04438de4e03ba3acc7cd789e +642 -0
  191. data/spec/dummy/tmp/dragonfly/cache/body/77/02b8ae247e83a86e819b150375bd2971911635 +882 -0
  192. data/spec/dummy/tmp/dragonfly/cache/body/79/0ba4208b6b095e78b15c6f2c4ef04b9e568fdf +976 -0
  193. data/spec/dummy/tmp/dragonfly/cache/body/7a/40b3b7e48d2fb4f8dc6b9ce3b2c6414cd3db4b +638 -0
  194. data/spec/dummy/tmp/dragonfly/cache/body/7a/44fbc7caa954feca99ae14cdd31700f3bc01ca +0 -0
  195. data/spec/dummy/tmp/dragonfly/cache/body/81/1412d99f15c17d9a52618013667ddc6acbb5e7 +560 -0
  196. data/spec/dummy/tmp/dragonfly/cache/body/82/bb0ce1f6b156348edb5d054b09681adbb1541c +638 -0
  197. data/spec/dummy/tmp/dragonfly/cache/body/82/f4aef50c7d0580ce3de59af781988f8c027e31 +0 -0
  198. data/spec/dummy/tmp/dragonfly/cache/body/84/3bafbd4a01aaae5795b68c2a21561fd78e8bfb +0 -0
  199. data/spec/dummy/tmp/dragonfly/cache/body/84/61cb5340e22fb0e266e5276613f5b218b793c0 +774 -0
  200. data/spec/dummy/tmp/dragonfly/cache/body/87/452e47dc8c565d70543b6a8b3aeeeafef5ede6 +1008 -0
  201. data/spec/dummy/tmp/dragonfly/cache/body/8e/6921af9cd9a9aa0cb4a521be98d497ff7fdeaf +700 -0
  202. data/spec/dummy/tmp/dragonfly/cache/body/8e/d1fec3f23b9477057019f581847f7f8b2051c3 +0 -0
  203. data/spec/dummy/tmp/dragonfly/cache/body/8f/e7d4976bf7e183cf4f6ab9409f8503351dad3c +709 -0
  204. data/spec/dummy/tmp/dragonfly/cache/body/90/1abfe79ed8fa57b0f367b8d6cc284742d74bd9 +703 -0
  205. data/spec/dummy/tmp/dragonfly/cache/body/93/fe1fa30d5fe0cb493dd11ea6eaee9201b50cd8 +712 -0
  206. data/spec/dummy/tmp/dragonfly/cache/body/94/7a175f9de08b84499763ba6cc25f6911ef315e +913 -0
  207. data/spec/dummy/tmp/dragonfly/cache/body/98/2828d5b0867095317a017415955ef31a50dbc5 +1014 -0
  208. data/spec/dummy/tmp/dragonfly/cache/body/98/f06faf5cfff9a92b4d99d400523e1f1551742e +1007 -0
  209. data/spec/dummy/tmp/dragonfly/cache/body/99/2dab09135d5fcbaa2c2b833a8284cb56be5c26 +1014 -0
  210. data/spec/dummy/tmp/dragonfly/cache/body/99/b545fe8ab3b930d8997fd75bb08feea0c9754d +915 -0
  211. data/spec/dummy/tmp/dragonfly/cache/body/9a/ff030c94bb0fbe5d9fbb8cf6865236cb7d74b2 +217 -0
  212. data/spec/dummy/tmp/dragonfly/cache/body/9f/8083640216ee29b9e8b4f10990f33d94aa352c +2360 -0
  213. data/spec/dummy/tmp/dragonfly/cache/body/9f/f4d177f296f259ff4ef3ddb38583daaf7c4dad +1011 -0
  214. data/spec/dummy/tmp/dragonfly/cache/body/a0/13144afc0d13219dad65508b046b9e0693a22b +926 -0
  215. data/spec/dummy/tmp/dragonfly/cache/body/a1/44a32dab1df021f54bf212d2a401b7fc69a2d8 +882 -0
  216. data/spec/dummy/tmp/dragonfly/cache/body/a2/7996e882d74e2e2c590fbfee8a8842b43f5c5e +1014 -0
  217. data/spec/dummy/tmp/dragonfly/cache/body/a2/e9ac7eba6c9ac611ec0cb7f26cbe0711b4b59c +694 -0
  218. data/spec/dummy/tmp/dragonfly/cache/body/a3/cd2fc5aabd1c551bba7f290844b8d89c94ab1e +523 -0
  219. data/spec/dummy/tmp/dragonfly/cache/body/a4/1a483a32348565e7afc810f49f55c1a9cbcd5d +707 -0
  220. data/spec/dummy/tmp/dragonfly/cache/body/a5/ddf1a8e968d20390ab06c94b19eb69a1e81ad7 +908 -0
  221. data/spec/dummy/tmp/dragonfly/cache/body/a6/f516919f720c81c119adadf1693ea44e5b90fe +490 -0
  222. data/spec/dummy/tmp/dragonfly/cache/body/a8/5137398b4d62aacbb0921f50eb9f62e7ec8de4 +0 -0
  223. data/spec/dummy/tmp/dragonfly/cache/body/a8/fb555a7e2420a17ce30758861ac3de784677eb +1011 -0
  224. data/spec/dummy/tmp/dragonfly/cache/body/b0/9703b98c965449cfbff801b8482e5c2c9b1b50 +954 -0
  225. data/spec/dummy/tmp/dragonfly/cache/body/b1/4c0f9e41101026eff8ebdc3fc9eae61c25372b +700 -0
  226. data/spec/dummy/tmp/dragonfly/cache/body/b3/d870794114f8ce678eeeddb0616abbea93ec7b +562 -0
  227. data/spec/dummy/tmp/dragonfly/cache/body/b4/1d331b6f64144bdee2ab598fd7f5ed2bcb6c3c +0 -0
  228. data/spec/dummy/tmp/dragonfly/cache/body/b4/84edbbb2dae5a5fc1cbfc8c8d3517bd1466a1b +2359 -0
  229. data/spec/dummy/tmp/dragonfly/cache/body/b5/52eaf4b5bac5fcf8667e5fb74f4b1c61984b0e +537 -0
  230. data/spec/dummy/tmp/dragonfly/cache/body/b6/9ec86cf5018fe63297e409da6638450c5041d2 +0 -0
  231. data/spec/dummy/tmp/dragonfly/cache/body/b7/31c759f6bf5b6adc13874d8ccf325a1715bf33 +882 -0
  232. data/spec/dummy/tmp/dragonfly/cache/body/b8/84c73fced17e1cb4f2efc18ed4f81789e5a622 +0 -0
  233. data/spec/dummy/tmp/dragonfly/cache/body/b9/43df43ad225c99d420cdb7e5d7714c2876273f +1007 -0
  234. data/spec/dummy/tmp/dragonfly/cache/body/b9/b4cb4d1647df4ec458ef3cc18782261a46bef2 +641 -0
  235. data/spec/dummy/tmp/dragonfly/cache/body/ba/1c57461ee48afadc870fca415b0e2aeaec3f4a +882 -0
  236. data/spec/dummy/tmp/dragonfly/cache/body/be/d14e3b72d93bfc0cace752edf21f5cc2af8949 +2358 -0
  237. data/spec/dummy/tmp/dragonfly/cache/body/c1/0767685a05c93f5e79a81ec5016820d7068afd +281 -0
  238. data/spec/dummy/tmp/dragonfly/cache/body/c3/5f95670b5171f06b0c450331c20ce59d44d5bd +537 -0
  239. data/spec/dummy/tmp/dragonfly/cache/body/c3/c76755904506b55cc288baed5e8f3ae767e1f9 +908 -0
  240. data/spec/dummy/tmp/dragonfly/cache/body/c7/48859071d0c1e701557a2b59181ae9d40b4c1c +1029 -0
  241. data/spec/dummy/tmp/dragonfly/cache/body/cc/e21614b70000b7a45bf382a696dfdf2e78811f +1029 -0
  242. data/spec/dummy/tmp/dragonfly/cache/body/cd/daa343d969732d44b9018e9e8403d758c1075b +2334 -0
  243. data/spec/dummy/tmp/dragonfly/cache/body/cd/dbba7b01cfb5eabf3c3b557d3cc1c7eeac9157 +523 -0
  244. data/spec/dummy/tmp/dragonfly/cache/body/d0/654133544a02cf512cdbe78256f913d684ee32 +894 -0
  245. data/spec/dummy/tmp/dragonfly/cache/body/d4/42ed09f48e3e24cd3cd958c9e0865df054419b +1029 -0
  246. data/spec/dummy/tmp/dragonfly/cache/body/d6/1eefad56108f5a8e1fa7aa72ff9b9f9cd633fc +538 -0
  247. data/spec/dummy/tmp/dragonfly/cache/body/d6/d1ac8848c469cd9094fa75b7528e0f5b6b632e +496 -0
  248. data/spec/dummy/tmp/dragonfly/cache/body/d7/899077450ebef4fdc0e9bb929825299f54457f +697 -0
  249. data/spec/dummy/tmp/dragonfly/cache/body/d9/f0d58e806b8697218740130d2ca12b3b86d6ef +1007 -0
  250. data/spec/dummy/tmp/dragonfly/cache/body/da/378953b0532aa6da1fa92abeeae89199ef8227 +1006 -0
  251. data/spec/dummy/tmp/dragonfly/cache/body/da/7c689c2f3a69f6770b63b71a8e71b6a1a28b37 +967 -0
  252. data/spec/dummy/tmp/dragonfly/cache/body/da/e26a3a67f1a9ea2332232ea28c90082c0e3bad +963 -0
  253. data/spec/dummy/tmp/dragonfly/cache/body/dc/abdd743fd3e9d7bd5647abeb86e66a3e6f9597 +0 -0
  254. data/spec/dummy/tmp/dragonfly/cache/body/e0/85f72a9f92bfadac77ceb40b9dcce7f1d0c0b4 +712 -0
  255. data/spec/dummy/tmp/dragonfly/cache/body/e1/f71dadeca1e7e8044d7ffe33168a41cf4b915e +712 -0
  256. data/spec/dummy/tmp/dragonfly/cache/body/e3/5e3eeacd0fa04028277861a7e20aca055126bf +705 -0
  257. data/spec/dummy/tmp/dragonfly/cache/body/e7/71af29ca1fb912746c2a8c252ce2dbda293797 +0 -0
  258. data/spec/dummy/tmp/dragonfly/cache/body/eb/d3df10f28dd5eb3361f2dea07bce8f31883cb4 +562 -0
  259. data/spec/dummy/tmp/dragonfly/cache/body/f2/0000c07c049d6b02b83c134a47f79d25c8f884 +1006 -0
  260. data/spec/dummy/tmp/dragonfly/cache/body/f3/81eaa388ae0115314da5ef3dff86dde481f6ea +1011 -0
  261. data/spec/dummy/tmp/dragonfly/cache/body/f4/f597679294dfce3758a1e23f8739ddadb7a07a +905 -0
  262. data/spec/dummy/tmp/dragonfly/cache/body/f6/5638ff81bbc2e264c25be9224311d5b88e199e +696 -0
  263. data/spec/dummy/tmp/dragonfly/cache/body/f8/4c49b7e7f1df8b9bf194c8e4f238965275a470 +638 -0
  264. data/spec/dummy/tmp/dragonfly/cache/body/f8/bce7bef222715dce37713e4b658bb432746046 +642 -0
  265. data/spec/dummy/tmp/dragonfly/cache/body/fb/4bbd9bd1b55ea5c5f029a98429cbe84fecbd56 +1029 -0
  266. data/spec/dummy/tmp/dragonfly/cache/body/fe/83a325403c35319d9539703bf8b707c48cbb81 +700 -0
  267. data/spec/dummy/tmp/dragonfly/cache/meta/0b/a9c9bfcc4c3c931157c0740283f9879ffbc80e +0 -0
  268. data/spec/dummy/tmp/dragonfly/cache/meta/16/82dfe14b1caadf556cccc78e6742ecba3c8f50 +0 -0
  269. data/spec/dummy/tmp/dragonfly/cache/meta/18/2807a34d96c2dc102f1c7f2c2fe2a3dea0152a +0 -0
  270. data/spec/dummy/tmp/dragonfly/cache/meta/1b/df42876b5661f82d4041d818e787e2f58949e7 +0 -0
  271. data/spec/dummy/tmp/dragonfly/cache/meta/1d/f723c27427056dd58a506f1e4f15020442098e +0 -0
  272. data/spec/dummy/tmp/dragonfly/cache/meta/22/66939b783406813e2f0a76f3a2f29473675994 +0 -0
  273. data/spec/dummy/tmp/dragonfly/cache/meta/23/4f7740cb6118c7c530ce379339a99828a75ef3 +0 -0
  274. data/spec/dummy/tmp/dragonfly/cache/meta/26/25fc31c2b02071c5c60621d36793dc55fdb33c +0 -0
  275. data/spec/dummy/tmp/dragonfly/cache/meta/29/717968cc2fa016a4911e7161b6423235f36c87 +0 -0
  276. data/spec/dummy/tmp/dragonfly/cache/meta/2d/83e1c5e84c02b8fee05b62d483999bfaba7be0 +0 -0
  277. data/spec/dummy/tmp/dragonfly/cache/meta/2d/b7fe2b8774fa388daa3c8370f34052119b4222 +0 -0
  278. data/spec/dummy/tmp/dragonfly/cache/meta/2d/fe381b58b48b16278672bd61db736e4e920955 +0 -0
  279. data/spec/dummy/tmp/dragonfly/cache/meta/32/e0d3566d2be50daabce5a94c515f772050829b +0 -0
  280. data/spec/dummy/tmp/dragonfly/cache/meta/38/5bb4a3ceace256ca114fc14a3c5ae12ec83fb0 +0 -0
  281. data/spec/dummy/tmp/dragonfly/cache/meta/39/b52b68255f54efe8cb853fd153088f94a7661a +0 -0
  282. data/spec/dummy/tmp/dragonfly/cache/meta/3e/0173e72157b702c4926d190389540028b0ae1d +0 -0
  283. data/spec/dummy/tmp/dragonfly/cache/meta/52/a111bad2ef8c87af7f55baf0ffc5cdefc446e4 +0 -0
  284. data/spec/dummy/tmp/dragonfly/cache/meta/55/32c60f25996b8e8a9fdf7125956c5204fa8792 +0 -0
  285. data/spec/dummy/tmp/dragonfly/cache/meta/64/61f1782e6f9ec4e6416c0aec429529ea70a1a1 +0 -0
  286. data/spec/dummy/tmp/dragonfly/cache/meta/66/b6e26427e56a9f9ade00d4cf5d615679f0f7a7 +0 -0
  287. data/spec/dummy/tmp/dragonfly/cache/meta/66/f44aba1428593600ff0e47ea6aa54362e39a59 +0 -0
  288. data/spec/dummy/tmp/dragonfly/cache/meta/6d/f4ba8735866613f9b640f6a0cc8e4583eba1f9 +0 -0
  289. data/spec/dummy/tmp/dragonfly/cache/meta/78/d74c0cd05a77c0c06acb622761d30c9ea00bb3 +0 -0
  290. data/spec/dummy/tmp/dragonfly/cache/meta/7a/6033b3a3f17fbddc765d138d39de24f94f0965 +0 -0
  291. data/spec/dummy/tmp/dragonfly/cache/meta/7a/d6666861b23fcf6c7ea45d61810fdb1c14d9d0 +0 -0
  292. data/spec/dummy/tmp/dragonfly/cache/meta/80/5841ac20acdd8dd41460c8346294abc5c4dd8f +0 -0
  293. data/spec/dummy/tmp/dragonfly/cache/meta/83/5df7873207b08f78fd9d690e5a0b759242b937 +0 -0
  294. data/spec/dummy/tmp/dragonfly/cache/meta/83/696c30e03b7215b60e076bc528c8829ddcc516 +0 -0
  295. data/spec/dummy/tmp/dragonfly/cache/meta/83/b01df8c183f9586aff3f30bd22f4c24793c52b +0 -0
  296. data/spec/dummy/tmp/dragonfly/cache/meta/85/289eb541e97e28d96dacfd07c314be3beb566a +0 -0
  297. data/spec/dummy/tmp/dragonfly/cache/meta/8c/1a23bf2dd650d0327255a5fe948c325d350107 +0 -0
  298. data/spec/dummy/tmp/dragonfly/cache/meta/8f/5281faf3f227ef4bbbd3b644cc9eafc86ff9b1 +0 -0
  299. data/spec/dummy/tmp/dragonfly/cache/meta/91/0922a2bd8308a75961dac5733d4907df678f65 +0 -0
  300. data/spec/dummy/tmp/dragonfly/cache/meta/92/8e4f3f982b856114506c590c291dea7f0c29d7 +0 -0
  301. data/spec/dummy/tmp/dragonfly/cache/meta/92/99ecbc80a7e8abcc02a36d9c3365b23b1a5b1a +0 -0
  302. data/spec/dummy/tmp/dragonfly/cache/meta/98/00e4dc8c2a89849e9d3cb8dd37f8c45d744dd3 +0 -0
  303. data/spec/dummy/tmp/dragonfly/cache/meta/9d/4531b3a9ffdee2c2b2b485675e8b055a2de25f +0 -0
  304. data/spec/dummy/tmp/dragonfly/cache/meta/a2/5920380e48276ad6f8bc26fb9a4a527db839c8 +0 -0
  305. data/spec/dummy/tmp/dragonfly/cache/meta/b7/407b5584752ca5298158a78be896bf810dd4e0 +0 -0
  306. data/spec/dummy/tmp/dragonfly/cache/meta/b7/ae83f0c4d7b4849a78af8830c31ffe4b166b52 +0 -0
  307. data/spec/dummy/tmp/dragonfly/cache/meta/d2/458b4acc8a67ee57346f1f4ebfa0f0e4bb4ea3 +0 -0
  308. data/spec/dummy/tmp/dragonfly/cache/meta/d5/341018026448c1d4f56801bd7ddb8380e1a73c +0 -0
  309. data/spec/dummy/tmp/dragonfly/cache/meta/e7/6d1dc2d45d19440e781f6c5d00f39d8aeb4da1 +0 -0
  310. data/spec/dummy/tmp/dragonfly/cache/meta/ee/fe74949a8c2a0bbc077385a12944d9f98a12e0 +0 -0
  311. data/spec/dummy/tmp/dragonfly/cache/meta/ef/d71b44567b90c7f85e9bd0576e4b7e55bd3565 +0 -0
  312. data/spec/dummy/tmp/dragonfly/cache/meta/f9/67ac04386c59253bd80f4034d18af166cc5691 +0 -0
  313. data/spec/dummy/tmp/sass-cache/6e61637ec8d1d247724328e8c4a6704fe36b468e/_hacks.scssc +0 -0
  314. data/spec/dummy/tmp/sass-cache/77824dc1336af71703311a2e58b21a32c1511e63/_border-radius.scssc +0 -0
  315. data/spec/dummy/tmp/sass-cache/77824dc1336af71703311a2e58b21a32c1511e63/_box-shadow.scssc +0 -0
  316. data/spec/dummy/tmp/sass-cache/77824dc1336af71703311a2e58b21a32c1511e63/_gradient.scssc +0 -0
  317. data/spec/dummy/tmp/sass-cache/77824dc1336af71703311a2e58b21a32c1511e63/_images.scssc +0 -0
  318. data/spec/dummy/tmp/sass-cache/77824dc1336af71703311a2e58b21a32c1511e63/_inline-block.scssc +0 -0
  319. data/spec/dummy/tmp/sass-cache/77824dc1336af71703311a2e58b21a32c1511e63/_shared.scssc +0 -0
  320. data/spec/dummy/tmp/sass-cache/bc54e898614d486bf9338d646e8cd056915d4779/buttons.css.scssc +0 -0
  321. data/spec/dummy/tmp/sass-cache/bc54e898614d486bf9338d646e8cd056915d4779/redactor.css.scssc +0 -0
  322. data/spec/dummy/tmp/sass-cache/d1a1c9c63df53223abb80676ef7dcc16c1375c54/_support.scssc +0 -0
  323. metadata +605 -20
  324. data/spec/dummy/tmp/pids/server.pid +0 -1
@@ -0,0 +1,2334 @@
1
+ /*
2
+ * jQuery UI Widget 1.8.17+amd
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6
+ * Dual licensed under the MIT or GPL Version 2 licenses.
7
+ * http://jquery.org/license
8
+ *
9
+ * http://docs.jquery.com/UI/Widget
10
+ */
11
+
12
+
13
+ (function (factory) {
14
+ if (typeof define === "function" && define.amd) {
15
+ // Register as an anonymous AMD module:
16
+ define(["jquery"], factory);
17
+ } else {
18
+ // Browser globals:
19
+ factory(jQuery);
20
+ }
21
+ }(function( $, undefined ) {
22
+
23
+ // jQuery 1.4+
24
+ if ( $.cleanData ) {
25
+ var _cleanData = $.cleanData;
26
+ $.cleanData = function( elems ) {
27
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
28
+ try {
29
+ $( elem ).triggerHandler( "remove" );
30
+ // http://bugs.jquery.com/ticket/8235
31
+ } catch( e ) {}
32
+ }
33
+ _cleanData( elems );
34
+ };
35
+ } else {
36
+ var _remove = $.fn.remove;
37
+ $.fn.remove = function( selector, keepData ) {
38
+ return this.each(function() {
39
+ if ( !keepData ) {
40
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
41
+ $( "*", this ).add( [ this ] ).each(function() {
42
+ try {
43
+ $( this ).triggerHandler( "remove" );
44
+ // http://bugs.jquery.com/ticket/8235
45
+ } catch( e ) {}
46
+ });
47
+ }
48
+ }
49
+ return _remove.call( $(this), selector, keepData );
50
+ });
51
+ };
52
+ }
53
+
54
+ $.widget = function( name, base, prototype ) {
55
+ var namespace = name.split( "." )[ 0 ],
56
+ fullName;
57
+ name = name.split( "." )[ 1 ];
58
+ fullName = namespace + "-" + name;
59
+
60
+ if ( !prototype ) {
61
+ prototype = base;
62
+ base = $.Widget;
63
+ }
64
+
65
+ // create selector for plugin
66
+ $.expr[ ":" ][ fullName ] = function( elem ) {
67
+ return !!$.data( elem, name );
68
+ };
69
+
70
+ $[ namespace ] = $[ namespace ] || {};
71
+ $[ namespace ][ name ] = function( options, element ) {
72
+ // allow instantiation without initializing for simple inheritance
73
+ if ( arguments.length ) {
74
+ this._createWidget( options, element );
75
+ }
76
+ };
77
+
78
+ var basePrototype = new base();
79
+ // we need to make the options hash a property directly on the new instance
80
+ // otherwise we'll modify the options hash on the prototype that we're
81
+ // inheriting from
82
+ // $.each( basePrototype, function( key, val ) {
83
+ // if ( $.isPlainObject(val) ) {
84
+ // basePrototype[ key ] = $.extend( {}, val );
85
+ // }
86
+ // });
87
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
88
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
89
+ namespace: namespace,
90
+ widgetName: name,
91
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
92
+ widgetBaseClass: fullName
93
+ }, prototype );
94
+
95
+ $.widget.bridge( name, $[ namespace ][ name ] );
96
+ };
97
+
98
+ $.widget.bridge = function( name, object ) {
99
+ $.fn[ name ] = function( options ) {
100
+ var isMethodCall = typeof options === "string",
101
+ args = Array.prototype.slice.call( arguments, 1 ),
102
+ returnValue = this;
103
+
104
+ // allow multiple hashes to be passed on init
105
+ options = !isMethodCall && args.length ?
106
+ $.extend.apply( null, [ true, options ].concat(args) ) :
107
+ options;
108
+
109
+ // prevent calls to internal methods
110
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
111
+ return returnValue;
112
+ }
113
+
114
+ if ( isMethodCall ) {
115
+ this.each(function() {
116
+ var instance = $.data( this, name ),
117
+ methodValue = instance && $.isFunction( instance[options] ) ?
118
+ instance[ options ].apply( instance, args ) :
119
+ instance;
120
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
121
+ // if ( !instance ) {
122
+ // throw "cannot call methods on " + name + " prior to initialization; " +
123
+ // "attempted to call method '" + options + "'";
124
+ // }
125
+ // if ( !$.isFunction( instance[options] ) ) {
126
+ // throw "no such method '" + options + "' for " + name + " widget instance";
127
+ // }
128
+ // var methodValue = instance[ options ].apply( instance, args );
129
+ if ( methodValue !== instance && methodValue !== undefined ) {
130
+ returnValue = methodValue;
131
+ return false;
132
+ }
133
+ });
134
+ } else {
135
+ this.each(function() {
136
+ var instance = $.data( this, name );
137
+ if ( instance ) {
138
+ instance.option( options || {} )._init();
139
+ } else {
140
+ $.data( this, name, new object( options, this ) );
141
+ }
142
+ });
143
+ }
144
+
145
+ return returnValue;
146
+ };
147
+ };
148
+
149
+ $.Widget = function( options, element ) {
150
+ // allow instantiation without initializing for simple inheritance
151
+ if ( arguments.length ) {
152
+ this._createWidget( options, element );
153
+ }
154
+ };
155
+
156
+ $.Widget.prototype = {
157
+ widgetName: "widget",
158
+ widgetEventPrefix: "",
159
+ options: {
160
+ disabled: false
161
+ },
162
+ _createWidget: function( options, element ) {
163
+ // $.widget.bridge stores the plugin instance, but we do it anyway
164
+ // so that it's stored even before the _create function runs
165
+ $.data( element, this.widgetName, this );
166
+ this.element = $( element );
167
+ this.options = $.extend( true, {},
168
+ this.options,
169
+ this._getCreateOptions(),
170
+ options );
171
+
172
+ var self = this;
173
+ this.element.bind( "remove." + this.widgetName, function() {
174
+ self.destroy();
175
+ });
176
+
177
+ this._create();
178
+ this._trigger( "create" );
179
+ this._init();
180
+ },
181
+ _getCreateOptions: function() {
182
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
183
+ },
184
+ _create: function() {},
185
+ _init: function() {},
186
+
187
+ destroy: function() {
188
+ this.element
189
+ .unbind( "." + this.widgetName )
190
+ .removeData( this.widgetName );
191
+ this.widget()
192
+ .unbind( "." + this.widgetName )
193
+ .removeAttr( "aria-disabled" )
194
+ .removeClass(
195
+ this.widgetBaseClass + "-disabled " +
196
+ "ui-state-disabled" );
197
+ },
198
+
199
+ widget: function() {
200
+ return this.element;
201
+ },
202
+
203
+ option: function( key, value ) {
204
+ var options = key;
205
+
206
+ if ( arguments.length === 0 ) {
207
+ // don't return a reference to the internal hash
208
+ return $.extend( {}, this.options );
209
+ }
210
+
211
+ if (typeof key === "string" ) {
212
+ if ( value === undefined ) {
213
+ return this.options[ key ];
214
+ }
215
+ options = {};
216
+ options[ key ] = value;
217
+ }
218
+
219
+ this._setOptions( options );
220
+
221
+ return this;
222
+ },
223
+ _setOptions: function( options ) {
224
+ var self = this;
225
+ $.each( options, function( key, value ) {
226
+ self._setOption( key, value );
227
+ });
228
+
229
+ return this;
230
+ },
231
+ _setOption: function( key, value ) {
232
+ this.options[ key ] = value;
233
+
234
+ if ( key === "disabled" ) {
235
+ this.widget()
236
+ [ value ? "addClass" : "removeClass"](
237
+ this.widgetBaseClass + "-disabled" + " " +
238
+ "ui-state-disabled" )
239
+ .attr( "aria-disabled", value );
240
+ }
241
+
242
+ return this;
243
+ },
244
+
245
+ enable: function() {
246
+ return this._setOption( "disabled", false );
247
+ },
248
+ disable: function() {
249
+ return this._setOption( "disabled", true );
250
+ },
251
+
252
+ _trigger: function( type, event, data ) {
253
+ var prop, orig,
254
+ callback = this.options[ type ];
255
+
256
+ data = data || {};
257
+ event = $.Event( event );
258
+ event.type = ( type === this.widgetEventPrefix ?
259
+ type :
260
+ this.widgetEventPrefix + type ).toLowerCase();
261
+ // the original event may come from any element
262
+ // so we need to reset the target on the new event
263
+ event.target = this.element[ 0 ];
264
+
265
+ // copy original event properties over to the new event
266
+ orig = event.originalEvent;
267
+ if ( orig ) {
268
+ for ( prop in orig ) {
269
+ if ( !( prop in event ) ) {
270
+ event[ prop ] = orig[ prop ];
271
+ }
272
+ }
273
+ }
274
+
275
+ this.element.trigger( event, data );
276
+
277
+ return !( $.isFunction(callback) &&
278
+ callback.call( this.element[0], event, data ) === false ||
279
+ event.isDefaultPrevented() );
280
+ }
281
+ };
282
+
283
+ }));
284
+ /*
285
+ * jQuery Iframe Transport Plugin 1.3
286
+ * https://github.com/blueimp/jQuery-File-Upload
287
+ *
288
+ * Copyright 2011, Sebastian Tschan
289
+ * https://blueimp.net
290
+ *
291
+ * Licensed under the MIT license:
292
+ * http://www.opensource.org/licenses/MIT
293
+ */
294
+
295
+ /*jslint unparam: true, nomen: true */
296
+ /*global define, window, document */
297
+
298
+
299
+ (function (factory) {
300
+ 'use strict';
301
+ if (typeof define === 'function' && define.amd) {
302
+ // Register as an anonymous AMD module:
303
+ define(['jquery'], factory);
304
+ } else {
305
+ // Browser globals:
306
+ factory(window.jQuery);
307
+ }
308
+ }(function ($) {
309
+ 'use strict';
310
+
311
+ // Helper variable to create unique names for the transport iframes:
312
+ var counter = 0;
313
+
314
+ // The iframe transport accepts three additional options:
315
+ // options.fileInput: a jQuery collection of file input fields
316
+ // options.paramName: the parameter name for the file form data,
317
+ // overrides the name property of the file input field(s)
318
+ // options.formData: an array of objects with name and value properties,
319
+ // equivalent to the return data of .serializeArray(), e.g.:
320
+ // [{name: 'a', value: 1}, {name: 'b', value: 2}]
321
+ $.ajaxTransport('iframe', function (options) {
322
+ if (options.async && (options.type === 'POST' || options.type === 'GET')) {
323
+ var form,
324
+ iframe;
325
+ return {
326
+ send: function (_, completeCallback) {
327
+ form = $('<form style="display:none;"></form>');
328
+ // javascript:false as initial iframe src
329
+ // prevents warning popups on HTTPS in IE6.
330
+ // IE versions below IE8 cannot set the name property of
331
+ // elements that have already been added to the DOM,
332
+ // so we set the name along with the iframe HTML markup:
333
+ iframe = $(
334
+ '<iframe src="javascript:false;" name="iframe-transport-' +
335
+ (counter += 1) + '"></iframe>'
336
+ ).bind('load', function () {
337
+ var fileInputClones;
338
+ iframe
339
+ .unbind('load')
340
+ .bind('load', function () {
341
+ var response;
342
+ // Wrap in a try/catch block to catch exceptions thrown
343
+ // when trying to access cross-domain iframe contents:
344
+ try {
345
+ response = iframe.contents();
346
+ // Google Chrome and Firefox do not throw an
347
+ // exception when calling iframe.contents() on
348
+ // cross-domain requests, so we unify the response:
349
+ if (!response.length || !response[0].firstChild) {
350
+ throw new Error();
351
+ }
352
+ } catch (e) {
353
+ response = undefined;
354
+ }
355
+ // The complete callback returns the
356
+ // iframe content document as response object:
357
+ completeCallback(
358
+ 200,
359
+ 'success',
360
+ {'iframe': response}
361
+ );
362
+ // Fix for IE endless progress bar activity bug
363
+ // (happens on form submits to iframe targets):
364
+ $('<iframe src="javascript:false;"></iframe>')
365
+ .appendTo(form);
366
+ form.remove();
367
+ });
368
+ form
369
+ .prop('target', iframe.prop('name'))
370
+ .prop('action', options.url)
371
+ .prop('method', options.type);
372
+ if (options.formData) {
373
+ $.each(options.formData, function (index, field) {
374
+ $('<input type="hidden"/>')
375
+ .prop('name', field.name)
376
+ .val(field.value)
377
+ .appendTo(form);
378
+ });
379
+ }
380
+ if (options.fileInput && options.fileInput.length &&
381
+ options.type === 'POST') {
382
+ fileInputClones = options.fileInput.clone();
383
+ // Insert a clone for each file input field:
384
+ options.fileInput.after(function (index) {
385
+ return fileInputClones[index];
386
+ });
387
+ if (options.paramName) {
388
+ options.fileInput.each(function () {
389
+ $(this).prop('name', options.paramName);
390
+ });
391
+ }
392
+ // Appending the file input fields to the hidden form
393
+ // removes them from their original location:
394
+ form
395
+ .append(options.fileInput)
396
+ .prop('enctype', 'multipart/form-data')
397
+ // enctype must be set as encoding for IE:
398
+ .prop('encoding', 'multipart/form-data');
399
+ }
400
+ form.submit();
401
+ // Insert the file input fields at their original location
402
+ // by replacing the clones with the originals:
403
+ if (fileInputClones && fileInputClones.length) {
404
+ options.fileInput.each(function (index, input) {
405
+ var clone = $(fileInputClones[index]);
406
+ $(input).prop('name', clone.prop('name'));
407
+ clone.replaceWith(input);
408
+ });
409
+ }
410
+ });
411
+ form.append(iframe).appendTo(document.body);
412
+ },
413
+ abort: function () {
414
+ if (iframe) {
415
+ // javascript:false as iframe src aborts the request
416
+ // and prevents warning popups on HTTPS in IE6.
417
+ // concat is used to avoid the "Script URL" JSLint error:
418
+ iframe
419
+ .unbind('load')
420
+ .prop('src', 'javascript'.concat(':false;'));
421
+ }
422
+ if (form) {
423
+ form.remove();
424
+ }
425
+ }
426
+ };
427
+ }
428
+ });
429
+
430
+ // The iframe transport returns the iframe content document as response.
431
+ // The following adds converters from iframe to text, json, html, and script:
432
+ $.ajaxSetup({
433
+ converters: {
434
+ 'iframe text': function (iframe) {
435
+ return $(iframe[0].body).text();
436
+ },
437
+ 'iframe json': function (iframe) {
438
+ return $.parseJSON($(iframe[0].body).text());
439
+ },
440
+ 'iframe html': function (iframe) {
441
+ return $(iframe[0].body).html();
442
+ },
443
+ 'iframe script': function (iframe) {
444
+ return $.globalEval($(iframe[0].body).text());
445
+ }
446
+ }
447
+ });
448
+
449
+ }));
450
+ /*
451
+ * jQuery File Upload Plugin 5.7
452
+ * https://github.com/blueimp/jQuery-File-Upload
453
+ *
454
+ * Copyright 2010, Sebastian Tschan
455
+ * https://blueimp.net
456
+ *
457
+ * Licensed under the MIT license:
458
+ * http://www.opensource.org/licenses/MIT
459
+ */
460
+
461
+ /*jslint nomen: true, unparam: true, regexp: true */
462
+ /*global define, window, document, XMLHttpRequestUpload, Blob, File, FormData, location */
463
+
464
+
465
+ (function (factory) {
466
+ 'use strict';
467
+ if (typeof define === 'function' && define.amd) {
468
+ // Register as an anonymous AMD module:
469
+ define([
470
+ 'jquery',
471
+ './vendor/jquery.ui.widget',
472
+ './jquery.iframe-transport'
473
+ ], factory);
474
+ } else {
475
+ // Browser globals:
476
+ factory(window.jQuery);
477
+ }
478
+ }(function ($) {
479
+ 'use strict';
480
+
481
+ // The fileupload widget listens for change events on file input fields defined
482
+ // via fileInput setting and paste or drop events of the given dropZone.
483
+ // In addition to the default jQuery Widget methods, the fileupload widget
484
+ // exposes the "add" and "send" methods, to add or directly send files using
485
+ // the fileupload API.
486
+ // By default, files added via file input selection, paste, drag & drop or
487
+ // "add" method are uploaded immediately, but it is possible to override
488
+ // the "add" callback option to queue file uploads.
489
+ $.widget('blueimp.fileupload', {
490
+
491
+ options: {
492
+ // The namespace used for event handler binding on the dropZone and
493
+ // fileInput collections.
494
+ // If not set, the name of the widget ("fileupload") is used.
495
+ namespace: undefined,
496
+ // The drop target collection, by the default the complete document.
497
+ // Set to null or an empty collection to disable drag & drop support:
498
+ dropZone: $(document),
499
+ // The file input field collection, that is listened for change events.
500
+ // If undefined, it is set to the file input fields inside
501
+ // of the widget element on plugin initialization.
502
+ // Set to null or an empty collection to disable the change listener.
503
+ fileInput: undefined,
504
+ // By default, the file input field is replaced with a clone after
505
+ // each input field change event. This is required for iframe transport
506
+ // queues and allows change events to be fired for the same file
507
+ // selection, but can be disabled by setting the following option to false:
508
+ replaceFileInput: true,
509
+ // The parameter name for the file form data (the request argument name).
510
+ // If undefined or empty, the name property of the file input field is
511
+ // used, or "files[]" if the file input name property is also empty:
512
+ paramName: undefined,
513
+ // By default, each file of a selection is uploaded using an individual
514
+ // request for XHR type uploads. Set to false to upload file
515
+ // selections in one request each:
516
+ singleFileUploads: true,
517
+ // To limit the number of files uploaded with one XHR request,
518
+ // set the following option to an integer greater than 0:
519
+ limitMultiFileUploads: undefined,
520
+ // Set the following option to true to issue all file upload requests
521
+ // in a sequential order:
522
+ sequentialUploads: false,
523
+ // To limit the number of concurrent uploads,
524
+ // set the following option to an integer greater than 0:
525
+ limitConcurrentUploads: undefined,
526
+ // Set the following option to true to force iframe transport uploads:
527
+ forceIframeTransport: false,
528
+ // Set the following option to the location of a redirect url on the
529
+ // origin server, for cross-domain iframe transport uploads:
530
+ redirect: undefined,
531
+ // The parameter name for the redirect url, sent as part of the form
532
+ // data and set to 'redirect' if this option is empty:
533
+ redirectParamName: undefined,
534
+ // Set the following option to the location of a postMessage window,
535
+ // to enable postMessage transport uploads:
536
+ postMessage: undefined,
537
+ // By default, XHR file uploads are sent as multipart/form-data.
538
+ // The iframe transport is always using multipart/form-data.
539
+ // Set to false to enable non-multipart XHR uploads:
540
+ multipart: true,
541
+ // To upload large files in smaller chunks, set the following option
542
+ // to a preferred maximum chunk size. If set to 0, null or undefined,
543
+ // or the browser does not support the required Blob API, files will
544
+ // be uploaded as a whole.
545
+ maxChunkSize: undefined,
546
+ // When a non-multipart upload or a chunked multipart upload has been
547
+ // aborted, this option can be used to resume the upload by setting
548
+ // it to the size of the already uploaded bytes. This option is most
549
+ // useful when modifying the options object inside of the "add" or
550
+ // "send" callbacks, as the options are cloned for each file upload.
551
+ uploadedBytes: undefined,
552
+ // By default, failed (abort or error) file uploads are removed from the
553
+ // global progress calculation. Set the following option to false to
554
+ // prevent recalculating the global progress data:
555
+ recalculateProgress: true,
556
+
557
+ // Additional form data to be sent along with the file uploads can be set
558
+ // using this option, which accepts an array of objects with name and
559
+ // value properties, a function returning such an array, a FormData
560
+ // object (for XHR file uploads), or a simple object.
561
+ // The form of the first fileInput is given as parameter to the function:
562
+ formData: function (form) {
563
+ return form.serializeArray();
564
+ },
565
+
566
+ // The add callback is invoked as soon as files are added to the fileupload
567
+ // widget (via file input selection, drag & drop, paste or add API call).
568
+ // If the singleFileUploads option is enabled, this callback will be
569
+ // called once for each file in the selection for XHR file uplaods, else
570
+ // once for each file selection.
571
+ // The upload starts when the submit method is invoked on the data parameter.
572
+ // The data object contains a files property holding the added files
573
+ // and allows to override plugin options as well as define ajax settings.
574
+ // Listeners for this callback can also be bound the following way:
575
+ // .bind('fileuploadadd', func);
576
+ // data.submit() returns a Promise object and allows to attach additional
577
+ // handlers using jQuery's Deferred callbacks:
578
+ // data.submit().done(func).fail(func).always(func);
579
+ add: function (e, data) {
580
+ data.submit();
581
+ },
582
+
583
+ // Other callbacks:
584
+ // Callback for the submit event of each file upload:
585
+ // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
586
+ // Callback for the start of each file upload request:
587
+ // send: function (e, data) {}, // .bind('fileuploadsend', func);
588
+ // Callback for successful uploads:
589
+ // done: function (e, data) {}, // .bind('fileuploaddone', func);
590
+ // Callback for failed (abort or error) uploads:
591
+ // fail: function (e, data) {}, // .bind('fileuploadfail', func);
592
+ // Callback for completed (success, abort or error) requests:
593
+ // always: function (e, data) {}, // .bind('fileuploadalways', func);
594
+ // Callback for upload progress events:
595
+ // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
596
+ // Callback for global upload progress events:
597
+ // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
598
+ // Callback for uploads start, equivalent to the global ajaxStart event:
599
+ // start: function (e) {}, // .bind('fileuploadstart', func);
600
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
601
+ // stop: function (e) {}, // .bind('fileuploadstop', func);
602
+ // Callback for change events of the fileInput collection:
603
+ // change: function (e, data) {}, // .bind('fileuploadchange', func);
604
+ // Callback for paste events to the dropZone collection:
605
+ // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
606
+ // Callback for drop events of the dropZone collection:
607
+ // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
608
+ // Callback for dragover events of the dropZone collection:
609
+ // dragover: function (e) {}, // .bind('fileuploaddragover', func);
610
+
611
+ // The plugin options are used as settings object for the ajax calls.
612
+ // The following are jQuery ajax settings required for the file uploads:
613
+ processData: false,
614
+ contentType: false,
615
+ cache: false
616
+ },
617
+
618
+ // A list of options that require a refresh after assigning a new value:
619
+ _refreshOptionsList: ['namespace', 'dropZone', 'fileInput'],
620
+
621
+ _isXHRUpload: function (options) {
622
+ var undef = 'undefined';
623
+ return !options.forceIframeTransport &&
624
+ typeof XMLHttpRequestUpload !== undef && typeof File !== undef &&
625
+ (!options.multipart || typeof FormData !== undef);
626
+ },
627
+
628
+ _getFormData: function (options) {
629
+ var formData;
630
+ if (typeof options.formData === 'function') {
631
+ return options.formData(options.form);
632
+ } else if ($.isArray(options.formData)) {
633
+ return options.formData;
634
+ } else if (options.formData) {
635
+ formData = [];
636
+ $.each(options.formData, function (name, value) {
637
+ formData.push({name: name, value: value});
638
+ });
639
+ return formData;
640
+ }
641
+ return [];
642
+ },
643
+
644
+ _getTotal: function (files) {
645
+ var total = 0;
646
+ $.each(files, function (index, file) {
647
+ total += file.size || 1;
648
+ });
649
+ return total;
650
+ },
651
+
652
+ _onProgress: function (e, data) {
653
+ if (e.lengthComputable) {
654
+ var total = data.total || this._getTotal(data.files),
655
+ loaded = parseInt(
656
+ e.loaded / e.total * (data.chunkSize || total),
657
+ 10
658
+ ) + (data.uploadedBytes || 0);
659
+ this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
660
+ data.lengthComputable = true;
661
+ data.loaded = loaded;
662
+ data.total = total;
663
+ // Trigger a custom progress event with a total data property set
664
+ // to the file size(s) of the current upload and a loaded data
665
+ // property calculated accordingly:
666
+ this._trigger('progress', e, data);
667
+ // Trigger a global progress event for all current file uploads,
668
+ // including ajax calls queued for sequential file uploads:
669
+ this._trigger('progressall', e, {
670
+ lengthComputable: true,
671
+ loaded: this._loaded,
672
+ total: this._total
673
+ });
674
+ }
675
+ },
676
+
677
+ _initProgressListener: function (options) {
678
+ var that = this,
679
+ xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
680
+ // Accesss to the native XHR object is required to add event listeners
681
+ // for the upload progress event:
682
+ if (xhr.upload) {
683
+ $(xhr.upload).bind('progress', function (e) {
684
+ var oe = e.originalEvent;
685
+ // Make sure the progress event properties get copied over:
686
+ e.lengthComputable = oe.lengthComputable;
687
+ e.loaded = oe.loaded;
688
+ e.total = oe.total;
689
+ that._onProgress(e, options);
690
+ });
691
+ options.xhr = function () {
692
+ return xhr;
693
+ };
694
+ }
695
+ },
696
+
697
+ _initXHRData: function (options) {
698
+ var formData,
699
+ file = options.files[0];
700
+ if (!options.multipart || options.blob) {
701
+ // For non-multipart uploads and chunked uploads,
702
+ // file meta data is not part of the request body,
703
+ // so we transmit this data as part of the HTTP headers.
704
+ // For cross domain requests, these headers must be allowed
705
+ // via Access-Control-Allow-Headers or removed using
706
+ // the beforeSend callback:
707
+ options.headers = $.extend(options.headers, {
708
+ 'X-File-Name': file.name,
709
+ 'X-File-Type': file.type,
710
+ 'X-File-Size': file.size
711
+ });
712
+ if (!options.blob) {
713
+ // Non-chunked non-multipart upload:
714
+ options.contentType = file.type;
715
+ options.data = file;
716
+ } else if (!options.multipart) {
717
+ // Chunked non-multipart upload:
718
+ options.contentType = 'application/octet-stream';
719
+ options.data = options.blob;
720
+ }
721
+ }
722
+ if (options.multipart && typeof FormData !== 'undefined') {
723
+ if (options.postMessage) {
724
+ // window.postMessage does not allow sending FormData
725
+ // objects, so we just add the File/Blob objects to
726
+ // the formData array and let the postMessage window
727
+ // create the FormData object out of this array:
728
+ formData = this._getFormData(options);
729
+ if (options.blob) {
730
+ formData.push({
731
+ name: options.paramName,
732
+ value: options.blob
733
+ });
734
+ } else {
735
+ $.each(options.files, function (index, file) {
736
+ formData.push({
737
+ name: options.paramName,
738
+ value: file
739
+ });
740
+ });
741
+ }
742
+ } else {
743
+ if (options.formData instanceof FormData) {
744
+ formData = options.formData;
745
+ } else {
746
+ formData = new FormData();
747
+ $.each(this._getFormData(options), function (index, field) {
748
+ formData.append(field.name, field.value);
749
+ });
750
+ }
751
+ if (options.blob) {
752
+ formData.append(options.paramName, options.blob, file.name);
753
+ } else {
754
+ $.each(options.files, function (index, file) {
755
+ // File objects are also Blob instances.
756
+ // This check allows the tests to run with
757
+ // dummy objects:
758
+ if (file instanceof Blob) {
759
+ formData.append(options.paramName, file, file.name);
760
+ }
761
+ });
762
+ }
763
+ }
764
+ options.data = formData;
765
+ }
766
+ // Blob reference is not needed anymore, free memory:
767
+ options.blob = null;
768
+ },
769
+
770
+ _initIframeSettings: function (options) {
771
+ // Setting the dataType to iframe enables the iframe transport:
772
+ options.dataType = 'iframe ' + (options.dataType || '');
773
+ // The iframe transport accepts a serialized array as form data:
774
+ options.formData = this._getFormData(options);
775
+ // Add redirect url to form data on cross-domain uploads:
776
+ if (options.redirect && $('<a></a>').prop('href', options.url)
777
+ .prop('host') !== location.host) {
778
+ options.formData.push({
779
+ name: options.redirectParamName || 'redirect',
780
+ value: options.redirect
781
+ });
782
+ }
783
+ },
784
+
785
+ _initDataSettings: function (options) {
786
+ if (this._isXHRUpload(options)) {
787
+ if (!this._chunkedUpload(options, true)) {
788
+ if (!options.data) {
789
+ this._initXHRData(options);
790
+ }
791
+ this._initProgressListener(options);
792
+ }
793
+ if (options.postMessage) {
794
+ // Setting the dataType to postmessage enables the
795
+ // postMessage transport:
796
+ options.dataType = 'postmessage ' + (options.dataType || '');
797
+ }
798
+ } else {
799
+ this._initIframeSettings(options, 'iframe');
800
+ }
801
+ },
802
+
803
+ _initFormSettings: function (options) {
804
+ // Retrieve missing options from the input field and the
805
+ // associated form, if available:
806
+ if (!options.form || !options.form.length) {
807
+ options.form = $(options.fileInput.prop('form'));
808
+ }
809
+ if (!options.paramName) {
810
+ options.paramName = options.fileInput.prop('name') ||
811
+ 'files[]';
812
+ }
813
+ if (!options.url) {
814
+ options.url = options.form.prop('action') || location.href;
815
+ }
816
+ // The HTTP request method must be "POST" or "PUT":
817
+ options.type = (options.type || options.form.prop('method') || '')
818
+ .toUpperCase();
819
+ if (options.type !== 'POST' && options.type !== 'PUT') {
820
+ options.type = 'POST';
821
+ }
822
+ },
823
+
824
+ _getAJAXSettings: function (data) {
825
+ var options = $.extend({}, this.options, data);
826
+ this._initFormSettings(options);
827
+ this._initDataSettings(options);
828
+ return options;
829
+ },
830
+
831
+ // Maps jqXHR callbacks to the equivalent
832
+ // methods of the given Promise object:
833
+ _enhancePromise: function (promise) {
834
+ promise.success = promise.done;
835
+ promise.error = promise.fail;
836
+ promise.complete = promise.always;
837
+ return promise;
838
+ },
839
+
840
+ // Creates and returns a Promise object enhanced with
841
+ // the jqXHR methods abort, success, error and complete:
842
+ _getXHRPromise: function (resolveOrReject, context, args) {
843
+ var dfd = $.Deferred(),
844
+ promise = dfd.promise();
845
+ context = context || this.options.context || promise;
846
+ if (resolveOrReject === true) {
847
+ dfd.resolveWith(context, args);
848
+ } else if (resolveOrReject === false) {
849
+ dfd.rejectWith(context, args);
850
+ }
851
+ promise.abort = dfd.promise;
852
+ return this._enhancePromise(promise);
853
+ },
854
+
855
+ // Uploads a file in multiple, sequential requests
856
+ // by splitting the file up in multiple blob chunks.
857
+ // If the second parameter is true, only tests if the file
858
+ // should be uploaded in chunks, but does not invoke any
859
+ // upload requests:
860
+ _chunkedUpload: function (options, testOnly) {
861
+ var that = this,
862
+ file = options.files[0],
863
+ fs = file.size,
864
+ ub = options.uploadedBytes = options.uploadedBytes || 0,
865
+ mcs = options.maxChunkSize || fs,
866
+ // Use the Blob methods with the slice implementation
867
+ // according to the W3C Blob API specification:
868
+ slice = file.webkitSlice || file.mozSlice || file.slice,
869
+ upload,
870
+ n,
871
+ jqXHR,
872
+ pipe;
873
+ if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
874
+ options.data) {
875
+ return false;
876
+ }
877
+ if (testOnly) {
878
+ return true;
879
+ }
880
+ if (ub >= fs) {
881
+ file.error = 'uploadedBytes';
882
+ return this._getXHRPromise(
883
+ false,
884
+ options.context,
885
+ [null, 'error', file.error]
886
+ );
887
+ }
888
+ // n is the number of blobs to upload,
889
+ // calculated via filesize, uploaded bytes and max chunk size:
890
+ n = Math.ceil((fs - ub) / mcs);
891
+ // The chunk upload method accepting the chunk number as parameter:
892
+ upload = function (i) {
893
+ if (!i) {
894
+ return that._getXHRPromise(true, options.context);
895
+ }
896
+ // Upload the blobs in sequential order:
897
+ return upload(i -= 1).pipe(function () {
898
+ // Clone the options object for each chunk upload:
899
+ var o = $.extend({}, options);
900
+ o.blob = slice.call(
901
+ file,
902
+ ub + i * mcs,
903
+ ub + (i + 1) * mcs
904
+ );
905
+ // Store the current chunk size, as the blob itself
906
+ // will be dereferenced after data processing:
907
+ o.chunkSize = o.blob.size;
908
+ // Process the upload data (the blob and potential form data):
909
+ that._initXHRData(o);
910
+ // Add progress listeners for this chunk upload:
911
+ that._initProgressListener(o);
912
+ jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
913
+ .done(function () {
914
+ // Create a progress event if upload is done and
915
+ // no progress event has been invoked for this chunk:
916
+ if (!o.loaded) {
917
+ that._onProgress($.Event('progress', {
918
+ lengthComputable: true,
919
+ loaded: o.chunkSize,
920
+ total: o.chunkSize
921
+ }), o);
922
+ }
923
+ options.uploadedBytes = o.uploadedBytes +=
924
+ o.chunkSize;
925
+ });
926
+ return jqXHR;
927
+ });
928
+ };
929
+ // Return the piped Promise object, enhanced with an abort method,
930
+ // which is delegated to the jqXHR object of the current upload,
931
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
932
+ pipe = upload(n);
933
+ pipe.abort = function () {
934
+ return jqXHR.abort();
935
+ };
936
+ return this._enhancePromise(pipe);
937
+ },
938
+
939
+ _beforeSend: function (e, data) {
940
+ if (this._active === 0) {
941
+ // the start callback is triggered when an upload starts
942
+ // and no other uploads are currently running,
943
+ // equivalent to the global ajaxStart event:
944
+ this._trigger('start');
945
+ }
946
+ this._active += 1;
947
+ // Initialize the global progress values:
948
+ this._loaded += data.uploadedBytes || 0;
949
+ this._total += this._getTotal(data.files);
950
+ },
951
+
952
+ _onDone: function (result, textStatus, jqXHR, options) {
953
+ if (!this._isXHRUpload(options)) {
954
+ // Create a progress event for each iframe load:
955
+ this._onProgress($.Event('progress', {
956
+ lengthComputable: true,
957
+ loaded: 1,
958
+ total: 1
959
+ }), options);
960
+ }
961
+ options.result = result;
962
+ options.textStatus = textStatus;
963
+ options.jqXHR = jqXHR;
964
+ this._trigger('done', null, options);
965
+ },
966
+
967
+ _onFail: function (jqXHR, textStatus, errorThrown, options) {
968
+ options.jqXHR = jqXHR;
969
+ options.textStatus = textStatus;
970
+ options.errorThrown = errorThrown;
971
+ this._trigger('fail', null, options);
972
+ if (options.recalculateProgress) {
973
+ // Remove the failed (error or abort) file upload from
974
+ // the global progress calculation:
975
+ this._loaded -= options.loaded || options.uploadedBytes || 0;
976
+ this._total -= options.total || this._getTotal(options.files);
977
+ }
978
+ },
979
+
980
+ _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
981
+ this._active -= 1;
982
+ options.textStatus = textStatus;
983
+ if (jqXHRorError && jqXHRorError.always) {
984
+ options.jqXHR = jqXHRorError;
985
+ options.result = jqXHRorResult;
986
+ } else {
987
+ options.jqXHR = jqXHRorResult;
988
+ options.errorThrown = jqXHRorError;
989
+ }
990
+ this._trigger('always', null, options);
991
+ if (this._active === 0) {
992
+ // The stop callback is triggered when all uploads have
993
+ // been completed, equivalent to the global ajaxStop event:
994
+ this._trigger('stop');
995
+ // Reset the global progress values:
996
+ this._loaded = this._total = 0;
997
+ }
998
+ },
999
+
1000
+ _onSend: function (e, data) {
1001
+ var that = this,
1002
+ jqXHR,
1003
+ slot,
1004
+ pipe,
1005
+ options = that._getAJAXSettings(data),
1006
+ send = function (resolve, args) {
1007
+ that._sending += 1;
1008
+ jqXHR = jqXHR || (
1009
+ (resolve !== false &&
1010
+ that._trigger('send', e, options) !== false &&
1011
+ (that._chunkedUpload(options) || $.ajax(options))) ||
1012
+ that._getXHRPromise(false, options.context, args)
1013
+ ).done(function (result, textStatus, jqXHR) {
1014
+ that._onDone(result, textStatus, jqXHR, options);
1015
+ }).fail(function (jqXHR, textStatus, errorThrown) {
1016
+ that._onFail(jqXHR, textStatus, errorThrown, options);
1017
+ }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
1018
+ that._sending -= 1;
1019
+ that._onAlways(
1020
+ jqXHRorResult,
1021
+ textStatus,
1022
+ jqXHRorError,
1023
+ options
1024
+ );
1025
+ if (options.limitConcurrentUploads &&
1026
+ options.limitConcurrentUploads > that._sending) {
1027
+ // Start the next queued upload,
1028
+ // that has not been aborted:
1029
+ var nextSlot = that._slots.shift();
1030
+ while (nextSlot) {
1031
+ if (!nextSlot.isRejected()) {
1032
+ nextSlot.resolve();
1033
+ break;
1034
+ }
1035
+ nextSlot = that._slots.shift();
1036
+ }
1037
+ }
1038
+ });
1039
+ return jqXHR;
1040
+ };
1041
+ this._beforeSend(e, options);
1042
+ if (this.options.sequentialUploads ||
1043
+ (this.options.limitConcurrentUploads &&
1044
+ this.options.limitConcurrentUploads <= this._sending)) {
1045
+ if (this.options.limitConcurrentUploads > 1) {
1046
+ slot = $.Deferred();
1047
+ this._slots.push(slot);
1048
+ pipe = slot.pipe(send);
1049
+ } else {
1050
+ pipe = (this._sequence = this._sequence.pipe(send, send));
1051
+ }
1052
+ // Return the piped Promise object, enhanced with an abort method,
1053
+ // which is delegated to the jqXHR object of the current upload,
1054
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
1055
+ pipe.abort = function () {
1056
+ var args = [undefined, 'abort', 'abort'];
1057
+ if (!jqXHR) {
1058
+ if (slot) {
1059
+ slot.rejectWith(args);
1060
+ }
1061
+ return send(false, args);
1062
+ }
1063
+ return jqXHR.abort();
1064
+ };
1065
+ return this._enhancePromise(pipe);
1066
+ }
1067
+ return send();
1068
+ },
1069
+
1070
+ _onAdd: function (e, data) {
1071
+ var that = this,
1072
+ result = true,
1073
+ options = $.extend({}, this.options, data),
1074
+ limit = options.limitMultiFileUploads,
1075
+ fileSet,
1076
+ i;
1077
+ if (!(options.singleFileUploads || limit) ||
1078
+ !this._isXHRUpload(options)) {
1079
+ fileSet = [data.files];
1080
+ } else if (!options.singleFileUploads && limit) {
1081
+ fileSet = [];
1082
+ for (i = 0; i < data.files.length; i += limit) {
1083
+ fileSet.push(data.files.slice(i, i + limit));
1084
+ }
1085
+ }
1086
+ data.originalFiles = data.files;
1087
+ $.each(fileSet || data.files, function (index, element) {
1088
+ var files = fileSet ? element : [element],
1089
+ newData = $.extend({}, data, {files: files});
1090
+ newData.submit = function () {
1091
+ newData.jqXHR = this.jqXHR =
1092
+ (that._trigger('submit', e, this) !== false) &&
1093
+ that._onSend(e, this);
1094
+ return this.jqXHR;
1095
+ };
1096
+ return (result = that._trigger('add', e, newData));
1097
+ });
1098
+ return result;
1099
+ },
1100
+
1101
+ // File Normalization for Gecko 1.9.1 (Firefox 3.5) support:
1102
+ _normalizeFile: function (index, file) {
1103
+ if (file.name === undefined && file.size === undefined) {
1104
+ file.name = file.fileName;
1105
+ file.size = file.fileSize;
1106
+ }
1107
+ },
1108
+
1109
+ _replaceFileInput: function (input) {
1110
+ var inputClone = input.clone(true);
1111
+ $('<form></form>').append(inputClone)[0].reset();
1112
+ // Detaching allows to insert the fileInput on another form
1113
+ // without loosing the file input value:
1114
+ input.after(inputClone).detach();
1115
+ // Avoid memory leaks with the detached file input:
1116
+ $.cleanData(input.unbind('remove'));
1117
+ // Replace the original file input element in the fileInput
1118
+ // collection with the clone, which has been copied including
1119
+ // event handlers:
1120
+ this.options.fileInput = this.options.fileInput.map(function (i, el) {
1121
+ if (el === input[0]) {
1122
+ return inputClone[0];
1123
+ }
1124
+ return el;
1125
+ });
1126
+ // If the widget has been initialized on the file input itself,
1127
+ // override this.element with the file input clone:
1128
+ if (input[0] === this.element[0]) {
1129
+ this.element = inputClone;
1130
+ }
1131
+ },
1132
+
1133
+ _onChange: function (e) {
1134
+ var that = e.data.fileupload,
1135
+ data = {
1136
+ files: $.each($.makeArray(e.target.files), that._normalizeFile),
1137
+ fileInput: $(e.target),
1138
+ form: $(e.target.form)
1139
+ };
1140
+ if (!data.files.length) {
1141
+ // If the files property is not available, the browser does not
1142
+ // support the File API and we add a pseudo File object with
1143
+ // the input value as name with path information removed:
1144
+ data.files = [{name: e.target.value.replace(/^.*\\/, '')}];
1145
+ }
1146
+ if (that.options.replaceFileInput) {
1147
+ that._replaceFileInput(data.fileInput);
1148
+ }
1149
+ if (that._trigger('change', e, data) === false ||
1150
+ that._onAdd(e, data) === false) {
1151
+ return false;
1152
+ }
1153
+ },
1154
+
1155
+ _onPaste: function (e) {
1156
+ var that = e.data.fileupload,
1157
+ cbd = e.originalEvent.clipboardData,
1158
+ items = (cbd && cbd.items) || [],
1159
+ data = {files: []};
1160
+ $.each(items, function (index, item) {
1161
+ var file = item.getAsFile && item.getAsFile();
1162
+ if (file) {
1163
+ data.files.push(file);
1164
+ }
1165
+ });
1166
+ if (that._trigger('paste', e, data) === false ||
1167
+ that._onAdd(e, data) === false) {
1168
+ return false;
1169
+ }
1170
+ },
1171
+
1172
+ _onDrop: function (e) {
1173
+ var that = e.data.fileupload,
1174
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
1175
+ data = {
1176
+ files: $.each(
1177
+ $.makeArray(dataTransfer && dataTransfer.files),
1178
+ that._normalizeFile
1179
+ )
1180
+ };
1181
+ if (that._trigger('drop', e, data) === false ||
1182
+ that._onAdd(e, data) === false) {
1183
+ return false;
1184
+ }
1185
+ e.preventDefault();
1186
+ },
1187
+
1188
+ _onDragOver: function (e) {
1189
+ var that = e.data.fileupload,
1190
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
1191
+ if (that._trigger('dragover', e) === false) {
1192
+ return false;
1193
+ }
1194
+ if (dataTransfer) {
1195
+ dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
1196
+ }
1197
+ e.preventDefault();
1198
+ },
1199
+
1200
+ _initEventHandlers: function () {
1201
+ var ns = this.options.namespace;
1202
+ this.options.dropZone
1203
+ .bind('dragover.' + ns, {fileupload: this}, this._onDragOver)
1204
+ .bind('drop.' + ns, {fileupload: this}, this._onDrop)
1205
+ .bind('paste.' + ns, {fileupload: this}, this._onPaste);
1206
+ this.options.fileInput
1207
+ .bind('change.' + ns, {fileupload: this}, this._onChange);
1208
+ },
1209
+
1210
+ _destroyEventHandlers: function () {
1211
+ var ns = this.options.namespace;
1212
+ this.options.dropZone
1213
+ .unbind('dragover.' + ns, this._onDragOver)
1214
+ .unbind('drop.' + ns, this._onDrop)
1215
+ .unbind('paste.' + ns, this._onPaste);
1216
+ this.options.fileInput
1217
+ .unbind('change.' + ns, this._onChange);
1218
+ },
1219
+
1220
+ _beforeSetOption: function (key, value) {
1221
+ this._destroyEventHandlers();
1222
+ },
1223
+
1224
+ _afterSetOption: function (key, value) {
1225
+ var options = this.options;
1226
+ if (!options.fileInput) {
1227
+ options.fileInput = $();
1228
+ }
1229
+ if (!options.dropZone) {
1230
+ options.dropZone = $();
1231
+ }
1232
+ this._initEventHandlers();
1233
+ },
1234
+
1235
+ _setOption: function (key, value) {
1236
+ var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
1237
+ if (refresh) {
1238
+ this._beforeSetOption(key, value);
1239
+ }
1240
+ $.Widget.prototype._setOption.call(this, key, value);
1241
+ if (refresh) {
1242
+ this._afterSetOption(key, value);
1243
+ }
1244
+ },
1245
+
1246
+ _create: function () {
1247
+ var options = this.options;
1248
+ options.namespace = options.namespace || this.widgetName;
1249
+ if (options.fileInput === undefined) {
1250
+ options.fileInput = this.element.is('input:file') ?
1251
+ this.element : this.element.find('input:file');
1252
+ } else if (!options.fileInput) {
1253
+ options.fileInput = $();
1254
+ }
1255
+ if (!options.dropZone) {
1256
+ options.dropZone = $();
1257
+ }
1258
+ this._slots = [];
1259
+ this._sequence = this._getXHRPromise(true);
1260
+ this._sending = this._active = this._loaded = this._total = 0;
1261
+ this._initEventHandlers();
1262
+ },
1263
+
1264
+ destroy: function () {
1265
+ this._destroyEventHandlers();
1266
+ $.Widget.prototype.destroy.call(this);
1267
+ },
1268
+
1269
+ enable: function () {
1270
+ $.Widget.prototype.enable.call(this);
1271
+ this._initEventHandlers();
1272
+ },
1273
+
1274
+ disable: function () {
1275
+ this._destroyEventHandlers();
1276
+ $.Widget.prototype.disable.call(this);
1277
+ },
1278
+
1279
+ // This method is exposed to the widget API and allows adding files
1280
+ // using the fileupload API. The data parameter accepts an object which
1281
+ // must have a files property and can contain additional options:
1282
+ // .fileupload('add', {files: filesList});
1283
+ add: function (data) {
1284
+ if (!data || this.options.disabled) {
1285
+ return;
1286
+ }
1287
+ data.files = $.each($.makeArray(data.files), this._normalizeFile);
1288
+ this._onAdd(null, data);
1289
+ },
1290
+
1291
+ // This method is exposed to the widget API and allows sending files
1292
+ // using the fileupload API. The data parameter accepts an object which
1293
+ // must have a files property and can contain additional options:
1294
+ // .fileupload('send', {files: filesList});
1295
+ // The method returns a Promise object for the file upload call.
1296
+ send: function (data) {
1297
+ if (data && !this.options.disabled) {
1298
+ data.files = $.each($.makeArray(data.files), this._normalizeFile);
1299
+ if (data.files.length) {
1300
+ return this._onSend(null, data);
1301
+ }
1302
+ }
1303
+ return this._getXHRPromise(false, data && data.context);
1304
+ }
1305
+
1306
+ });
1307
+
1308
+ }));
1309
+ $.fn.ImperaviLanguages = {
1310
+ ru : {
1311
+ html : 'Код',
1312
+
1313
+ // Styles dropdown menu
1314
+ styles : {
1315
+ name : 'Стили',
1316
+ paragraph : 'Параграф',
1317
+ quote : 'Цитата',
1318
+ code : 'Код',
1319
+ h2 : 'Заголовок 2',
1320
+ h3 : 'Заголовок 3',
1321
+ h4 : 'Заголовок 4',
1322
+ h5 : 'Заголовок 5',
1323
+ h6 : 'Заголовок 6',
1324
+ },
1325
+
1326
+ // Formatting dropdown menu
1327
+ format : {
1328
+ name : 'Формат',
1329
+ bold : 'Полужирный',
1330
+ italic : 'Наклонный',
1331
+ sup : 'Надстрочный',
1332
+ sub : 'Надстрочный',
1333
+ strike : 'Зачеркнутый',
1334
+ remove : 'Очистить форматирование'
1335
+ },
1336
+
1337
+ // Lists dropdown menu
1338
+ lists : {
1339
+ name : 'Списки',
1340
+ unordered : 'Обычный список',
1341
+ ordered : 'Нумерованный список',
1342
+ outdent : 'Уменьшить отступ',
1343
+ indent : 'Увеличить отступ'
1344
+ },
1345
+
1346
+ // Working with images
1347
+ image : {
1348
+ name : 'Изображение',
1349
+ download : 'Скачать изображение',
1350
+ text : 'Текст',
1351
+ mailto : 'Эл. почта',
1352
+ web : 'URL',
1353
+ title : 'Подсказка',
1354
+ buttons : {
1355
+ save : 'Сохранить',
1356
+ cancel : 'Отменить',
1357
+ insert : 'Вставить',
1358
+ remove : 'Удалить'
1359
+ },
1360
+ align : {
1361
+ name : 'Обтекание текстом',
1362
+ none : 'нет',
1363
+ left : 'слева',
1364
+ right : 'справа'
1365
+ }
1366
+ },
1367
+
1368
+ // Insert and format tables
1369
+ table : {
1370
+ name : 'Таблица',
1371
+ insert : 'Вставить таблицу',
1372
+ remove : 'Удалить таблицу',
1373
+ row: {
1374
+ name : 'Строки',
1375
+ above : 'Добавить строку сверху',
1376
+ below : 'Добавить строку снизу',
1377
+ remove : 'Удалить строку'
1378
+ },
1379
+ column : {
1380
+ name : 'Столбцы',
1381
+ left : 'Добавить столбец слева',
1382
+ right : 'Добавить столбец справа',
1383
+ remove : 'Удалить столбец',
1384
+ },
1385
+ header : {
1386
+ add : 'Добавить заголовок',
1387
+ remove : 'Удалить заголовок'
1388
+ }
1389
+ },
1390
+
1391
+ // Insert video from youtube etc
1392
+ video : {
1393
+ name : 'Видео',
1394
+ code : 'Код видео ролика'
1395
+ },
1396
+
1397
+ // Insert or remove hyperlink to a file
1398
+ file : {
1399
+ name : 'Файл',
1400
+ upload : 'Загрузить',
1401
+ download : 'Скачать',
1402
+ choose : 'Выбрать',
1403
+ or_choose : 'Или выберите',
1404
+ drop : 'Перетащите файл сюда'
1405
+ },
1406
+
1407
+ // Insert or remove hyperlink
1408
+ hyperlink : 'Ссылка'
1409
+ }
1410
+ }
1411
+ ;
1412
+ $.fn.ImperaviToolbarDefault = {
1413
+ html : true,
1414
+
1415
+ // Styles dropdown menu
1416
+ // TODO: User styles here. Move all to format section from here
1417
+ styles : {
1418
+ paragraph : true,
1419
+ quote : true,
1420
+ code : true,
1421
+ h2 : true,
1422
+ h3 : true,
1423
+ h4 : true,
1424
+ h5 : true,
1425
+ h6 : true
1426
+ },
1427
+
1428
+ // Formatting dropdown menu
1429
+ format : {
1430
+ bold : true,
1431
+ italic : true,
1432
+ sup : true,
1433
+ sub : true,
1434
+ strike : true,
1435
+ remove : true
1436
+ },
1437
+
1438
+ // Lists dropdown menu
1439
+ lists : {
1440
+ unordered : true,
1441
+ ordered : true,
1442
+ outdent : true,
1443
+ indent : true
1444
+ },
1445
+
1446
+ // Working with images
1447
+ image : true,
1448
+
1449
+ // Insert and format tables
1450
+ table : {
1451
+ insert : true,
1452
+ remove : true,
1453
+ header : {
1454
+ add : true,
1455
+ remove : true
1456
+ },
1457
+ row : {
1458
+ above : true,
1459
+ below : true,
1460
+ remove : true
1461
+ },
1462
+ column : {
1463
+ left : true,
1464
+ right : true,
1465
+ remove : true
1466
+ }
1467
+ },
1468
+
1469
+ // Insert video from youtube etc
1470
+ video : true,
1471
+
1472
+ // Insert or remove hyperlink to a file
1473
+ file : true,
1474
+
1475
+ // Insert or remove hyperlink
1476
+ hyperlink : true
1477
+ }
1478
+ ;
1479
+ (function( $ ) {
1480
+ $.fn.ImperaviActionDelegator = function(o) { this.initialize() }
1481
+
1482
+ $.fn.ImperaviActionDelegator.prototype = {
1483
+ initialize: function() {},
1484
+
1485
+ delegateButtonClick: function(button, iframe) {
1486
+ switch (button.attr('rel')) {
1487
+ case 'indent':
1488
+ case 'outdent':
1489
+ alert('yay!')
1490
+ break;
1491
+ case 'video':
1492
+ new $.fn.ImperaviPluginVideo
1493
+ break;
1494
+ case 'image':
1495
+ new $.fn.ImperaviPluginImage
1496
+ break;
1497
+ case 'hyperlink':
1498
+ new $.fn.ImperaviPluginHyperlink
1499
+ break;
1500
+ case 'file':
1501
+ new $.fn.ImperaviPluginFile
1502
+ break;
1503
+ default:
1504
+ return button
1505
+ break;
1506
+ }
1507
+ }
1508
+ }
1509
+ })(jQuery);
1510
+ // Internationalization
1511
+ (function( $ ) {
1512
+ $.fn.ImperaviI18n = function(o) {
1513
+ var o = $.extend({
1514
+ locale : 'en'
1515
+ }, o)
1516
+
1517
+ this.initialize(o)
1518
+ }
1519
+
1520
+ $.fn.ImperaviI18n.prototype = {
1521
+ o : null,
1522
+ locales : null,
1523
+
1524
+ initialize: function(o) {
1525
+ this.o = $.extend({ locale : $.fn.ImperaviOptions().options.locale }, o)
1526
+ this.locales = $.fn.ImperaviLanguages[this.o.locale]
1527
+ },
1528
+
1529
+ t: function(key) {
1530
+
1531
+ }
1532
+ }
1533
+ })(jQuery);
1534
+ (function( $ ) {
1535
+ $.fn.ImperaviPluginVideo = function(o) { this.initialize(o) }
1536
+
1537
+ $.fn.ImperaviPluginVideo.prototype = {
1538
+ initialize: function(o) {
1539
+ this.o = o
1540
+
1541
+ this.dialog = new $.fn.ImperaviDialog({
1542
+ title : 'Insert video',
1543
+ width : 600,
1544
+ height : 300,
1545
+ onOkay : function() {
1546
+ alert(this.el.find('textarea').val())
1547
+ this.hide()
1548
+ }
1549
+ })
1550
+
1551
+ this.dialog.show()
1552
+ this.dialog.el.addClass('imperavi-plugin-video')
1553
+ this.build()
1554
+ },
1555
+
1556
+ build: function() {
1557
+ var textarea = $(document.createElement('textarea'))
1558
+ this.dialog.setContent(textarea)
1559
+ }
1560
+ }
1561
+ })(jQuery);
1562
+ (function( $ ) {
1563
+ $.fn.ImperaviPluginImage = function(o) { this.initialize(o) }
1564
+
1565
+ $.fn.ImperaviPluginImage.prototype = {
1566
+ initialize: function(o) {
1567
+ this.o = o
1568
+
1569
+ this.dialog = new $.fn.ImperaviDialog({
1570
+ title : 'Insert image',
1571
+ width : 800,
1572
+ height : 600,
1573
+ onRemove : function() {
1574
+ alert('fuck yeah!')
1575
+ this.hide()
1576
+ },
1577
+ onOkay : function() {
1578
+ this.hide()
1579
+ }
1580
+ })
1581
+
1582
+ this.dialog.show()
1583
+ this.dialog.el.addClass('imperavi-plugin-image')
1584
+ this.build()
1585
+ },
1586
+
1587
+ build: function() {
1588
+ // Add 'remove' button
1589
+ this.removeButton = this.dialog.addButton('Remove', 'remove')
1590
+ this.removeButton.hide();
1591
+
1592
+ // Create tabs and content for tabs
1593
+ this.tabsArea = this.buildTabsArea()
1594
+
1595
+ this.uploadTab = this.buildTab('Upload image', this.buildUploadTabContent())
1596
+ .appendTo(this.tabsArea)
1597
+ .addClass('current')
1598
+
1599
+ this.pickTab = this.buildTab('Pick image', this.buildPickTabContent())
1600
+ .appendTo(this.tabsArea)
1601
+
1602
+ this.dialog.setContent(this.tabsArea)
1603
+ this.switchTabs();
1604
+ },
1605
+
1606
+ // Build tabs container
1607
+ buildTabsArea: function() {
1608
+ var article = $(document.createElement('article'))
1609
+ .addClass('imperavi-tabs')
1610
+
1611
+ return article
1612
+ },
1613
+
1614
+ // Add another one tab
1615
+ buildTab: function(title, content) {
1616
+ var section = $(document.createElement('section'))
1617
+ var heading = $(document.createElement('h3'))
1618
+ .html(title)
1619
+ .addClass('imperavi-tab')
1620
+ .appendTo(section)
1621
+
1622
+ var content = $(document.createElement('div'))
1623
+ .appendTo(section)
1624
+ .html(content)
1625
+
1626
+ return section
1627
+ },
1628
+
1629
+ // Switch between tabs
1630
+ switchTabs: function() {
1631
+ var currentTab = this.uploadTab
1632
+
1633
+ this.tabsArea.on('click', '.imperavi-tab', function(e){
1634
+ e.preventDefault();
1635
+
1636
+ if (currentTab.length) {
1637
+ currentTab.removeClass('current')
1638
+ }
1639
+
1640
+ currentTab = $(this).closest('section').addClass('current')
1641
+ })
1642
+ },
1643
+
1644
+ buildPickTabContent: function() {
1645
+
1646
+ },
1647
+
1648
+ buildUploadTabContent: function() {
1649
+ // Create wrapper
1650
+ var wrapper = $(document.createElement('div'))
1651
+ .attr('id', 'upload-wrapper')
1652
+
1653
+ // Create place for thumbnail
1654
+ var thumbnail = $(document.createElement('figure'))
1655
+ .addClass('thumbnail')
1656
+ .appendTo(wrapper)
1657
+
1658
+ var caption = $(document.createElement('span'))
1659
+ .html('No image yet')
1660
+ .appendTo(thumbnail)
1661
+
1662
+ // Create form
1663
+ var form = $(document.createElement('form'))
1664
+ .attr('enctype', 'multipart/form-data')
1665
+ .attr('method', 'post')
1666
+ .attr('action', '/images')
1667
+ //.attr('accept-charset', 'UTF-8')
1668
+ .appendTo(wrapper)
1669
+
1670
+ // Choose image from disk field
1671
+ var imageLocal = this.buildInput('Choose image from disk', 'image[image]', 'file')
1672
+ .appendTo(form)
1673
+
1674
+ // Image url field
1675
+ var imageUrl = this.buildInput('or specify link to image', 'image[url]', 'text')
1676
+ .appendTo(wrapper)
1677
+
1678
+ // Image align dropdown
1679
+ var imagePos = this.buildAlignSelect().appendTo(wrapper)
1680
+
1681
+
1682
+ $('body').fileupload({
1683
+ dataType: 'json',
1684
+ url: '/images',
1685
+ done: function (e, data) {
1686
+ $.each(data.result, function (index, file) {
1687
+ $('<p/>').text(file.name).appendTo(document.body);
1688
+ });
1689
+ }
1690
+ });
1691
+
1692
+ // Submit form
1693
+ /*form.on("change", ":file", function() {
1694
+ thumbnail.addClass("loading");
1695
+
1696
+ $.ajax(form.attr("action"), {
1697
+ files : form.find(":file"),
1698
+ iframe : true,
1699
+ dataType : "json",
1700
+ contentType : 'multipart/form-data',
1701
+ type : form.attr('method')
1702
+ }).always(function() {
1703
+ thumbnail.removeClass("loading");
1704
+ }).done(function(data) {
1705
+
1706
+ if (data.errors) {
1707
+ // Some errors occurs
1708
+ alert(data.errors) // TODO
1709
+ } else {
1710
+ // No errors
1711
+ thumbnail.empty()
1712
+
1713
+ $(document.createElement('img'))
1714
+ .attr('src', data.file)
1715
+ .attr('width', 300)
1716
+ .attr('height', 340)
1717
+ .appendTo(thumbnail)
1718
+ }
1719
+ });
1720
+ });*/
1721
+
1722
+ return wrapper
1723
+ },
1724
+
1725
+ buildInput: function(title, name, type) {
1726
+ var wrapper = $(document.createElement('div'))
1727
+ .addClass('field')
1728
+
1729
+ var label = $(document.createElement('label'))
1730
+ .attr('for', name)
1731
+ .html(title)
1732
+ .appendTo(wrapper)
1733
+
1734
+ var url = $(document.createElement('input'))
1735
+ .attr('type', type)
1736
+ .attr('name', name)
1737
+ .attr('id', name)
1738
+ .appendTo(wrapper)
1739
+
1740
+ return wrapper
1741
+ },
1742
+
1743
+ buildAlignSelect: function() {
1744
+ var wrapper = $(document.createElement('div'))
1745
+ .addClass('field')
1746
+
1747
+ var label = $(document.createElement('label'))
1748
+ .attr('for', 'image-align')
1749
+ .html('Image position')
1750
+ .appendTo(wrapper)
1751
+
1752
+ var select = $(document.createElement('select'))
1753
+ .attr('id', 'image-align')
1754
+ .attr('name', 'image[align]')
1755
+ .appendTo(wrapper)
1756
+
1757
+ // Create select options
1758
+ var options = {
1759
+ none : 'None',
1760
+ left : 'To left',
1761
+ right : 'To right'
1762
+ }
1763
+
1764
+ $.each(options, function(value, caption) {
1765
+ var option = $(document.createElement('option'))
1766
+ .attr('value', value)
1767
+ .html(caption)
1768
+ .appendTo(select)
1769
+
1770
+ if (value == 'left') option.attr('selected', true)
1771
+ })
1772
+
1773
+ return wrapper
1774
+ }
1775
+ }
1776
+ })(jQuery);
1777
+ (function( $ ) {
1778
+ $.fn.ImperaviPluginHyperlink = function(o) { this.initialize(o) }
1779
+
1780
+ $.fn.ImperaviPluginHyperlink.prototype = {
1781
+ initialize: function(o) {
1782
+ this.o = o
1783
+
1784
+ this.dialog = new $.fn.ImperaviDialog({
1785
+ title : 'Insert hyperlink',
1786
+ width : 450,
1787
+ height : 237,
1788
+ onRemove : function() {
1789
+ alert('fuck yeah!')
1790
+ this.hide()
1791
+ },
1792
+ onOkay : function() {
1793
+ alert('fuck')
1794
+ this.hide()
1795
+ }
1796
+ })
1797
+
1798
+ this.dialog.show()
1799
+ this.dialog.el.addClass('imperavi-plugin-hyperlink')
1800
+ this.dialog.addButton('Remove', 'remove')
1801
+ this.build()
1802
+ },
1803
+
1804
+ build: function() {
1805
+ var wrapper = $(document.createElement('div'))
1806
+ var url = this.build_input('Url', 'url').appendTo(wrapper)
1807
+ var caption = this.build_input('Title', 'title').appendTo(wrapper)
1808
+
1809
+ this.dialog.setContent(wrapper)
1810
+ },
1811
+
1812
+ build_input: function(title, name) {
1813
+ var wrapper = $(document.createElement('div'))
1814
+ .addClass('field')
1815
+
1816
+ var label = $(document.createElement('label'))
1817
+ .attr('for', name)
1818
+ .html(title)
1819
+ .appendTo(wrapper)
1820
+
1821
+ var url = $(document.createElement('input'))
1822
+ .attr('type', 'text')
1823
+ .attr('name', name)
1824
+ .attr('id', name)
1825
+ .appendTo(wrapper)
1826
+
1827
+ return wrapper
1828
+ }
1829
+ }
1830
+ })(jQuery);
1831
+ (function( $ ) {
1832
+ $.fn.ImperaviPluginFile = function(o) { this.initialize(o) }
1833
+
1834
+ $.fn.ImperaviPluginFile.prototype = {
1835
+ initialize: function(o) {
1836
+ this.o = o
1837
+
1838
+ this.dialog = new $.fn.ImperaviDialog({
1839
+ title : 'Attach file',
1840
+ width : 450,
1841
+ height : 237,
1842
+ onRemove : function() {
1843
+ alert('fuck yeah!')
1844
+ this.hide()
1845
+ },
1846
+ onOkay : function() {
1847
+ alert('fuck')
1848
+ this.hide()
1849
+ }
1850
+ })
1851
+
1852
+ this.dialog.show()
1853
+ this.dialog.el.addClass('imperavi-plugin-file')
1854
+ this.dialog.addButton('Remove', 'remove')
1855
+ this.build()
1856
+ },
1857
+
1858
+ build: function() {
1859
+ var wrapper = $(document.createElement('div'))
1860
+ var file = this.build_input('File', 'attachment').appendTo(wrapper)
1861
+ //var caption = this.build_input('Title', 'title').appendTo(wrapper)
1862
+
1863
+ this.dialog.setContent(wrapper)
1864
+ },
1865
+
1866
+ build_input: function(title, name) {
1867
+ var wrapper = $(document.createElement('div'))
1868
+ .addClass('field')
1869
+
1870
+ var label = $(document.createElement('label'))
1871
+ .attr('for', name)
1872
+ .html(title)
1873
+ .appendTo(wrapper)
1874
+
1875
+ var file = $(document.createElement('input'))
1876
+ .attr('type', 'file')
1877
+ .attr('name', name)
1878
+ .attr('id', name)
1879
+ .appendTo(wrapper)
1880
+
1881
+ return wrapper
1882
+ }
1883
+ }
1884
+ })(jQuery);
1885
+ // TODO: add custom events
1886
+ // - onShow
1887
+ // - onClose
1888
+ // - onBuilt
1889
+ // - onContentLoaded
1890
+ // - onOkay
1891
+ // - onCancel
1892
+
1893
+ (function( $ ) {
1894
+ $.fn.ImperaviDialog = function(o) {
1895
+ var o = $.extend({
1896
+ onOkay : function() { this.hide() },
1897
+ onCancel : function() { this.hide() },
1898
+ onClose : function(e) { this.close(e) },
1899
+ onBuilt : function() {},
1900
+ onLoad : function() {}
1901
+ }, o)
1902
+
1903
+ this.initialize(o)
1904
+ }
1905
+
1906
+ $.fn.ImperaviDialog.prototype = {
1907
+ el : null,
1908
+ o : null,
1909
+ overlay : null,
1910
+
1911
+ initialize: function(o) {
1912
+ // Retrieve user options passed to imperavi
1913
+ this.o = $.extend($.fn.ImperaviOptions().options.dialog, o)
1914
+ },
1915
+
1916
+ build: function() {
1917
+ // Build dialog just once
1918
+ if (this.el) return;
1919
+
1920
+ // Create overlay
1921
+ this.overlay = new $.fn.ImperaviOverlay()
1922
+
1923
+ // Dialog window
1924
+ this.el = $(document.createElement('div'))
1925
+ .attr('id', 'imperavi-dialog')
1926
+ .appendTo($('body'));
1927
+
1928
+ this.container = $(document.createElement('div'))
1929
+ .attr('id', 'imperavi-dialog-container')
1930
+ .appendTo(this.el);
1931
+
1932
+ // Close button
1933
+ this.closeBtn = $(document.createElement('a'))
1934
+ .attr('href', 'javascript:;')
1935
+ .html('&times;')
1936
+ .attr('id', 'imperavi-dialog-close')
1937
+ .appendTo(this.container);
1938
+
1939
+ // Dialog title
1940
+ this.title = $(document.createElement('h1'))
1941
+ .attr('id', 'imperavi-dialog-title')
1942
+ .appendTo(this.container);
1943
+
1944
+ // Dialog content
1945
+ this.article = $(document.createElement('article'))
1946
+ .attr('id', 'imperavi-dialog-content')
1947
+ .appendTo(this.container);
1948
+
1949
+ // Buttons panel
1950
+ this.buttons_wrapper = $(document.createElement('div'))
1951
+ .attr('id', 'imperavi-dialog-buttons-wrapper')
1952
+ .appendTo(this.container);
1953
+
1954
+ this.buttons = $(document.createElement('div'))
1955
+ .attr('id', 'imperavi-dialog-buttons')
1956
+ .appendTo(this.buttons_wrapper);
1957
+
1958
+ this.okay_button = this.addButton('Okay', 'okay')
1959
+ this.cancel_button = this.addButton('Cancel', 'cancel')
1960
+
1961
+ // Set default size
1962
+ this.setSize(this.o.width, this.o.height)
1963
+
1964
+ // Set default title
1965
+ this.setTitle(this.o.title)
1966
+
1967
+ this.o.onBuilt.call(this)
1968
+ },
1969
+
1970
+ addButton: function(caption, name) {
1971
+ var callbackName = 'on' + name.charAt(0).toUpperCase() + name.slice(1)
1972
+
1973
+ return $(document.createElement('a'))
1974
+ .attr('id', 'imperavi-dialog-' + name)
1975
+ .attr('href', 'javascript:;')
1976
+ .html(caption)
1977
+ .click($.proxy(function(){ this.o[callbackName].call(this) }, this))
1978
+ .appendTo(this.buttons);
1979
+ },
1980
+
1981
+ addEvents: function() {
1982
+ var onCloseCallback = $.proxy(function(e){ this.o.onClose.call(this, e) }, this)
1983
+
1984
+ $(document).keyup(function(e) { onCloseCallback(e) })
1985
+ this.closeBtn.click(function(e) { onCloseCallback(e) })
1986
+ this.overlay.el.click(function(e) { onCloseCallback(e) })
1987
+ },
1988
+
1989
+ removeEvents: function() {
1990
+ var onCloseCallback = $.proxy(function(e){ this.o.onClose.call(this, e) }, this)
1991
+
1992
+ $(document).unbind('keyup', onCloseCallback)
1993
+ this.closeBtn.unbind('click', onCloseCallback)
1994
+ this.overlay.el.unbind('click', onCloseCallback)
1995
+ },
1996
+
1997
+ setSize: function(width, height) {
1998
+ this.el.css({
1999
+ width : width + 'px',
2000
+ height : height + 'px',
2001
+ marginTop : '-' + height / 2 + 'px',
2002
+ marginLeft : '-' + width / 2 + 'px'
2003
+ }).fadeIn('fast');
2004
+
2005
+ this.container.css({
2006
+ width : width + 'px',
2007
+ height : height + 'px',
2008
+ })
2009
+ },
2010
+
2011
+ setTitle: function(title) {
2012
+ this.title.html(title)
2013
+ },
2014
+
2015
+ setContent: function(content) {
2016
+ this.article.html(content)
2017
+ },
2018
+
2019
+ // TODO Load content via ajax
2020
+ loadContent: function(url) {
2021
+ this.setContent('')
2022
+ this.o.onLoad.call(this)
2023
+ },
2024
+
2025
+ cleanUp: function() {
2026
+ this.removeEvents()
2027
+ this.setContent('')
2028
+ this.setTitle('')
2029
+ },
2030
+
2031
+ show: function() {
2032
+ this.build()
2033
+ this.overlay.show()
2034
+ this.el.show()
2035
+ this.addEvents()
2036
+ },
2037
+
2038
+ hide: function() {
2039
+ this.el.hide()
2040
+ this.overlay.hide()
2041
+ this.cleanUp()
2042
+ },
2043
+
2044
+ close: function(e) {
2045
+ if (e.keyCode == 27 || e.type == 'click')
2046
+ this.hide()
2047
+ }
2048
+ }
2049
+ })(jQuery);
2050
+ (function( $ ) {
2051
+ $.fn.ImperaviOverlay = function(o) { this.initialize(o) }
2052
+
2053
+ $.fn.ImperaviOverlay.prototype = {
2054
+ el : null,
2055
+
2056
+ initialize: function(o) {
2057
+ this.o = o
2058
+ },
2059
+
2060
+ build: function() {
2061
+ if (this.el) return;
2062
+
2063
+ this.el = $(document.createElement('div'))
2064
+ .attr('id', 'imperavi-overlay')
2065
+ .appendTo($('body'));
2066
+ },
2067
+
2068
+ show: function() {
2069
+ this.build()
2070
+ this.el.show()
2071
+ },
2072
+
2073
+ hide: function() {
2074
+ this.el.hide()
2075
+ }
2076
+ }
2077
+ })(jQuery);
2078
+ (function( $ ) {
2079
+ $.fn.ImperaviIframe = function(textarea, o) { this.initialize(textarea, o) }
2080
+
2081
+ $.fn.ImperaviIframe.prototype = {
2082
+ textarea : null,
2083
+ wrapper : null,
2084
+ el : null,
2085
+
2086
+ initialize: function(textarea, o) {
2087
+ this.textarea = textarea
2088
+ this.o = o
2089
+
2090
+ this.textarea.hide();
2091
+
2092
+ this.build()
2093
+ this.populate()
2094
+ this.enable(true)
2095
+ },
2096
+
2097
+ // Build Iframe object and stuff
2098
+ build: function() {
2099
+ this.wrapper = $(document.createElement('div'))
2100
+ .addClass('imperavi')
2101
+ .insertAfter(this.textarea)
2102
+
2103
+ this.el = $(document.createElement('iframe'))
2104
+ .appendTo(this.wrapper)
2105
+ .css({ width : this.textarea.outerWidth(), height : this.textarea.outerHeight() })
2106
+ },
2107
+
2108
+ populate: function() {
2109
+ html = '<!DOCTYPE html>'
2110
+ html += '<head><meta charset="utf-8" />'
2111
+ //html += '<link rel="stylesheet" href="/assets/wysiwyg.css?body=1" />'
2112
+ //html += '<script src="/assets/mootools.js?body=1"></script>'
2113
+ html += '</head><html><body>' + this.textarea.val()
2114
+ html += '</body></html>'
2115
+
2116
+ this.doc().open();
2117
+ this.doc().write(html);
2118
+ this.doc().close();
2119
+ },
2120
+
2121
+ enableObjects: function() {
2122
+ if (!$.browser.mozilla) return;
2123
+
2124
+ //this.doc().execCommand('styleWithCSS', false, false)
2125
+ //this.doc().execCommand('enableObjectResizing', false, false)
2126
+ //this.doc().execCommand('enableInlineTableEditing', false, false)
2127
+ },
2128
+
2129
+ observe: function() {
2130
+
2131
+ },
2132
+
2133
+ enable: function(status) {
2134
+ // Located here for Chrome support
2135
+ this.doc().designMode = status ? 'on' : 'off';
2136
+
2137
+ this.el.load($.proxy(function() {
2138
+ this.enableObjects();
2139
+ this.observe();
2140
+ }, this));
2141
+ },
2142
+
2143
+ doc: function() {
2144
+ var i = this.el.get(0)
2145
+ if (i.contentDocument) return i.contentDocument
2146
+ if (i.contentWindow) return i.contentWindow.document
2147
+
2148
+ return i.document
2149
+ }
2150
+ }
2151
+ })(jQuery);
2152
+ (function( $ ) {
2153
+ $.fn.ImperaviIframeResizer = function(iframe, o) { this.initialize(iframe, o) }
2154
+
2155
+ $.fn.ImperaviIframeResizer.prototype = {
2156
+ iframe : null,
2157
+ el : null,
2158
+
2159
+ initialize: function(iframe, o) {
2160
+ this.iframe = iframe
2161
+ this.o = o
2162
+
2163
+ this.build()
2164
+ },
2165
+
2166
+ build: function() {
2167
+ this.el = $(document.createElement('div'))
2168
+ .addClass('imperavi-resizer')
2169
+ .insertAfter(this.iframe.el)
2170
+
2171
+ this.el.append($(document.createElement('div')))
2172
+ }
2173
+ }
2174
+ })(jQuery);
2175
+ (function( $ ) {
2176
+ $.fn.ImperaviToolbar = function(iframe, o) {
2177
+ var o = $.extend({
2178
+ onButtonClick : function(button) {},
2179
+ }, o)
2180
+
2181
+ this.initialize(iframe, o)
2182
+ }
2183
+
2184
+ $.fn.ImperaviToolbar.prototype = {
2185
+ iframe : null,
2186
+ el : null,
2187
+
2188
+ initialize: function(iframe, o) {
2189
+ this.iframe = iframe
2190
+ this.o = o
2191
+ this.x = $.fn.ImperaviToolbarDefault // TODO make it pretty
2192
+ this.l = $.fn.ImperaviLanguages.ru // TODO make it pretty
2193
+
2194
+ this.build()
2195
+ },
2196
+
2197
+ // Build Toolbar object
2198
+ build: function() {
2199
+ this.el = $(document.createElement('ul'))
2200
+ .insertBefore(this.iframe.el);
2201
+
2202
+ $.each(this.x, $.proxy(function(key, value) {
2203
+ // Buttons with dropdown
2204
+ if (typeof value == 'object') {
2205
+ this.el.append(this.addDropdown(key, value))
2206
+ } else if (typeof value == 'boolean' && value == true) {
2207
+ var title = typeof this.l[key] == 'object' ? this.l[key].name : this.l[key]
2208
+ this.el.append(this.addButton(key, title, null))
2209
+ }
2210
+ }, this));
2211
+ },
2212
+
2213
+ addButton: function(name, title, caption) {
2214
+ var li = $(document.createElement('li')).addClass('button-' + name)
2215
+ var a = $(document.createElement('a'))
2216
+ .attr('href', 'javascript:;')
2217
+ .attr('rel', name)
2218
+ .attr('title', title)
2219
+ .appendTo(li)
2220
+ // This executes a custom callback on button click
2221
+ .click($.proxy(function(){ this.o.onButtonClick.call(this, a) }, this))
2222
+
2223
+ var span = $(document.createElement('span'))
2224
+ .html(caption)
2225
+ .appendTo(a);
2226
+
2227
+ return li.append(a)
2228
+ },
2229
+
2230
+ addDropdown: function(name, items) {
2231
+ var button = this.addButton(name, this.l[name].name, null)
2232
+ var ul = $(document.createElement('ul'))
2233
+
2234
+ button.addClass('has-dropdown')
2235
+
2236
+ // Add dropdown items
2237
+ $.each(items, $.proxy(function(key, value) {
2238
+ if (typeof value == 'object') {
2239
+ var separator = true
2240
+
2241
+ $.each(value, $.proxy(function(key2, value2) {
2242
+ if (value2 == true) {
2243
+ var item = this.addButton(key2, null, this.l[name][key][key2])
2244
+ if (separator) item.addClass('separator')
2245
+
2246
+ ul.append(item)
2247
+ separator = false
2248
+ }
2249
+ }, this));
2250
+ } else if (typeof value == 'boolean' && value == true) {
2251
+ ul.append( this.addButton(key, null, this.l[name][key]) )
2252
+ }
2253
+ }, this));
2254
+
2255
+ return button.append(ul)
2256
+ }
2257
+ }
2258
+ })(jQuery);
2259
+ (function( $ ) {
2260
+ $.fn.imperavi = function(o) {
2261
+ // Editor options
2262
+ var o = $.extend({
2263
+ locale : 'ru', // TODO replace with $.fn.ImperaviLanguage
2264
+ resizer : $.fn.ImperaviIframeResizer,
2265
+ dialog : $.fn.ImperaviDialog,
2266
+ overlay : $.fn.ImperaviOverlay,
2267
+ iframe : $.fn.ImperaviIframe,
2268
+ toolbar : $.fn.ImperaviToolbar,
2269
+ delegator : $.fn.ImperaviActionDelegator,
2270
+ options : {
2271
+ dialog : {
2272
+ title : 'Default title',
2273
+ width : 500,
2274
+ height : 300
2275
+ }
2276
+ }
2277
+ }, o)
2278
+
2279
+ // Global options
2280
+ $.fn.ImperaviOptions = function() { return o }
2281
+
2282
+ // Main object
2283
+ $.fn.Imperavi = function(el) { this.initialize(el) }
2284
+
2285
+ $.fn.Imperavi.prototype = {
2286
+ textarea : null,
2287
+ iframe : null,
2288
+ toolbar : null,
2289
+ resizer : null,
2290
+ delegator : null,
2291
+
2292
+ // Initialize imperavi
2293
+ initialize: function(el) {
2294
+ this.textarea = $(el)
2295
+ this.build()
2296
+ this.autosave()
2297
+ },
2298
+
2299
+ build: function() {
2300
+ // Delegate action to another object
2301
+ this.delegator = new o.delegator
2302
+
2303
+ // Create iframe
2304
+ this.iframe = new o.iframe(this.textarea, o)
2305
+
2306
+ // Create editor resizer
2307
+ this.resizer = new o.resizer(this.iframe, o)
2308
+
2309
+ // Create toolbar
2310
+ this.toolbar = new o.toolbar(this.iframe, {
2311
+ onButtonClick : $.proxy(function(button) {
2312
+ this.delegator.delegateButtonClick(button, this.iframe)
2313
+ }, this)
2314
+ })
2315
+ },
2316
+
2317
+ autosave: function() {
2318
+ // TODO: implement
2319
+ }
2320
+ }
2321
+
2322
+ // Apply imperavi for each selected element
2323
+ return this.each(function() {
2324
+ new $.fn.Imperavi(this)
2325
+ })
2326
+ }
2327
+ })(jQuery);
2328
+ // Vendor
2329
+
2330
+ // Imperavi
2331
+
2332
+
2333
+
2334
+ ;