type_station 0.4.7 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/type_station/editables/admin_bar.js.coffee +2 -0
  3. data/lib/type_station/version.rb +2 -2
  4. data/spec/dummy/log/development.log +403 -0
  5. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-1/-10rQme50p6Wweb3Wq6CrJWl6V6adB8FUd-QGx37n-Y.cache +1 -0
  6. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-E/-EnK7iHIgtrb6US5s9rqFOOp7Xe30iBs8b8TVubIWO8.cache +0 -0
  7. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-_/-_vP4UrvVxIRNll7qrd5MMD6fVyIoqLiVWFJPJQxT-k.cache +1 -0
  8. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-d/-dFcvM4RhMIQSz7CYdi0GDXPHyVCoxHFJRGr5W4r9EY.cache +1 -0
  9. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-Xfzrb5ZpAgU7nq8xMib9ad1o3oOuOE25Vo4aII5fb4.cache +1 -0
  10. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-xVryxrtaDdzxDYNjnC4VmQB9g6g5b1NvjTz9mMa-io.cache +0 -0
  11. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/06/06dJumVHqstRhdIeTOqyATaRHdBGujn7s6nOXweTvN0.cache +1 -0
  12. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/0X/0XEtcbBJIfbhytXfuesQektnrA0CwdWRLDAC-iVmwss.cache +0 -0
  13. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/0_/0_szgaMxxOSt83yeibDRDbvtc3YKgf89jF3ksplGmGs.cache +0 -0
  14. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/0g/0gnIJzElqH6mTZ2BkYWSQ_L7bkhOl3pNpFEeU1l3Pdk.cache +1 -0
  15. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1B/1BRaQZ9YrnzELpmWduuFBUoY5eGH4Q6yI-l1-YfoYLk.cache +1 -0
  16. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1C/1CNztfUU44hV3JDVFULBbBPDhs30n2cr7mpAq3ObPV4.cache +2 -0
  17. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1F/1FW3JoQWdW7lBwY0JY2fn8UuYycxSGptLf1deCT3uU8.cache +1 -0
  18. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/21/21Gr6eOJ8GXD790upLual16rQqQnI_4lH5dbsIy1ufk.cache +1 -0
  19. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2K/2Km33P_YXYBOTwzlcImlHFNz9t5-o_Vw4Mq1SFLm_8Q.cache +1 -0
  20. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2u/2ublvlfkT634ytTQmjIYBwtnC0rhivD1ketIrrQ6CU8.cache +1 -0
  21. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/32/320BromjZqZdZ7wyjOmVVo18t52xt4JpAXNURQYa0jw.cache +3 -0
  22. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3J/3JcRTve3gt1KOnGy3p2PmZkMgmD6Fua5oCvuiofReOc.cache +5 -0
  23. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3T/3T7Re1TRKeatfec64qlG3QkOkww7JaeR8hIfbJFu5mc.cache +1 -0
  24. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3_/3_ImLijvfNRP8So1cLL4cy7JadLPUbiHFJdmn_5NjJc.cache +1 -0
  25. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3k/3kBBxXro4BowZhaPIwPc3zV3q45-0dWVFsP2_X8WZ2U.cache +1 -0
  26. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3l/3lGXO34nSiCirzB8LWIaPeeRvP4P8IyP7JzdhUI9A4U.cache +1 -0
  27. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4d/4dUNLfIQ0DKP3Wvb1nbw4uDuMOwOCqRJ_DCE_r-Jh3o.cache +3 -0
  28. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4j/4jrlN6WljXx-hRZscgz9YAzRk2w4MPUTCmwSDDy0AzQ.cache +5 -0
  29. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4k/4kQbacDL0TNocHDAw13KxFkQ_DSjwY6jKPGrdoJWlk8.cache +0 -0
  30. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4u/4u_VmkqsowTVo9LQoexdUHBUVm9GwcnZLBZbtzCh2Yo.cache +1 -0
  31. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/57/574hwjRz-ekbl1ZH5_R-oqPkevbZR4h3Et_ImyVKuJo.cache +1 -0
  32. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5M/5MPskXp3t9FXleqjoNo4_EJvNjLIIpu7F7cHyNkgDNU.cache +0 -0
  33. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5Z/5Z9bweNefjqm4beRWuRMP_xmZnJ_USwS7Pw0Uz0FoJM.cache +3 -0
  34. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5q/5qHrWnJz5DtepM21QDxfHhyDK0N4WXhlU8W0yyb7m4w.cache +0 -0
  35. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6-/6-FoMmlvvYjq5v2LIssZJtaYGm_QQwbd5ssHoSFrcjY.cache +3 -0
  36. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/69/69rHH1VMRR3mpGyh9DAV0n6mmjTNtjkPLhjsMWTEHHc.cache +3 -0
  37. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6m/6m-pr002PuDw2yTU5yFMHZr_Yrccz60ji4gNVHFEkAg.cache +0 -0
  38. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7G/7Gly1atK83fTrN51FSQGTgnfn97DjgF8SBQR1Bd3U-o.cache +1 -0
  39. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7e/7eF40Rm_qyH_4Nm_68U1-tDsetTS9nMq8YE9yIyXckw.cache +1 -0
  40. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7e/7ebo33Vd-l__3L9Fxb70DEROgy8a74Ej0vpx68vELLs.cache +3 -0
  41. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/86/86TK63TT3eKKPtgVOilhedFmln3GU_gNl8SLwnYUpVQ.cache +0 -0
  42. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8N/8NBHtc1wobpJfiL3tQjpLu8BMvUA4zKT4txyVqj2y50.cache +1 -0
  43. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8U/8UoDUqI-BUttTAhww61lOM_rkXVyvKOGT3T3VKoG5tY.cache +1 -0
  44. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8X/8XKLpGd9EuzDeOGXNoQhjx_O_l7g5PNGEfgQQ3B7RmU.cache +3 -0
  45. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8t/8twZMW-FUpP8p_OEa9QreZAxiMMdK9HkBXmNeXP52S8.cache +0 -0
  46. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9K/9KbuswPTMS7PawTuPAvnzj0MWDhLamr9MZs9NB8LbF4.cache +0 -0
  47. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9N/9N9UzZTf_8cp-J0Y5mJNBEv-q6deiDxWz3qFhAVyEDY.cache +1 -0
  48. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/9t/9t-rXGMpFphptuPIUcuZ9cuhRjg5hgzMR5l8B_Ldr68.cache +1 -0
  49. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Aa/AaFwiOQMywTIyc3a1hlGpA2c5iHODYmUtUo6zjWEV7c.cache +3 -0
  50. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Aa/aAkEUPRPYtYYF3E-1WG70JrvxCvm8MgfxNnxUqUhSp8.cache +0 -0
  51. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Am/AmVg_Jj2o4JM_UGqemT3K8XI_PDuZPFEph-nXP4KoH4.cache +0 -0
  52. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/As/AsL4XHrP4VKkEKkO_MnQnc_SJHe22utc2-lTOHTzCig.cache +1 -0
  53. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/B2/B2HuSfJz1cPCkvjRca5XDAvsZf-1Njnsg6eqwit2yyQ.cache +1 -0
  54. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BE/BEBiuAKKv_b5JU2nAsuDuxKSzxeNVm65zCUpMTaXuIQ.cache +1 -0
  55. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BE/be_8pDtyM3BfBjCqSUO1VXxHrUBEfr0TOBKXSOCU0RM.cache +7 -0
  56. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/C7/C7xwxKSOmqUwd7QVyJnosVPYIJyWuWOznENeca7n4v4.cache +1 -0
  57. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ck/Ck14ZIbAAZVzvFCo_i-wOcxvZ-sPWGAPjJrSN0ktCZ0.cache +0 -0
  58. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DT/DTzkFbkAtx008DAK3DZuvHWHmEe8YVl_DnYs0DyL8GI.cache +0 -0
  59. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/D_/D_Z1zIyT7v84IIMEZo6Js1wyN3zJOtu0XdDVBn-K3H4.cache +2 -0
  60. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/E7/E7iV-VCGhKOb9ALHXIp0x_n4iInQ_Nb-kC94j5RtvTI.cache +0 -0
  61. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/E8/E8PPnVqWdHywt7FoP_EQijQkkTuDxAaW1TVURKYMyG8.cache +1 -0
  62. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/EZ/EZdj1Bl4liC1AHdINp1S9EW1eQBzMuRt32WLRRNYtXo.cache +0 -0
  63. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ed/EDsKjKgBzcSckInqeRWc8HrA3ge785W1ays_6sgf7Hc.cache +1 -0
  64. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ed/EdgdBZrG0e9RH-iHerASLLjfp13_RvY9Lvx4RIVBNq4.cache +1 -0
  65. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ev/Ev3oOkLEmQubGb-eCdBSmjscsqJhLYoX-o_i-ZFSOzU.cache +1 -0
  66. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FE/FEdryRZiKVEuoH0iH3nGUYxkM7Sa23yajyYWzrsbHjY.cache +1 -0
  67. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FX/FXxWz10FR_us4RdWWUBML-E7OENaRWEPpwMcLhfO_Fo.cache +0 -0
  68. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FY/FYqN2Ac1j7BMyNogLx_cteuh7_1dBaxhWd-_c_Wo2E0.cache +0 -0
  69. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Fc/FcYQnFc4I3un07fEZ5l0F1_SxepCRCRKKKj-jKCYFZ0.cache +3 -0
  70. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Fo/FoSMs5aq7Xv-kvf1WuRifL92pz-Fgfi8LRPfiu5FHYU.cache +1 -0
  71. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/G6/G6MikivBUN2KUBjrHGGIC3wENlINFcIVCw6Gn-ddCdw.cache +1 -0
  72. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/G6/G6yucKm37FVAIuk9tbwva8kBbP43R8BbWIqUH07erVc.cache +1 -0
  73. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/G9/G9HZWSg_gU5oyY0JQ6Ey0mPQD7z9dyvm5Se7bMZv44U.cache +0 -0
  74. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Gb/GbXpghlwxL3-D34h-js5lxV-Zcg5mVVIuSbABCNUG4k.cache +54 -0
  75. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Gk/Gk3FEPItxd0G8f_9qMSIUELpMBd316BhlZv0BKjMg9w.cache +3 -0
  76. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Gp/GpuHwTT4pDxN3wYMqvJUaQieM4usp4K6aLosDOSHeh4.cache +0 -0
  77. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Gs/GsCFFBB7vqOuUIwK2R7ojH-h0easzXhEik8PPwK0rbA.cache +0 -0
  78. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/H8/H89KGYfXFNK9mUxAJqaq9z4-ZKjQebFZvNuMiKv639Q.cache +1 -0
  79. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HS/HShYUosSZKIUMEo8BEq2R4hFcf8H1_BDJUSs4dlFP6k.cache +3 -0
  80. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HT/HT2kN19u1OcyfoZO7XYbF4WJzw0fiCgKu0dn47x2jPo.cache +1 -0
  81. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HT/HThMz-Cjbn-rFt8whApH3ZTUgYA4FYAwMzeAYd_RlvM.cache +1 -0
  82. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/I8/I8DnWLuQhuhWpbPrnCz1fphFbItKDnf55C_wHzY8LYo.cache +3 -0
  83. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/IW/IWIrxSp8b0ijG9WhjHUcI4ItxST45hha3_y-qcCIqMY.cache +3 -0
  84. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/In/INZ3M6aJG1VyG0dAE9RRhZg8HJFTrna7H4hAW6Htkxg.cache +1 -0
  85. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/In/IntFFrdNm3Z9thZKc1TukosqhX3kTubxyKDi4LgGJdg.cache +1 -0
  86. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Iv/Iv1eMKXC6HYUPOM6s5lWfGSpquaXSOjB46LeddlLEa0.cache +2 -0
  87. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Iz/Izk1nqGo8c-jzgUhOIesyTu1mSJMEFNvhy0X98X4N_I.cache +0 -0
  88. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/JN/JNdbDdWZkpmHrs-l_DtWYVoBZgYFfk-NO9JDhFL07MY.cache +3 -0
  89. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/K2/K28WZ7CVE4r2FcrzlB3LwdMKA3LrPIaaCfDvO3pUMCE.cache +3 -0
  90. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Kb/KbtPuR6P0LmOAkE2MX-taOFtwj0Guc_JWZAjwowJsuQ.cache +1 -0
  91. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Kd/KdKTsxUH-rphnRhirijVLW9KRM2uGKUOvjIulnLI2tY.cache +2 -0
  92. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Kn/Kn3GTp-awnb2ge3KQkMJP8bOTW7m0V37vAhd0x-6P20.cache +73 -0
  93. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/L-/L-P7DErCeB11t9VDUaotF9wkPDAOeyvrG0d5sII281w.cache +1 -0
  94. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/LO/LOIw_QrLu6EqRv2po1AhlmvJ5T0AcIZuJV0rK15RRx0.cache +2 -0
  95. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Lb/Lb-EGRk7E0qDE9p8Hqjkx6MpCebFJOvPxPkfqu-ITng.cache +1 -0
  96. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MK/MKSn3iii8fftCls3xw4XwTGICzZh2OfVqxKiwo6psTQ.cache +1 -0
  97. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MK/mKYeqBhwhMfHnyIshyjiIYfk3cgRWGS-BqkqE48T_xg.cache +0 -0
  98. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/MT/MTc4quu6XDggHl_641Gv2UFv55Kttrhx49TkYDhmEH8.cache +0 -0
  99. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mc/Mcd2DhI9dXIrZ2qk3vyeqp8MlR3-uhumgu7L1lZq84o.cache +1 -0
  100. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Nr/Nr_lRFccJIQhRupPc0IYXf7_0K85m3XNcOQ26s01wdg.cache +1 -0
  101. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Nr/nrLpo0Li-lZKBQgFvoYBYk6oVgbgDKpiy1zgT0cthlc.cache +1 -0
  102. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/O8/O8akbUwAbmIKY-AhITimq-JDQ6IgsO3Hvq2v5etufFw.cache +2 -0
  103. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/OZ/OZRjc9y3CedBSOBSwEsGIEcaz8rJcSHucMyKrlKRzvA.cache +1 -0
  104. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/O_/O_LQ9rTo-ySqWYbC7zLFnus7phfUOitpjyLozLTHb6k.cache +1 -0
  105. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Oi/Oi1nr81Bfmxe3X2tEmifRFoGnXev1CbJYKTYal8365A.cache +0 -0
  106. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ow/OwccXl1Ic3lqgRBGIYGM5tadia8IdkfUeJMmP4n1tTM.cache +1 -0
  107. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Oy/OYMZbkT20G0_iILqjfr63sCmV_trlMdxLp1WoltE8AQ.cache +1 -0
  108. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Oy/OyVt39k9qOctveYmFl-STXKJKNeueCyOEbGZ2_B4ZD0.cache +3 -0
  109. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Oy/oyFBxJ8Z8i2Xb2Lll4uH6W2A3f9vSVhA9oXM2r-0R7w.cache +5 -0
  110. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/P3/P3WVCvTrDc2yHhngtC9uXOAewMmWcXdPi7ASSDrV5lo.cache +1 -0
  111. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/PC/PCjtAJWBdT0swUVHaAWwI3bojT1phBdmw9HQisn_pbM.cache +1 -0
  112. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Q8/Q8A_ahhm51CmbHk4WpTRCpwtI9mxcu2bW6NqhYdcfwM.cache +1 -0
  113. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QX/QX0JH72se01xT2fNmLyg-sUtrk7DlLmkxNV01s_MEfg.cache +1 -0
  114. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qv/QvrJG0y21_i6f_tzu-nClfX01QyRZF4QIkZ-4um5r_U.cache +104 -0
  115. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/R9/R9NVbLRnVzczRdRyD2VV5x97VrIowtBQLyypSZBQt90.cache +1 -0
  116. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/RE/RE53knr2hrEvDFyr33gwJBL7twGjHEmN6s6FwGtyKFs.cache +1 -0
  117. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/RM/RMsrl8AKW4-xiwQlQyHKpF51XeuKQGv6VcSj6lpC-gg.cache +1 -0
  118. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/RQ/RQUnHc8WheunBLgn7V-Yrrm9cdYxr1fqAp9jNkexDrg.cache +2 -0
  119. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/RU/RUWGCr1p2-QM0JD8NwJpLrWrH3UwTw8ypOEEnyaHRgM.cache +3 -0
  120. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/S-/S-vKRdJnmmIzYIa4KShhx689AY-lTdGFd44UYa-DLFc.cache +1 -0
  121. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/S0/S0weHOttlNPgxahIyNUKB3qj2vN71d526XRHMxMje9Q.cache +0 -0
  122. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/S7/S7lL2J7tx5oHCtsOvZuBoNGOeOoe4n7qJgZCQGHXfYQ.cache +3 -0
  123. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SM/SMlFyPb3qixKxxPQ6XSkdrOSDxOFptdM4jt1AK4Mync.cache +0 -0
  124. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/SP/SP1YDfGWTQNPPbv4TlimqUvdr1n3QAj3ceHunawMq88.cache +1 -0
  125. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Se/Se8yKp4PKGEiDiwrH_AL_pSzl6CRnCa2VyaOv5zUj1o.cache +0 -0
  126. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tf/TfIQqzFTX0vKu3IJM4C9An0gkeY0WFFZebfDYcQKQ60.cache +2 -0
  127. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tj/TjiJSeh-VRpcoiI0Z_JvKlg2jE3lGsKkLwCvGsxTVhg.cache +3 -0
  128. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Tw/Tw4qTe4pikph13nkN4d8AZjSb8F9Z8zVlmNjfMNiDMo.cache +3 -0
  129. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/U2/U2Gr71iJOUl-Ydg0rMZBlsTM07x5MlSWPokr1lBwF-E.cache +1 -0
  130. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UA/UASYkjJr9XL3Lmr0L5lWqDRLPJ7Ap9rk_VKVTkM3Q3Q.cache +1 -0
  131. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UG/UGa0U-476ZNYV3aEVKwnEUoTXohti_85esgeDAtC_BA.cache +3 -0
  132. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UO/UOPeDrSCvYLR_Fyw4iPO7bsBQqo8-BpzBB5GlJBopZM.cache +1 -0
  133. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UY/UYcoe2gw7Ke7pEASDPCU4GSnL8fzo8QS5k5xOVJCk3U.cache +1 -0
  134. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ud/UdxiCBYFzfE8nB_w-gcXpjYo9RQN5bhe6iwmsvNoMhE.cache +3 -0
  135. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/V-/V-7ZMoSNgEgBzS6M_LwBK_4N7MxPjyvUYchxsVCmBDM.cache +1 -0
  136. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/V3/V3VGAxQ3BvryMb_SnWDEYPMHj9zs5FzSD641sbWPjSo.cache +1 -0
  137. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/VB/VBrI6MZEfEAzYQj1PQbGjhxHf4TaI3VrxO2bqpfTjj0.cache +3 -0
  138. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/VK/VKGnil96gVh9Kck5z8wxfQ-9msIJjkjLnQZ2b8XMhfY.cache +3 -0
  139. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/V_/V_2BcaJttZWkKJHdfrM2v04okvdAGSxW0SQ3rkwxJvM.cache +1 -0
  140. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Vs/Vspr6E12ZPcDDrfEFKL6ba5UK_SbpQi07kyw2ILTBNk.cache +1 -0
  141. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/W_/W_dL_pApK43bcE2g5lXwOf3ZHkFUmaNTnWceZz1CHo0.cache +0 -0
  142. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/W_/w_sXspjWODK2ApqfRBF_sKQi5hFIVuZuWqISpnxTefE.cache +0 -0
  143. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wi/WiPaSahUX5qyQtuSi4aWFHUY4RRbTpleVQBJWsqvDFg.cache +1 -0
  144. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wu/WuHL0qKgH6ZWO0xi1N0_F-L9chmMwlEws29DipzK7i4.cache +0 -0
  145. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XP/XPG0OQg_5xBL7_XGSAB6ruND4NZRsicqwGihb7QfgKA.cache +0 -0
  146. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X_/X_bRAdkpQIWNFyBCdNXCJqteo2utcpaQpv9V4YQE3OQ.cache +1 -0
  147. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Xi/XimxZHdFWVLh8hQab9TCpu4t7DTp8MBGP1_SEZ6Cnxs.cache +2 -0
  148. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Y4/Y4PclklRbbVX6Acy3DA_YzrhNt3WEQkRqZ677XpiLRc.cache +1 -0
  149. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YG/YGdG9wrRMRcR_iITaLv__Abu-IoHqhdPZfP5k4s6T2A.cache +0 -0
  150. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YO/YOADM86O0eaqQpwNTmvhU1ArE_pJ2l3pQ-tsCDYZLec.cache +1 -0
  151. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YO/YOrKIrDaBMyp989-0d7RjAOGcCESA8wZhtagnByGmVc.cache +3 -0
  152. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YR/YRS1gAx6MWMkF04LBtqmFEb47i6X3i1nwRTHi8u-Je4.cache +1 -0
  153. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yd/Yd3_dnSRf8H7Df3u1spB2vUso6M0WDutGEqXUOwZDWI.cache +1 -0
  154. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yd/ydw1ho6l1Elu8E4sv2Pn65RmkgGhDQ0OlujSJlGFgPo.cache +0 -0
  155. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ye/Ye9C84pAvhKWoqAduD9R7jiiUfpO1_5MfwPHPQyMSQs.cache +3 -0
  156. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ys/YsRjDc40EirSbmV2_PUdU5IsK6XvVgyfnpwJNPz1Pwk.cache +3 -0
  157. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Zk/ZkIfGkcCJSiftkYYunIxnzDnAamuZaL9x5ulbwiKrIE.cache +3 -0
  158. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Zo/ZofRNaIwOcCjvdrVkwSlvhd9jRO3QapQl9xH08DGz-w.cache +1 -0
  159. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_3/_34TKSBAHO8RGnZnJy37nrGK8p3P4EG2rI65OW2ZH78.cache +0 -0
  160. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_d/_dA_64XleYGAVMcz6Ge-7Yb9__m9Hf3ZQ_jZHN6-f_0.cache +1 -0
  161. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_g/_glx-WMt43JuezTWAI-GM6HieDwxOsrSzqYwcLerQDY.cache +3 -0
  162. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_t/_t1tLqXmi1lHiSlwmU-zSZVbcBPJ3j9rRBbHSutcgpo.cache +1 -0
  163. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/aE/aEAkRAdMBJp7IrmAyKIzkh6UUsm6OaeRzQ-T5CHP2PA.cache +0 -0
  164. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bd/bdRhpZ6VD7GNUv40StMsfowJEjlZCvAVLNW6q99Zzhw.cache +3 -0
  165. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bw/bwQdQakeOA80sOssAi0AL0eCbN7jTYZdMWZY-7ghdmA.cache +0 -0
  166. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/c8/c8D39zSpjZ9lxfWJLahsQcz7AvIzZmZ7bSYEo85dxzo.cache +0 -0
  167. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cO/cOBeuOQojpWO_MSC_nk_O-OfC-tCXz1V4d4xXcu_QwQ.cache +0 -0
  168. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cg/cgXlwVggiz17racws5jMBrsSPqIWMY9mDl9enuvFCUM.cache +1 -0
  169. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ch/chbXFl4E9bqZVTpC3IxzIUCkGDMX8pvm8Pxjs2LYSrM.cache +0 -0
  170. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/d0/d0rr17-3lWfRQ0Wo55j8e6YNQ9itz_RBh-3RqCYlcM0.cache +0 -0
  171. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/d3/d3wnBf2fkXxkR8-XxMzkRCr1oyarxSOC0L9fH6LKbv8.cache +0 -0
  172. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/d5/d5ppfzn29-UhjtDhCsMsdotk_GVxTYT0xg-DEHIcYwo.cache +3 -0
  173. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/e-/e-kcN4_NtWHjaNUnMJoSiqwEz4dirmu2QiGwblFRk-I.cache +0 -0
  174. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ec/ecdv8EaiQV_ma8QCsB7U88kjF-tTfZQb7bLiWnro5us.cache +1 -0
  175. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fD/fDQxtoKk9UP8CxHIDc1841LNAFdH7Sda9GwhYqiKWxo.cache +0 -0
  176. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fS/fSD-q4iDT__seP_fNO7tq5w6RX1QUA7Kyj4lH8zmHhU.cache +0 -0
  177. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fz/fzgRkEKX9VfGmqVCl2cdeuc8BzxtZsh4Wi2HEbCqyZI.cache +1 -0
  178. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g2/g2Wl8vGAQHSJ00zXGw74Ywrw161dkkv75rySfk6TF1s.cache +0 -0
  179. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g7/g7ctztTZ8C8Og4cjS0esPTqZRMrYHawSQoylHFuq5Tk.cache +2 -0
  180. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gH/gHZ91xw-QZ6XiSYGHx-zvUaMvj1jRHv32OXYWGesyzY.cache +1 -0
  181. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/g_/g_AyDddrdALmJv_racfhwX-MXCzhMhSiJqBBhkOXJSI.cache +0 -0
  182. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/h0/h0C5r1YmxeWZ7xmvBZWPFnske5XtWCy8IHKEhYxz1GY.cache +1 -0
  183. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/h4/h48kbOdKbM4E10Vs0wVgEhr4-FhMTf18RB1lLBm1LUQ.cache +1 -0
  184. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hu/hu3COgettdZo3gMm8DPcQBAUu3l0zxDiLm84wQt5Kwg.cache +0 -0
  185. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/i4/i4pF9Bmmu2_lS3v48TNP2C1MUPf7EiXjedNwl7_X8D4.cache +1 -0
  186. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ib/ibRU-oP7ekrNYNIM0ERyOPouLBngmxnDaHp14QYNCQM.cache +0 -0
  187. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jD/jDPIMat4OMQzKLeqRF3Nb4kY9HLS4usXrYZWerxFUho.cache +3 -0
  188. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jF/jFxYi7n0kw3Ev0DMfVbN0BYm7i9ZAWb-5lrTgQLkzkw.cache +4 -0
  189. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jr/jrOrf3u-MWeBtMvmEPyVhHjRRDWY60ycXP3G9S6PxH8.cache +0 -0
  190. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/kK/kKUwBWRfsfIkHyKBuznJcpd5W2quP1WG0Qvm8SIong0.cache +2 -0
  191. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/kL/kLvC5Jztau9WmLo1_LQBFT9R6XnmXYSuQHTmhVwLBnU.cache +0 -0
  192. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/l7/l73JBt8d21O2R5jHuAoSF1t3yac5sUyTRinAHEA7Nro.cache +0 -0
  193. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lL/lLc5z7qdJY4WfFBzyGhJnOF31wBBqJoD4OAxYPy23oI.cache +2 -0
  194. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lZ/lZxqodqscAFPbLUWfizriuYB0LstFAJEmIZIknQGjf4.cache +0 -0
  195. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m4/m4qnz1XKKl5TmVc_nfNUxnDOcWIF3vjCrybysx5S5dE.cache +3 -0
  196. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ml/mlDzBJPZseI3ONA4G-cFVXRf67T5l11vzlCZuXNLCqg.cache +0 -0
  197. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mq/mqM2btO-0T9M5u_Apb-hnetpL9Ot0Za1lmhmbkazXJo.cache +1 -0
  198. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/nK/nKQZUwnWgjgSHJRzgMX6T1rS0o5OXmCUNf7kOwDWt-Q.cache +3 -0
  199. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/nq/nq-FMjeOP3ccPBV3KIWlsIXz00Y-DxcZLDbMy41w0ns.cache +5 -0
  200. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/nv/nvMFDG0qM90wst7hl2gCp72SUCmYoFYvoZfxyk7F3-w.cache +3 -0
  201. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oA/oA0wFKJ3fV76DLsMuI5FYOv7KArBhjcmuMEBUVh-IEI.cache +1 -0
  202. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oG/oGWbT11h9CntgsRYeHVvRUSRM_pXctuvso5bD1E-_Rg.cache +75 -0
  203. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oJ/oJf6gvISJUzPzOZfzlm0RPXE8pkRsk4Liou1wiR4bwU.cache +1 -0
  204. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oS/oSsCcH0Y1Pb72IewPEMMZgthmjZ-aBCsmPRDQY6IsWE.cache +2 -0
  205. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oc/ocCdznCTiDsf5SnX-XbzboHKIsa5N_0JJvcFaIa0v4k.cache +0 -0
  206. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pZ/pZs_OT7KhpWl5Bw2QXAZBUJv4L4B0ZvjroNOOVNYHew.cache +1 -0
  207. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pi/piPpAsxRDhkhXCpgy5rNfwev2FCllQeOpv2T46jFlgk.cache +1 -0
  208. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q4/q4iH6hAaHRsNLtNNQwjyuV1nrRqUqSvOP2tOLHUWmw0.cache +1 -0
  209. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qB/qBoVS2DfU2y1_uaxk__lSg4q7qgpRjZ0yCRA62ViaSk.cache +0 -0
  210. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qG/qG4Hk7ZYCV4GcPgAVWFnzBPzGUXMjsPNlWAxzXFDIzY.cache +1 -0
  211. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qh/qhdWM55QpY_1Wel6alhcgtJJ1o1i_pvD5m4pR7Gf2H8.cache +1 -0
  212. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qi/qiZJ4AD7a-JZBnkgliJipAqlqobsszSWew-8qJMEBuc.cache +0 -0
  213. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qn/qnxANHDXRgytq0YwdMMqTCjJkR_7u-AIYodo6H2yWZk.cache +0 -0
  214. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r2/r2wUxqXPZGyL8yJQ8xQKBW62cJs1uE_kUeiDnjOt3eI.cache +1 -0
  215. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rI/rI8pww981NHG22krf5FbLsuRHjYf85Nlom5uxJQwoqY.cache +1 -0
  216. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ra/rahIaRydDKWOwY0mWr9MsvBG5ia5q8RgLBZsVUS1Z-k.cache +1 -0
  217. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rd/RdfB0OzMfmjFAubT3THbRNJY7_LwFJZJKrUGU8q3708.cache +0 -0
  218. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rd/rdiz0vLTLXOjXgmyGaa9Rtn9U1rxIR70X39htU2l0uM.cache +2 -0
  219. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rg/rgsvMxrjiJSAFeE_Rawd4cjIlNniYQ2LLMr-WfHcEmE.cache +2 -0
  220. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ro/ron72ZitBqwTzm-mJk-_TnXub4HXPM6x0Cv4FSERVJA.cache +0 -0
  221. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/rw/rwAUBS6_7P7KsaV-huzkfaoGbbPCL_TLREXtEGxNGto.cache +0 -0
  222. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sR/sR2TAOkCQmj-R7OEG_CPlIBvcf5qxFqq5uwJ3n7GHyQ.cache +1 -0
  223. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sX/sX4wwS_efcIabnhLoa6LYb_lRY5Zv2E_coiw4-cgESg.cache +1 -0
  224. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sb/sbIfIYytasmqOfY26ylrPhJnvWLmgYauZ6XOjXMjssU.cache +3 -0
  225. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sj/sjeKBH2T__mODBuQr0RqtBnDJeyDutqYZ1fssGam_rs.cache +1 -0
  226. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tN/tNZQPVNwKhR_JK2mlhPvLHQxlrN8Fk5prdVXg5x7CLs.cache +1 -0
  227. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tP/tPF6H9NRpGO3whu2y5_e_R_1EACKdCwu5437D83qJT0.cache +2 -0
  228. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tY/tYhhOTVTALHMYiY0UZ1-mTCJDNXZ_a8SB9nDvb4fZKs.cache +1 -0
  229. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tu/tu6UFqTPo1b-UrtPhSJXYAfv2t3ba3adAGKGi-RaEuI.cache +1 -0
  230. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tx/tXTuLOynyl3e0YWQyhD3E50mipG6rWV5rJh7DUIJZmY.cache +1 -0
  231. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tx/tXbf5ehiC_jNJ1nYVORlPm8XC5mukmFnPBDopf4ds3U.cache +1 -0
  232. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tx/tx4eRwuD66QCa9fWI5DpiQsC6TjXTndahVzhzsqxezU.cache +1 -0
  233. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/u0/u0t4_vnTeokERX9UCHD5W7IMs8CV2wE5Y2Zh8ozQtd4.cache +1 -0
  234. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/u3/u3Jt2hHm68soUkdfP4pUF2RbuciMhpJMZaye7golzjk.cache +0 -0
  235. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/u4/u4UmICDQX9_TmlF9dagNGljgWQwWxyJcjHARwcmhgXs.cache +1 -0
  236. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ur/uRZ3Og-L4J6uWe9e35T_tOklxCVrd94Ke4q8fVELXX4.cache +1 -0
  237. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ur/urq6cvvM8i1tBGilXO29tzaeGpWTgFWe8wgrQyBGQco.cache +1 -0
  238. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/uv/uv3cZO4PygxIjlJsSwYJwyHrVVqObs2ACSK1ZDpciXg.cache +0 -0
  239. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v6/v64K6Lupt6J92uk_MwUXTfGMobanMksIxKX-zamg8IU.cache +3 -0
  240. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vN/vNGzkJNd8jZKUpldX9gm2gb3QR8CJRHo72vHHMHPVYU.cache +1 -0
  241. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vf/vf6pS83AJcKYSl-DcY_ScZeYkB0yDhbxKl_jnVPColY.cache +0 -0
  242. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vo/voUX3N1PGX-aokkt4gRSJMc0ZaWrL0i2pGo-9--xDvA.cache +1 -0
  243. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vv/vvmwM1iU3kXTcgVdOcdKSaTOp5RCXRv_xvb7AZkL594.cache +0 -0
  244. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/w5/w5QMt63TSr_XbGyWPix58UVdQew5zaVFIls9Q05leCU.cache +2 -0
  245. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/w9/w9EGr404Ec8iWX-TW5NwtOX7CZFxbLuJrLrPXegwie4.cache +0 -0
  246. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wK/wKaiZcrtqWwNr8hquK3JBngxCtsqbKMMPfUlBZB4FAo.cache +0 -0
  247. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wQ/wQdUXI6R5rwkq8dRFsjrgiJ0E6eF_0M75B_SxoMK8-w.cache +1 -0
  248. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wV/Wv-6bVwsTp_LqZ1ZD4iZR8kOhuIO4M5yCctID5n98Q8.cache +1 -0
  249. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wV/wVjAOidZ-lZqani0lwAeuul_ma2e9nNZfuEQgaqZ6N8.cache +78 -0
  250. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wg/wgvpP2Zxu3BaOgAP1nz0MTp3TnSPZLLD7njzJyTAY0k.cache +5 -0
  251. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/x-/X-GTjAJs0k4DdFqoUzfRXbSpu0lHkC7WuXFo6i9mtcQ.cache +1 -0
  252. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/x-/x-n_OHI0W_PinN8NC6kdtfkflbqTvZTEzWLZBGotSvQ.cache +1 -0
  253. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xs/xsz1Xli1rjewlmkdAsFaTqU1QF1bAZ9r2VABTS63a-E.cache +0 -0
  254. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yH/yHR_S3o-CR62iV2PhE_BBYQANZqqn1Hun_xVebhOx0k.cache +0 -0
  255. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yM/yMGwsY99j5fPgf5LWsCwNt4JJdvIJ8T1A9tnEgiNG3k.cache +1 -0
  256. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/z4/z4R50-aot5DTt3qdrnIv3L7tzYF5Ts_OZ_UBkdgZQew.cache +2 -0
  257. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/z9/z9RyRiOc7eWfq0AQht0-e2T8BCDWGxuElTNRNyF-i60.cache +0 -0
  258. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zQ/Zqlhmo8u-4j5v6Js-q3mxfbqc-DM0nZ3rQUiMMdtQnQ.cache +0 -0
  259. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zQ/zQpUaxTk07z9j0wKNLDhvRU1cCHLOPsB8nftF3rwGTg.cache +0 -0
  260. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zy/zyyLbt3lCJcXlGtjIxh7PoGOlX3t6Sr00yVzT6jhtx4.cache +81 -0
  261. data/spec/dummy/tmp/pids/server.pid +1 -1
  262. data/vendor/assets/javascripts/medium-editor.js +443 -114
  263. data/vendor/assets/stylesheets/medium-editor/medium-editor.css +15 -5
  264. data/vendor/assets/stylesheets/medium-editor/medium-editor.min.css +1 -1
  265. data/vendor/assets/stylesheets/medium-editor/themes/flat.css +1 -1
  266. data/vendor/assets/stylesheets/medium-editor/themes/flat.min.css +1 -1
  267. metadata +523 -11
@@ -1 +1 @@
1
- 8
1
+ 259
@@ -385,7 +385,8 @@ if (!("classList" in document.createElement("_"))) {
385
385
 
386
386
  (function (root, factory) {
387
387
  'use strict';
388
- if (typeof module === 'object') {
388
+ var isElectron = typeof module === 'object' && typeof process !== 'undefined' && process && process.versions && process.versions.electron;
389
+ if (!isElectron && typeof module === 'object') {
389
390
  module.exports = factory;
390
391
  } else if (typeof define === 'function' && define.amd) {
391
392
  define(function () {
@@ -628,11 +629,10 @@ MediumEditor.extensions = {};
628
629
  splitEndNodeIfNeeded: function (currentNode, newNode, matchEndIndex, currentTextIndex) {
629
630
  var textIndexOfEndOfFarthestNode,
630
631
  endSplitPoint;
631
- textIndexOfEndOfFarthestNode = currentTextIndex + (newNode || currentNode).nodeValue.length +
632
- (newNode ? currentNode.nodeValue.length : 0) -
633
- 1;
634
- endSplitPoint = (newNode || currentNode).nodeValue.length -
635
- (textIndexOfEndOfFarthestNode + 1 - matchEndIndex);
632
+ textIndexOfEndOfFarthestNode = currentTextIndex + currentNode.nodeValue.length +
633
+ (newNode ? newNode.nodeValue.length : 0) - 1;
634
+ endSplitPoint = matchEndIndex - currentTextIndex -
635
+ (newNode ? currentNode.nodeValue.length : 0);
636
636
  if (textIndexOfEndOfFarthestNode >= matchEndIndex &&
637
637
  currentTextIndex !== textIndexOfEndOfFarthestNode &&
638
638
  endSplitPoint !== 0) {
@@ -1019,6 +1019,11 @@ MediumEditor.extensions = {};
1019
1019
  }
1020
1020
  },
1021
1021
 
1022
+ /*
1023
+ * this function adds one or several classes on an a element.
1024
+ * if el parameter is not an a, it will look for a children of el.
1025
+ * if no a children are found, it will look for the a parent.
1026
+ */
1022
1027
  addClassToAnchors: function (el, buttonClass) {
1023
1028
  var classes = buttonClass.split(' '),
1024
1029
  i,
@@ -1028,7 +1033,13 @@ MediumEditor.extensions = {};
1028
1033
  el.classList.add(classes[j]);
1029
1034
  }
1030
1035
  } else {
1031
- el = el.getElementsByTagName('a');
1036
+ var aChildren = el.getElementsByTagName('a');
1037
+ if (aChildren.length === 0) {
1038
+ var parentAnchor = Util.getClosestTag(el, 'a');
1039
+ el = parentAnchor ? [parentAnchor] : [];
1040
+ } else {
1041
+ el = aChildren;
1042
+ }
1032
1043
  for (i = 0; i < el.length; i += 1) {
1033
1044
  for (j = 0; j < classes.length; j += 1) {
1034
1045
  el[i].classList.add(classes[j]);
@@ -1429,11 +1440,15 @@ MediumEditor.extensions = {};
1429
1440
  },
1430
1441
 
1431
1442
  cleanupTags: function (el, tags) {
1432
- tags.forEach(function (tag) {
1433
- if (el.nodeName.toLowerCase() === tag) {
1434
- el.parentNode.removeChild(el);
1435
- }
1436
- });
1443
+ if (tags.indexOf(el.nodeName.toLowerCase()) !== -1) {
1444
+ el.parentNode.removeChild(el);
1445
+ }
1446
+ },
1447
+
1448
+ unwrapTags: function (el, tags) {
1449
+ if (tags.indexOf(el.nodeName.toLowerCase()) !== -1) {
1450
+ MediumEditor.util.unwrap(el, document);
1451
+ }
1437
1452
  },
1438
1453
 
1439
1454
  // get the closest parent
@@ -1653,6 +1668,19 @@ MediumEditor.extensions = {};
1653
1668
  */
1654
1669
  setInactive: undefined,
1655
1670
 
1671
+ /* getInteractionElements: [function ()]
1672
+ *
1673
+ * If the extension renders any elements that the user can interact with,
1674
+ * this method should be implemented and return the root element or an array
1675
+ * containing all of the root elements. MediumEditor will call this function
1676
+ * during interaction to see if the user clicked on something outside of the editor.
1677
+ * The elements are used to check if the target element of a click or
1678
+ * other user event is a descendant of any extension elements.
1679
+ * This way, the editor can also count user interaction within editor elements as
1680
+ * interactions with the editor, and thus not trigger 'blur'
1681
+ */
1682
+ getInteractionElements: undefined,
1683
+
1656
1684
  /************************ Helpers ************************
1657
1685
  * The following are helpers that are either set by MediumEditor
1658
1686
  * during initialization, or are helper methods which either
@@ -2416,6 +2444,26 @@ MediumEditor.extensions = {};
2416
2444
  (function () {
2417
2445
  'use strict';
2418
2446
 
2447
+ function isElementDescendantOfExtension(extensions, element) {
2448
+ return extensions.some(function (extension) {
2449
+ if (typeof extension.getInteractionElements !== 'function') {
2450
+ return false;
2451
+ }
2452
+
2453
+ var extensionElements = extension.getInteractionElements();
2454
+ if (!extensionElements) {
2455
+ return false;
2456
+ }
2457
+
2458
+ if (!Array.isArray(extensionElements)) {
2459
+ extensionElements = [extensionElements];
2460
+ }
2461
+ return extensionElements.some(function (el) {
2462
+ return MediumEditor.util.isDescendant(el, element, true);
2463
+ });
2464
+ });
2465
+ }
2466
+
2419
2467
  var Events = function (instance) {
2420
2468
  this.base = instance;
2421
2469
  this.options = this.base.options;
@@ -2431,7 +2479,10 @@ MediumEditor.extensions = {};
2431
2479
  // Helpers for event handling
2432
2480
 
2433
2481
  attachDOMEvent: function (targets, event, listener, useCapture) {
2434
- targets = MediumEditor.util.isElement(targets) || [window, document].indexOf(targets) > -1 ? [targets] : targets;
2482
+ var win = this.base.options.contentWindow,
2483
+ doc = this.base.options.ownerDocument;
2484
+
2485
+ targets = MediumEditor.util.isElement(targets) || [win, doc].indexOf(targets) > -1 ? [targets] : targets;
2435
2486
 
2436
2487
  Array.prototype.forEach.call(targets, function (target) {
2437
2488
  target.addEventListener(event, listener, useCapture);
@@ -2440,16 +2491,21 @@ MediumEditor.extensions = {};
2440
2491
  },
2441
2492
 
2442
2493
  detachDOMEvent: function (targets, event, listener, useCapture) {
2443
- var index, e;
2444
- targets = MediumEditor.util.isElement(targets) || [window, document].indexOf(targets) > -1 ? [targets] : targets;
2445
-
2446
- Array.prototype.forEach.call(targets, function (target) {
2447
- index = this.indexOfListener(target, event, listener, useCapture);
2448
- if (index !== -1) {
2449
- e = this.events.splice(index, 1)[0];
2450
- e[0].removeEventListener(e[1], e[2], e[3]);
2451
- }
2452
- }.bind(this));
2494
+ var index, e,
2495
+ win = this.base.options.contentWindow,
2496
+ doc = this.base.options.ownerDocument;
2497
+
2498
+ if (targets !== null) {
2499
+ targets = MediumEditor.util.isElement(targets) || [win, doc].indexOf(targets) > -1 ? [targets] : targets;
2500
+
2501
+ Array.prototype.forEach.call(targets, function (target) {
2502
+ index = this.indexOfListener(target, event, listener, useCapture);
2503
+ if (index !== -1) {
2504
+ e = this.events.splice(index, 1)[0];
2505
+ e[0].removeEventListener(e[1], e[2], e[3]);
2506
+ }
2507
+ }.bind(this));
2508
+ }
2453
2509
  },
2454
2510
 
2455
2511
  indexOfListener: function (target, event, listener, useCapture) {
@@ -2609,23 +2665,23 @@ MediumEditor.extensions = {};
2609
2665
 
2610
2666
  // Helper method to call all listeners to execCommand
2611
2667
  var callListeners = function (args, result) {
2612
- if (doc.execCommand.listeners) {
2613
- doc.execCommand.listeners.forEach(function (listener) {
2614
- listener({
2615
- command: args[0],
2616
- value: args[2],
2617
- args: args,
2618
- result: result
2619
- });
2668
+ if (doc.execCommand.listeners) {
2669
+ doc.execCommand.listeners.forEach(function (listener) {
2670
+ listener({
2671
+ command: args[0],
2672
+ value: args[2],
2673
+ args: args,
2674
+ result: result
2620
2675
  });
2621
- }
2622
- },
2676
+ });
2677
+ }
2678
+ },
2623
2679
 
2624
- // Create a wrapper method for execCommand which will:
2625
- // 1) Call document.execCommand with the correct arguments
2626
- // 2) Loop through any listeners and notify them that execCommand was called
2627
- // passing extra info on the call
2628
- // 3) Return the result
2680
+ // Create a wrapper method for execCommand which will:
2681
+ // 1) Call document.execCommand with the correct arguments
2682
+ // 2) Loop through any listeners and notify them that execCommand was called
2683
+ // passing extra info on the call
2684
+ // 3) Return the result
2629
2685
  wrapper = function () {
2630
2686
  var result = doc.execCommand.orig.apply(this, arguments);
2631
2687
 
@@ -2755,6 +2811,8 @@ MediumEditor.extensions = {};
2755
2811
  // Detecting drop on the contenteditables
2756
2812
  this.attachToEachElement('drop', this.handleDrop);
2757
2813
  break;
2814
+ // TODO: We need to have a custom 'paste' event separate from 'editablePaste'
2815
+ // Need to think about the way to introduce this without breaking folks
2758
2816
  case 'editablePaste':
2759
2817
  // Detecting paste on the contenteditables
2760
2818
  this.attachToEachElement('paste', this.handlePaste);
@@ -2792,21 +2850,16 @@ MediumEditor.extensions = {};
2792
2850
  },
2793
2851
 
2794
2852
  updateFocus: function (target, eventObj) {
2795
- var toolbar = this.base.getExtensionByName('toolbar'),
2796
- toolbarEl = toolbar ? toolbar.getToolbarElement() : null,
2797
- anchorPreview = this.base.getExtensionByName('anchor-preview'),
2798
- previewEl = (anchorPreview && anchorPreview.getPreviewElement) ? anchorPreview.getPreviewElement() : null,
2799
- hadFocus = this.base.getFocusedElement(),
2853
+ var hadFocus = this.base.getFocusedElement(),
2800
2854
  toFocus;
2801
2855
 
2802
- // For clicks, we need to know if the mousedown that caused the click happened inside the existing focused element.
2803
- // If so, we don't want to focus another element
2856
+ // For clicks, we need to know if the mousedown that caused the click happened inside the existing focused element
2857
+ // or one of the extension elements. If so, we don't want to focus another element
2804
2858
  if (hadFocus &&
2805
- eventObj.type === 'click' &&
2806
- this.lastMousedownTarget &&
2807
- (MediumEditor.util.isDescendant(hadFocus, this.lastMousedownTarget, true) ||
2808
- MediumEditor.util.isDescendant(toolbarEl, this.lastMousedownTarget, true) ||
2809
- MediumEditor.util.isDescendant(previewEl, this.lastMousedownTarget, true))) {
2859
+ eventObj.type === 'click' &&
2860
+ this.lastMousedownTarget &&
2861
+ (MediumEditor.util.isDescendant(hadFocus, this.lastMousedownTarget, true) ||
2862
+ isElementDescendantOfExtension(this.base.extensions, this.lastMousedownTarget))) {
2810
2863
  toFocus = hadFocus;
2811
2864
  }
2812
2865
 
@@ -2822,10 +2875,9 @@ MediumEditor.extensions = {};
2822
2875
  }, this);
2823
2876
  }
2824
2877
 
2825
- // Check if the target is external (not part of the editor, toolbar, or anchorpreview)
2878
+ // Check if the target is external (not part of the editor, toolbar, or any other extension)
2826
2879
  var externalEvent = !MediumEditor.util.isDescendant(hadFocus, target, true) &&
2827
- !MediumEditor.util.isDescendant(toolbarEl, target, true) &&
2828
- !MediumEditor.util.isDescendant(previewEl, target, true);
2880
+ !isElementDescendantOfExtension(this.base.extensions, target);
2829
2881
 
2830
2882
  if (toFocus !== hadFocus) {
2831
2883
  // If element has focus, and focus is going outside of editor
@@ -3310,6 +3362,14 @@ MediumEditor.extensions = {};
3310
3362
  contentDefault: '<b>image</b>',
3311
3363
  contentFA: '<i class="fa fa-picture-o"></i>'
3312
3364
  },
3365
+ 'html': {
3366
+ name: 'html',
3367
+ action: 'html',
3368
+ aria: 'evaluate html',
3369
+ tagNames: ['iframe', 'object'],
3370
+ contentDefault: '<b>html</b>',
3371
+ contentFA: '<i class="fa fa-code"></i>'
3372
+ },
3313
3373
  'orderedlist': {
3314
3374
  name: 'orderedlist',
3315
3375
  action: 'insertorderedlist',
@@ -3471,6 +3531,7 @@ MediumEditor.extensions = {};
3471
3531
  };
3472
3532
 
3473
3533
  })();
3534
+
3474
3535
  (function () {
3475
3536
  'use strict';
3476
3537
 
@@ -3703,8 +3764,8 @@ MediumEditor.extensions = {};
3703
3764
  // figure out how to deprecate? also consider `fa-` icon default implcations.
3704
3765
  template.push(
3705
3766
  '<div class="medium-editor-toolbar-form-row">',
3706
- '<input type="checkbox" class="medium-editor-toolbar-anchor-target">',
3707
- '<label>',
3767
+ '<input type="checkbox" class="medium-editor-toolbar-anchor-target" id="medium-editor-toolbar-anchor-target-field-' + this.getEditorId() + '">',
3768
+ '<label for="medium-editor-toolbar-anchor-target-field-' + this.getEditorId() + '">',
3708
3769
  this.targetCheckboxText,
3709
3770
  '</label>',
3710
3771
  '</div>'
@@ -3824,19 +3885,61 @@ MediumEditor.extensions = {};
3824
3885
  this.base.checkSelection();
3825
3886
  },
3826
3887
 
3888
+ ensureEncodedUri: function (str) {
3889
+ return str === decodeURI(str) ? encodeURI(str) : str;
3890
+ },
3891
+
3892
+ ensureEncodedUriComponent: function (str) {
3893
+ return str === decodeURIComponent(str) ? encodeURIComponent(str) : str;
3894
+ },
3895
+
3896
+ ensureEncodedParam: function (param) {
3897
+ var split = param.split('='),
3898
+ key = split[0],
3899
+ val = split[1];
3900
+
3901
+ return key + (val === undefined ? '' : '=' + this.ensureEncodedUriComponent(val));
3902
+ },
3903
+
3904
+ ensureEncodedQuery: function (queryString) {
3905
+ return queryString.split('&').map(this.ensureEncodedParam.bind(this)).join('&');
3906
+ },
3907
+
3827
3908
  checkLinkFormat: function (value) {
3828
3909
  // Matches any alphabetical characters followed by ://
3829
3910
  // Matches protocol relative "//"
3830
3911
  // Matches common external protocols "mailto:" "tel:" "maps:"
3831
- var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):/i,
3832
- // var te is a regex for checking if the string is a telephone number
3833
- telRegex = /^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/;
3912
+ // Matches relative hash link, begins with "#"
3913
+ var urlSchemeRegex = /^([a-z]+:)?\/\/|^(mailto|tel|maps):|^\#/i,
3914
+ hasScheme = urlSchemeRegex.test(value),
3915
+ scheme = '',
3916
+ // telRegex is a regex for checking if the string is a telephone number
3917
+ telRegex = /^\+?\s?\(?(?:\d\s?\-?\)?){3,20}$/,
3918
+ urlParts = value.match(/^(.*?)(?:\?(.*?))?(?:#(.*))?$/),
3919
+ path = urlParts[1],
3920
+ query = urlParts[2],
3921
+ fragment = urlParts[3];
3922
+
3834
3923
  if (telRegex.test(value)) {
3835
3924
  return 'tel:' + value;
3836
- } else {
3837
- // Check for URL scheme and default to http:// if none found
3838
- return (urlSchemeRegex.test(value) ? '' : 'http://') + encodeURI(value);
3839
3925
  }
3926
+
3927
+ if (!hasScheme) {
3928
+ var host = path.split('/')[0];
3929
+ // if the host part of the path looks like a hostname
3930
+ if (host.match(/.+(\.|:).+/) || host === 'localhost') {
3931
+ scheme = 'http://';
3932
+ }
3933
+ }
3934
+
3935
+ return scheme +
3936
+ // Ensure path is encoded
3937
+ this.ensureEncodedUri(path) +
3938
+ // Ensure query is encoded
3939
+ (query === undefined ? '' : '?' + this.ensureEncodedQuery(query)) +
3940
+ // Include fragment unencoded as encodeUriComponent is too
3941
+ // heavy handed for the many characters allowed in a fragment
3942
+ (fragment === undefined ? '' : '#' + fragment);
3840
3943
  },
3841
3944
 
3842
3945
  doFormCancel: function () {
@@ -3948,6 +4051,11 @@ MediumEditor.extensions = {};
3948
4051
  */
3949
4052
  showWhenToolbarIsVisible: false,
3950
4053
 
4054
+ /* showOnEmptyLinks: [boolean]
4055
+ * determines whether the anchor tag preview shows up on links with href="" or href="#something"
4056
+ */
4057
+ showOnEmptyLinks: true,
4058
+
3951
4059
  init: function () {
3952
4060
  this.anchorPreview = this.createPreview();
3953
4061
 
@@ -3956,6 +4064,11 @@ MediumEditor.extensions = {};
3956
4064
  this.attachToEditables();
3957
4065
  },
3958
4066
 
4067
+ getInteractionElements: function () {
4068
+ return this.getPreviewElement();
4069
+ },
4070
+
4071
+ // TODO: Remove this function in 6.0.0
3959
4072
  getPreviewElement: function () {
3960
4073
  return this.anchorPreview;
3961
4074
  },
@@ -3988,7 +4101,9 @@ MediumEditor.extensions = {};
3988
4101
  },
3989
4102
 
3990
4103
  hidePreview: function () {
3991
- this.anchorPreview.classList.remove('medium-editor-anchor-preview-active');
4104
+ if (this.anchorPreview) {
4105
+ this.anchorPreview.classList.remove('medium-editor-anchor-preview-active');
4106
+ }
3992
4107
  this.activeAnchor = null;
3993
4108
  },
3994
4109
 
@@ -4020,13 +4135,15 @@ MediumEditor.extensions = {};
4020
4135
 
4021
4136
  positionPreview: function (activeAnchor) {
4022
4137
  activeAnchor = activeAnchor || this.activeAnchor;
4023
- var buttonHeight = this.anchorPreview.offsetHeight,
4138
+ var containerWidth = this.window.innerWidth,
4139
+ buttonHeight = this.anchorPreview.offsetHeight,
4024
4140
  boundary = activeAnchor.getBoundingClientRect(),
4025
- middleBoundary = (boundary.left + boundary.right) / 2,
4026
4141
  diffLeft = this.diffLeft,
4027
4142
  diffTop = this.diffTop,
4028
- halfOffsetWidth,
4029
- defaultLeft;
4143
+ elementsContainer = this.getEditorOption('elementsContainer'),
4144
+ elementsContainerAbsolute = ['absolute', 'fixed'].indexOf(window.getComputedStyle(elementsContainer).getPropertyValue('position')) > -1,
4145
+ relativeBoundary = {},
4146
+ halfOffsetWidth, defaultLeft, middleBoundary, elementsContainerBoundary, top;
4030
4147
 
4031
4148
  halfOffsetWidth = this.anchorPreview.offsetWidth / 2;
4032
4149
  var toolbarExtension = this.base.getExtensionByName('toolbar');
@@ -4036,12 +4153,35 @@ MediumEditor.extensions = {};
4036
4153
  }
4037
4154
  defaultLeft = diffLeft - halfOffsetWidth;
4038
4155
 
4039
- this.anchorPreview.style.top = Math.round(buttonHeight + boundary.bottom - diffTop + this.window.pageYOffset - this.anchorPreview.offsetHeight) + 'px';
4156
+ // If container element is absolute / fixed, recalculate boundaries to be relative to the container
4157
+ if (elementsContainerAbsolute) {
4158
+ elementsContainerBoundary = elementsContainer.getBoundingClientRect();
4159
+ ['top', 'left'].forEach(function (key) {
4160
+ relativeBoundary[key] = boundary[key] - elementsContainerBoundary[key];
4161
+ });
4162
+
4163
+ relativeBoundary.width = boundary.width;
4164
+ relativeBoundary.height = boundary.height;
4165
+ boundary = relativeBoundary;
4166
+
4167
+ containerWidth = elementsContainerBoundary.width;
4168
+
4169
+ // Adjust top position according to container scroll position
4170
+ top = elementsContainer.scrollTop;
4171
+ } else {
4172
+ // Adjust top position according to window scroll position
4173
+ top = this.window.pageYOffset;
4174
+ }
4175
+
4176
+ middleBoundary = boundary.left + boundary.width / 2;
4177
+ top += buttonHeight + boundary.top + boundary.height - diffTop - this.anchorPreview.offsetHeight;
4178
+
4179
+ this.anchorPreview.style.top = Math.round(top) + 'px';
4040
4180
  this.anchorPreview.style.right = 'initial';
4041
4181
  if (middleBoundary < halfOffsetWidth) {
4042
4182
  this.anchorPreview.style.left = defaultLeft + halfOffsetWidth + 'px';
4043
4183
  this.anchorPreview.style.right = 'initial';
4044
- } else if ((this.window.innerWidth - middleBoundary) < halfOffsetWidth) {
4184
+ } else if ((containerWidth - middleBoundary) < halfOffsetWidth) {
4045
4185
  this.anchorPreview.style.left = 'auto';
4046
4186
  this.anchorPreview.style.right = 0;
4047
4187
  } else {
@@ -4077,7 +4217,7 @@ MediumEditor.extensions = {};
4077
4217
  this.base.delay(function () {
4078
4218
  if (activeAnchor) {
4079
4219
  var opts = {
4080
- url: activeAnchor.attributes.href.value,
4220
+ value: activeAnchor.attributes.href.value,
4081
4221
  target: activeAnchor.getAttribute('target'),
4082
4222
  buttonClass: activeAnchor.getAttribute('class')
4083
4223
  };
@@ -4106,7 +4246,8 @@ MediumEditor.extensions = {};
4106
4246
  // Detect empty href attributes
4107
4247
  // The browser will make href="" or href="#top"
4108
4248
  // into absolute urls when accessed as event.target.href, so check the html
4109
- if (!/href=["']\S+["']/.test(target.outerHTML) || /href=["']#\S+["']/.test(target.outerHTML)) {
4249
+ if (!this.showOnEmptyLinks &&
4250
+ (!/href=["']\S+["']/.test(target.outerHTML) || /href=["']#\S+["']/.test(target.outerHTML))) {
4110
4251
  return true;
4111
4252
  }
4112
4253
 
@@ -4200,7 +4341,8 @@ MediumEditor.extensions = {};
4200
4341
  var WHITESPACE_CHARS,
4201
4342
  KNOWN_TLDS_FRAGMENT,
4202
4343
  LINK_REGEXP_TEXT,
4203
- KNOWN_TLDS_REGEXP;
4344
+ KNOWN_TLDS_REGEXP,
4345
+ LINK_REGEXP;
4204
4346
 
4205
4347
  WHITESPACE_CHARS = [' ', '\t', '\n', '\r', '\u00A0', '\u2000', '\u2001', '\u2002', '\u2003',
4206
4348
  '\u2028', '\u2029'];
@@ -4222,6 +4364,8 @@ MediumEditor.extensions = {};
4222
4364
 
4223
4365
  KNOWN_TLDS_REGEXP = new RegExp('^(' + KNOWN_TLDS_FRAGMENT + ')$', 'i');
4224
4366
 
4367
+ LINK_REGEXP = new RegExp(LINK_REGEXP_TEXT, 'gi');
4368
+
4225
4369
  function nodeIsNotInsideAnchorTag(node) {
4226
4370
  return !MediumEditor.util.getClosestTag(node, 'a');
4227
4371
  }
@@ -4403,12 +4547,11 @@ MediumEditor.extensions = {};
4403
4547
  },
4404
4548
 
4405
4549
  findLinkableText: function (contenteditable) {
4406
- var linkRegExp = new RegExp(LINK_REGEXP_TEXT, 'gi'),
4407
- textContent = contenteditable.textContent,
4550
+ var textContent = contenteditable.textContent,
4408
4551
  match = null,
4409
4552
  matches = [];
4410
4553
 
4411
- while ((match = linkRegExp.exec(textContent)) !== null) {
4554
+ while ((match = LINK_REGEXP.exec(textContent)) !== null) {
4412
4555
  var matchOk = true,
4413
4556
  matchEnd = match.index + match[0].length;
4414
4557
  // If the regexp detected something as a link that has text immediately preceding/following it, bail out.
@@ -5027,13 +5170,13 @@ MediumEditor.extensions = {};
5027
5170
  [new RegExp(/<br class="Apple-interchange-newline">/g), '<br>'],
5028
5171
 
5029
5172
  // replace google docs italics+bold with a span to be replaced once the html is inserted
5030
- [new RegExp(/<span[^>]*(font-style:italic;font-weight:bold|font-weight:bold;font-style:italic)[^>]*>/gi), '<span class="replace-with italic bold">'],
5173
+ [new RegExp(/<span[^>]*(font-style:italic;font-weight:(bold|700)|font-weight:(bold|700);font-style:italic)[^>]*>/gi), '<span class="replace-with italic bold">'],
5031
5174
 
5032
5175
  // replace google docs italics with a span to be replaced once the html is inserted
5033
5176
  [new RegExp(/<span[^>]*font-style:italic[^>]*>/gi), '<span class="replace-with italic">'],
5034
5177
 
5035
5178
  //[replace google docs bolds with a span to be replaced once the html is inserted
5036
- [new RegExp(/<span[^>]*font-weight:bold[^>]*>/gi), '<span class="replace-with bold">'],
5179
+ [new RegExp(/<span[^>]*font-weight:(bold|700)[^>]*>/gi), '<span class="replace-with bold">'],
5037
5180
 
5038
5181
  // replace manually entered b/i/a tags with real ones
5039
5182
  [new RegExp(/&lt;(\/?)(i|b|a)&gt;/gi), '<$1$2>'],
@@ -5129,15 +5272,31 @@ MediumEditor.extensions = {};
5129
5272
  */
5130
5273
  cleanTags: ['meta'],
5131
5274
 
5275
+ /* unwrapTags: [Array]
5276
+ * list of element tag names to unwrap (remove the element tag but retain its child elements)
5277
+ * during paste when __cleanPastedHTML__ is `true` or when
5278
+ * calling `cleanPaste(text)` or `pasteHTML(html, options)` helper methods.
5279
+ */
5280
+ unwrapTags: [],
5281
+
5132
5282
  init: function () {
5133
5283
  MediumEditor.Extension.prototype.init.apply(this, arguments);
5134
5284
 
5135
5285
  if (this.forcePlainText || this.cleanPastedHTML) {
5136
- this.subscribe('editablePaste', this.handlePaste.bind(this));
5137
5286
  this.subscribe('editableKeydown', this.handleKeydown.bind(this));
5287
+ // We need access to the full event data in paste
5288
+ // so we can't use the editablePaste event here
5289
+ this.getEditorElements().forEach(function (element) {
5290
+ this.on(element, 'paste', this.handlePaste.bind(this));
5291
+ }, this);
5292
+ this.subscribe('addElement', this.handleAddElement.bind(this));
5138
5293
  }
5139
5294
  },
5140
5295
 
5296
+ handleAddElement: function (event, editable) {
5297
+ this.on(editable, 'paste', this.handlePaste.bind(this));
5298
+ },
5299
+
5141
5300
  destroy: function () {
5142
5301
  // Make sure pastebin is destroyed in case it's still around for some reason
5143
5302
  if (this.forcePlainText || this.cleanPastedHTML) {
@@ -5214,6 +5373,12 @@ MediumEditor.extensions = {};
5214
5373
  event.preventDefault();
5215
5374
  this.removePasteBin();
5216
5375
  this.doPaste(pastedHTML, pastedPlain, editable);
5376
+
5377
+ // The event handling code listens for paste on the editable element
5378
+ // in order to trigger the editablePaste event. Since this paste event
5379
+ // is happening on the pastebin, the event handling code never knows about it
5380
+ // So, we have to trigger editablePaste manually
5381
+ this.trigger('editablePaste', { currentTarget: editable, target: editable }, editable);
5217
5382
  return;
5218
5383
  }
5219
5384
 
@@ -5231,6 +5396,12 @@ MediumEditor.extensions = {};
5231
5396
 
5232
5397
  // Handle the paste with the html from the paste bin
5233
5398
  this.doPaste(pastedHTML, pastedPlain, editable);
5399
+
5400
+ // The event handling code listens for paste on the editable element
5401
+ // in order to trigger the editablePaste event. Since this paste event
5402
+ // is happening on the pastebin, the event handling code never knows about it
5403
+ // So, we have to trigger editablePaste manually
5404
+ this.trigger('editablePaste', { currentTarget: editable, target: editable }, editable);
5234
5405
  }.bind(this), 0);
5235
5406
  },
5236
5407
 
@@ -5391,7 +5562,8 @@ MediumEditor.extensions = {};
5391
5562
  pasteHTML: function (html, options) {
5392
5563
  options = MediumEditor.util.defaults({}, options, {
5393
5564
  cleanAttrs: this.cleanAttrs,
5394
- cleanTags: this.cleanTags
5565
+ cleanTags: this.cleanTags,
5566
+ unwrapTags: this.unwrapTags
5395
5567
  });
5396
5568
 
5397
5569
  var elList, workEl, i, fragmentBody, pasteBlock = this.document.createDocumentFragment();
@@ -5413,6 +5585,7 @@ MediumEditor.extensions = {};
5413
5585
 
5414
5586
  MediumEditor.util.cleanupAttrs(workEl, options.cleanAttrs);
5415
5587
  MediumEditor.util.cleanupTags(workEl, options.cleanTags);
5588
+ MediumEditor.util.unwrapTags(workEl, options.unwrapTags);
5416
5589
  }
5417
5590
 
5418
5591
  MediumEditor.util.insertHTMLCommand(this.document, fragmentBody.innerHTML.replace(/&nbsp;/g, ' '));
@@ -5523,37 +5696,61 @@ MediumEditor.extensions = {};
5523
5696
  },
5524
5697
 
5525
5698
  initPlaceholders: function () {
5526
- this.getEditorElements().forEach(function (el) {
5527
- if (!el.getAttribute('data-placeholder')) {
5528
- el.setAttribute('data-placeholder', this.text);
5529
- }
5530
- this.updatePlaceholder(el);
5531
- }, this);
5699
+ this.getEditorElements().forEach(this.initElement, this);
5700
+ },
5701
+
5702
+ handleAddElement: function (event, editable) {
5703
+ this.initElement(editable);
5704
+ },
5705
+
5706
+ initElement: function (el) {
5707
+ if (!el.getAttribute('data-placeholder')) {
5708
+ el.setAttribute('data-placeholder', this.text);
5709
+ }
5710
+ this.updatePlaceholder(el);
5532
5711
  },
5533
5712
 
5534
5713
  destroy: function () {
5535
- this.getEditorElements().forEach(function (el) {
5536
- if (el.getAttribute('data-placeholder') === this.text) {
5537
- el.removeAttribute('data-placeholder');
5538
- }
5539
- }, this);
5714
+ this.getEditorElements().forEach(this.cleanupElement, this);
5715
+ },
5716
+
5717
+ handleRemoveElement: function (event, editable) {
5718
+ this.cleanupElement(editable);
5719
+ },
5720
+
5721
+ cleanupElement: function (el) {
5722
+ if (el.getAttribute('data-placeholder') === this.text) {
5723
+ el.removeAttribute('data-placeholder');
5724
+ }
5540
5725
  },
5541
5726
 
5542
5727
  showPlaceholder: function (el) {
5543
5728
  if (el) {
5544
- el.classList.add('medium-editor-placeholder');
5729
+ // https://github.com/yabwe/medium-editor/issues/234
5730
+ // In firefox, styling the placeholder with an absolutely positioned
5731
+ // pseudo element causes the cursor to appear in a bad location
5732
+ // when the element is completely empty, so apply a different class to
5733
+ // style it with a relatively positioned pseudo element
5734
+ if (MediumEditor.util.isFF && el.childNodes.length === 0) {
5735
+ el.classList.add('medium-editor-placeholder-relative');
5736
+ el.classList.remove('medium-editor-placeholder');
5737
+ } else {
5738
+ el.classList.add('medium-editor-placeholder');
5739
+ el.classList.remove('medium-editor-placeholder-relative');
5740
+ }
5545
5741
  }
5546
5742
  },
5547
5743
 
5548
5744
  hidePlaceholder: function (el) {
5549
5745
  if (el) {
5550
5746
  el.classList.remove('medium-editor-placeholder');
5747
+ el.classList.remove('medium-editor-placeholder-relative');
5551
5748
  }
5552
5749
  },
5553
5750
 
5554
5751
  updatePlaceholder: function (el, dontShow) {
5555
5752
  // If the element has content, hide the placeholder
5556
- if (el.querySelector('img, blockquote, ul, ol') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) {
5753
+ if (el.querySelector('img, blockquote, ul, ol, table') || (el.textContent.replace(/^\s+|\s+$/g, '') !== '')) {
5557
5754
  return this.hidePlaceholder(el);
5558
5755
  }
5559
5756
 
@@ -5573,6 +5770,10 @@ MediumEditor.extensions = {};
5573
5770
 
5574
5771
  // When the editor loses focus, check if the placeholder should be visible
5575
5772
  this.subscribe('blur', this.handleBlur.bind(this));
5773
+
5774
+ // Need to know when elements are added/removed from the editor
5775
+ this.subscribe('addElement', this.handleAddElement.bind(this));
5776
+ this.subscribe('removeElement', this.handleRemoveElement.bind(this));
5576
5777
  },
5577
5778
 
5578
5779
  handleInput: function (event, element) {
@@ -5789,6 +5990,10 @@ MediumEditor.extensions = {};
5789
5990
 
5790
5991
  // Toolbar accessors
5791
5992
 
5993
+ getInteractionElements: function () {
5994
+ return this.getToolbarElement();
5995
+ },
5996
+
5792
5997
  getToolbarElement: function () {
5793
5998
  if (!this.toolbar) {
5794
5999
  this.toolbar = this.createToolbar();
@@ -6212,35 +6417,66 @@ MediumEditor.extensions = {};
6212
6417
  }
6213
6418
  }
6214
6419
 
6215
- var windowWidth = this.window.innerWidth,
6216
- middleBoundary = (boundary.left + boundary.right) / 2,
6420
+ var containerWidth = this.window.innerWidth,
6217
6421
  toolbarElement = this.getToolbarElement(),
6218
6422
  toolbarHeight = toolbarElement.offsetHeight,
6219
6423
  toolbarWidth = toolbarElement.offsetWidth,
6220
6424
  halfOffsetWidth = toolbarWidth / 2,
6221
6425
  buttonHeight = 50,
6222
- defaultLeft = this.diffLeft - halfOffsetWidth;
6426
+ defaultLeft = this.diffLeft - halfOffsetWidth,
6427
+ elementsContainer = this.getEditorOption('elementsContainer'),
6428
+ elementsContainerAbsolute = ['absolute', 'fixed'].indexOf(window.getComputedStyle(elementsContainer).getPropertyValue('position')) > -1,
6429
+ positions = {},
6430
+ relativeBoundary = {},
6431
+ middleBoundary, elementsContainerBoundary;
6432
+
6433
+ // If container element is absolute / fixed, recalculate boundaries to be relative to the container
6434
+ if (elementsContainerAbsolute) {
6435
+ elementsContainerBoundary = elementsContainer.getBoundingClientRect();
6436
+ ['top', 'left'].forEach(function (key) {
6437
+ relativeBoundary[key] = boundary[key] - elementsContainerBoundary[key];
6438
+ });
6439
+
6440
+ relativeBoundary.width = boundary.width;
6441
+ relativeBoundary.height = boundary.height;
6442
+ boundary = relativeBoundary;
6443
+
6444
+ containerWidth = elementsContainerBoundary.width;
6445
+
6446
+ // Adjust top position according to container scroll position
6447
+ positions.top = elementsContainer.scrollTop;
6448
+ } else {
6449
+ // Adjust top position according to window scroll position
6450
+ positions.top = this.window.pageYOffset;
6451
+ }
6452
+
6453
+ middleBoundary = boundary.left + boundary.width / 2;
6454
+ positions.top += boundary.top - toolbarHeight;
6223
6455
 
6224
6456
  if (boundary.top < buttonHeight) {
6225
6457
  toolbarElement.classList.add('medium-toolbar-arrow-over');
6226
6458
  toolbarElement.classList.remove('medium-toolbar-arrow-under');
6227
- toolbarElement.style.top = buttonHeight + boundary.bottom - this.diffTop + this.window.pageYOffset - toolbarHeight + 'px';
6459
+ positions.top += buttonHeight + boundary.height - this.diffTop;
6228
6460
  } else {
6229
6461
  toolbarElement.classList.add('medium-toolbar-arrow-under');
6230
6462
  toolbarElement.classList.remove('medium-toolbar-arrow-over');
6231
- toolbarElement.style.top = boundary.top + this.diffTop + this.window.pageYOffset - toolbarHeight + 'px';
6463
+ positions.top += this.diffTop;
6232
6464
  }
6233
6465
 
6234
6466
  if (middleBoundary < halfOffsetWidth) {
6235
- toolbarElement.style.left = defaultLeft + halfOffsetWidth + 'px';
6236
- toolbarElement.style.right = 'initial';
6237
- } else if ((windowWidth - middleBoundary) < halfOffsetWidth) {
6238
- toolbarElement.style.left = 'auto';
6239
- toolbarElement.style.right = 0;
6467
+ positions.left = defaultLeft + halfOffsetWidth;
6468
+ positions.right = 'initial';
6469
+ } else if ((containerWidth - middleBoundary) < halfOffsetWidth) {
6470
+ positions.left = 'auto';
6471
+ positions.right = 0;
6240
6472
  } else {
6241
- toolbarElement.style.left = defaultLeft + middleBoundary + 'px';
6242
- toolbarElement.style.right = 'initial';
6473
+ positions.left = defaultLeft + middleBoundary;
6474
+ positions.right = 'initial';
6243
6475
  }
6476
+
6477
+ ['top', 'left', 'right'].forEach(function (key) {
6478
+ toolbarElement.style[key] = positions[key] + (isNaN(positions[key]) ? '' : 'px');
6479
+ });
6244
6480
  }
6245
6481
  });
6246
6482
 
@@ -6447,6 +6683,31 @@ MediumEditor.extensions = {};
6447
6683
  // then pressing backspace key should change the <blockquote> to a <p> tag
6448
6684
  event.preventDefault();
6449
6685
  MediumEditor.util.execFormatBlock(this.options.ownerDocument, 'p');
6686
+ } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.ENTER) &&
6687
+ (MediumEditor.util.getClosestTag(node, 'blockquote') !== false) &&
6688
+ MediumEditor.selection.getCaretOffsets(node).right === 0) {
6689
+
6690
+ // when cursor is at the end of <blockquote>,
6691
+ // then pressing enter key should create <p> tag, not <blockquote>
6692
+ p = this.options.ownerDocument.createElement('p');
6693
+ p.innerHTML = '<br>';
6694
+ node.parentElement.insertBefore(p, node.nextSibling);
6695
+
6696
+ // move the cursor into the new paragraph
6697
+ MediumEditor.selection.moveCursor(this.options.ownerDocument, p);
6698
+
6699
+ event.preventDefault();
6700
+ } else if (MediumEditor.util.isKey(event, MediumEditor.util.keyCode.BACKSPACE) &&
6701
+ MediumEditor.util.isMediumEditorElement(node.parentElement) &&
6702
+ !node.previousElementSibling &&
6703
+ node.nextElementSibling &&
6704
+ isEmpty.test(node.innerHTML)) {
6705
+
6706
+ // when cursor is in the first element, it's empty and user presses backspace,
6707
+ // do delete action instead to get rid of the first element and move caret to 2nd
6708
+ event.preventDefault();
6709
+ MediumEditor.selection.moveCursor(this.options.ownerDocument, node.nextSibling);
6710
+ node.parentElement.removeChild(node);
6450
6711
  }
6451
6712
  }
6452
6713
 
@@ -6642,17 +6903,17 @@ MediumEditor.extensions = {};
6642
6903
  return !this.options.extensions['imageDragging'];
6643
6904
  }
6644
6905
 
6645
- function createContentEditable(textarea, id, doc) {
6646
- var div = doc.createElement('div'),
6906
+ function createContentEditable(textarea) {
6907
+ var div = this.options.ownerDocument.createElement('div'),
6647
6908
  now = Date.now(),
6648
- uniqueId = 'medium-editor-' + now + '-' + id,
6909
+ uniqueId = 'medium-editor-' + now,
6649
6910
  atts = textarea.attributes;
6650
6911
 
6651
6912
  // Some browsers can move pretty fast, since we're using a timestamp
6652
6913
  // to make a unique-id, ensure that the id is actually unique on the page
6653
- while (doc.getElementById(uniqueId)) {
6914
+ while (this.options.ownerDocument.getElementById(uniqueId)) {
6654
6915
  now++;
6655
- uniqueId = 'medium-editor-' + now + '-' + id;
6916
+ uniqueId = 'medium-editor-' + now;
6656
6917
  }
6657
6918
 
6658
6919
  div.className = textarea.className;
@@ -6669,6 +6930,16 @@ MediumEditor.extensions = {};
6669
6930
  }
6670
6931
  }
6671
6932
 
6933
+ // If textarea has a form, listen for reset on the form to clear
6934
+ // the content of the created div
6935
+ if (textarea.form) {
6936
+ this.on(textarea.form, 'reset', function (event) {
6937
+ if (!event.defaultPrevented) {
6938
+ this.resetContent(this.options.ownerDocument.getElementById(uniqueId));
6939
+ }
6940
+ }.bind(this));
6941
+ }
6942
+
6672
6943
  textarea.classList.add('medium-editor-hidden');
6673
6944
  textarea.parentNode.insertBefore(
6674
6945
  div,
@@ -6678,10 +6949,10 @@ MediumEditor.extensions = {};
6678
6949
  return div;
6679
6950
  }
6680
6951
 
6681
- function initElement(element, id) {
6952
+ function initElement(element, editorId) {
6682
6953
  if (!element.getAttribute('data-medium-editor-element')) {
6683
6954
  if (element.nodeName.toLowerCase() === 'textarea') {
6684
- element = createContentEditable(element, id, this.options.ownerDocument);
6955
+ element = createContentEditable.call(this, element);
6685
6956
 
6686
6957
  // Make sure we only attach to editableInput once for <textarea> elements
6687
6958
  if (!this.instanceHandleEditableInput) {
@@ -6709,10 +6980,18 @@ MediumEditor.extensions = {};
6709
6980
  this.on(element, 'keyup', handleKeyup.bind(this));
6710
6981
  }
6711
6982
 
6983
+ var elementId = MediumEditor.util.guid();
6984
+
6712
6985
  element.setAttribute('data-medium-editor-element', true);
6986
+ element.classList.add('medium-editor-element');
6713
6987
  element.setAttribute('role', 'textbox');
6714
6988
  element.setAttribute('aria-multiline', true);
6715
- element.setAttribute('medium-editor-index', MediumEditor.util.guid());
6989
+ element.setAttribute('data-medium-editor-editor-index', editorId);
6990
+ // TODO: Merge data-medium-editor-element and medium-editor-index attributes for 6.0.0
6991
+ // medium-editor-index is not named correctly anymore and can be re-purposed to signify
6992
+ // whether the element has been initialized or not
6993
+ element.setAttribute('medium-editor-index', elementId);
6994
+ initialContent[elementId] = element.innerHTML;
6716
6995
 
6717
6996
  this.events.attachAllEventsToElement(element);
6718
6997
  }
@@ -6870,6 +7149,11 @@ MediumEditor.extensions = {};
6870
7149
  return this.options.ownerDocument.execCommand('insertImage', false, src);
6871
7150
  }
6872
7151
 
7152
+ if (action === 'html') {
7153
+ var html = this.options.contentWindow.getSelection().toString().trim();
7154
+ return MediumEditor.util.insertHTMLCommand(this.options.ownerDocument, html);
7155
+ }
7156
+
6873
7157
  /* Issue: https://github.com/yabwe/medium-editor/issues/595
6874
7158
  * If the action is to justify the text */
6875
7159
  if (justifyAction.exec(action)) {
@@ -6931,6 +7215,8 @@ MediumEditor.extensions = {};
6931
7215
  }
6932
7216
  }
6933
7217
 
7218
+ var initialContent = {};
7219
+
6934
7220
  MediumEditor.prototype = {
6935
7221
  // NOT DOCUMENTED - exposed for backwards compatability
6936
7222
  init: function (elements, options) {
@@ -6949,6 +7235,7 @@ MediumEditor.extensions = {};
6949
7235
  return;
6950
7236
  }
6951
7237
 
7238
+ addToEditors.call(this, this.options.contentWindow);
6952
7239
  this.events = new MediumEditor.Events(this);
6953
7240
  this.elements = [];
6954
7241
 
@@ -6959,7 +7246,6 @@ MediumEditor.extensions = {};
6959
7246
  }
6960
7247
 
6961
7248
  this.isActive = true;
6962
- addToEditors.call(this, this.options.contentWindow);
6963
7249
 
6964
7250
  // Call initialization helpers
6965
7251
  initExtensions.call(this);
@@ -6991,9 +7277,11 @@ MediumEditor.extensions = {};
6991
7277
  element.removeAttribute('contentEditable');
6992
7278
  element.removeAttribute('spellcheck');
6993
7279
  element.removeAttribute('data-medium-editor-element');
7280
+ element.classList.remove('medium-editor-element');
6994
7281
  element.removeAttribute('role');
6995
7282
  element.removeAttribute('aria-multiline');
6996
7283
  element.removeAttribute('medium-editor-index');
7284
+ element.removeAttribute('data-medium-editor-editor-index');
6997
7285
 
6998
7286
  // Remove any elements created for textareas
6999
7287
  if (element.getAttribute('medium-editor-textarea-id')) {
@@ -7452,11 +7740,38 @@ MediumEditor.extensions = {};
7452
7740
  }
7453
7741
  },
7454
7742
 
7743
+ getContent: function (index) {
7744
+ index = index || 0;
7745
+
7746
+ if (this.elements[index]) {
7747
+ return this.elements[index].innerHTML.trim();
7748
+ }
7749
+ return null;
7750
+ },
7751
+
7455
7752
  checkContentChanged: function (editable) {
7456
7753
  editable = editable || MediumEditor.selection.getSelectionElement(this.options.contentWindow);
7457
7754
  this.events.updateInput(editable, { target: editable, currentTarget: editable });
7458
7755
  },
7459
7756
 
7757
+ resetContent: function (element) {
7758
+ // For all elements that exist in the this.elements array, we can assume:
7759
+ // - Its initial content has been set in the initialContent object
7760
+ // - It has a medium-editor-index attribute which is the key value in the initialContent object
7761
+
7762
+ if (element) {
7763
+ var index = this.elements.indexOf(element);
7764
+ if (index !== -1) {
7765
+ this.setContent(initialContent[element.getAttribute('medium-editor-index')], index);
7766
+ }
7767
+ return;
7768
+ }
7769
+
7770
+ this.elements.forEach(function (el, idx) {
7771
+ this.setContent(initialContent[el.getAttribute('medium-editor-index')], idx);
7772
+ }, this);
7773
+ },
7774
+
7460
7775
  addElements: function (selector) {
7461
7776
  // Convert elements into an array
7462
7777
  var elements = createElementsArray(selector, this.options.ownerDocument, true);
@@ -7468,10 +7783,13 @@ MediumEditor.extensions = {};
7468
7783
 
7469
7784
  elements.forEach(function (element) {
7470
7785
  // Initialize all new elements (we check that in those functions don't worry)
7471
- element = initElement.call(this, element);
7786
+ element = initElement.call(this, element, this.id);
7472
7787
 
7473
7788
  // Add new elements to our internal elements array
7474
7789
  this.elements.push(element);
7790
+
7791
+ // Trigger event so extensions can know when an element has been added
7792
+ this.trigger('addElement', { target: element, currentTarget: element }, element);
7475
7793
  }, this);
7476
7794
  },
7477
7795
 
@@ -7494,12 +7812,23 @@ MediumEditor.extensions = {};
7494
7812
  if (element.getAttribute('medium-editor-textarea-id')) {
7495
7813
  cleanupTextareaElement(element);
7496
7814
  }
7815
+ // Trigger event so extensions can clean-up elements that are being removed
7816
+ this.trigger('removeElement', { target: element, currentTarget: element }, element);
7497
7817
  return false;
7498
7818
  }
7499
7819
  return true;
7500
7820
  }, this);
7501
7821
  }
7502
7822
  };
7823
+
7824
+ MediumEditor.getEditorFromElement = function (element) {
7825
+ var index = element.getAttribute('data-medium-editor-editor-index'),
7826
+ win = element && element.ownerDocument && (element.ownerDocument.defaultView || element.ownerDocument.parentWindow);
7827
+ if (win && win._mediumEditors && win._mediumEditors[index]) {
7828
+ return win._mediumEditors[index];
7829
+ }
7830
+ return null;
7831
+ };
7503
7832
  }());
7504
7833
 
7505
7834
  (function () {
@@ -7540,7 +7869,7 @@ MediumEditor.parseVersionString = function (release) {
7540
7869
 
7541
7870
  MediumEditor.version = MediumEditor.parseVersionString.call(this, ({
7542
7871
  // grunt-bump looks for this:
7543
- 'version': '5.18.0'
7872
+ 'version': '5.23.1'
7544
7873
  }).version);
7545
7874
 
7546
7875
  return MediumEditor;