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
@@ -1,1726 +1,2365 @@
1
- o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1328243689.832844: @value{ I" length:EFi��I" digest;
2
- F"%eee4dc3c2d01d8913bbfd697e19e7ffbI" source;
3
- FI"��// Define: Linkify plugin from stackoverflow
4
- (function($){
5
- var url2 = /(^|<|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|>|$)/g;
6
-
7
- linkifyThis = function ()
8
- {
9
- var childNodes = this.childNodes,
10
- i = childNodes.length;
11
- while(i--)
12
- {
13
- var n = childNodes[i];
14
- if (n.nodeType == 3)
15
- {
16
- var html = n.nodeValue;
17
- if (html)
18
- {
19
- html = html.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(url2, '$1<a href="$2">$2</a>$5');
20
- $(n).after(html).remove();
21
- }
22
- }
23
- else if (n.nodeType == 1 && !/^(a|button|textarea)$/i.test(n.tagName)) linkifyThis.call(n);
24
- }
25
- };
26
-
27
- $.fn.linkify = function ()
28
- {
29
- this.each(linkifyThis);
30
- };
31
-
32
- })(jQuery);
33
- /* jQuery plugin textselect
34
- * version: 0.9
35
- * author: Josef Moravec, josef.moravec@gmail.com
36
- * updated: Imperavi
37
- *
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1329486801.3007154: @value{ I" length:EFi�@I" digest;
2
+ F"%5856222b7b70c9d4e6cdda24f46f5550I" source;
3
+ FI"�@/*
4
+ * jQuery UI Widget 1.8.17+amd
5
+ * https://github.com/blueimp/jQuery-File-Upload
6
+ *
7
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
8
+ * Dual licensed under the MIT or GPL Version 2 licenses.
9
+ * http://jquery.org/license
10
+ *
11
+ * http://docs.jquery.com/UI/Widget
38
12
  */
39
13
 
40
- (function($){$.event.special.textselect={setup:function(data,namespaces)
41
- {$(this).data("textselected",false);$(this).data("ttt",data);$(this).bind('mouseup',$.event.special.textselect.handler);},teardown:function(data)
42
- {$(this).unbind('mouseup',$.event.special.textselect.handler);},handler:function(event)
43
- {var data=$(this).data("ttt");var text=$.event.special.textselect.getSelectedText(data).toString();if(text!='')
44
- {$(this).data("textselected",true);event.type="textselect";event.text=text;$.event.handle.apply(this,arguments);}},getSelectedText:function(data)
45
- {var text='';var frame=$('#imp_redactor_frame_'+data).get(0);if(frame.contentWindow.getSelection)text=frame.contentWindow.getSelection();else if(frame.contentWindow.document.getSelection) text=frame.contentWindow.document.getSelection();else if(frame.contentWindow.document.selection)text=frame.contentWindow.document.selection.createRange().text;return text;}}
46
- $.event.special.textunselect={setup:function(data,namespaces){$(this).data("rttt",data);$(this).data("textselected",false);$(this).bind('mouseup',$.event.special.textunselect.handler);$(this).bind('keyup',$.event.special.textunselect.handlerKey)},teardown:function(data){$(this).unbind('mouseup',$.event.special.textunselect.handler);},handler:function(event){if($(this).data("textselected")){var data=$(this).data("rttt");var text=$.event.special.textselect.getSelectedText(data).toString();if(text==''){$(this).data("textselected",false);event.type="textunselect";$.event.handle.apply(this,arguments);}}},handlerKey:function(event){if($(this).data("textselected")){var data=$(this).data("rttt");var text=$.event.special.textselect.getSelectedText(data).toString();if((event.keyCode=27)&&(text=='')){$(this).data("textselected",false);event.type="textunselect";$.event.handle.apply(this,arguments);}}}}})(jQuery);
47
14
 
48
- /*
49
- Plugin Drag and drop Upload v1.0.0
50
- http://imperavi.com/
51
- Copyright 2011, Imperavi Ltd.
52
- */
53
-
54
- (function($){
55
-
56
- // Initialization
57
- $.fn.dragupload = function(options)
58
- {
15
+ (function (factory) {
16
+ if (typeof define === "function" && define.amd) {
17
+ // Register as an anonymous AMD module:
18
+ define(["jquery"], factory);
19
+ } else {
20
+ // Browser globals:
21
+ factory(jQuery);
22
+ }
23
+ }(function( $, undefined ) {
24
+
25
+ // jQuery 1.4+
26
+ if ( $.cleanData ) {
27
+ var _cleanData = $.cleanData;
28
+ $.cleanData = function( elems ) {
29
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
30
+ try {
31
+ $( elem ).triggerHandler( "remove" );
32
+ // http://bugs.jquery.com/ticket/8235
33
+ } catch( e ) {}
34
+ }
35
+ _cleanData( elems );
36
+ };
37
+ } else {
38
+ var _remove = $.fn.remove;
39
+ $.fn.remove = function( selector, keepData ) {
59
40
  return this.each(function() {
60
- var obj = new Construct(this, options);
61
- obj.init();
41
+ if ( !keepData ) {
42
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
43
+ $( "*", this ).add( [ this ] ).each(function() {
44
+ try {
45
+ $( this ).triggerHandler( "remove" );
46
+ // http://bugs.jquery.com/ticket/8235
47
+ } catch( e ) {}
48
+ });
49
+ }
50
+ }
51
+ return _remove.call( $(this), selector, keepData );
62
52
  });
63
53
  };
64
-
65
- // Options and variables
66
- function Construct(el, options) {
67
- this.opts = $.extend({
68
- url: false,
69
- success: false,
70
- maxfilesize: 10485760, // 10MB
71
- preview: false,
72
- text: RLANG.drop_file_here,
73
- atext: RLANG.or_choose
74
- }, options);
75
-
76
- this.$el = $(el);
54
+ }
55
+
56
+ $.widget = function( name, base, prototype ) {
57
+ var namespace = name.split( "." )[ 0 ],
58
+ fullName;
59
+ name = name.split( "." )[ 1 ];
60
+ fullName = namespace + "-" + name;
61
+
62
+ if ( !prototype ) {
63
+ prototype = base;
64
+ base = $.Widget;
65
+ }
66
+
67
+ // create selector for plugin
68
+ $.expr[ ":" ][ fullName ] = function( elem ) {
69
+ return !!$.data( elem, name );
77
70
  };
78
71
 
79
- // Functionality
80
- Construct.prototype = {
81
- init: function()
82
- {
83
- if (!$.browser.opera && !$.browser.msie)
84
- {
85
- this.droparea = $('<div class="redactor_droparea"></div>');
86
- this.dropareabox = $('<div class="redactor_dropareabox">' + this.opts.text + '</div>');
87
- this.dropalternative = $('<div class="redactor_dropalternative">' + this.opts.atext + '</div>');
88
-
89
- this.droparea.append(this.dropareabox);
90
-
91
- this.$el.before(this.droparea);
92
- this.$el.before(this.dropalternative);
93
-
94
-
95
- // drag over
96
- this.dropareabox.bind('dragover', function() { return this.ondrag(); }.bind2(this));
97
-
98
- // drag leave
99
- this.dropareabox.bind('dragleave', function() { return this.ondragleave(); }.bind2(this));
100
-
101
-
102
- // drop
103
- this.dropareabox.get(0).ondrop = function(event) {
104
- event.preventDefault();
105
-
106
- this.dropareabox.removeClass('hover').addClass('drop');
107
-
108
- var file = event.dataTransfer.files[0];
109
- var fd = new FormData();
110
-
111
- fd.append('file', file);
112
-
113
- $.ajax({
114
- url: this.opts.url,
115
- data: fd,
116
- //xhr: provider,
117
- cache: false,
118
- contentType: false,
119
- processData: false,
120
- type: 'POST',
121
- success: function(data)
122
- {
123
- if (this.opts.success !== false) this.opts.success(data);
124
-
125
- if (this.opts.preview === true) this.dropareabox.html(data);
126
- //else this.dropareabox.text(this.opts.success_text);
127
-
128
- }.bind2(this)
129
- });
130
-
131
-
132
- }.bind2(this);
133
- }
134
- },
135
- ondrag: function()
136
- {
137
- this.dropareabox.addClass('hover');
138
- return false;
139
- },
140
- ondragleave: function()
141
- {
142
- this.dropareabox.removeClass('hover');
143
- return false;
72
+ $[ namespace ] = $[ namespace ] || {};
73
+ $[ namespace ][ name ] = function( options, element ) {
74
+ // allow instantiation without initializing for simple inheritance
75
+ if ( arguments.length ) {
76
+ this._createWidget( options, element );
144
77
  }
145
78
  };
146
79
 
147
-
148
- })(jQuery);
149
- /*
150
- Redactor v7.2.0
151
- Updated 20.11.2011
152
-
153
- In English http://imperavi.com/
154
- In Russian http://imperavi.ru/
155
-
156
- Copyright (c) 2009-2012, Imperavi Ltd.
157
- Dual licensed under the MIT or GPL Version 2 licenses.
158
-
159
- Usage: $('#content').redactor();
160
- */
161
-
162
-
163
- var isCtrl = false;
164
- var redactorActive = false;
165
-
166
- var $table = false;
167
- var $tbody = false;
168
- var $thead = false;
169
- var $current_tr = false;
170
- var $current_td = false;
171
-
172
- var deviceAndroid = "android";
173
- var uagent = navigator.userAgent.toLowerCase();
174
-
175
- // detect iOS and Android
176
- function isiOS() {
177
- return ((navigator.platform.indexOf("iPhone") != -1) || (navigator.platform.indexOf("iPod") != -1) || (navigator.platform.indexOf("iPad") != -1));
178
- }
80
+ var basePrototype = new base();
81
+ // we need to make the options hash a property directly on the new instance
82
+ // otherwise we'll modify the options hash on the prototype that we're
83
+ // inheriting from
84
+ // $.each( basePrototype, function( key, val ) {
85
+ // if ( $.isPlainObject(val) ) {
86
+ // basePrototype[ key ] = $.extend( {}, val );
87
+ // }
88
+ // });
89
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
90
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
91
+ namespace: namespace,
92
+ widgetName: name,
93
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
94
+ widgetBaseClass: fullName
95
+ }, prototype );
96
+
97
+ $.widget.bridge( name, $[ namespace ][ name ] );
98
+ };
99
+
100
+ $.widget.bridge = function( name, object ) {
101
+ $.fn[ name ] = function( options ) {
102
+ var isMethodCall = typeof options === "string",
103
+ args = Array.prototype.slice.call( arguments, 1 ),
104
+ returnValue = this;
105
+
106
+ // allow multiple hashes to be passed on init
107
+ options = !isMethodCall && args.length ?
108
+ $.extend.apply( null, [ true, options ].concat(args) ) :
109
+ options;
110
+
111
+ // prevent calls to internal methods
112
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
113
+ return returnValue;
114
+ }
179
115
 
180
- function detectAndroid() {
181
- return uagent.search(deviceAndroid) > -1
182
- }
116
+ if ( isMethodCall ) {
117
+ this.each(function() {
118
+ var instance = $.data( this, name ),
119
+ methodValue = instance && $.isFunction( instance[options] ) ?
120
+ instance[ options ].apply( instance, args ) :
121
+ instance;
122
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
123
+ // if ( !instance ) {
124
+ // throw "cannot call methods on " + name + " prior to initialization; " +
125
+ // "attempted to call method '" + options + "'";
126
+ // }
127
+ // if ( !$.isFunction( instance[options] ) ) {
128
+ // throw "no such method '" + options + "' for " + name + " widget instance";
129
+ // }
130
+ // var methodValue = instance[ options ].apply( instance, args );
131
+ if ( methodValue !== instance && methodValue !== undefined ) {
132
+ returnValue = methodValue;
133
+ return false;
134
+ }
135
+ });
136
+ } else {
137
+ this.each(function() {
138
+ var instance = $.data( this, name );
139
+ if ( instance ) {
140
+ instance.option( options || {} )._init();
141
+ } else {
142
+ $.data( this, name, new object( options, this ) );
143
+ }
144
+ });
145
+ }
183
146
 
184
- function detectAndroidWebKit() {
185
- if (detectAndroid()) {
186
- return uagent.search('webkit') > -1
187
- }
147
+ return returnValue;
148
+ };
149
+ };
150
+
151
+ $.Widget = function( options, element ) {
152
+ // allow instantiation without initializing for simple inheritance
153
+ if ( arguments.length ) {
154
+ this._createWidget( options, element );
155
+ }
156
+ };
157
+
158
+ $.Widget.prototype = {
159
+ widgetName: "widget",
160
+ widgetEventPrefix: "",
161
+ options: {
162
+ disabled: false
163
+ },
164
+ _createWidget: function( options, element ) {
165
+ // $.widget.bridge stores the plugin instance, but we do it anyway
166
+ // so that it's stored even before the _create function runs
167
+ $.data( element, this.widgetName, this );
168
+ this.element = $( element );
169
+ this.options = $.extend( true, {},
170
+ this.options,
171
+ this._getCreateOptions(),
172
+ options );
173
+
174
+ var self = this;
175
+ this.element.bind( "remove." + this.widgetName, function() {
176
+ self.destroy();
177
+ });
188
178
 
189
- return false;
190
- }
179
+ this._create();
180
+ this._trigger( "create" );
181
+ this._init();
182
+ },
183
+ _getCreateOptions: function() {
184
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
185
+ },
186
+ _create: function() {},
187
+ _init: function() {},
188
+
189
+ destroy: function() {
190
+ this.element
191
+ .unbind( "." + this.widgetName )
192
+ .removeData( this.widgetName );
193
+ this.widget()
194
+ .unbind( "." + this.widgetName )
195
+ .removeAttr( "aria-disabled" )
196
+ .removeClass(
197
+ this.widgetBaseClass + "-disabled " +
198
+ "ui-state-disabled" );
199
+ },
200
+
201
+ widget: function() {
202
+ return this.element;
203
+ },
204
+
205
+ option: function( key, value ) {
206
+ var options = key;
207
+
208
+ if ( arguments.length === 0 ) {
209
+ // don't return a reference to the internal hash
210
+ return $.extend( {}, this.options );
211
+ }
191
212
 
192
- // redactor
193
- (function($){
194
- // Initialization
195
- $.fn.redactor = function(options) {
196
- if (isiOS() || detectAndroid() || detectAndroidWebKit()) return false;
197
- var obj = new Construct(this, options);
198
- obj.init();
199
- return obj;
200
- };
201
-
202
- // Options and variables
203
- function Construct(el, options) {
204
- this.opts = $.extend({
205
- air : false,
206
- autosave : false, // false or url
207
- interval : 20, // seconds
208
- resize : true,
209
- visual : true,
210
- focus : false,
211
- autoclear : true,
212
- removeClasses : false,
213
- removeStyles : true,
214
- convertLinks : true,
215
- autoformat : true,
216
- clearOnInit : false,
217
- overlay : true, // modal overlay
218
- fileUploadCallback : false, // callback function
219
- imageUploadCallback : false, // callback function
220
-
221
- // Paths to various handlers
222
- paths : {
223
- // Editor css
224
- stylesheets : ['/assets/imperavi-rails/imperavi/wym.css'],
225
-
226
- // Toolbar
227
- toolbar : '/imperavi/toolbar.js',
228
-
229
- // Interface translations
230
- language : '/imperavi/language.js',
231
-
232
- // Typograf
233
- typograf : '/imperavi/typograf',
234
-
235
- // Dialogs
236
- // TODO Add dialogs sizes
237
- dialogs : {
238
- file : '/imperavi/file?r',
239
- fileEdit : '/imperavi/file_edit',
240
- image : '/imperavi/image?r',
241
- imageEdit : '/imperavi/image_edit',
242
- link : '/imperavi/link',
243
- table : '/imperavi/table',
244
- video : '/imperavi/video'
245
- },
246
-
247
- // Images
248
- images : {
249
- upload : '/imperavi/images',
250
- download : '/imperavi/images/777',
251
- list : '/imperavi/images.json'
252
- },
253
-
254
- // Files
255
- files : {
256
- upload : '/imperavi/files',
257
- download : '/imperavi/files/777', // /tests/file_download.php?file=
258
- remove : '/imperavi/files/777' // /tests/file_delete.php?delete=
259
- }
213
+ if (typeof key === "string" ) {
214
+ if ( value === undefined ) {
215
+ return this.options[ key ];
260
216
  }
261
- }, options);
262
-
263
- this.$el = $(el);
264
- };
217
+ options = {};
218
+ options[ key ] = value;
219
+ }
265
220
 
266
- // Functionality
267
- Construct.prototype = {
268
- init: function() {
269
- if (this.opts.air) this.opts.toolbar = 'air';
270
-
271
- // include lang and toolbar
272
- this.include();
273
-
274
- // sizes and id
275
- this.frameID = this.$el.attr('id');
276
- this.width = this.$el.css('width');
277
- this.height = this.$el.css('height');
278
-
279
- // modal overlay
280
- if ($('#redactor_imp_modal_overlay').size() == 0) {
281
- this.overlay = $('<div id="redactor_imp_modal_overlay" style="display: none;"></div>');
282
- $('body').prepend(this.overlay);
283
- }
284
-
285
- // create container
286
- this.box = $('<div id="imp_redactor_box_' + this.frameID + '" style="width: ' + this.width + ';" class="imp_redactor_box imp_redactor_box"></div>');
287
-
288
- // air box
289
- if (this.opts.air) {
290
- this.air = $('<div id="imp_redactor_air_' + this.frameID + '" class="redactor_air" style="display: none;"></div>');
291
- }
221
+ this._setOptions( options );
292
222
 
293
- // create iframe
294
- this.frame = $('<iframe frameborder="0" marginheight="0" marginwidth="0" vspace="0" hspace="0" scrolling="auto" id="imp_redactor_frame_' + this.frameID + '" style="height: ' + this.height + ';" class="imp_redactor_frame"></iframe>');
295
-
296
- this.$el.hide();
297
-
298
- // append box and frame
299
- $(this.box).insertAfter(this.$el).append(this.frame).append(this.$el);
300
-
301
- // toolbar
302
- if (this.opts.toolbar !== false) this.buildToolbar();
303
-
304
- // resizer
305
- if (this.opts.resize) {
306
- this.resizer = $('<div id="imp_redactor_resize' + this.frameID + '" class="imp_redactor_resize"><div></div></div>');
307
- $(this.box).append(this.resizer);
308
-
309
- $(this.resizer).mousedown(function(e) { this.initResize(e) }.bind2(this));
310
- }
311
-
312
- // enable
313
- this.enable(this.$el.val());
314
-
315
- $(this.doc).click(function() { this.hideAllDropDown() }.bind2(this));
316
-
317
- if (this.opts.autoclear) {
318
- $(this.doc).bind('paste', function(e) {
319
- setTimeout(function () { this.clean(); }.bind2(this), 200);
320
- }.bind2(this));
321
- }
223
+ return this;
224
+ },
225
+ _setOptions: function( options ) {
226
+ var self = this;
227
+ $.each( options, function( key, value ) {
228
+ self._setOption( key, value );
229
+ });
322
230
 
323
- // air enable
324
- this.enableAir();
325
-
326
- // doc events
327
- $(this.doc).keydown(function(e) {
328
- if (e.ctrlKey || e.metaKey) isCtrl = true;
329
- if (e.keyCode == 9) { this.execCommand('indent', false); return false; }
330
- if (e.keyCode == 66 && isCtrl) { this.execCommand('bold', 'bold'); return false; }
331
- if (e.keyCode == 73 && isCtrl) { this.execCommand('italic', 'italic'); return false; }
332
-
333
- }.bind2(this)).keyup(function(e) {
334
- isCtrl = false;
335
-
336
- if (e.keyCode == 13) {
337
- $(this.doc).linkify();
338
- return true;
339
- }
340
-
341
- this.syncCode();
342
- }.bind2(this));
343
-
344
- // autosave
345
- if (this.opts.autosave) {
346
- setInterval(function() {
347
- var html = this.getHtml();
348
- $.post(this.opts.autosave, { data: html });
349
- }.bind2(this), this.opts.interval*1000);
350
- }
351
-
352
- this.formSets();
353
-
354
- // focus
355
- if (this.opts.focus) this.focus();
356
- },
357
-
358
- /*
359
- API
360
- */
361
- setHtml: function(html) {
362
- this.doc.body.innerHTML = html;
363
- this.docObserve();
364
- },
365
-
366
- getHtml: function() {
367
- return this.doc.body.innerHTML;
368
- },
369
-
370
- getCode: function(clear) {
371
- return this.$el.val();
372
- },
373
-
374
- focus: function() {
375
- if ($.browser.msie) $(this.frame).load(function() { $(this).get(0).contentWindow.focus(); });
376
- else this.frame.get(0).contentWindow.focus();
377
- },
378
-
379
- typo: function() {
380
- var html = this.getHtml();
381
-
382
- $.ajax({
383
- url : this.opts.paths.typograf,
384
- type : 'post',
385
- data : 'redactor=' + escape(encodeURIComponent(html)),
386
- success: function(data) {
387
- this.setHtml(data);
388
- }.bind2(this)
389
- });
390
- },
391
-
392
- syncCode: function() {
393
- var html = this.getHtml();
394
-
395
- html = this.tidyUp(html);
396
- html = html.replace(/\%7B/gi, '{');
397
- html = html.replace(/\%7D/gi, '}');
398
- html = html.replace(/<hr class="redactor_cut">/gi, '<!--more-->');
399
- html = html.replace(/<hr class=redactor_cut>/gi, '<!--more-->');
400
- this.$el.val(html);
401
- },
402
-
403
- destroy: function() {
404
- var html = this.getCode();
405
- $(this.box).after(this.$el)
406
- this.box.remove();
407
- this.$el.val(html).show();
408
- },
409
-
410
- // Include
411
- include: function() {
412
- // lang
413
- $('head').append(
414
- $('<script src="' + this.opts.paths.language + '"></script>')
415
- );
416
-
417
- // toolbar
418
- // @tanraya
419
- if (this.opts.toolbar !== false) {
420
- $('head').append($('<script src="' + this.opts.paths.toolbar + '"></script>'));
421
- }
422
- },
423
-
424
- // Enable
425
- enable: function(html) {
426
- this.doc = this.contentDocumentFrame(this.frame);
427
-
428
- // flash replace
429
- html = html.replace(/\<object([\w\W]*?)\<\/object\>/gi, '<p class="redactor_video_box"><object$1</object></p>');
430
-
431
- if (html == '') {
432
- if (this.opts.autoformat === true) {
433
- html = $.browser.msie ? "<p></p>" : "<p>&nbsp;</p>";
434
- }
435
- }
436
-
437
- this.redactorWrite(this.getRedactorDoc(html));
438
- if (this.opts.clearOnInit) this.clean();
439
- this.designMode();
440
- },
441
-
442
- enableAir: function() {
443
- if (this.opts.air) {
444
- $('#imp_redactor_air_' + this.frameID).hide();
445
-
446
- $(this.doc).bind('textselect', this.frameID, function(e) {
447
- var width = $('#imp_redactor_air_' + this.frameID).width();
448
- var width_area = $(this.frame).width();
449
- var diff = width_area - e.clientX;
450
-
451
- if (diff < width) e.clientX = e.clientX - width;
452
-
453
- $('#imp_redactor_air_' + this.frameID).css({ left: e.clientX + 'px', top: (e.clientY + 8) + 'px' }).show();
454
-
455
- }.bind2(this));
456
-
457
- $(this.doc).bind('textunselect', this.frameID, function() {
458
- $('#imp_redactor_air_' + this.frameID).hide();
459
- }.bind2(this));
460
- }
461
- },
462
-
463
- redactorWrite: function(html) {
464
- this.doc.open();
465
- this.doc.write(html);
466
- this.doc.close();
467
- },
468
-
469
- getRedactorDoc: function(html) {
470
- css = '';
471
-
472
- for (stylesheet in this.opts.paths.stylesheets) {
473
- css += '<link media="all" href="' + this.opts.paths.stylesheets[stylesheet] + '" rel="stylesheet">';
474
- }
231
+ return this;
232
+ },
233
+ _setOption: function( key, value ) {
234
+ this.options[ key ] = value;
235
+
236
+ if ( key === "disabled" ) {
237
+ this.widget()
238
+ [ value ? "addClass" : "removeClass"](
239
+ this.widgetBaseClass + "-disabled" + " " +
240
+ "ui-state-disabled" )
241
+ .attr( "aria-disabled", value );
242
+ }
475
243
 
476
- var frameHtml = '<!DOCTYPE html>\n';
477
- frameHtml += '<html><head>' + css + '</head><body>';
478
- frameHtml += html;
479
- frameHtml += '</body></html>';
480
-
481
- return frameHtml;
482
- },
483
-
484
- contentDocumentFrame: function(frame) {
485
- frame = frame.get(0);
486
-
487
- if (frame.contentDocument) return frame.contentDocument;
488
- else if (frame.contentWindow && frame.contentWindow.document) return frame.contentWindow.document;
489
- else if (frame.document) return frame.document;
490
- else return null;
491
- },
492
-
493
- designMode: function() {
494
- if (this.doc) {
495
- this.doc.designMode = 'on';
496
- this.frame.load(function() {
497
- this.enableObjects();
498
- this.docObserve();
499
- this.doc.designMode = 'on';
500
- }.bind2(this));
501
- }
502
- },
503
-
504
- enableObjects: function() {
505
- if ($.browser.mozilla) {
506
- this.doc.execCommand("enableObjectResizing", false, "false");
507
- this.doc.execCommand("enableInlineTableEditing", false, "false");
508
- }
509
- },
510
-
511
-
512
- // Observers
513
- docObserve: function() {
514
- var body = $(this.doc).find('body');
515
-
516
- body.find('img').click(function(e) { this.imageEdit(e); }.bind2(this));
517
- body.find('table').click(function(e) { this.tableObserver(e); }.bind2(this));
518
- body.find('.redactor_file_link').click(function(e) { this.fileEdit(e); }.bind2(this));
519
-
520
- },
521
-
522
- // Format on submit form
523
- formSets: function() {
524
- var oldOnsubmit = null;
525
- var theForm = $(this.box).parents('form');
526
-
527
- if (theForm.length == 0) return false;
528
-
529
- oldOnsubmit = theForm.get(0).onsubmit;
530
-
531
- if (typeof theForm.get(0).onsubmit != "function") {
532
- theForm.get(0).onsubmit = function() {
533
- if (this.opts.visual) {
534
- this.syncCode();
535
- return true;
536
- }
537
- }.bind2(this)
538
- } else {
539
- theForm.get(0).onsubmit = function() {
540
- if (this.opts.visual) {
541
- this.syncCode();
542
- return oldOnsubmit();
543
- }
544
- }.bind2(this)
545
- }
546
-
547
- return true;
548
- },
549
-
550
- // Exec
551
- execCommand: function(cmd, param) {
552
- if (this.opts.visual && this.doc) {
553
- try {
554
- this.frame.get(0).contentWindow.focus();
555
-
556
- if (cmd == 'inserthtml' && $.browser.msie) {
557
- this.doc.selection.createRange().pasteHTML(param);
558
- } else {
559
- this.doc.execCommand(cmd, false, param);
560
-
561
- if (param == "blockquote" || param == 'pre')
562
- this.doc.body.appendChild(this.doc.createElement("BR"));
563
- }
564
- } catch (e) { }
565
-
566
- this.syncCode();
567
- if (this.opts.air) $('#imp_redactor_air_' + this.frameID).hide();
568
- }
569
- },
570
-
571
- // Format and clean
572
- clean: function() {
573
- var html = this.getHtml();
574
-
575
- if ($.browser.mozilla) html = this.convertSpan(html);
576
-
577
- // strip tags
578
- html = html.replace(/<(?!\s*\/?(a|br|p|b|i|strong|em|table|tr|td|th|tbody|thead|tfoot|h2|h3|h4)\b)[^>]+>/ig,"");
579
-
580
- if (this.opts.removeStyles) html = html.replace(/ style=".*?"/g, '');
581
- if (this.opts.removeClasses) html = html.replace(/ class=".*?"/g, '');
582
-
583
- html = this.tidyUp(html);
584
-
585
- this.setHtml(html);
586
- this.paragraphise();
587
-
588
- return html;
589
- },
590
-
591
- tidyUp: function (html) {
592
- // lowercase
593
- if ($.browser.msie)
594
- {
595
- html = html.replace(/< *(\/ *)?(\w+)/g,function(w){return w.toLowerCase()});
596
- html = html.replace(/ jQuery(.*?)=\"(.*?)\"/gi, '');
597
- }
598
-
599
- if (this.opts.convertLinks) html = this.convertLinks(html);
600
-
601
- html = html.replace(/[\t]*/g, '');
602
- html = html.replace(/[\r\n]*/g, '');
603
- html = html.replace(/\n\s*\n/g, "\n");
604
- html = html.replace(/^[\s\n]*/, '');
605
- html = html.replace(/[\s\n]*$/, '');
606
-
607
- var lb = '\r\n';
608
- var btags = ["<html","</html>","</head>","<title","</title>","<meta","<link","<style","</style>","</body>","<body","<head","<div","<p","<form","<fieldset","<label","</label>","<legend","</legend>","<object","</object>","<embed","</embed>","<select","</select>","<option","<option","<input","<textarea","</textarea>","</form>","</fieldset>","<br>","<br />","<hr","<pre","</pre>","<blockquote","</blockquote>","<ul","</ul>","<ol","</ol>","<li","<dl","</dl>","<dt","</dt>","<dd","</dd>","<\!--","<table","</table>","</thead>","<tbody","</tbody>","<caption","</caption>","<th","</th>","<tr","</tr>","<td","<script","</script>","<noscript","</noscript>"];
609
- for (i = 0; i < btags.length; ++i)
610
- {
611
- var bbb = btags[i];
612
- html = html.replace(new RegExp(bbb,'gi'),lb+bbb);
613
- }
614
-
615
- // indenting
616
- html = html.replace(/<li/g, "\t<li");
617
- html = html.replace(/<tr/g, "\t<tr");
618
- html = html.replace(/<td/g, "\t\t<td");
619
- html = html.replace(/<\/tr>/g, "\t</tr>");
620
-
621
- // empty tags
622
- var btags = ["<pre></pre>","<blockquote></blockquote>","<ul></ul>","<ol></ol>","<li></li>","<table></table>","<tr></tr>","<span><span>", "<p>&nbsp;</p>", "<p></p>", "<p><br></p>", "<div></div>"];
623
- for (i = 0; i < btags.length; ++i)
624
- {
625
- var bbb = btags[i];
626
- html = html.replace(new RegExp(bbb,'gi'), "");
627
- }
628
-
629
- return html;
630
- },
631
-
632
- convertLinks: function(html)
633
- {
634
- html = html.replace(/\<a(.*?)href="http:\/\/(.*?)"(.*?)>([\w\W]*?)\<\/a\>/gi, "<a$1href=\"rttp://$2\"$3>$4</a>");
635
- html = html.replace(/\<a(.*?)href="rttp:\/\/(.*?)"(.*?)>http:\/\/([\w\W]*?)\<\/a\>/gi, "<a$1href=\"rttp://$2\"$3>rttp:\/\/$4</a>");
636
-
637
- //var url1 = /(^|>|\s)(www\..+?\..+?)(\s|<|$)/g;
638
- var url2 = /(^|>|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|<|$)/g;
639
-
640
- //html = html.replace(url1, '$1<a href="http://$2">$2</a>$3')
641
- html = html.replace(url2, '$1<a href="$2">$2</a>$5');
642
-
643
- html = html.replace(/\<a(.*?)href="rttp:\/\/(.*?)"(.*?)>([\w\W]*?)\<\/a\>/gi, "<a$1href=\"http://$2\"$3>$4</a>");
644
- html = html.replace(/\<a(.*?)href="http:\/\/(.*?)"(.*?)>rttp:\/\/([\w\W]*?)\<\/a\>/gi, "<a$1href=\"http://$2\"$3>http://$4</a>");
645
-
646
- return html;
647
- },
648
-
649
- convertSpan: function(html)
650
- {
651
- html = html.replace(/\<span(.*?)style="font-weight: bold;"\>([\w\W]*?)\<\/span\>/gi, "<strong>$2</strong>");
652
- html = html.replace(/\<span(.*?)style="font-style: italic;"\>([\w\W]*?)\<\/span\>/gi, "<em>$2</em>");
653
- html = html.replace(/\<span(.*?)style="font-weight: bold; font-style: italic;"\>([\w\W]*?)\<\/span\>/gi, "<em><strong>$2</strong></em>");
654
- html = html.replace(/\<span(.*?)style="font-style: italic; font-weight: bold;"\>([\w\W]*?)\<\/span\>/gi, "<strong><em>$2</em></strong>");
655
-
656
- return html;
657
- },
658
-
659
- /*
660
- Paragraphise
661
- */
662
- paragraphise: function()
663
- {
664
-
665
- if (this.opts.autoformat === false) return true;
666
- if (this.opts.visual)
667
- {
668
- var theBody = this.doc.body;
669
-
670
- /* Remove all text nodes containing just whitespace */
671
- for (var i = 0; i < theBody.childNodes.length; i++)
672
- {
673
- if (theBody.childNodes[i].nodeName.toLowerCase() == "#text" && theBody.childNodes[i].data.search(/^\s*$/) != -1)
674
- {
675
- theBody.removeChild(theBody.childNodes[i]);
676
- i--;
677
- }
244
+ return this;
245
+ },
246
+
247
+ enable: function() {
248
+ return this._setOption( "disabled", false );
249
+ },
250
+ disable: function() {
251
+ return this._setOption( "disabled", true );
252
+ },
253
+
254
+ _trigger: function( type, event, data ) {
255
+ var prop, orig,
256
+ callback = this.options[ type ];
257
+
258
+ data = data || {};
259
+ event = $.Event( event );
260
+ event.type = ( type === this.widgetEventPrefix ?
261
+ type :
262
+ this.widgetEventPrefix + type ).toLowerCase();
263
+ // the original event may come from any element
264
+ // so we need to reset the target on the new event
265
+ event.target = this.element[ 0 ];
266
+
267
+ // copy original event properties over to the new event
268
+ orig = event.originalEvent;
269
+ if ( orig ) {
270
+ for ( prop in orig ) {
271
+ if ( !( prop in event ) ) {
272
+ event[ prop ] = orig[ prop ];
678
273
  }
679
-
680
- var removedElements = new Array();
681
- for (var i = 0; i < theBody.childNodes.length; i++)
682
- {
683
- if (theBody.childNodes[i].nodeName.isInlineName())
684
- {
685
- removedElements.push(theBody.childNodes[i].cloneNode(true));
686
- theBody.removeChild(theBody.childNodes[i]);
687
- i--;
688
- }
689
- else if (theBody.childNodes[i].nodeName.toLowerCase() == "br")
690
- {
691
- if (i + 1 < theBody.childNodes.length)
692
- {
693
- if (theBody.childNodes[i + 1].nodeName.toLowerCase() == "br")
694
- {
695
- while (i < theBody.childNodes.length && theBody.childNodes[i].nodeName.toLowerCase() == "br")
696
- {
697
- theBody.removeChild(theBody.childNodes[i]);
698
- }
699
-
700
- if (removedElements.length > 0)
701
- {
702
- this.insertNewParagraph(removedElements, theBody.childNodes[i]);
703
- removedElements = new Array();
704
- }
705
- }
706
- else if (!theBody.childNodes[i + 1].nodeName.isInlineName()) theBody.removeChild(theBody.childNodes[i]);
707
- else if (removedElements.length > 0)
708
- {
709
- removedElements.push(theBody.childNodes[i].cloneNode(true));
710
- theBody.removeChild(theBody.childNodes[i]);
711
- }
712
- else theBody.removeChild(theBody.childNodes[i]);
713
- i--;
714
- }
715
- else theBody.removeChild(theBody.childNodes[i]);
716
- }
717
- else if (removedElements.length > 0)
718
- {
719
- this.insertNewParagraph(removedElements, theBody.childNodes[i]);
720
- removedElements = new Array();
721
- }
722
- }
723
-
724
- if (removedElements.length > 0) this.insertNewParagraph(removedElements);
725
- }
726
-
727
- return true;
728
- },
729
- insertNewParagraph: function(elementArray, succeedingElement)
730
- {
731
- var theBody = this.doc.getElementsByTagName("body")[0];
732
- var theParagraph = this.doc.createElement("p");
733
-
734
- for (var i = 0; i < elementArray.length; i++) theParagraph.appendChild(elementArray[i]);
735
-
736
- if (typeof(succeedingElement) != "undefined") theBody.insertBefore(theParagraph, succeedingElement);
737
- else theBody.appendChild(theParagraph);
738
-
739
- return true;
740
- },
741
-
742
- /*
743
- Selection
744
- */
745
- get_selection: function ()
746
- {
747
- if (this.frame.get(0).contentWindow.getSelection) return this.frame.get(0).contentWindow.getSelection();
748
- else if (this.frame.get(0).contentWindow.document.selection) return this.frame.contentWindow.get(0).document.selection.createRange();
749
- },
750
-
751
- setCut: function()
752
- {
753
- this.execCommand('inserthtml', '<hr class="redactor_cut" />');
754
- },
755
-
756
- /*
757
- Toggle
758
- */
759
- toggle: function()
760
- {
761
- if (this.opts.visual)
762
- {
763
- this.addSelButton('html');
764
-
765
- var html = this.getHtml();
766
-
767
- html = this.tidyUp(html);
768
-
769
- html = html.replace(/\%7B/gi, '{');
770
- html = html.replace(/\%7D/gi, '}');
771
-
772
- // flash replace
773
- html = html.replace(/<p(.*?)class="redactor_video_box"(.*?)>([\w\W]*?)\<\/p>/gi, "$3");
774
-
775
- // files replace
776
- html = html.replace(/<a(.*?)rel="(.*?)"(.*?)class="redactor_file_link(.*?)"(.*?)>([\w\W]*?)\<\/a>/gi, "<a href=\"" + this.opts.paths.files.download + "$2\" rel=\"$2\" class=\"redactor_file_link$4\">$6</a>");
777
-
778
- // cut replace
779
- html = html.replace(/<hr class="redactor_cut"\/>/gi, '<!--more-->');
780
- html = html.replace(/<hr class=redactor_cut>/gi, '<!--more-->');
781
-
782
-
783
- this.frame.hide();
784
- this.$el.val(html);
785
- this.$el.show().focus();
786
-
787
- var height = this.$el.height();
788
-
789
- this.opts.visual = false;
790
274
  }
791
- else
792
- {
793
- this.removeSelButton('html');
794
- this.$el.hide();
795
-
796
- var html = this.$el.val();
797
-
798
- // cut replace
799
- html = html.replace(/<!--more-->/gi, '<hr class="redactor_cut"/>');
800
-
801
- // flash replace
802
- html = html.replace(/\<object([\w\W]*?)\<\/object\>/gi, '<p class="redactor_video_box"><object$1</object></p>');
803
-
804
- // files replace
805
- html = html.replace(/<a(.*?)href="(.*?)"(.*?)rel="(.*?)"(.*?)class="redactor_file_link(.*?)">(.*?)<\/a>/gi, "<a href=\"javascript:void(null);\" rel=\"$4\" class=\"redactor_file_link$6\">$7</a>");
806
-
807
-
808
- this.opts.visual = true;
809
-
810
- this.setHtml(html);
811
-
812
- this.frame.show();
813
- this.focus();
814
- }
815
- },
816
-
817
-
818
- /*
819
- Video
820
- */
821
- showVideo: function()
822
- {
823
- redactorActive = this;
824
- this.modalInit(RLANG.video, this.opts.paths.dialogs.video, 600, 360, function()
825
- {
826
- $('#redactor_insert_video_area').focus();
827
- });
828
- },
829
- insertVideo: function()
830
- {
831
- var data = $('#redactor_insert_video_area').val();
832
- if (redactorActive.opts.visual)
833
- {
834
- // iframe video
835
- if (data.search('iframe')) {}
836
- // flash
837
- else data = '<p class="redactor_video_box">' + data + '</p>';
838
- }
839
-
840
- redactorActive.execCommand('inserthtml', data);
841
- this.modalClose();
842
-
843
- },
844
-
845
-
846
-
847
- /*
848
- File
849
- */
850
- showFile: function()
851
- {
852
- redactorActive = this;
853
-
854
- var handler = function()
855
- {
856
- // upload params
857
- var params = '';
858
- if (this.opts.fileUploadCallback) params = this.opts.fileUploadCallback();
859
-
860
- $('#redactor_file').dragupload(
861
- {
862
- url: this.opts.paths.files.upload + params,
863
- success: function(data)
864
- {
865
- this.fileUploadCallback(data);
866
-
867
- }.bind2(this)
275
+ }
276
+
277
+ this.element.trigger( event, data );
278
+
279
+ return !( $.isFunction(callback) &&
280
+ callback.call( this.element[0], event, data ) === false ||
281
+ event.isDefaultPrevented() );
282
+ }
283
+ };
284
+
285
+ }));
286
+ /*
287
+ * jQuery Iframe Transport Plugin 1.3
288
+ * https://github.com/blueimp/jQuery-File-Upload
289
+ *
290
+ * Copyright 2011, Sebastian Tschan
291
+ * https://blueimp.net
292
+ *
293
+ * Licensed under the MIT license:
294
+ * http://www.opensource.org/licenses/MIT
295
+ */
296
+
297
+ /*jslint unparam: true, nomen: true */
298
+ /*global define, window, document */
299
+
300
+
301
+ (function (factory) {
302
+ 'use strict';
303
+ if (typeof define === 'function' && define.amd) {
304
+ // Register as an anonymous AMD module:
305
+ define(['jquery'], factory);
306
+ } else {
307
+ // Browser globals:
308
+ factory(window.jQuery);
309
+ }
310
+ }(function ($) {
311
+ 'use strict';
312
+
313
+ // Helper variable to create unique names for the transport iframes:
314
+ var counter = 0;
315
+
316
+ // The iframe transport accepts three additional options:
317
+ // options.fileInput: a jQuery collection of file input fields
318
+ // options.paramName: the parameter name for the file form data,
319
+ // overrides the name property of the file input field(s)
320
+ // options.formData: an array of objects with name and value properties,
321
+ // equivalent to the return data of .serializeArray(), e.g.:
322
+ // [{name: 'a', value: 1}, {name: 'b', value: 2}]
323
+ $.ajaxTransport('iframe', function (options) {
324
+ if (options.async && (options.type === 'POST' || options.type === 'GET')) {
325
+ var form,
326
+ iframe;
327
+ return {
328
+ send: function (_, completeCallback) {
329
+ form = $('<form style="display:none;"></form>');
330
+ // javascript:false as initial iframe src
331
+ // prevents warning popups on HTTPS in IE6.
332
+ // IE versions below IE8 cannot set the name property of
333
+ // elements that have already been added to the DOM,
334
+ // so we set the name along with the iframe HTML markup:
335
+ iframe = $(
336
+ '<iframe src="javascript:false;" name="iframe-transport-' +
337
+ (counter += 1) + '"></iframe>'
338
+ ).bind('load', function () {
339
+ var fileInputClones;
340
+ iframe
341
+ .unbind('load')
342
+ .bind('load', function () {
343
+ var response;
344
+ // Wrap in a try/catch block to catch exceptions thrown
345
+ // when trying to access cross-domain iframe contents:
346
+ try {
347
+ response = iframe.contents();
348
+ // Google Chrome and Firefox do not throw an
349
+ // exception when calling iframe.contents() on
350
+ // cross-domain requests, so we unify the response:
351
+ if (!response.length || !response[0].firstChild) {
352
+ throw new Error();
353
+ }
354
+ } catch (e) {
355
+ response = undefined;
356
+ }
357
+ // The complete callback returns the
358
+ // iframe content document as response object:
359
+ completeCallback(
360
+ 200,
361
+ 'success',
362
+ {'iframe': response}
363
+ );
364
+ // Fix for IE endless progress bar activity bug
365
+ // (happens on form submits to iframe targets):
366
+ $('<iframe src="javascript:false;"></iframe>')
367
+ .appendTo(form);
368
+ form.remove();
369
+ });
370
+ form
371
+ .prop('target', iframe.prop('name'))
372
+ .prop('action', options.url)
373
+ .prop('method', options.type);
374
+ if (options.formData) {
375
+ $.each(options.formData, function (index, field) {
376
+ $('<input type="hidden"/>')
377
+ .prop('name', field.name)
378
+ .val(field.value)
379
+ .appendTo(form);
380
+ });
381
+ }
382
+ if (options.fileInput && options.fileInput.length &&
383
+ options.type === 'POST') {
384
+ fileInputClones = options.fileInput.clone();
385
+ // Insert a clone for each file input field:
386
+ options.fileInput.after(function (index) {
387
+ return fileInputClones[index];
388
+ });
389
+ if (options.paramName) {
390
+ options.fileInput.each(function () {
391
+ $(this).prop('name', options.paramName);
392
+ });
393
+ }
394
+ // Appending the file input fields to the hidden form
395
+ // removes them from their original location:
396
+ form
397
+ .append(options.fileInput)
398
+ .prop('enctype', 'multipart/form-data')
399
+ // enctype must be set as encoding for IE:
400
+ .prop('encoding', 'multipart/form-data');
401
+ }
402
+ form.submit();
403
+ // Insert the file input fields at their original location
404
+ // by replacing the clones with the originals:
405
+ if (fileInputClones && fileInputClones.length) {
406
+ options.fileInput.each(function (index, input) {
407
+ var clone = $(fileInputClones[index]);
408
+ $(input).prop('name', clone.prop('name'));
409
+ clone.replaceWith(input);
410
+ });
411
+ }
412
+ });
413
+ form.append(iframe).appendTo(document.body);
414
+ },
415
+ abort: function () {
416
+ if (iframe) {
417
+ // javascript:false as iframe src aborts the request
418
+ // and prevents warning popups on HTTPS in IE6.
419
+ // concat is used to avoid the "Script URL" JSLint error:
420
+ iframe
421
+ .unbind('load')
422
+ .prop('src', 'javascript'.concat(':false;'));
423
+ }
424
+ if (form) {
425
+ form.remove();
426
+ }
427
+ }
428
+ };
429
+ }
430
+ });
431
+
432
+ // The iframe transport returns the iframe content document as response.
433
+ // The following adds converters from iframe to text, json, html, and script:
434
+ $.ajaxSetup({
435
+ converters: {
436
+ 'iframe text': function (iframe) {
437
+ return $(iframe[0].body).text();
438
+ },
439
+ 'iframe json': function (iframe) {
440
+ return $.parseJSON($(iframe[0].body).text());
441
+ },
442
+ 'iframe html': function (iframe) {
443
+ return $(iframe[0].body).html();
444
+ },
445
+ 'iframe script': function (iframe) {
446
+ return $.globalEval($(iframe[0].body).text());
447
+ }
448
+ }
449
+ });
450
+
451
+ }));
452
+ /*
453
+ * jQuery File Upload Plugin 5.7
454
+ * https://github.com/blueimp/jQuery-File-Upload
455
+ *
456
+ * Copyright 2010, Sebastian Tschan
457
+ * https://blueimp.net
458
+ *
459
+ * Licensed under the MIT license:
460
+ * http://www.opensource.org/licenses/MIT
461
+ */
462
+
463
+ /*jslint nomen: true, unparam: true, regexp: true */
464
+ /*global define, window, document, XMLHttpRequestUpload, Blob, File, FormData, location */
465
+
466
+
467
+ (function (factory) {
468
+ 'use strict';
469
+ if (typeof define === 'function' && define.amd) {
470
+ // Register as an anonymous AMD module:
471
+ define([
472
+ 'jquery',
473
+ './vendor/jquery.ui.widget',
474
+ './jquery.iframe-transport'
475
+ ], factory);
476
+ } else {
477
+ // Browser globals:
478
+ factory(window.jQuery);
479
+ }
480
+ }(function ($) {
481
+ 'use strict';
482
+
483
+ // The fileupload widget listens for change events on file input fields defined
484
+ // via fileInput setting and paste or drop events of the given dropZone.
485
+ // In addition to the default jQuery Widget methods, the fileupload widget
486
+ // exposes the "add" and "send" methods, to add or directly send files using
487
+ // the fileupload API.
488
+ // By default, files added via file input selection, paste, drag & drop or
489
+ // "add" method are uploaded immediately, but it is possible to override
490
+ // the "add" callback option to queue file uploads.
491
+ $.widget('blueimp.fileupload', {
492
+
493
+ options: {
494
+ // The namespace used for event handler binding on the dropZone and
495
+ // fileInput collections.
496
+ // If not set, the name of the widget ("fileupload") is used.
497
+ namespace: undefined,
498
+ // The drop target collection, by the default the complete document.
499
+ // Set to null or an empty collection to disable drag & drop support:
500
+ dropZone: $(document),
501
+ // The file input field collection, that is listened for change events.
502
+ // If undefined, it is set to the file input fields inside
503
+ // of the widget element on plugin initialization.
504
+ // Set to null or an empty collection to disable the change listener.
505
+ fileInput: undefined,
506
+ // By default, the file input field is replaced with a clone after
507
+ // each input field change event. This is required for iframe transport
508
+ // queues and allows change events to be fired for the same file
509
+ // selection, but can be disabled by setting the following option to false:
510
+ replaceFileInput: true,
511
+ // The parameter name for the file form data (the request argument name).
512
+ // If undefined or empty, the name property of the file input field is
513
+ // used, or "files[]" if the file input name property is also empty:
514
+ paramName: undefined,
515
+ // By default, each file of a selection is uploaded using an individual
516
+ // request for XHR type uploads. Set to false to upload file
517
+ // selections in one request each:
518
+ singleFileUploads: true,
519
+ // To limit the number of files uploaded with one XHR request,
520
+ // set the following option to an integer greater than 0:
521
+ limitMultiFileUploads: undefined,
522
+ // Set the following option to true to issue all file upload requests
523
+ // in a sequential order:
524
+ sequentialUploads: false,
525
+ // To limit the number of concurrent uploads,
526
+ // set the following option to an integer greater than 0:
527
+ limitConcurrentUploads: undefined,
528
+ // Set the following option to true to force iframe transport uploads:
529
+ forceIframeTransport: false,
530
+ // Set the following option to the location of a redirect url on the
531
+ // origin server, for cross-domain iframe transport uploads:
532
+ redirect: undefined,
533
+ // The parameter name for the redirect url, sent as part of the form
534
+ // data and set to 'redirect' if this option is empty:
535
+ redirectParamName: undefined,
536
+ // Set the following option to the location of a postMessage window,
537
+ // to enable postMessage transport uploads:
538
+ postMessage: undefined,
539
+ // By default, XHR file uploads are sent as multipart/form-data.
540
+ // The iframe transport is always using multipart/form-data.
541
+ // Set to false to enable non-multipart XHR uploads:
542
+ multipart: true,
543
+ // To upload large files in smaller chunks, set the following option
544
+ // to a preferred maximum chunk size. If set to 0, null or undefined,
545
+ // or the browser does not support the required Blob API, files will
546
+ // be uploaded as a whole.
547
+ maxChunkSize: undefined,
548
+ // When a non-multipart upload or a chunked multipart upload has been
549
+ // aborted, this option can be used to resume the upload by setting
550
+ // it to the size of the already uploaded bytes. This option is most
551
+ // useful when modifying the options object inside of the "add" or
552
+ // "send" callbacks, as the options are cloned for each file upload.
553
+ uploadedBytes: undefined,
554
+ // By default, failed (abort or error) file uploads are removed from the
555
+ // global progress calculation. Set the following option to false to
556
+ // prevent recalculating the global progress data:
557
+ recalculateProgress: true,
558
+
559
+ // Additional form data to be sent along with the file uploads can be set
560
+ // using this option, which accepts an array of objects with name and
561
+ // value properties, a function returning such an array, a FormData
562
+ // object (for XHR file uploads), or a simple object.
563
+ // The form of the first fileInput is given as parameter to the function:
564
+ formData: function (form) {
565
+ return form.serializeArray();
566
+ },
567
+
568
+ // The add callback is invoked as soon as files are added to the fileupload
569
+ // widget (via file input selection, drag & drop, paste or add API call).
570
+ // If the singleFileUploads option is enabled, this callback will be
571
+ // called once for each file in the selection for XHR file uplaods, else
572
+ // once for each file selection.
573
+ // The upload starts when the submit method is invoked on the data parameter.
574
+ // The data object contains a files property holding the added files
575
+ // and allows to override plugin options as well as define ajax settings.
576
+ // Listeners for this callback can also be bound the following way:
577
+ // .bind('fileuploadadd', func);
578
+ // data.submit() returns a Promise object and allows to attach additional
579
+ // handlers using jQuery's Deferred callbacks:
580
+ // data.submit().done(func).fail(func).always(func);
581
+ add: function (e, data) {
582
+ data.submit();
583
+ },
584
+
585
+ // Other callbacks:
586
+ // Callback for the submit event of each file upload:
587
+ // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
588
+ // Callback for the start of each file upload request:
589
+ // send: function (e, data) {}, // .bind('fileuploadsend', func);
590
+ // Callback for successful uploads:
591
+ // done: function (e, data) {}, // .bind('fileuploaddone', func);
592
+ // Callback for failed (abort or error) uploads:
593
+ // fail: function (e, data) {}, // .bind('fileuploadfail', func);
594
+ // Callback for completed (success, abort or error) requests:
595
+ // always: function (e, data) {}, // .bind('fileuploadalways', func);
596
+ // Callback for upload progress events:
597
+ // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
598
+ // Callback for global upload progress events:
599
+ // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
600
+ // Callback for uploads start, equivalent to the global ajaxStart event:
601
+ // start: function (e) {}, // .bind('fileuploadstart', func);
602
+ // Callback for uploads stop, equivalent to the global ajaxStop event:
603
+ // stop: function (e) {}, // .bind('fileuploadstop', func);
604
+ // Callback for change events of the fileInput collection:
605
+ // change: function (e, data) {}, // .bind('fileuploadchange', func);
606
+ // Callback for paste events to the dropZone collection:
607
+ // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
608
+ // Callback for drop events of the dropZone collection:
609
+ // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
610
+ // Callback for dragover events of the dropZone collection:
611
+ // dragover: function (e) {}, // .bind('fileuploaddragover', func);
612
+
613
+ // The plugin options are used as settings object for the ajax calls.
614
+ // The following are jQuery ajax settings required for the file uploads:
615
+ processData: false,
616
+ contentType: false,
617
+ cache: false
618
+ },
619
+
620
+ // A list of options that require a refresh after assigning a new value:
621
+ _refreshOptionsList: ['namespace', 'dropZone', 'fileInput'],
622
+
623
+ _isXHRUpload: function (options) {
624
+ var undef = 'undefined';
625
+ return !options.forceIframeTransport &&
626
+ typeof XMLHttpRequestUpload !== undef && typeof File !== undef &&
627
+ (!options.multipart || typeof FormData !== undef);
628
+ },
629
+
630
+ _getFormData: function (options) {
631
+ var formData;
632
+ if (typeof options.formData === 'function') {
633
+ return options.formData(options.form);
634
+ } else if ($.isArray(options.formData)) {
635
+ return options.formData;
636
+ } else if (options.formData) {
637
+ formData = [];
638
+ $.each(options.formData, function (name, value) {
639
+ formData.push({name: name, value: value});
868
640
  });
869
-
870
- this.uploadInit('redactor_file', { auto: true, url: this.opts.paths.files.upload + params, success: function(data) {
871
-
872
- this.fileUploadCallback(data);
873
-
874
- }.bind2(this) });
875
-
876
-
877
- }.bind2(this);
878
-
879
-
880
- redactorActive = this;
881
- this.modalInit(RLANG.file, this.opts.paths.dialogs.file, 500, 400, handler);
882
- },
883
- fileUploadCallback: function(data)
884
- {
885
- redactorActive.frame.get(0).contentWindow.focus();
886
- redactorActive.execCommand('inserthtml', data);
887
- this.modalClose();
888
- this.docObserve();
889
- },
890
- fileEdit: function(e)
891
- {
892
- var el = e.target;
893
- var file_id = $(el).attr('rel');
894
-
895
- var handler = function()
896
- {
897
- $('#file').val($(el).text());
898
- $('#redactorFileDeleteBtn').click(function()
899
- {
900
- this.fileDelete(el, file_id);
901
- }.bind2(this));
902
-
903
- $('#redactorFileDownloadBtn').click(function()
904
- {
905
- this.fileDownload(el, file_id);
906
- }.bind2(this));
907
-
908
- }.bind2(this);
909
-
910
- redactorActive = this;
911
- this.modalInit(RLANG.file, this.opts.paths.dialogs.fileEdit, 400, 200, handler);
912
- },
913
- fileDelete: function(el, file_id)
914
- {
915
- $(el).remove();
916
- $.get(this.opts.paths.files.remove + file_id);
917
- redactorActive.frame.get(0).contentWindow.focus();
918
- this.modalClose();
919
- },
920
- fileDownload: function(el, file_id)
921
- {
922
- top.location.href = this.opts.paths.files.download + file_id;
923
- },
924
-
925
- /*
926
- Table
927
- */
928
- showTable: function()
929
- {
930
- redactorActive = this;
931
- this.modalInit(RLANG.table, this.opts.paths.dialogs.table, 360, 200);
641
+ return formData;
642
+ }
643
+ return [];
932
644
  },
933
- insertTable: function()
934
- {
935
- var rows = $('#redactor_table_rows').val();
936
- var columns = $('#redactor_table_columns').val();
937
-
938
- var table_box = $('<div></div>');
939
-
940
- var tableid = Math.floor(Math.random() * 99999);
941
- var table = $('<table id="table' + tableid + '"><tbody></tbody></table>');
942
-
943
- for (i = 0; i < rows; i++)
944
- {
945
- var row = $('<tr></tr>')
946
- for (z = 0; z < columns; z++)
947
- {
948
- var column = $('<td>&nbsp;</td>');
949
- $(row).append(column);
950
- }
951
- $(table).append(row);
645
+
646
+ _getTotal: function (files) {
647
+ var total = 0;
648
+ $.each(files, function (index, file) {
649
+ total += file.size || 1;
650
+ });
651
+ return total;
652
+ },
653
+
654
+ _onProgress: function (e, data) {
655
+ if (e.lengthComputable) {
656
+ var total = data.total || this._getTotal(data.files),
657
+ loaded = parseInt(
658
+ e.loaded / e.total * (data.chunkSize || total),
659
+ 10
660
+ ) + (data.uploadedBytes || 0);
661
+ this._loaded += loaded - (data.loaded || data.uploadedBytes || 0);
662
+ data.lengthComputable = true;
663
+ data.loaded = loaded;
664
+ data.total = total;
665
+ // Trigger a custom progress event with a total data property set
666
+ // to the file size(s) of the current upload and a loaded data
667
+ // property calculated accordingly:
668
+ this._trigger('progress', e, data);
669
+ // Trigger a global progress event for all current file uploads,
670
+ // including ajax calls queued for sequential file uploads:
671
+ this._trigger('progressall', e, {
672
+ lengthComputable: true,
673
+ loaded: this._loaded,
674
+ total: this._total
675
+ });
952
676
  }
953
-
954
- $(table_box).append(table);
955
- var html = $(table_box).html();
956
- if ($.browser.msie) html += '<p></p>';
957
- else html += '<p>&nbsp;</p>';
958
-
959
- redactorActive.execCommand('inserthtml', html);
960
- this.enableObjects();
961
- this.docObserve();
962
- this.modalClose();
963
-
964
- $table = $(this.doc).find('body').find('#table' + tableid);
965
-
966
-
967
677
  },
968
- tableObserver: function(e)
969
- {
970
- $table = $(e.target).parents('table');
971
-
972
- $tbody = $(e.target).parents('tbody');
973
- $thead = $($table).find('thead');
974
-
975
- $current_td = $(e.target);
976
- $current_tr = $(e.target).parents('tr');
977
- },
978
- deleteTable: function()
979
- {
980
- $($table).remove();
981
- $table = false;
982
- },
983
- deleteRow: function()
984
- {
985
- $($current_tr).remove();
986
- },
987
- deleteColumn: function()
988
- {
989
- var index = $($current_td).attr('cellIndex');
990
-
991
- $($table).find('tr').each(function()
992
- {
993
- $(this).find('td').eq(index).remove();
994
- });
995
- },
996
- addHead: function()
997
- {
998
- if ($($table).find('thead').size() != 0) this.deleteHead();
999
- else
1000
- {
1001
- var tr = $($table).find('tr').first().clone();
1002
- tr.find('td').html('&nbsp;');
1003
- $thead = $('<thead></thead>');
1004
- $thead.append(tr);
1005
- $($table).prepend($thead);
678
+
679
+ _initProgressListener: function (options) {
680
+ var that = this,
681
+ xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
682
+ // Accesss to the native XHR object is required to add event listeners
683
+ // for the upload progress event:
684
+ if (xhr.upload) {
685
+ $(xhr.upload).bind('progress', function (e) {
686
+ var oe = e.originalEvent;
687
+ // Make sure the progress event properties get copied over:
688
+ e.lengthComputable = oe.lengthComputable;
689
+ e.loaded = oe.loaded;
690
+ e.total = oe.total;
691
+ that._onProgress(e, options);
692
+ });
693
+ options.xhr = function () {
694
+ return xhr;
695
+ };
1006
696
  }
1007
- },
1008
- deleteHead: function()
1009
- {
1010
- $($thead).remove();
1011
- $thead = false;
1012
- },
1013
- insertRowAbove: function()
1014
- {
1015
- this.insertRow('before');
1016
- },
1017
- insertRowBelow: function()
1018
- {
1019
- this.insertRow('after');
1020
- },
1021
- insertColumnLeft: function()
1022
- {
1023
- this.insertColumn('before');
1024
- },
1025
- insertColumnRight: function()
1026
- {
1027
- this.insertColumn('after');
1028
- },
1029
- insertRow: function(type)
1030
- {
1031
- var new_tr = $($current_tr).clone();
1032
- new_tr.find('td').html('&nbsp;');
1033
- if (type == 'after') $($current_tr).after(new_tr);
1034
- else $($current_tr).before(new_tr);
1035
- },
1036
- insertColumn: function(type)
1037
- {
1038
- var index = $($current_td).attr('cellIndex');
1039
-
1040
- $($table).find('tr').each(function(i,s)
1041
- {
1042
- var current = $(s).find('td').eq(index);
1043
- var td = current.clone();
1044
- td.html('&nbsp;');
1045
- if (type == 'after') $(current).after(td);
1046
- else $(current).before(td);
1047
- });
1048
- },
1049
-
1050
- /*
1051
- Image
1052
- */
1053
- imageEdit: function(e)
1054
- {
1055
- var handler = function()
1056
- {
1057
- var $el = $(e.target);
1058
- var src = $el.attr('src');
1059
- $('#redactor_image_edit_src').attr('href', src);
1060
- $('#redactor_image_edit_delete').click(function() { this.deleteImage(e.target); }.bind2(this));
1061
- $('#redactorSaveBtn').click(function() { this.imageSave(e.target); }.bind2(this));
1062
-
1063
- $('#redactor_file_alt').val($el.attr('alt'));
1064
-
1065
- var float = $el.css('float');
1066
- if (float == 'none') float = 0;
1067
-
1068
- $('#redactor_form_image_align').val(float);
1069
-
1070
- }.bind2(this);
1071
-
1072
- redactorActive = this;
1073
- this.modalInit(RLANG.image, this.opts.paths.dialogs.imageEdit, 380, 290, handler);
1074
697
  },
1075
- imageSave: function(el)
1076
- {
1077
- $(el).attr('alt', $('#redactor_file_alt').val());
1078
-
1079
- var style = '';
1080
- if ($('#redactor_form_image_align') != 0)
1081
- {
1082
- var float = $('#redactor_form_image_align').val();
1083
-
1084
- // @tanraya AddedClasses
1085
- $(el).removeClass('img_left').removeClass('img_right')
1086
-
1087
- if (float == 'left')
1088
- $(el).addClass('img_left');
1089
- else if (float == 'right')
1090
- $(el).addClass('img_right')
698
+
699
+ _initXHRData: function (options) {
700
+ var formData,
701
+ file = options.files[0];
702
+ if (!options.multipart || options.blob) {
703
+ // For non-multipart uploads and chunked uploads,
704
+ // file meta data is not part of the request body,
705
+ // so we transmit this data as part of the HTTP headers.
706
+ // For cross domain requests, these headers must be allowed
707
+ // via Access-Control-Allow-Headers or removed using
708
+ // the beforeSend callback:
709
+ options.headers = $.extend(options.headers, {
710
+ 'X-File-Name': file.name,
711
+ 'X-File-Type': file.type,
712
+ 'X-File-Size': file.size
713
+ });
714
+ if (!options.blob) {
715
+ // Non-chunked non-multipart upload:
716
+ options.contentType = file.type;
717
+ options.data = file;
718
+ } else if (!options.multipart) {
719
+ // Chunked non-multipart upload:
720
+ options.contentType = 'application/octet-stream';
721
+ options.data = options.blob;
722
+ }
1091
723
  }
1092
- else $(el).css({ float: 'none', margin: '0' });
724
+ if (options.multipart && typeof FormData !== 'undefined') {
725
+ if (options.postMessage) {
726
+ // window.postMessage does not allow sending FormData
727
+ // objects, so we just add the File/Blob objects to
728
+ // the formData array and let the postMessage window
729
+ // create the FormData object out of this array:
730
+ formData = this._getFormData(options);
731
+ if (options.blob) {
732
+ formData.push({
733
+ name: options.paramName,
734
+ value: options.blob
735
+ });
736
+ } else {
737
+ $.each(options.files, function (index, file) {
738
+ formData.push({
739
+ name: options.paramName,
740
+ value: file
741
+ });
742
+ });
743
+ }
744
+ } else {
745
+ if (options.formData instanceof FormData) {
746
+ formData = options.formData;
747
+ } else {
748
+ formData = new FormData();
749
+ $.each(this._getFormData(options), function (index, field) {
750
+ formData.append(field.name, field.value);
751
+ });
752
+ }
753
+ if (options.blob) {
754
+ formData.append(options.paramName, options.blob, file.name);
755
+ } else {
756
+ $.each(options.files, function (index, file) {
757
+ // File objects are also Blob instances.
758
+ // This check allows the tests to run with
759
+ // dummy objects:
760
+ if (file instanceof Blob) {
761
+ formData.append(options.paramName, file, file.name);
762
+ }
763
+ });
764
+ }
765
+ }
766
+ options.data = formData;
767
+ }
768
+ // Blob reference is not needed anymore, free memory:
769
+ options.blob = null;
770
+ },
1093
771
 
1094
- this.modalClose();
772
+ _initIframeSettings: function (options) {
773
+ // Setting the dataType to iframe enables the iframe transport:
774
+ options.dataType = 'iframe ' + (options.dataType || '');
775
+ // The iframe transport accepts a serialized array as form data:
776
+ options.formData = this._getFormData(options);
777
+ // Add redirect url to form data on cross-domain uploads:
778
+ if (options.redirect && $('<a></a>').prop('href', options.url)
779
+ .prop('host') !== location.host) {
780
+ options.formData.push({
781
+ name: options.redirectParamName || 'redirect',
782
+ value: options.redirect
783
+ });
784
+ }
1095
785
  },
1096
- deleteImage: function(el)
1097
- {
1098
- $(el).remove();
1099
- this.modalClose();
1100
- },
1101
- showImage: function()
1102
- {
1103
- this.spanid = Math.floor(Math.random() * 99999);
1104
- if (jQuery.browser.msie)
1105
- {
1106
- this.execCommand('inserthtml', '<span id="span' + this.spanid + '"></span>');
786
+
787
+ _initDataSettings: function (options) {
788
+ if (this._isXHRUpload(options)) {
789
+ if (!this._chunkedUpload(options, true)) {
790
+ if (!options.data) {
791
+ this._initXHRData(options);
792
+ }
793
+ this._initProgressListener(options);
794
+ }
795
+ if (options.postMessage) {
796
+ // Setting the dataType to postmessage enables the
797
+ // postMessage transport:
798
+ options.dataType = 'postmessage ' + (options.dataType || '');
799
+ }
800
+ } else {
801
+ this._initIframeSettings(options, 'iframe');
1107
802
  }
803
+ },
1108
804
 
1109
- var handler = function() {
1110
- if (this.opts.paths.images.list !== false) {
1111
- $.getJSON(this.opts.paths.images.list, function(data) {
1112
- $.each(data, function(key, val) {
1113
- var img = $('<img src="' + val.thumb + '" rel="' + val.image + '">');
1114
- img.click(function() { redactorActive.imageSetThumb($(this).attr('rel')); });
1115
- $('#redactor_image_box').append(img);
1116
- });
1117
- });
1118
- } else {
1119
- $('#redactor_tabs li').eq(0).remove();
1120
- $('#redactor_tabs a').eq(1).addClass('redactor_tabs_act');
1121
- $('#redactor_tabs1').hide();
1122
- $('#redactor_tabs2').show();
1123
- }
1124
-
1125
- // upload params
1126
- var params = '';
1127
- if (this.opts.imageUploadCallback) var params = this.opts.imageUploadCallback();
1128
-
1129
- $('#redactor_file').dragupload({
1130
- url : this.opts.paths.images.upload + params,
1131
- success : function(data) {
1132
- this.imageUploadCallback(data);
1133
- }.bind2(this)
1134
- });
1135
-
1136
- this.uploadInit('redactor_file', {
1137
- auto : true,
1138
- url : this.opts.paths.images.upload + params,
1139
- trigger : 'redactorUploadBtn',
1140
- success : function(data) {
1141
- this.imageUploadCallback(data);
1142
- }.bind2(this)});
1143
- }.bind2(this);
1144
-
1145
- redactorActive = this;
1146
- this.modalInit(RLANG.image, this.opts.paths.dialogs.image, 570, 450, handler);
1147
-
805
+ _initFormSettings: function (options) {
806
+ // Retrieve missing options from the input field and the
807
+ // associated form, if available:
808
+ if (!options.form || !options.form.length) {
809
+ options.form = $(options.fileInput.prop('form'));
810
+ }
811
+ if (!options.paramName) {
812
+ options.paramName = options.fileInput.prop('name') ||
813
+ 'files[]';
814
+ }
815
+ if (!options.url) {
816
+ options.url = options.form.prop('action') || location.href;
817
+ }
818
+ // The HTTP request method must be "POST" or "PUT":
819
+ options.type = (options.type || options.form.prop('method') || '')
820
+ .toUpperCase();
821
+ if (options.type !== 'POST' && options.type !== 'PUT') {
822
+ options.type = 'POST';
823
+ }
1148
824
  },
1149
- imageSetThumb: function(data)
1150
- {
1151
- this._imageSet('<img alt="" src="' + data + '" />');
825
+
826
+ _getAJAXSettings: function (data) {
827
+ var options = $.extend({}, this.options, data);
828
+ this._initFormSettings(options);
829
+ this._initDataSettings(options);
830
+ return options;
1152
831
  },
1153
- imageUploadCallback: function(data)
1154
- {
1155
- if ($('#redactor_file_link').val() != '') data = $('#redactor_file_link').val();
1156
832
 
1157
- this._imageSet(data);
1158
-
1159
- },
1160
- _imageSet: function(html)
1161
- {
1162
- redactorActive.frame.get(0).contentWindow.focus();
1163
-
1164
- if ($.browser.msie)
1165
- {
1166
- $(redactorActive.doc.getElementById('span' + redactorActive.spanid)).after(html);
1167
- $(redactorActive.doc.getElementById('span' + redactorActive.spanid)).remove();
1168
- }
1169
- else
1170
- {
1171
- redactorActive.execCommand('inserthtml', html);
833
+ // Maps jqXHR callbacks to the equivalent
834
+ // methods of the given Promise object:
835
+ _enhancePromise: function (promise) {
836
+ promise.success = promise.done;
837
+ promise.error = promise.fail;
838
+ promise.complete = promise.always;
839
+ return promise;
840
+ },
841
+
842
+ // Creates and returns a Promise object enhanced with
843
+ // the jqXHR methods abort, success, error and complete:
844
+ _getXHRPromise: function (resolveOrReject, context, args) {
845
+ var dfd = $.Deferred(),
846
+ promise = dfd.promise();
847
+ context = context || this.options.context || promise;
848
+ if (resolveOrReject === true) {
849
+ dfd.resolveWith(context, args);
850
+ } else if (resolveOrReject === false) {
851
+ dfd.rejectWith(context, args);
1172
852
  }
1173
-
1174
- this.modalClose();
1175
- this.docObserve();
853
+ promise.abort = dfd.promise;
854
+ return this._enhancePromise(promise);
1176
855
  },
1177
-
1178
-
1179
- /*
1180
- Link
1181
- */
1182
- showLink: function()
1183
- {
1184
- redactorActive = this;
1185
-
1186
- var handler = function()
1187
- {
1188
- var sel = this.get_selection();
1189
- if ($.browser.msie)
1190
- {
1191
- var temp = sel.htmlText.match(/href="(.*?)"/gi);
1192
- if (temp != null)
1193
- {
1194
- temp = new String(temp);
1195
- temp = temp.replace(/href="(.*?)"/gi, '$1');
1196
- }
1197
-
1198
- var text = sel.text;
1199
- if (temp != null) var url = temp;
1200
- else var url = '';
1201
- var title = '';
1202
- }
1203
- else
1204
- {
1205
- if (sel.anchorNode.parentNode.tagName == 'A')
1206
- {
1207
- var url = sel.anchorNode.parentNode.href;
1208
- var text = sel.anchorNode.parentNode.text;
1209
- var title = sel.anchorNode.parentNode.title;
1210
- if (sel.toString() == '') this.insert_link_node = sel.anchorNode.parentNode
1211
-
1212
- }
1213
- else
1214
- {
1215
- var text = sel.toString();
1216
- var url = '';
1217
- var title = '';
1218
- }
1219
- }
1220
856
 
1221
- $('#redactor_link_url').val(url).focus();
1222
- $('#redactor_link_text').val(text);
1223
- $('#redactor_link_title').val(title);
1224
-
1225
- }.bind2(this);
1226
-
1227
- this.modalInit(RLANG.link, this.opts.paths.dialogs.link, 400, 300, handler);
1228
-
1229
- },
1230
- insertLink: function()
1231
- {
1232
- var value = $('#redactor_link_text').val();
1233
- if (value == '') return true;
1234
-
1235
- var title = $('#redactor_link_title').val();
1236
- if (title != '') title = ' title="' + $('#redactor_link_title').val() + '"';
1237
-
1238
- if ($('#redactor_link_id_url').get(0).checked) var mailto = '';
1239
- else var mailto = 'mailto:';
1240
-
1241
- var a = '<a href="' + mailto + $('#redactor_link_url').val() + '"' + title +'>' + value + '</a> ';
1242
-
1243
- if (a)
1244
- {
1245
- if (this.insert_link_node)
1246
- {
1247
- $(this.insert_link_node).text(value);
1248
- $(this.insert_link_node).attr('href', $('#redactor_link_url').val());
1249
-
1250
- var title = $('#redactor_link_title').val();
1251
- if (title != '') $(this.insert_link_node).attr('title', title);
1252
-
1253
- this.modalClose();
1254
- }
1255
- else
1256
- {
1257
- redactorActive.frame.get(0).contentWindow.focus();
1258
- redactorActive.execCommand('inserthtml', a);
1259
- }
1260
- }
1261
-
1262
- this.modalClose();
1263
- },
1264
-
1265
-
1266
- /*
1267
- Modal
1268
- */
1269
- modalInit: function(title, url, width, height, handler, scroll)
1270
- {
1271
- if (this.opts.overlay)
1272
- {
1273
- $('#redactor_imp_modal_overlay').show();
1274
- $('#redactor_imp_modal_overlay').click(function() { this.modalClose(); }.bind2(this));
1275
- }
1276
-
1277
- if ($('#redactor_imp_modal').size() == 0)
1278
- {
1279
- this.modal = $('<div id="redactor_imp_modal" style="display: none;"><div id="redactor_imp_modal_close"></div><div id="redactor_imp_modal_header"></div><div id="redactor_imp_modal_inner"></div></div>');
1280
- $('body').append(this.modal);
1281
- }
1282
-
1283
- $('#redactor_imp_modal_close').click(function() { this.modalClose(); }.bind2(this));
1284
- $(document).keyup(function(e) { if( e.keyCode == 27) this.modalClose(); }.bind2(this));
1285
- $(this.doc).keyup(function(e) { if( e.keyCode == 27) this.modalClose(); }.bind2(this));
1286
-
1287
- $.ajax({
1288
- url: url,
1289
- success: function(data)
1290
- {
1291
- // parse lang
1292
- $.each(RLANG, function(i,s)
1293
- {
1294
- var re = new RegExp("%RLANG\." + i + "%","gi");
1295
- data = data.replace(re, s);
1296
- });
1297
-
1298
- $('#redactor_imp_modal_inner').html(data);
1299
- $('#redactor_imp_modal_header').html(title);
1300
-
1301
- if (height === false) theight = 'auto';
1302
- else theight = height + 'px';
1303
-
1304
- $('#redactor_imp_modal').css({ width: width + 'px', height: theight, marginTop: '-' + height/2 + 'px', marginLeft: '-' + width/2 + 'px' }).fadeIn('fast');
1305
-
1306
- if (scroll === true)
1307
- {
1308
- $('#imp_redactor_table_box').height(height-$('#redactor_imp_modal_header').outerHeight()-130).css('overflow', 'auto');
1309
- }
1310
-
1311
- if (typeof(handler) == 'function') handler();
1312
-
1313
-
1314
- }.bind2(this)
1315
- });
1316
- },
1317
- modalClose: function()
1318
- {
1319
-
1320
- $('#redactor_imp_modal_close').unbind('click', function() { this.modalClose(); }.bind2(this));
1321
- $('#redactor_imp_modal').fadeOut('fast', function()
1322
- {
1323
- $('#redactor_imp_modal_inner').html('');
1324
-
1325
- if (this.opts.overlay)
1326
- {
1327
- $('#redactor_imp_modal_overlay').hide();
1328
- $('#redactor_imp_modal_overlay').unbind('click', function() { this.modalClose(); }.bind2(this));
1329
- }
1330
-
1331
- $(document).unbind('keyup', function(e) { if( e.keyCode == 27) this.modalClose(); }.bind2(this));
1332
- $(this.doc).unbind('keyup', function(e) { if( e.keyCode == 27) this.modalClose(); }.bind2(this));
1333
-
1334
- }.bind2(this));
1335
-
1336
- },
1337
-
1338
- /*
1339
- Upload
1340
- */
1341
- uploadInit: function(element, options)
1342
- {
1343
- /*
1344
- Options
1345
- */
1346
- this.uploadOptions = {
1347
- url: false,
1348
- success: false,
1349
- start: false,
1350
- trigger: false,
1351
- auto: false,
1352
- input: false
857
+ // Uploads a file in multiple, sequential requests
858
+ // by splitting the file up in multiple blob chunks.
859
+ // If the second parameter is true, only tests if the file
860
+ // should be uploaded in chunks, but does not invoke any
861
+ // upload requests:
862
+ _chunkedUpload: function (options, testOnly) {
863
+ var that = this,
864
+ file = options.files[0],
865
+ fs = file.size,
866
+ ub = options.uploadedBytes = options.uploadedBytes || 0,
867
+ mcs = options.maxChunkSize || fs,
868
+ // Use the Blob methods with the slice implementation
869
+ // according to the W3C Blob API specification:
870
+ slice = file.webkitSlice || file.mozSlice || file.slice,
871
+ upload,
872
+ n,
873
+ jqXHR,
874
+ pipe;
875
+ if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
876
+ options.data) {
877
+ return false;
878
+ }
879
+ if (testOnly) {
880
+ return true;
881
+ }
882
+ if (ub >= fs) {
883
+ file.error = 'uploadedBytes';
884
+ return this._getXHRPromise(
885
+ false,
886
+ options.context,
887
+ [null, 'error', file.error]
888
+ );
889
+ }
890
+ // n is the number of blobs to upload,
891
+ // calculated via filesize, uploaded bytes and max chunk size:
892
+ n = Math.ceil((fs - ub) / mcs);
893
+ // The chunk upload method accepting the chunk number as parameter:
894
+ upload = function (i) {
895
+ if (!i) {
896
+ return that._getXHRPromise(true, options.context);
897
+ }
898
+ // Upload the blobs in sequential order:
899
+ return upload(i -= 1).pipe(function () {
900
+ // Clone the options object for each chunk upload:
901
+ var o = $.extend({}, options);
902
+ o.blob = slice.call(
903
+ file,
904
+ ub + i * mcs,
905
+ ub + (i + 1) * mcs
906
+ );
907
+ // Store the current chunk size, as the blob itself
908
+ // will be dereferenced after data processing:
909
+ o.chunkSize = o.blob.size;
910
+ // Process the upload data (the blob and potential form data):
911
+ that._initXHRData(o);
912
+ // Add progress listeners for this chunk upload:
913
+ that._initProgressListener(o);
914
+ jqXHR = ($.ajax(o) || that._getXHRPromise(false, o.context))
915
+ .done(function () {
916
+ // Create a progress event if upload is done and
917
+ // no progress event has been invoked for this chunk:
918
+ if (!o.loaded) {
919
+ that._onProgress($.Event('progress', {
920
+ lengthComputable: true,
921
+ loaded: o.chunkSize,
922
+ total: o.chunkSize
923
+ }), o);
924
+ }
925
+ options.uploadedBytes = o.uploadedBytes +=
926
+ o.chunkSize;
927
+ });
928
+ return jqXHR;
929
+ });
1353
930
  };
1354
-
1355
- $.extend(this.uploadOptions, options);
1356
-
1357
-
1358
- // Test input or form
1359
- if ($('#' + element).get(0).tagName == 'INPUT')
1360
- {
1361
- this.uploadOptions.input = $('#' + element);
1362
- this.element = $($('#' + element).get(0).form);
931
+ // Return the piped Promise object, enhanced with an abort method,
932
+ // which is delegated to the jqXHR object of the current upload,
933
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
934
+ pipe = upload(n);
935
+ pipe.abort = function () {
936
+ return jqXHR.abort();
937
+ };
938
+ return this._enhancePromise(pipe);
939
+ },
940
+
941
+ _beforeSend: function (e, data) {
942
+ if (this._active === 0) {
943
+ // the start callback is triggered when an upload starts
944
+ // and no other uploads are currently running,
945
+ // equivalent to the global ajaxStart event:
946
+ this._trigger('start');
1363
947
  }
1364
- else
1365
- {
1366
- this.element = $('#' + element);
948
+ this._active += 1;
949
+ // Initialize the global progress values:
950
+ this._loaded += data.uploadedBytes || 0;
951
+ this._total += this._getTotal(data.files);
952
+ },
953
+
954
+ _onDone: function (result, textStatus, jqXHR, options) {
955
+ if (!this._isXHRUpload(options)) {
956
+ // Create a progress event for each iframe load:
957
+ this._onProgress($.Event('progress', {
958
+ lengthComputable: true,
959
+ loaded: 1,
960
+ total: 1
961
+ }), options);
1367
962
  }
1368
-
1369
-
1370
- this.element_action = this.element.attr('action');
1371
-
1372
- // Auto or trigger
1373
- if (this.uploadOptions.auto)
1374
- {
1375
- $(this.uploadOptions.input).change(function()
1376
- {
1377
- this.element.submit(function(e) { return false; });
1378
- this.uploadSubmit();
1379
- }.bind2(this));
963
+ options.result = result;
964
+ options.textStatus = textStatus;
965
+ options.jqXHR = jqXHR;
966
+ this._trigger('done', null, options);
967
+ },
968
+
969
+ _onFail: function (jqXHR, textStatus, errorThrown, options) {
970
+ options.jqXHR = jqXHR;
971
+ options.textStatus = textStatus;
972
+ options.errorThrown = errorThrown;
973
+ this._trigger('fail', null, options);
974
+ if (options.recalculateProgress) {
975
+ // Remove the failed (error or abort) file upload from
976
+ // the global progress calculation:
977
+ this._loaded -= options.loaded || options.uploadedBytes || 0;
978
+ this._total -= options.total || this._getTotal(options.files);
979
+ }
980
+ },
1380
981
 
982
+ _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
983
+ this._active -= 1;
984
+ options.textStatus = textStatus;
985
+ if (jqXHRorError && jqXHRorError.always) {
986
+ options.jqXHR = jqXHRorError;
987
+ options.result = jqXHRorResult;
988
+ } else {
989
+ options.jqXHR = jqXHRorResult;
990
+ options.errorThrown = jqXHRorError;
1381
991
  }
1382
- else if (this.uploadOptions.trigger)
1383
- {
1384
- $('#' + this.uploadOptions.trigger).click(function() { this.uploadSubmit(); }.bind2(this));
992
+ this._trigger('always', null, options);
993
+ if (this._active === 0) {
994
+ // The stop callback is triggered when all uploads have
995
+ // been completed, equivalent to the global ajaxStop event:
996
+ this._trigger('stop');
997
+ // Reset the global progress values:
998
+ this._loaded = this._total = 0;
1385
999
  }
1386
1000
  },
1387
- uploadSubmit : function()
1388
- {
1389
- this.uploadForm(this.element, this.uploadFrame());
1390
- },
1391
- uploadFrame : function()
1392
- {
1393
- this.id = 'f' + Math.floor(Math.random() * 99999);
1394
-
1395
- var d = document.createElement('div');
1396
- var iframe = '<iframe style="display:none" src="about:blank" id="'+this.id+'" name="'+this.id+'"></iframe>';
1397
- d.innerHTML = iframe;
1398
- document.body.appendChild(d);
1399
-
1400
- // Start
1401
- if (this.uploadOptions.start) this.uploadOptions.start();
1402
-
1403
- $('#' + this.id).load(function () { this.uploadLoaded() }.bind2(this));
1404
-
1405
- return this.id;
1001
+
1002
+ _onSend: function (e, data) {
1003
+ var that = this,
1004
+ jqXHR,
1005
+ slot,
1006
+ pipe,
1007
+ options = that._getAJAXSettings(data),
1008
+ send = function (resolve, args) {
1009
+ that._sending += 1;
1010
+ jqXHR = jqXHR || (
1011
+ (resolve !== false &&
1012
+ that._trigger('send', e, options) !== false &&
1013
+ (that._chunkedUpload(options) || $.ajax(options))) ||
1014
+ that._getXHRPromise(false, options.context, args)
1015
+ ).done(function (result, textStatus, jqXHR) {
1016
+ that._onDone(result, textStatus, jqXHR, options);
1017
+ }).fail(function (jqXHR, textStatus, errorThrown) {
1018
+ that._onFail(jqXHR, textStatus, errorThrown, options);
1019
+ }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
1020
+ that._sending -= 1;
1021
+ that._onAlways(
1022
+ jqXHRorResult,
1023
+ textStatus,
1024
+ jqXHRorError,
1025
+ options
1026
+ );
1027
+ if (options.limitConcurrentUploads &&
1028
+ options.limitConcurrentUploads > that._sending) {
1029
+ // Start the next queued upload,
1030
+ // that has not been aborted:
1031
+ var nextSlot = that._slots.shift();
1032
+ while (nextSlot) {
1033
+ if (!nextSlot.isRejected()) {
1034
+ nextSlot.resolve();
1035
+ break;
1036
+ }
1037
+ nextSlot = that._slots.shift();
1038
+ }
1039
+ }
1040
+ });
1041
+ return jqXHR;
1042
+ };
1043
+ this._beforeSend(e, options);
1044
+ if (this.options.sequentialUploads ||
1045
+ (this.options.limitConcurrentUploads &&
1046
+ this.options.limitConcurrentUploads <= this._sending)) {
1047
+ if (this.options.limitConcurrentUploads > 1) {
1048
+ slot = $.Deferred();
1049
+ this._slots.push(slot);
1050
+ pipe = slot.pipe(send);
1051
+ } else {
1052
+ pipe = (this._sequence = this._sequence.pipe(send, send));
1053
+ }
1054
+ // Return the piped Promise object, enhanced with an abort method,
1055
+ // which is delegated to the jqXHR object of the current upload,
1056
+ // and jqXHR callbacks mapped to the equivalent Promise methods:
1057
+ pipe.abort = function () {
1058
+ var args = [undefined, 'abort', 'abort'];
1059
+ if (!jqXHR) {
1060
+ if (slot) {
1061
+ slot.rejectWith(args);
1062
+ }
1063
+ return send(false, args);
1064
+ }
1065
+ return jqXHR.abort();
1066
+ };
1067
+ return this._enhancePromise(pipe);
1068
+ }
1069
+ return send();
1406
1070
  },
1407
- uploadForm : function(f, name)
1408
- {
1409
- if (this.uploadOptions.input)
1410
- {
1411
- var formId = 'redactorUploadForm' + this.id;
1412
- var fileId = 'redactorUploadFile' + this.id;
1413
- this.form = $('<form action="' + this.uploadOptions.url + '" method="POST" target="' + name + '" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
1414
-
1415
- var oldElement = this.uploadOptions.input;
1416
- var newElement = $(oldElement).clone();
1417
- $(oldElement).attr('id', fileId);
1418
- $(oldElement).before(newElement);
1419
- $(oldElement).appendTo(this.form);
1420
- $(this.form).css('position', 'absolute');
1421
- $(this.form).css('top', '-2000px');
1422
- $(this.form).css('left', '-2000px');
1423
- $(this.form).appendTo('body');
1424
-
1425
- this.form.submit();
1071
+
1072
+ _onAdd: function (e, data) {
1073
+ var that = this,
1074
+ result = true,
1075
+ options = $.extend({}, this.options, data),
1076
+ limit = options.limitMultiFileUploads,
1077
+ fileSet,
1078
+ i;
1079
+ if (!(options.singleFileUploads || limit) ||
1080
+ !this._isXHRUpload(options)) {
1081
+ fileSet = [data.files];
1082
+ } else if (!options.singleFileUploads && limit) {
1083
+ fileSet = [];
1084
+ for (i = 0; i < data.files.length; i += limit) {
1085
+ fileSet.push(data.files.slice(i, i + limit));
1086
+ }
1426
1087
  }
1427
- else
1428
- {
1429
- f.attr('target', name);
1430
- f.attr('method', 'POST');
1431
- f.attr('enctype', 'multipart/form-data');
1432
- f.attr('action', this.uploadOptions.url);
1433
-
1434
- this.element.submit();
1088
+ data.originalFiles = data.files;
1089
+ $.each(fileSet || data.files, function (index, element) {
1090
+ var files = fileSet ? element : [element],
1091
+ newData = $.extend({}, data, {files: files});
1092
+ newData.submit = function () {
1093
+ newData.jqXHR = this.jqXHR =
1094
+ (that._trigger('submit', e, this) !== false) &&
1095
+ that._onSend(e, this);
1096
+ return this.jqXHR;
1097
+ };
1098
+ return (result = that._trigger('add', e, newData));
1099
+ });
1100
+ return result;
1101
+ },
1102
+
1103
+ // File Normalization for Gecko 1.9.1 (Firefox 3.5) support:
1104
+ _normalizeFile: function (index, file) {
1105
+ if (file.name === undefined && file.size === undefined) {
1106
+ file.name = file.fileName;
1107
+ file.size = file.fileSize;
1435
1108
  }
1436
-
1437
1109
  },
1438
- uploadLoaded : function()
1439
- {
1440
- var i = $('#' + this.id);
1441
-
1442
- if (i.contentDocument) var d = i.contentDocument;
1443
- else if (i.contentWindow) var d = i.contentWindow.document;
1444
- else var d = window.frames[this.id].document;
1445
-
1446
- if (d.location.href == "about:blank") return true;
1110
+
1111
+ _replaceFileInput: function (input) {
1112
+ var inputClone = input.clone(true);
1113
+ $('<form></form>').append(inputClone)[0].reset();
1114
+ // Detaching allows to insert the fileInput on another form
1115
+ // without loosing the file input value:
1116
+ input.after(inputClone).detach();
1117
+ // Avoid memory leaks with the detached file input:
1118
+ $.cleanData(input.unbind('remove'));
1119
+ // Replace the original file input element in the fileInput
1120
+ // collection with the clone, which has been copied including
1121
+ // event handlers:
1122
+ this.options.fileInput = this.options.fileInput.map(function (i, el) {
1123
+ if (el === input[0]) {
1124
+ return inputClone[0];
1125
+ }
1126
+ return el;
1127
+ });
1128
+ // If the widget has been initialized on the file input itself,
1129
+ // override this.element with the file input clone:
1130
+ if (input[0] === this.element[0]) {
1131
+ this.element = inputClone;
1132
+ }
1133
+ },
1134
+
1135
+ _onChange: function (e) {
1136
+ var that = e.data.fileupload,
1137
+ data = {
1138
+ files: $.each($.makeArray(e.target.files), that._normalizeFile),
1139
+ fileInput: $(e.target),
1140
+ form: $(e.target.form)
1141
+ };
1142
+ if (!data.files.length) {
1143
+ // If the files property is not available, the browser does not
1144
+ // support the File API and we add a pseudo File object with
1145
+ // the input value as name with path information removed:
1146
+ data.files = [{name: e.target.value.replace(/^.*\\/, '')}];
1147
+ }
1148
+ if (that.options.replaceFileInput) {
1149
+ that._replaceFileInput(data.fileInput);
1150
+ }
1151
+ if (that._trigger('change', e, data) === false ||
1152
+ that._onAdd(e, data) === false) {
1153
+ return false;
1154
+ }
1155
+ },
1156
+
1157
+ _onPaste: function (e) {
1158
+ var that = e.data.fileupload,
1159
+ cbd = e.originalEvent.clipboardData,
1160
+ items = (cbd && cbd.items) || [],
1161
+ data = {files: []};
1162
+ $.each(items, function (index, item) {
1163
+ var file = item.getAsFile && item.getAsFile();
1164
+ if (file) {
1165
+ data.files.push(file);
1166
+ }
1167
+ });
1168
+ if (that._trigger('paste', e, data) === false ||
1169
+ that._onAdd(e, data) === false) {
1170
+ return false;
1171
+ }
1172
+ },
1173
+
1174
+ _onDrop: function (e) {
1175
+ var that = e.data.fileupload,
1176
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer,
1177
+ data = {
1178
+ files: $.each(
1179
+ $.makeArray(dataTransfer && dataTransfer.files),
1180
+ that._normalizeFile
1181
+ )
1182
+ };
1183
+ if (that._trigger('drop', e, data) === false ||
1184
+ that._onAdd(e, data) === false) {
1185
+ return false;
1186
+ }
1187
+ e.preventDefault();
1188
+ },
1189
+
1190
+ _onDragOver: function (e) {
1191
+ var that = e.data.fileupload,
1192
+ dataTransfer = e.dataTransfer = e.originalEvent.dataTransfer;
1193
+ if (that._trigger('dragover', e) === false) {
1194
+ return false;
1195
+ }
1196
+ if (dataTransfer) {
1197
+ dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
1198
+ }
1199
+ e.preventDefault();
1200
+ },
1201
+
1202
+ _initEventHandlers: function () {
1203
+ var ns = this.options.namespace;
1204
+ this.options.dropZone
1205
+ .bind('dragover.' + ns, {fileupload: this}, this._onDragOver)
1206
+ .bind('drop.' + ns, {fileupload: this}, this._onDrop)
1207
+ .bind('paste.' + ns, {fileupload: this}, this._onPaste);
1208
+ this.options.fileInput
1209
+ .bind('change.' + ns, {fileupload: this}, this._onChange);
1210
+ },
1211
+
1212
+ _destroyEventHandlers: function () {
1213
+ var ns = this.options.namespace;
1214
+ this.options.dropZone
1215
+ .unbind('dragover.' + ns, this._onDragOver)
1216
+ .unbind('drop.' + ns, this._onDrop)
1217
+ .unbind('paste.' + ns, this._onPaste);
1218
+ this.options.fileInput
1219
+ .unbind('change.' + ns, this._onChange);
1220
+ },
1221
+
1222
+ _beforeSetOption: function (key, value) {
1223
+ this._destroyEventHandlers();
1224
+ },
1225
+
1226
+ _afterSetOption: function (key, value) {
1227
+ var options = this.options;
1228
+ if (!options.fileInput) {
1229
+ options.fileInput = $();
1230
+ }
1231
+ if (!options.dropZone) {
1232
+ options.dropZone = $();
1233
+ }
1234
+ this._initEventHandlers();
1235
+ },
1236
+
1237
+ _setOption: function (key, value) {
1238
+ var refresh = $.inArray(key, this._refreshOptionsList) !== -1;
1239
+ if (refresh) {
1240
+ this._beforeSetOption(key, value);
1241
+ }
1242
+ $.Widget.prototype._setOption.call(this, key, value);
1243
+ if (refresh) {
1244
+ this._afterSetOption(key, value);
1245
+ }
1246
+ },
1247
+
1248
+ _create: function () {
1249
+ var options = this.options;
1250
+ options.namespace = options.namespace || this.widgetName;
1251
+ if (options.fileInput === undefined) {
1252
+ options.fileInput = this.element.is('input:file') ?
1253
+ this.element : this.element.find('input:file');
1254
+ } else if (!options.fileInput) {
1255
+ options.fileInput = $();
1256
+ }
1257
+ if (!options.dropZone) {
1258
+ options.dropZone = $();
1259
+ }
1260
+ this._slots = [];
1261
+ this._sequence = this._getXHRPromise(true);
1262
+ this._sending = this._active = this._loaded = this._total = 0;
1263
+ this._initEventHandlers();
1264
+ },
1265
+
1266
+ destroy: function () {
1267
+ this._destroyEventHandlers();
1268
+ $.Widget.prototype.destroy.call(this);
1269
+ },
1270
+
1271
+ enable: function () {
1272
+ $.Widget.prototype.enable.call(this);
1273
+ this._initEventHandlers();
1274
+ },
1275
+
1276
+ disable: function () {
1277
+ this._destroyEventHandlers();
1278
+ $.Widget.prototype.disable.call(this);
1279
+ },
1280
+
1281
+ // This method is exposed to the widget API and allows adding files
1282
+ // using the fileupload API. The data parameter accepts an object which
1283
+ // must have a files property and can contain additional options:
1284
+ // .fileupload('add', {files: filesList});
1285
+ add: function (data) {
1286
+ if (!data || this.options.disabled) {
1287
+ return;
1288
+ }
1289
+ data.files = $.each($.makeArray(data.files), this._normalizeFile);
1290
+ this._onAdd(null, data);
1291
+ },
1292
+
1293
+ // This method is exposed to the widget API and allows sending files
1294
+ // using the fileupload API. The data parameter accepts an object which
1295
+ // must have a files property and can contain additional options:
1296
+ // .fileupload('send', {files: filesList});
1297
+ // The method returns a Promise object for the file upload call.
1298
+ send: function (data) {
1299
+ if (data && !this.options.disabled) {
1300
+ data.files = $.each($.makeArray(data.files), this._normalizeFile);
1301
+ if (data.files.length) {
1302
+ return this._onSend(null, data);
1303
+ }
1304
+ }
1305
+ return this._getXHRPromise(false, data && data.context);
1306
+ }
1307
+
1308
+ });
1309
+
1310
+ }));
1311
+ /* jQuery plugin textselect
1312
+ * version: 0.9
1313
+ * author: Josef Moravec, josef.moravec@gmail.com
1314
+ * updated: Imperavi
1315
+ *
1316
+ */
1317
+
1318
+ (function($){$.event.special.textselect={setup:function(data,namespaces)
1319
+ {$(this).data("textselected",false);$(this).data("ttt",data);$(this).bind('mouseup',$.event.special.textselect.handler);},teardown:function(data)
1320
+ {$(this).unbind('mouseup',$.event.special.textselect.handler);},handler:function(event)
1321
+ {var data=$(this).data("ttt");var text=$.event.special.textselect.getSelectedText(data).toString();if(text!='')
1322
+ {$(this).data("textselected",true);event.type="textselect";event.text=text;$.event.handle.apply(this,arguments);}},getSelectedText:function(data)
1323
+ {var text='';var frame=$('#imp_redactor_frame_'+data).get(0);if(frame.contentWindow.getSelection)text=frame.contentWindow.getSelection();else if(frame.contentWindow.document.getSelection) text=frame.contentWindow.document.getSelection();else if(frame.contentWindow.document.selection)text=frame.contentWindow.document.selection.createRange().text;return text;}}
1324
+ $.event.special.textunselect={setup:function(data,namespaces){$(this).data("rttt",data);$(this).data("textselected",false);$(this).bind('mouseup',$.event.special.textunselect.handler);$(this).bind('keyup',$.event.special.textunselect.handlerKey)},teardown:function(data){$(this).unbind('mouseup',$.event.special.textunselect.handler);},handler:function(event){if($(this).data("textselected")){var data=$(this).data("rttt");var text=$.event.special.textselect.getSelectedText(data).toString();if(text==''){$(this).data("textselected",false);event.type="textunselect";$.event.handle.apply(this,arguments);}}},handlerKey:function(event){if($(this).data("textselected")){var data=$(this).data("rttt");var text=$.event.special.textselect.getSelectedText(data).toString();if((event.keyCode=27)&&(text=='')){$(this).data("textselected",false);event.type="textunselect";$.event.handle.apply(this,arguments);}}}}})(jQuery);
1325
+
1326
+ $.fn.ImperaviLanguages = {
1327
+ ru : {
1328
+ html : 'Код',
1329
+
1330
+ // Styles dropdown menu
1331
+ styles : {
1332
+ name : 'Стили',
1333
+ paragraph : 'Параграф',
1334
+ quote : 'Цитата',
1335
+ code : 'Код',
1336
+ h2 : 'Заголовок 2',
1337
+ h3 : 'Заголовок 3',
1338
+ h4 : 'Заголовок 4',
1339
+ h5 : 'Заголовок 5',
1340
+ h6 : 'Заголовок 6',
1341
+ },
1447
1342
 
1448
- // Success
1449
- if (this.uploadOptions.success) this.uploadOptions.success(d.body.innerHTML);
1343
+ // Formatting dropdown menu
1344
+ format : {
1345
+ name : 'Формат',
1346
+ bold : 'Полужирный',
1347
+ italic : 'Наклонный',
1348
+ sup : 'Надстрочный',
1349
+ sub : 'Надстрочный',
1350
+ strike : 'Зачеркнутый',
1351
+ remove : 'Очистить форматирование'
1352
+ },
1353
+
1354
+ // Lists dropdown menu
1355
+ lists : {
1356
+ name : 'Списки',
1357
+ unordered : 'Обычный список',
1358
+ ordered : 'Нумерованный список',
1359
+ outdent : 'Уменьшить отступ',
1360
+ indent : 'Увеличить отступ'
1361
+ },
1362
+
1363
+ // Working with images
1364
+ image : {
1365
+ name : 'Изображение',
1366
+ download : 'Скачать изображение',
1367
+ text : 'Текст',
1368
+ mailto : 'Эл. почта',
1369
+ web : 'URL',
1370
+ title : 'Подсказка',
1371
+ buttons : {
1372
+ save : 'Сохранить',
1373
+ cancel : 'Отменить',
1374
+ insert : 'Вставить',
1375
+ remove : 'Удалить'
1376
+ },
1377
+ align : {
1378
+ name : 'Обтекание текстом',
1379
+ none : 'нет',
1380
+ left : 'слева',
1381
+ right : 'справа'
1382
+ }
1383
+ },
1384
+
1385
+ // Insert and format tables
1386
+ table : {
1387
+ name : 'Таблица',
1388
+ insert : 'Вставить таблицу',
1389
+ remove : 'Удалить таблицу',
1390
+ row: {
1391
+ name : 'Строки',
1392
+ above : 'Добавить строку сверху',
1393
+ below : 'Добавить строку снизу',
1394
+ remove : 'Удалить строку'
1395
+ },
1396
+ column : {
1397
+ name : 'Столбцы',
1398
+ left : 'Добавить столбец слева',
1399
+ right : 'Добавить столбец справа',
1400
+ remove : 'Удалить столбец',
1401
+ },
1402
+ header : {
1403
+ add : 'Добавить заголовок',
1404
+ remove : 'Удалить заголовок'
1405
+ }
1406
+ },
1407
+
1408
+ // Insert video from youtube etc
1409
+ video : {
1410
+ name : 'Видео',
1411
+ code : 'Код видео ролика'
1412
+ },
1413
+
1414
+ // Insert or remove hyperlink to a file
1415
+ file : {
1416
+ name : 'Файл',
1417
+ upload : 'Загрузить',
1418
+ download : 'Скачать',
1419
+ choose : 'Выбрать',
1420
+ or_choose : 'Или выберите',
1421
+ drop : 'Перетащите файл сюда'
1422
+ },
1423
+
1424
+ // Insert or remove hyperlink
1425
+ hyperlink : 'Ссылка'
1426
+ }
1427
+ }
1428
+ ;
1429
+ $.fn.ImperaviToolbarDefault = {
1430
+ html : true,
1431
+
1432
+ // Styles dropdown menu
1433
+ // TODO: User styles here. Move all to format section from here
1434
+ styles : {
1435
+ paragraph : true,
1436
+ quote : true,
1437
+ code : true,
1438
+ h2 : true,
1439
+ h3 : true,
1440
+ h4 : true,
1441
+ h5 : true,
1442
+ h6 : true
1443
+ },
1444
+
1445
+ // Formatting dropdown menu
1446
+ format : {
1447
+ bold : true,
1448
+ italic : true,
1449
+ sup : true,
1450
+ sub : true,
1451
+ strike : true,
1452
+ remove : true
1453
+ },
1454
+
1455
+ // Lists dropdown menu
1456
+ lists : {
1457
+ unordered : true,
1458
+ ordered : true,
1459
+ outdent : true,
1460
+ indent : true
1461
+ },
1462
+
1463
+ // Working with images
1464
+ image : true,
1465
+
1466
+ // Insert and format tables
1467
+ table : {
1468
+ insert : true,
1469
+ remove : true,
1470
+ header : {
1471
+ add : true,
1472
+ remove : true
1473
+ },
1474
+ row : {
1475
+ above : true,
1476
+ below : true,
1477
+ remove : true
1478
+ },
1479
+ column : {
1480
+ left : true,
1481
+ right : true,
1482
+ remove : true
1483
+ }
1484
+ },
1485
+
1486
+ // Insert video from youtube etc
1487
+ video : true,
1488
+
1489
+ // Insert or remove hyperlink to a file
1490
+ file : true,
1491
+
1492
+ // Insert or remove hyperlink
1493
+ hyperlink : true
1494
+ }
1495
+ ;
1496
+ (function( $ ) {
1497
+ $.fn.ImperaviActionDelegator = function(o) { this.initialize() }
1498
+
1499
+ $.fn.ImperaviActionDelegator.prototype = {
1500
+ initialize: function() {},
1501
+
1502
+ delegateButtonClick: function(button, iframe) {
1503
+ switch (button.attr('rel')) {
1504
+ case 'indent':
1505
+ case 'outdent':
1506
+ alert('yay!')
1507
+ break;
1508
+ case 'video':
1509
+ new $.fn.ImperaviPluginVideo
1510
+ break;
1511
+ case 'image':
1512
+ new $.fn.ImperaviPluginImage
1513
+ break;
1514
+ case 'hyperlink':
1515
+ new $.fn.ImperaviPluginHyperlink
1516
+ break;
1517
+ case 'file':
1518
+ new $.fn.ImperaviPluginFile
1519
+ break;
1520
+ default:
1521
+ return button
1522
+ break;
1523
+ }
1524
+ }
1525
+ }
1526
+ })(jQuery);
1527
+ // Internationalization
1528
+ (function( $ ) {
1529
+ $.fn.ImperaviI18n = function(o) {
1530
+ var o = $.extend({
1531
+ locale : 'en'
1532
+ }, o)
1450
1533
 
1451
- this.element.attr('action', this.element_action);
1452
- this.element.attr('target', '');
1453
- //this.element.unbind('submit');
1454
- //if (this.uploadOptions.input) $(this.form).remove();
1455
- },
1456
-
1457
- /*
1458
- Toolbar
1459
- */
1460
- buildToolbar: function()
1461
- {
1462
- this.toolbar = $('<ul id="imp_redactor_toolbar_' + this.frameID + '" class="imp_redactor_toolbar"></ul>');
1463
-
1464
- if (this.opts.air)
1465
- {
1466
- $(this.air).append(this.toolbar);
1467
- this.box.prepend(this.air);
1468
- }
1469
- else $(this.box).prepend(this.toolbar);
1470
-
1471
-
1472
- $.each(RTOOLBAR,
1473
- function (i, s)
1474
- {
1475
- if (s.name == 'separator')
1476
- {
1477
- var li = $('<li class="separator"></li>');
1478
- $(this.toolbar).append(li);
1479
- }
1480
- else
1481
- {
1482
-
1483
- var a = $('<a href="javascript:void(null);" class="imp_btn imp_btn_' + s.name + '" title="' + s.title + '"></a>');
1484
-
1485
- if (typeof(s.func) == 'undefined') a.click(function() { this.execCommand(s.exec, s.name); }.bind2(this));
1486
- else if (s.func != 'show') a.click(function(e) { this[s.func](e); }.bind2(this));
1487
-
1488
- var li = $('<li class="imp_li_btn imp_li_btn_' + s.name + '"></li>');
1489
- $(li).append(a);
1490
- $(this.toolbar).append(li);
1491
-
1492
- // build dropdown box
1493
- if (s.name == 'backcolor' || s.name == 'fontcolor' || typeof(s.dropdown) != 'undefined')
1494
- {
1495
- var ul = $('<ul class="imp_redactor_drop_down imp_redactor_drop_down' + this.frameID + '" id="imp_redactor_drop_down' + this.frameID + '_' + s.name + '" style="display: none;"></ul>');
1496
- if ($.browser.msie) ul.css({ borderLeft: '1px solid #ddd', borderRight: '1px solid #ddd', borderBottom: '1px solid #ddd' });
1497
- }
1498
-
1499
- // build dropdown
1500
- if (typeof(s.dropdown) != 'undefined')
1501
- {
1502
-
1503
- $.each(s.dropdown,
1504
- function (x, d)
1505
- {
1506
- if (typeof(d.style) == 'undefined') d.style = '';
1507
-
1508
- if (d.name == 'separator')
1509
- {
1510
- var ul_li = $('<li class="separator_drop"></li>');
1511
- $(ul).append(ul_li);
1512
- }
1513
- else
1514
- {
1515
-
1516
- var ul_li = $('<li></li>');
1517
- var ul_li_a = $('<a href="javascript:void(null);" style="' + d.style + '">' + d.title + '</a>');
1518
- $(ul_li).append(ul_li_a);
1519
- $(ul).append(ul_li);
1520
-
1521
- if (typeof(d.func) == 'undefined') $(ul_li_a).click(function() { this.execCommand(d.exec, d.name); }.bind2(this));
1522
- else $(ul_li_a).click(function(e) { this[d.func](e); }.bind2(this));
1523
- }
1524
-
1525
-
1526
-
1527
- }.bind2(this)
1528
- );
1529
- }
1530
- else a.mouseover(function() { this.hideAllDropDown() }.bind2(this));
1531
-
1532
- // observing dropdown
1533
- if (s.name == 'backcolor' || s.name == 'fontcolor' || typeof(s.dropdown) != 'undefined')
1534
- {
1535
- $('#imp_redactor_toolbar_' + this.frameID).after(ul);
1536
-
1537
- this.hdlHideDropDown = function(e) { this.hideDropDown(e, ul, s.name) }.bind2(this);
1538
- this.hdlShowDropDown = function(e) { this.showDropDown(e, ul, s.name) }.bind2(this);
1539
- this.hdlShowerDropDown = function(e) { this.showerDropDown(e, ul, s.name) }.bind2(this);
1540
-
1541
- a.click(this.hdlShowDropDown).mouseover(this.hdlShowerDropDown);
1542
-
1543
- $(document).click(this.hdlHideDropDown);
1544
- }
1545
-
1546
-
1547
- }
1548
- }.bind2(this)
1549
- );
1550
- },
1551
-
1552
- /*
1553
- DropDown
1554
- */
1555
- showedDropDown: false,
1556
- showDropDown: function(e, ul, name)
1557
- {
1558
-
1559
- if (this.showedDropDown) this.hideAllDropDown();
1560
- else
1561
- {
1562
- this.showedDropDown = true;
1563
- this.showingDropDown(e, ul, name);
1564
- }
1565
-
1566
- },
1567
- showingDropDown: function(e, ul, name)
1568
- {
1569
- this.hideAllDropDown();
1570
- this.addSelButton(name);
1571
-
1572
- var left = $('#imp_redactor_toolbar_' + this.frameID + ' li.imp_li_btn_' + name).position().left;
1573
- $(ul).css('left', left + 'px').show();
1574
- },
1575
- showerDropDown: function(e, ul, name)
1576
- {
1577
- if (this.showedDropDown) this.showingDropDown(e, ul, name);
1578
- },
1579
- hideAllDropDown: function()
1580
- {
1581
- $('#imp_redactor_toolbar_' + this.frameID + ' li.imp_li_btn').removeClass('act');
1582
- $('ul.imp_redactor_drop_down' + this.frameID).hide();
1583
- },
1584
- hideDropDown: function(e, ul, name)
1585
- {
1586
- if (!$(e.target).parent().hasClass('act'))
1587
- {
1588
- this.showedDropDown = false;
1589
- this.hideAllDropDown();
1590
- }
1591
-
1592
- $(document).unbind('click', this.hdlHideDropDown);
1593
- $(this.doc).unbind('click', this.hdlHideDropDown);
1594
-
1595
- },
1596
- addSelButton: function(name)
1597
- {
1598
- var element = $('#imp_redactor_toolbar_' + this.frameID + ' li.imp_li_btn_' + name);
1599
- element.addClass('act');
1600
- },
1601
- removeSelButton: function(name)
1602
- {
1603
- var element = $('#imp_redactor_toolbar_' + this.frameID + ' li.imp_li_btn_' + name);
1604
- element.removeClass('act');
1605
- },
1606
- toggleSelButton: function(name)
1607
- {
1608
- $('#imp_redactor_toolbar_' + this.frameID + ' li.imp_li_btn_' + name).toggleClass('act');
1609
- },
1610
-
1611
-
1612
- /*
1613
- Resizer
1614
- */
1615
- initResize: function(e)
1616
- {
1617
- if (e.preventDefault) e.preventDefault();
1618
- else e.returnValue = false;
1619
-
1620
- this.splitter = e.target;
1621
-
1622
- if (this.opts.visual)
1623
- {
1624
- this.element_resize = this.frame;
1625
- this.element_resize.get(0).style.visibility = 'hidden';
1626
- this.element_resize_parent = this.$el;
1627
- }
1628
- else
1629
- {
1630
- this.element_resize = this.$el;
1631
- this.element_resize_parent = this.frame;
1632
- }
1633
-
1634
- this.stopResizeHdl = function (e) { this.stopResize(e) }.bind2(this);
1635
- this.startResizeHdl = function (e) { this.startResize(e) }.bind2(this);
1636
- this.resizeHdl = function (e) { this.resize(e) }.bind2(this);
1637
-
1638
- $(document).mousedown(this.startResizeHdl);
1639
- $(document).mouseup(this.stopResizeHdl);
1640
- $(this.splitter).mouseup(this.stopResizeHdl);
1641
-
1642
- this.null_point = false;
1643
- this.h_new = false;
1644
- this.h = this.element_resize.height();
1645
- },
1646
- startResize: function()
1647
- {
1648
- $(document).mousemove(this.resizeHdl);
1649
- },
1650
- resize: function(e)
1651
- {
1652
- if (e.preventDefault) e.preventDefault();
1653
- else e.returnValue = false;
1654
-
1655
- var y = e.pageY;
1656
- if (this.null_point == false) this.null_point = y;
1657
- if (this.h_new == false) this.h_new = this.element_resize.height();
1658
-
1659
- var s_new = (this.h_new + y - this.null_point) - 10;
1660
-
1661
- if (s_new <= 30) return true;
1662
-
1663
- if (s_new >= 0)
1664
- {
1665
- this.element_resize.get(0).style.height = s_new + 'px';
1666
- this.element_resize_parent.get(0).style.height = s_new + 'px';
1667
- }
1668
- },
1669
- stopResize: function(e)
1670
- {
1671
- $(document).unbind('mousemove', this.resizeHdl);
1672
- $(document).unbind('mousedown', this.startResizeHdl);
1673
- $(document).unbind('mouseup', this.stopResizeHdl);
1674
- $(this.splitter).unbind('mouseup', this.stopResizeHdl);
1675
-
1676
- this.element_resize.get(0).style.visibility = 'visible';
1677
- }
1678
-
1679
- };
1534
+ this.initialize(o)
1535
+ }
1680
1536
 
1537
+ $.fn.ImperaviI18n.prototype = {
1538
+ o : null,
1539
+ locales : null,
1681
1540
 
1682
- String.prototype.isInlineName = function()
1683
- {
1684
- var inlineList = new Array("#text", "a", "em", "font", "span", "strong", "u");
1685
- var theName = this.toLowerCase();
1686
-
1687
- for (var i = 0; i < inlineList.length; i++)
1688
- {
1689
- if (theName == inlineList[i])
1690
- {
1691
- return true;
1692
- }
1693
- }
1694
-
1695
- return false;
1696
- };
1697
-
1698
-
1699
- // bind2
1700
- Function.prototype.bind2 = function(object)
1701
- {
1702
- var method = this; var oldArguments = $.makeArray(arguments).slice(1);
1703
- return function (argument)
1704
- {
1705
- if (argument == new Object) { method = null; oldArguments = null; }
1706
- else if (method == null) throw "Attempt to invoke destructed method reference.";
1707
- else { var newArguments = $.makeArray(arguments); return method.apply(object, oldArguments.concat(newArguments)); }
1708
- };
1709
- };
1710
-
1711
-
1541
+ initialize: function(o) {
1542
+ this.o = $.extend({ locale : $.fn.ImperaviOptions().options.locale }, o)
1543
+ this.locales = $.fn.ImperaviLanguages[this.o.locale]
1544
+ },
1545
+
1546
+ t: function(key) {
1547
+
1548
+ }
1549
+ }
1712
1550
  })(jQuery);
1551
+ (function( $ ) {
1552
+ $.fn.ImperaviPluginVideo = function(o) { this.initialize(o) }
1553
+
1554
+ $.fn.ImperaviPluginVideo.prototype = {
1555
+ initialize: function(o) {
1556
+ this.o = o
1557
+
1558
+ this.dialog = new $.fn.ImperaviDialog({
1559
+ title : 'Insert video',
1560
+ width : 600,
1561
+ height : 300,
1562
+ onOkay : function() {
1563
+ alert(this.el.find('textarea').val())
1564
+ this.hide()
1565
+ }
1566
+ })
1567
+
1568
+ this.dialog.show()
1569
+ this.dialog.el.addClass('imperavi-plugin-video')
1570
+ this.build()
1571
+ },
1572
+
1573
+ build: function() {
1574
+ var textarea = $(document.createElement('textarea'))
1575
+ this.dialog.setContent(textarea)
1576
+ }
1577
+ }
1578
+ })(jQuery);
1579
+ (function( $ ) {
1580
+ $.fn.ImperaviPluginImage = function(o) { this.initialize(o) }
1581
+
1582
+ $.fn.ImperaviPluginImage.prototype = {
1583
+ initialize: function(o) {
1584
+ this.o = o
1585
+ this.image = null
1586
+ var image = this.image
1587
+
1588
+ this.dialog = new $.fn.ImperaviDialog({
1589
+ title : 'Insert image',
1590
+ width : 800,
1591
+ height : 600,
1592
+ onRemove : function() {
1593
+ alert('fuck yeah!')
1594
+ this.hide()
1595
+ },
1596
+ onOkay : function() {
1597
+ //this.doc.selection.createRange().pasteHTML(param);
1598
+ image.appendTo($('body'))
1599
+ this.hide()
1600
+ }
1601
+ })
1602
+
1603
+ this.dialog.show()
1604
+ this.dialog.el.addClass('imperavi-plugin-image')
1605
+ this.build()
1606
+ },
1607
+
1608
+ build: function() {
1609
+ // Add 'remove' button
1610
+ this.removeButton = this.dialog.addButton('Remove', 'remove')
1611
+ this.removeButton.hide();
1612
+
1613
+ // Create tabs and content for tabs
1614
+ this.tabsArea = this.buildTabsArea()
1615
+
1616
+ this.uploadTab = this.buildTab('Upload image', this.buildUploadTabContent())
1617
+ .appendTo(this.tabsArea)
1618
+ .addClass('current')
1619
+
1620
+ this.pickTab = this.buildTab('Pick image', this.buildPickTabContent())
1621
+ .appendTo(this.tabsArea)
1622
+
1623
+ this.dialog.setContent(this.tabsArea)
1624
+ this.switchTabs();
1625
+ },
1626
+
1627
+ // Build tabs container
1628
+ buildTabsArea: function() {
1629
+ var article = $(document.createElement('article'))
1630
+ .addClass('imperavi-tabs')
1631
+
1632
+ return article
1633
+ },
1634
+
1635
+ // Add another one tab
1636
+ buildTab: function(title, content) {
1637
+ var section = $(document.createElement('section'))
1638
+ var heading = $(document.createElement('h3'))
1639
+ .html(title)
1640
+ .addClass('imperavi-tab')
1641
+ .appendTo(section)
1642
+
1643
+ var content = $(document.createElement('div'))
1644
+ .appendTo(section)
1645
+ .html(content)
1646
+
1647
+ return section
1648
+ },
1649
+
1650
+ // Switch between tabs
1651
+ switchTabs: function() {
1652
+ var currentTab = this.uploadTab
1653
+
1654
+ this.tabsArea.on('click', '.imperavi-tab', function(e){
1655
+ e.preventDefault();
1656
+
1657
+ if (currentTab.length) {
1658
+ currentTab.removeClass('current')
1659
+ }
1660
+
1661
+ currentTab = $(this).closest('section').addClass('current')
1662
+ })
1663
+ },
1664
+
1665
+ buildPickTabContent: function() {
1666
+
1667
+ },
1668
+
1669
+ buildUploadTabContent: function() {
1670
+ // Create wrapper
1671
+ var wrapper = $(document.createElement('div'))
1672
+ .attr('id', 'upload-wrapper')
1673
+
1674
+ // Create place for thumbnail
1675
+ var thumbnail = $(document.createElement('figure'))
1676
+ .addClass('thumbnail')
1677
+ .appendTo(wrapper)
1678
+
1679
+ var caption = $(document.createElement('span'))
1680
+ .html('No image yet')
1681
+ .appendTo(thumbnail)
1682
+
1683
+ // Create form
1684
+ var form = $(document.createElement('form'))
1685
+ .attr('enctype', 'multipart/form-data')
1686
+ .attr('method', 'post')
1687
+ .attr('action', '/images')
1688
+ //.attr('accept-charset', 'UTF-8')
1689
+ .appendTo(wrapper)
1690
+
1691
+ // Choose image from disk field
1692
+ var imageLocal = this.buildInput('Choose image from disk', 'image[image]', 'file')
1693
+ .appendTo(form)
1694
+
1695
+ // Image url field
1696
+ var imageUrl = this.buildInput('or specify link to image', 'image[url]', 'text')
1697
+ .appendTo(wrapper)
1698
+
1699
+ // Image align dropdown
1700
+ var imagePos = this.buildAlignSelect().appendTo(wrapper)
1701
+
1702
+ imageLocal.fileupload({
1703
+ dataType : 'json',
1704
+ url : '/images',
1705
+ change : function() {
1706
+ thumbnail.addClass('loading')
1707
+ },
1708
+ done : $.proxy(function(e, data) {
1709
+ thumbnail.empty()
1710
+ thumbnail.removeClass('loading')
1711
+
1712
+ this.image = $(document.createElement('img'))
1713
+ .attr('src', data.result.thumbnail_url)
1714
+ .attr('width', 300)
1715
+ .attr('height', 340)
1716
+ .appendTo(thumbnail)
1717
+ }, this)
1718
+ });
1719
+
1720
+ // Submit form
1721
+ /*form.on("change", ":file", function() {
1722
+ thumbnail.addClass("loading");
1723
+
1724
+ $.ajax(form.attr("action"), {
1725
+ files : form.find(":file"),
1726
+ iframe : true,
1727
+ dataType : "json",
1728
+ contentType : 'multipart/form-data',
1729
+ type : form.attr('method')
1730
+ }).always(function() {
1731
+ thumbnail.removeClass("loading");
1732
+ }).done(function(data) {
1733
+
1734
+ if (data.errors) {
1735
+ // Some errors occurs
1736
+ alert(data.errors) // TODO
1737
+ } else {
1738
+ // No errors
1739
+ thumbnail.empty()
1740
+
1741
+ $(document.createElement('img'))
1742
+ .attr('src', data.file)
1743
+ .attr('width', 300)
1744
+ .attr('height', 340)
1745
+ .appendTo(thumbnail)
1746
+ }
1747
+ });
1748
+ });*/
1749
+
1750
+ return wrapper
1751
+ },
1752
+
1753
+ buildInput: function(title, name, type) {
1754
+ var wrapper = $(document.createElement('div'))
1755
+ .addClass('field')
1756
+
1757
+ var label = $(document.createElement('label'))
1758
+ .attr('for', name)
1759
+ .html(title)
1760
+ .appendTo(wrapper)
1761
+
1762
+ var url = $(document.createElement('input'))
1763
+ .attr('type', type)
1764
+ .attr('name', name)
1765
+ .attr('id', name)
1766
+ .appendTo(wrapper)
1767
+
1768
+ return wrapper
1769
+ },
1770
+
1771
+ buildAlignSelect: function() {
1772
+ var wrapper = $(document.createElement('div'))
1773
+ .addClass('field')
1774
+
1775
+ var label = $(document.createElement('label'))
1776
+ .attr('for', 'image-align')
1777
+ .html('Image position')
1778
+ .appendTo(wrapper)
1779
+
1780
+ var select = $(document.createElement('select'))
1781
+ .attr('id', 'image-align')
1782
+ .attr('name', 'image[align]')
1783
+ .appendTo(wrapper)
1784
+
1785
+ // Create select options
1786
+ var options = {
1787
+ none : 'None',
1788
+ left : 'To left',
1789
+ right : 'To right'
1790
+ }
1791
+
1792
+ $.each(options, function(value, caption) {
1793
+ var option = $(document.createElement('option'))
1794
+ .attr('value', value)
1795
+ .html(caption)
1796
+ .appendTo(select)
1797
+
1798
+ if (value == 'left') option.attr('selected', true)
1799
+ })
1800
+
1801
+ return wrapper
1802
+ }
1803
+ }
1804
+ })(jQuery);
1805
+ (function( $ ) {
1806
+ $.fn.ImperaviPluginHyperlink = function(o) { this.initialize(o) }
1807
+
1808
+ $.fn.ImperaviPluginHyperlink.prototype = {
1809
+ initialize: function(o) {
1810
+ this.o = o
1811
+
1812
+ this.dialog = new $.fn.ImperaviDialog({
1813
+ title : 'Insert hyperlink',
1814
+ width : 450,
1815
+ height : 237,
1816
+ onRemove : function() {
1817
+ alert('fuck yeah!')
1818
+ this.hide()
1819
+ },
1820
+ onOkay : function() {
1821
+ alert('fuck')
1822
+ this.hide()
1823
+ }
1824
+ })
1825
+
1826
+ this.dialog.show()
1827
+ this.dialog.el.addClass('imperavi-plugin-hyperlink')
1828
+ this.dialog.addButton('Remove', 'remove')
1829
+ this.build()
1830
+ },
1831
+
1832
+ build: function() {
1833
+ var wrapper = $(document.createElement('div'))
1834
+ var url = this.build_input('Url', 'url').appendTo(wrapper)
1835
+ var caption = this.build_input('Title', 'title').appendTo(wrapper)
1836
+
1837
+ this.dialog.setContent(wrapper)
1838
+ },
1839
+
1840
+ build_input: function(title, name) {
1841
+ var wrapper = $(document.createElement('div'))
1842
+ .addClass('field')
1843
+
1844
+ var label = $(document.createElement('label'))
1845
+ .attr('for', name)
1846
+ .html(title)
1847
+ .appendTo(wrapper)
1848
+
1849
+ var url = $(document.createElement('input'))
1850
+ .attr('type', 'text')
1851
+ .attr('name', name)
1852
+ .attr('id', name)
1853
+ .appendTo(wrapper)
1854
+
1855
+ return wrapper
1856
+ }
1857
+ }
1858
+ })(jQuery);
1859
+ (function( $ ) {
1860
+ $.fn.ImperaviPluginFile = function(o) { this.initialize(o) }
1861
+
1862
+ $.fn.ImperaviPluginFile.prototype = {
1863
+ initialize: function(o) {
1864
+ this.o = o
1865
+
1866
+ this.dialog = new $.fn.ImperaviDialog({
1867
+ title : 'Attach file',
1868
+ width : 450,
1869
+ height : 237,
1870
+ onRemove : function() {
1871
+ alert('fuck yeah!')
1872
+ this.hide()
1873
+ },
1874
+ onOkay : function() {
1875
+ alert('fuck')
1876
+ this.hide()
1877
+ }
1878
+ })
1879
+
1880
+ this.dialog.show()
1881
+ this.dialog.el.addClass('imperavi-plugin-file')
1882
+ this.dialog.addButton('Remove', 'remove')
1883
+ this.build()
1884
+ },
1885
+
1886
+ build: function() {
1887
+ var wrapper = $(document.createElement('div'))
1888
+ var file = this.build_input('File', 'attachment').appendTo(wrapper)
1889
+ //var caption = this.build_input('Title', 'title').appendTo(wrapper)
1890
+
1891
+ this.dialog.setContent(wrapper)
1892
+ },
1893
+
1894
+ build_input: function(title, name) {
1895
+ var wrapper = $(document.createElement('div'))
1896
+ .addClass('field')
1897
+
1898
+ var label = $(document.createElement('label'))
1899
+ .attr('for', name)
1900
+ .html(title)
1901
+ .appendTo(wrapper)
1902
+
1903
+ var file = $(document.createElement('input'))
1904
+ .attr('type', 'file')
1905
+ .attr('name', name)
1906
+ .attr('id', name)
1907
+ .appendTo(wrapper)
1908
+
1909
+ return wrapper
1910
+ }
1911
+ }
1912
+ })(jQuery);
1913
+ // TODO: add custom events
1914
+ // - onShow
1915
+ // - onClose
1916
+ // - onBuilt
1917
+ // - onContentLoaded
1918
+ // - onOkay
1919
+ // - onCancel
1920
+
1921
+ (function( $ ) {
1922
+ $.fn.ImperaviDialog = function(o) {
1923
+ var o = $.extend({
1924
+ onOkay : function() { this.hide() },
1925
+ onCancel : function() { this.hide() },
1926
+ onClose : function(e) { this.close(e) },
1927
+ onBuilt : function() {},
1928
+ onLoad : function() {}
1929
+ }, o)
1930
+
1931
+ this.initialize(o)
1932
+ }
1933
+
1934
+ $.fn.ImperaviDialog.prototype = {
1935
+ el : null,
1936
+ o : null,
1937
+ overlay : null,
1938
+
1939
+ initialize: function(o) {
1940
+ // Retrieve user options passed to imperavi
1941
+ this.o = $.extend($.fn.ImperaviOptions().options.dialog, o)
1942
+ },
1943
+
1944
+ build: function() {
1945
+ // Build dialog just once
1946
+ if (this.el) return;
1947
+
1948
+ // Create overlay
1949
+ this.overlay = new $.fn.ImperaviOverlay()
1950
+
1951
+ // Dialog window
1952
+ this.el = $(document.createElement('div'))
1953
+ .attr('id', 'imperavi-dialog')
1954
+ .appendTo($('body'));
1955
+
1956
+ this.container = $(document.createElement('div'))
1957
+ .attr('id', 'imperavi-dialog-container')
1958
+ .appendTo(this.el);
1959
+
1960
+ // Close button
1961
+ this.closeBtn = $(document.createElement('a'))
1962
+ .attr('href', 'javascript:;')
1963
+ .html('&times;')
1964
+ .attr('id', 'imperavi-dialog-close')
1965
+ .appendTo(this.container);
1966
+
1967
+ // Dialog title
1968
+ this.title = $(document.createElement('h1'))
1969
+ .attr('id', 'imperavi-dialog-title')
1970
+ .appendTo(this.container);
1971
+
1972
+ // Dialog content
1973
+ this.article = $(document.createElement('article'))
1974
+ .attr('id', 'imperavi-dialog-content')
1975
+ .appendTo(this.container);
1976
+
1977
+ // Buttons panel
1978
+ this.buttons_wrapper = $(document.createElement('div'))
1979
+ .attr('id', 'imperavi-dialog-buttons-wrapper')
1980
+ .appendTo(this.container);
1981
+
1982
+ this.buttons = $(document.createElement('div'))
1983
+ .attr('id', 'imperavi-dialog-buttons')
1984
+ .appendTo(this.buttons_wrapper);
1985
+
1986
+ this.okay_button = this.addButton('Okay', 'okay')
1987
+ this.cancel_button = this.addButton('Cancel', 'cancel')
1988
+
1989
+ // Set default size
1990
+ this.setSize(this.o.width, this.o.height)
1991
+
1992
+ // Set default title
1993
+ this.setTitle(this.o.title)
1994
+
1995
+ this.o.onBuilt.call(this)
1996
+ },
1997
+
1998
+ addButton: function(caption, name) {
1999
+ var callbackName = 'on' + name.charAt(0).toUpperCase() + name.slice(1)
2000
+
2001
+ return $(document.createElement('a'))
2002
+ .attr('id', 'imperavi-dialog-' + name)
2003
+ .attr('href', 'javascript:;')
2004
+ .html(caption)
2005
+ .click($.proxy(function(){ this.o[callbackName].call(this) }, this))
2006
+ .appendTo(this.buttons);
2007
+ },
2008
+
2009
+ addEvents: function() {
2010
+ var onCloseCallback = $.proxy(function(e){ this.o.onClose.call(this, e) }, this)
2011
+
2012
+ $(document).keyup(function(e) { onCloseCallback(e) })
2013
+ this.closeBtn.click(function(e) { onCloseCallback(e) })
2014
+ this.overlay.el.click(function(e) { onCloseCallback(e) })
2015
+ },
2016
+
2017
+ removeEvents: function() {
2018
+ var onCloseCallback = $.proxy(function(e){ this.o.onClose.call(this, e) }, this)
2019
+
2020
+ $(document).unbind('keyup', onCloseCallback)
2021
+ this.closeBtn.unbind('click', onCloseCallback)
2022
+ this.overlay.el.unbind('click', onCloseCallback)
2023
+ },
2024
+
2025
+ setSize: function(width, height) {
2026
+ this.el.css({
2027
+ width : width + 'px',
2028
+ height : height + 'px',
2029
+ marginTop : '-' + height / 2 + 'px',
2030
+ marginLeft : '-' + width / 2 + 'px'
2031
+ }).fadeIn('fast');
2032
+
2033
+ this.container.css({
2034
+ width : width + 'px',
2035
+ height : height + 'px',
2036
+ })
2037
+ },
2038
+
2039
+ setTitle: function(title) {
2040
+ this.title.html(title)
2041
+ },
2042
+
2043
+ setContent: function(content) {
2044
+ this.article.html(content)
2045
+ },
2046
+
2047
+ // TODO Load content via ajax
2048
+ loadContent: function(url) {
2049
+ this.setContent('')
2050
+ this.o.onLoad.call(this)
2051
+ },
2052
+
2053
+ cleanUp: function() {
2054
+ this.removeEvents()
2055
+ this.setContent('')
2056
+ this.setTitle('')
2057
+ },
2058
+
2059
+ show: function() {
2060
+ this.build()
2061
+ this.overlay.show()
2062
+ this.el.show()
2063
+ this.addEvents()
2064
+ },
2065
+
2066
+ hide: function() {
2067
+ this.el.hide()
2068
+ this.overlay.hide()
2069
+ this.cleanUp()
2070
+ },
2071
+
2072
+ close: function(e) {
2073
+ if (e.keyCode == 27 || e.type == 'click')
2074
+ this.hide()
2075
+ }
2076
+ }
2077
+ })(jQuery);
2078
+ (function( $ ) {
2079
+ $.fn.ImperaviOverlay = function(o) { this.initialize(o) }
2080
+
2081
+ $.fn.ImperaviOverlay.prototype = {
2082
+ el : null,
2083
+
2084
+ initialize: function(o) {
2085
+ this.o = o
2086
+ },
2087
+
2088
+ build: function() {
2089
+ if (this.el) return;
2090
+
2091
+ this.el = $(document.createElement('div'))
2092
+ .attr('id', 'imperavi-overlay')
2093
+ .appendTo($('body'));
2094
+ },
2095
+
2096
+ show: function() {
2097
+ this.build()
2098
+ this.el.show()
2099
+ },
2100
+
2101
+ hide: function() {
2102
+ this.el.hide()
2103
+ }
2104
+ }
2105
+ })(jQuery);
2106
+ (function( $ ) {
2107
+ $.fn.ImperaviIframe = function(textarea, o) { this.initialize(textarea, o) }
2108
+
2109
+ $.fn.ImperaviIframe.prototype = {
2110
+ textarea : null,
2111
+ wrapper : null,
2112
+ el : null,
2113
+
2114
+ initialize: function(textarea, o) {
2115
+ this.textarea = textarea
2116
+ this.o = o
2117
+
2118
+ this.textarea.hide();
2119
+
2120
+ this.build()
2121
+ this.populate()
2122
+ this.enable(true)
2123
+ },
2124
+
2125
+ // Build Iframe object and stuff
2126
+ build: function() {
2127
+ this.wrapper = $(document.createElement('div'))
2128
+ .addClass('imperavi')
2129
+ .insertAfter(this.textarea)
2130
+
2131
+ this.el = $(document.createElement('iframe'))
2132
+ .appendTo(this.wrapper)
2133
+ .css({ width : this.textarea.outerWidth(), height : this.textarea.outerHeight() })
2134
+ },
2135
+
2136
+ populate: function() {
2137
+ html = '<!DOCTYPE html>'
2138
+ html += '<head><meta charset="utf-8" />'
2139
+ //html += '<link rel="stylesheet" href="/assets/wysiwyg.css?body=1" />'
2140
+ //html += '<script src="/assets/mootools.js?body=1"></script>'
2141
+ html += '</head><html><body>' + this.textarea.val()
2142
+ html += '</body></html>'
2143
+
2144
+ this.doc().open();
2145
+ this.doc().write(html);
2146
+ this.doc().close();
2147
+ },
2148
+
2149
+ enableObjects: function() {
2150
+ if (!$.browser.mozilla) return;
2151
+
2152
+ //this.doc().execCommand('styleWithCSS', false, false)
2153
+ //this.doc().execCommand('enableObjectResizing', false, false)
2154
+ //this.doc().execCommand('enableInlineTableEditing', false, false)
2155
+ },
2156
+
2157
+ observe: function() {
2158
+
2159
+ },
2160
+
2161
+ enable: function(status) {
2162
+ // Located here for Chrome support
2163
+ this.doc().designMode = status ? 'on' : 'off';
2164
+
2165
+ this.el.load($.proxy(function() {
2166
+ this.enableObjects();
2167
+ this.observe();
2168
+ }, this));
2169
+ },
2170
+
2171
+ doc: function() {
2172
+ var i = this.el.get(0)
2173
+ if (i.contentDocument) return i.contentDocument
2174
+ if (i.contentWindow) return i.contentWindow.document
2175
+
2176
+ return i.document
2177
+ }
2178
+ }
2179
+ })(jQuery);
2180
+ (function( $ ) {
2181
+ $.fn.ImperaviIframeResizer = function(iframe, o) { this.initialize(iframe, o) }
2182
+
2183
+ $.fn.ImperaviIframeResizer.prototype = {
2184
+ iframe : null,
2185
+ el : null,
2186
+
2187
+ initialize: function(iframe, o) {
2188
+ this.iframe = iframe
2189
+ this.o = o
2190
+
2191
+ this.build()
2192
+ },
2193
+
2194
+ build: function() {
2195
+ this.el = $(document.createElement('div'))
2196
+ .addClass('imperavi-resizer')
2197
+ .insertAfter(this.iframe.el)
2198
+
2199
+ this.el.append($(document.createElement('div')))
2200
+ }
2201
+ }
2202
+ })(jQuery);
2203
+ (function( $ ) {
2204
+ $.fn.ImperaviToolbar = function(iframe, o) {
2205
+ var o = $.extend({
2206
+ onButtonClick : function(button) {},
2207
+ }, o)
2208
+
2209
+ this.initialize(iframe, o)
2210
+ }
2211
+
2212
+ $.fn.ImperaviToolbar.prototype = {
2213
+ iframe : null,
2214
+ el : null,
2215
+
2216
+ initialize: function(iframe, o) {
2217
+ this.iframe = iframe
2218
+ this.o = o
2219
+ this.x = $.fn.ImperaviToolbarDefault // TODO make it pretty
2220
+ this.l = $.fn.ImperaviLanguages.ru // TODO make it pretty
2221
+
2222
+ this.build()
2223
+ },
2224
+
2225
+ // Build Toolbar object
2226
+ build: function() {
2227
+ this.el = $(document.createElement('ul'))
2228
+ .insertBefore(this.iframe.el);
2229
+
2230
+ $.each(this.x, $.proxy(function(key, value) {
2231
+ // Buttons with dropdown
2232
+ if (typeof value == 'object') {
2233
+ this.el.append(this.addDropdown(key, value))
2234
+ } else if (typeof value == 'boolean' && value == true) {
2235
+ var title = typeof this.l[key] == 'object' ? this.l[key].name : this.l[key]
2236
+ this.el.append(this.addButton(key, title, null))
2237
+ }
2238
+ }, this));
2239
+ },
2240
+
2241
+ addButton: function(name, title, caption) {
2242
+ var li = $(document.createElement('li')).addClass('button-' + name)
2243
+ var a = $(document.createElement('a'))
2244
+ .attr('href', 'javascript:;')
2245
+ .attr('rel', name)
2246
+ .attr('title', title)
2247
+ .appendTo(li)
2248
+ // This executes a custom callback on button click
2249
+ .click($.proxy(function(){ this.o.onButtonClick.call(this, a) }, this))
2250
+
2251
+ var span = $(document.createElement('span'))
2252
+ .html(caption)
2253
+ .appendTo(a);
2254
+
2255
+ return li.append(a)
2256
+ },
2257
+
2258
+ addDropdown: function(name, items) {
2259
+ var button = this.addButton(name, this.l[name].name, null)
2260
+ var ul = $(document.createElement('ul'))
2261
+
2262
+ button.addClass('has-dropdown')
2263
+
2264
+ // Add dropdown items
2265
+ $.each(items, $.proxy(function(key, value) {
2266
+ if (typeof value == 'object') {
2267
+ var separator = true
2268
+
2269
+ $.each(value, $.proxy(function(key2, value2) {
2270
+ if (value2 == true) {
2271
+ var item = this.addButton(key2, null, this.l[name][key][key2])
2272
+ if (separator) item.addClass('separator')
2273
+
2274
+ ul.append(item)
2275
+ separator = false
2276
+ }
2277
+ }, this));
2278
+ } else if (typeof value == 'boolean' && value == true) {
2279
+ ul.append( this.addButton(key, null, this.l[name][key]) )
2280
+ }
2281
+ }, this));
2282
+
2283
+ return button.append(ul)
2284
+ }
2285
+ }
2286
+ })(jQuery);
2287
+ (function( $ ) {
2288
+ $.fn.imperavi = function(o) {
2289
+ // Editor options
2290
+ var o = $.extend({
2291
+ locale : 'ru', // TODO replace with $.fn.ImperaviLanguage
2292
+ resizer : $.fn.ImperaviIframeResizer,
2293
+ dialog : $.fn.ImperaviDialog,
2294
+ overlay : $.fn.ImperaviOverlay,
2295
+ iframe : $.fn.ImperaviIframe,
2296
+ toolbar : $.fn.ImperaviToolbar,
2297
+ delegator : $.fn.ImperaviActionDelegator,
2298
+ options : {
2299
+ dialog : {
2300
+ title : 'Default title',
2301
+ width : 500,
2302
+ height : 300
2303
+ }
2304
+ }
2305
+ }, o)
2306
+
2307
+ // Global options
2308
+ $.fn.ImperaviOptions = function() { return o }
2309
+
2310
+ // Main object
2311
+ $.fn.Imperavi = function(el) { this.initialize(el) }
2312
+
2313
+ $.fn.Imperavi.prototype = {
2314
+ textarea : null,
2315
+ iframe : null,
2316
+ toolbar : null,
2317
+ resizer : null,
2318
+ delegator : null,
2319
+
2320
+ // Initialize imperavi
2321
+ initialize: function(el) {
2322
+ this.textarea = $(el)
2323
+ this.build()
2324
+ this.autosave()
2325
+ },
2326
+
2327
+ build: function() {
2328
+ // Delegate action to another object
2329
+ this.delegator = new o.delegator
2330
+
2331
+ // Create iframe
2332
+ this.iframe = new o.iframe(this.textarea, o)
2333
+
2334
+ // Create editor resizer
2335
+ this.resizer = new o.resizer(this.iframe, o)
2336
+
2337
+ // Create toolbar
2338
+ this.toolbar = new o.toolbar(this.iframe, {
2339
+ onButtonClick : $.proxy(function(button) {
2340
+ this.delegator.delegateButtonClick(button, this.iframe)
2341
+ }, this)
2342
+ })
2343
+ },
2344
+
2345
+ autosave: function() {
2346
+ // TODO: implement
2347
+ }
2348
+ }
2349
+
2350
+ // Apply imperavi for each selected element
2351
+ return this.each(function() {
2352
+ new $.fn.Imperavi(this)
2353
+ })
2354
+ }
2355
+ })(jQuery);
2356
+ // Vendor
2357
+
2358
+ // Imperavi
2359
+
2360
+
1713
2361
 
1714
- // redactor_tabs
1715
- function showRedactorTabs(el, index)
1716
- {
1717
- $('#redactor_tabs a').removeClass('redactor_tabs_act');
1718
- $(el).addClass('redactor_tabs_act');
1719
-
1720
- $('.redactor_tabs').hide();
1721
- $('#redactor_tabs' + index).show();
1722
- }
1723
2362
  ;
1724
2363
  ;
1725
2364
  TI"
1726
- F"%b41556c4fd89cd7be3ea96f523972044
2365
+ F"%89e6f1a23e8f0c3e789c3dbc2342c62b