Comparar commits
796 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| c8b92526ec | |||
| 92a9c7aef6 | |||
| d51a86e804 | |||
| 278a507653 | |||
| 7422f4378e | |||
| f2ab14656b | |||
| 453abf8b90 | |||
| 7866f0819d | |||
| 921e3c581d | |||
| 58aa87438d | |||
| ad73902382 | |||
| bf63a9715c | |||
| 06c52c6873 | |||
| 9ac27bc2f8 | |||
| 98caaf0d70 | |||
| a102d1e134 | |||
| 6caa86fb04 | |||
| b1e0c8132d | |||
| f3947dd6e0 | |||
| 27dbbabe09 | |||
| 5950110860 | |||
| ab5d71e6b5 | |||
| 1ee2839245 | |||
| a6f31ed791 | |||
| e04b5a74d7 | |||
| 4acf143f45 | |||
| 5ad5ce0841 | |||
| 31d1ca12c1 | |||
| ace3325db8 | |||
| b718114fc4 | |||
| 1df8c77f41 | |||
| 26e867d65e | |||
| 2688761c29 | |||
| b64d9db198 | |||
| bc5b786bb2 | |||
| 13025c17f1 | |||
| 8b4b5230ab | |||
| 7d6d634ceb | |||
| b386b00bc0 | |||
| 2028045254 | |||
| ca60dae630 | |||
| a5605bd408 | |||
| caf6fdd5ac | |||
| 19872959bc | |||
| 299ea18c58 | |||
| 966360e022 | |||
| 70a2be849a | |||
| 1c7843d9b2 | |||
| 5291f1c62c | |||
| c9e7cfc02c | |||
| e93ca3c901 | |||
| 48bd330a5e | |||
| 6240bc1fc9 | |||
| 6ccc60342f | |||
| 03750d0b6c | |||
| 03e31ad918 | |||
| 610c07870a | |||
| 5c37d208f5 | |||
| 88c119f4ad | |||
| d03cfda6c4 | |||
| 8f02b21d08 | |||
| 953f2c61f7 | |||
| 15e95d0d21 | |||
| 391a71fed0 | |||
| 67ed490618 | |||
| c812dfef9b | |||
| 631bca6c89 | |||
| 095c1b74a7 | |||
| 7e408ad268 | |||
| 4945fd7aae | |||
| 0db5549b64 | |||
| 96095f9c30 | |||
| e2b4fcad65 | |||
| 3ea1c80fe7 | |||
| 525b4ac3eb | |||
| 6ffc750e18 | |||
| 66716db4d1 | |||
| 95d03fc5fa | |||
| b816fca75e | |||
| 6f148f681d | |||
| a489358f55 | |||
| 1cd0caeb2d | |||
| 310939338c | |||
| e39d50972d | |||
| 9a5f3ab000 | |||
| 9285f2605f | |||
| b654209adb | |||
| 0c07166a8e | |||
| de36ceb00c | |||
| aa292874ec | |||
| 736b6f37e4 | |||
| 8d9098464c | |||
| eb6ce74a12 | |||
| 33ee1cb0de | |||
| 11a07f41ac | |||
| 5cf97db07c | |||
| f095d38978 | |||
| 218f6ab629 | |||
| 26edd40f14 | |||
| 8241351143 | |||
| 286361bf2b | |||
| 3d5437c1e9 | |||
| 95b9140dcf | |||
| fc82e5ffd6 | |||
| 20521ad487 | |||
| 99f91fac48 | |||
| d4b0b33d86 | |||
| 790c125e0b | |||
| 4afe133f85 | |||
| 763e83584d | |||
| 62a671aae6 | |||
| c0eb5d0ebe | |||
| d1e9ad3ed1 | |||
| 396b53b8dc | |||
| d87d98278e | |||
| 682a4be285 | |||
| 14c68a4280 | |||
| ddfbc6c335 | |||
| 779642b3da | |||
| 705c78bf18 | |||
| 07a21a15a1 | |||
| 287895c78c | |||
| fcf7b6747b | |||
| 1af25ea401 | |||
| aecd689593 | |||
| 8ad8a61aab | |||
| 6a83246838 | |||
| a7fc1c4138 | |||
| c19aee5472 | |||
| e9d49b1df3 | |||
| 5a456c8552 | |||
| 1179ced85c | |||
| 7738472eb8 | |||
| 45274eaad3 | |||
| 24f7638e8b | |||
| 6ec7b7b38d | |||
| 094a7e9a5f | |||
| 97181121c9 | |||
| 3e4c7a8ab7 | |||
| f4b08649a0 | |||
| c1a93395f5 | |||
| 53b538311e | |||
| 19ae78e062 | |||
| 5a93f14199 | |||
| d7dd0f3224 | |||
| 37e6f03346 | |||
| 0aa3cd58c1 | |||
| ac23717f8c | |||
| 491561db4a | |||
| edfd67b093 | |||
| dd63d47c11 | |||
| 067f5ea7e8 | |||
| eb223c4f21 | |||
| f632b6fe79 | |||
| 5bdc8af850 | |||
| b03931371a | |||
| c02755f59a | |||
| e178b25f17 | |||
| 96efb232ee | |||
| 714cbc9f4b | |||
| 64e4053a19 | |||
| a7f1f90c1d | |||
| cacaba936b | |||
| b20589fbb6 | |||
| d3f14d8939 | |||
| 094ba81758 | |||
| 8a40be8345 | |||
| 2d8d330df7 | |||
| fbc9c05096 | |||
| 1eab423a1c | |||
| cfca6ecc86 | |||
| fb96b01f30 | |||
| 625b95a6d9 | |||
| 0fe9dc6aa9 | |||
| 38e6aee46d | |||
| 01f87d9678 | |||
| 93bf9357b0 | |||
| ed42a275ab | |||
| 6998337144 | |||
| 8b92aef3ff | |||
| 66d6af54bf | |||
| 2a06ece3df | |||
| 1c0c8db042 | |||
| 9293ef766b | |||
| a7a9b3707f | |||
| 7e16e42b3f | |||
| 179fb2d274 | |||
| f804006d6c | |||
| 9a9347e3a5 | |||
| e4bcb96dcc | |||
| 8a0992d689 | |||
| db17a6cba4 | |||
| 5449fc2e15 | |||
| 0a84ad5307 | |||
| 485c402661 | |||
| 4591f00a65 | |||
| b635fa0c97 | |||
| 004103d579 | |||
| 2c952fad95 | |||
| adc983e8da | |||
| 7dc9d0c8ce | |||
| 3d3521962c | |||
| 46a1f69ab1 | |||
| 298d3e5fb6 | |||
| 27291980cb | |||
| 64ae4bf6c3 | |||
| 90a71d1171 | |||
| a5b7d15bcc | |||
| be2d49a410 | |||
| 8a9805cc6d | |||
| 196694e352 | |||
| 12683571e3 | |||
| c0991447ff | |||
| f9fcb9f2e2 | |||
| 1daab1b956 | |||
| fc7f922de0 | |||
| 5f1f2cd9be | |||
| dca0576496 | |||
| aa7d8fb382 | |||
| 08f20adc35 | |||
| c5f1165f61 | |||
| 58499aeec7 | |||
| 83c73fc94a | |||
| b28a1aa5c7 | |||
| bcb72394f9 | |||
| efe7baf140 | |||
| 4b07103fcf | |||
| 9d60fd2322 | |||
| 71228a5f45 | |||
| 6b3ba8e332 | |||
| 5da4846fff | |||
| de619a731b | |||
| d2283b0567 | |||
| 2a00acfdaf | |||
| b2025ebad0 | |||
| 0b44cee8db | |||
| 5fed6199ec | |||
| ddc04f2278 | |||
| f64a813fc6 | |||
| 68bc3f6ead | |||
| ffbcddf063 | |||
| b341749d54 | |||
| d2ab75382a | |||
| b125565776 | |||
| 9cec02420c | |||
| 6f82281b8f | |||
| ffda2386c3 | |||
| aefc647155 | |||
| 83455a7f3a | |||
| d8f64c15b8 | |||
| c927e95c2c | |||
| 5b12646a44 | |||
| 68bb43ee7d | |||
| 4048fb978c | |||
| 2d885496a3 | |||
| 64222d3096 | |||
| 2c7bbf8e9f | |||
| a45e9a1e8b | |||
| 3fd5ba9b3c | |||
| eb0e3df720 | |||
| 60a49d9c81 | |||
| 43ccf0a041 | |||
| 1f6764e708 | |||
| 48f714d5fb | |||
| e2813b4dd9 | |||
| 41b3d65e05 | |||
| 1e50985ec7 | |||
| 1d6087fcd3 | |||
| f2e74f216c | |||
| b9950ef2df | |||
| 67f4d51774 | |||
| 1bf4db15b2 | |||
| 28eb03ed29 | |||
| 2843af458b | |||
| 163a7587f9 | |||
| 18f83e90f7 | |||
| 7094701c66 | |||
| d7d23f7fc9 | |||
| bdbc850695 | |||
| 4e0ab92827 | |||
| b662281958 | |||
| 4d2cc86ada | |||
| 19fcc1c441 | |||
| 1f5fa27113 | |||
| 362bd2e61a | |||
| 4cb80d3c7e | |||
| 7f108dab38 | |||
| cec5a83eff | |||
| a7c3c15885 | |||
| 1c16738969 | |||
| b4a456d911 | |||
| c92f805e6e | |||
| 859a4db242 | |||
| 3a94b70270 | |||
| 85d6689344 | |||
| e0726b0354 | |||
| 0abd25ad6f | |||
| 42522686d7 | |||
| 1e9a8b92f2 | |||
| dda2b2e893 | |||
| e04c05ffee | |||
| 8cb0197638 | |||
| 73763d3e41 | |||
| 9d1c3124ee | |||
| aaee54bd08 | |||
| 1ae8862a9c | |||
| f3dd757537 | |||
| 68693e3ca0 | |||
| e24a562387 | |||
| 9c6a5fb4fa | |||
| 25caaa92f1 | |||
| 78ee02f0c6 | |||
| e462fdc4ce | |||
| 96d8721c9e | |||
| 568151b1a5 | |||
| 3d6c9ee554 | |||
| d5d6422d28 | |||
| 8cf24bc7de | |||
| 5727865b94 | |||
| b95b86396e | |||
| d75c35285c | |||
| a7bc7c198d | |||
| d2f24615c1 | |||
| e4b942e991 | |||
| c9f8ffc749 | |||
| c2086eee0e | |||
| d5a66c590a | |||
| b374c1a11a | |||
| 509d16b65a | |||
| e8e13ca645 | |||
| 35f8e6a5a7 | |||
| 36a9ad7d90 | |||
| 6ff304094f | |||
| 0e51def6be | |||
| f366a67fee | |||
| f30f0de45e | |||
| 9e36cd705e | |||
| 2a5081f0e0 | |||
| 2c93b1459e | |||
| bf83fb7b10 | |||
| f4cc8c31b3 | |||
| e62ecbab6b | |||
| 4cef3bfef5 | |||
| 85fae83195 | |||
| f79b78054c | |||
| e803c06b28 | |||
| 1963a7f437 | |||
| 48eb5307e6 | |||
| 95d6ab1d4f | |||
| 9224c86452 | |||
| 0fa2b4426a | |||
| 1e4e59ad1c | |||
| 97a56574e0 | |||
| c06fefce14 | |||
| 00027e892c | |||
| d4dee07b41 | |||
| f475552673 | |||
| 6e33f10050 | |||
| 61651db0b0 | |||
| 982346b142 | |||
| 92ba107c89 | |||
| 7b4a9aa2e4 | |||
| 446398ad01 | |||
| 8afbab311f | |||
| 32f2a95f07 | |||
| d53d01d95b | |||
| 131522f93d | |||
| 1601a1fbfa | |||
| 2c89a5c82a | |||
| e4ec932513 | |||
| a834920fb7 | |||
| b5edefcae8 | |||
| 616a94a10e | |||
| 7034fe3b36 | |||
| 5f68af27f5 | |||
| ea207f0938 | |||
| 732f053d4a | |||
| 78e61c3ff9 | |||
| 22c9a222c9 | |||
| cc4ab0d36b | |||
| 7bdf3b1719 | |||
| 175d7811b4 | |||
| 3f3fca872b | |||
| 421c64347e | |||
| 557d277e9f | |||
| 3fc514659a | |||
| 747398f2a5 | |||
| 1f51317a10 | |||
| f592a5d11f | |||
| fb223db958 | |||
| 1d73c57f9e | |||
| 016f32d62e | |||
| 9ee4d334b2 | |||
| ddb16dcc6f | |||
| 8403e6583f | |||
| 6bdbabecbd | |||
| 2cda86efda | |||
| 46ff794c8b | |||
| 1406fbfe03 | |||
| dde13a5d4e | |||
| bfc7995aee | |||
| 7fd9c75d24 | |||
| 677be2df82 | |||
| b3bf47dd69 | |||
| a25920da72 | |||
| 9b28e7a47c | |||
| db811cfa9e | |||
| 6d0be70dbc | |||
| 74966bd547 | |||
| 488abc8c24 | |||
| 362d7712ad | |||
| 6ed3626133 | |||
| fc87c98261 | |||
| 46a7ea5936 | |||
| f412d88edd | |||
| 49471070a3 | |||
| 0ca9d7b97e | |||
| d42878164a | |||
| 9adad17e27 | |||
| be420b042c | |||
| 270642b2ea | |||
| 9a080bfd1b | |||
| 7c43ea7a0f | |||
| 28c5bd7814 | |||
| 8c3bae4275 | |||
| 71e3ab9d2b | |||
| a1634b2f9b | |||
| fb6351d9d7 | |||
| 90041b7115 | |||
| d6ba6067b8 | |||
| aface45084 | |||
| 16fc52b351 | |||
| 56184be6fe | |||
| 8f623db092 | |||
| 081c2efc98 | |||
| 3296674605 | |||
| 1e18e2b4e5 | |||
| 13b28c26f0 | |||
| 760f6d280a | |||
| f39ca3ea48 | |||
| d379582248 | |||
| 84f160f88e | |||
| c3d1dd82f0 | |||
| 32ff599a61 | |||
| cbdf93b075 | |||
| c721300be4 | |||
| 6630147b69 | |||
| 08076a4af1 | |||
| b9897d8b34 | |||
| 68fbff59d8 | |||
| 0b2bd468b5 | |||
| a36eae8e4d | |||
| ed23058af0 | |||
| c3d8f4843a | |||
| 085933c55e | |||
| 01987cb762 | |||
| 75a6c51ac7 | |||
| 1575ee9037 | |||
| 64612d4734 | |||
| 3aac342c21 | |||
| 69d3b3cfa2 | |||
| 84232d76de | |||
| dc69b07045 | |||
| 971539c438 | |||
| c36be85dd6 | |||
| 4bbc498d1d | |||
| 3ac992d5d5 | |||
| ddbedcee3e | |||
| ba8cc9e1c0 | |||
| ec4a2a468e | |||
| f09423e020 | |||
| 7e34e8c4ed | |||
| cc785de974 | |||
| a8c4d2e4ca | |||
| d918eb6fa7 | |||
| 69efdc2292 | |||
| fc891f8706 | |||
| 9fc96ba7d4 | |||
| b8a263c570 | |||
| c9a9b51238 | |||
| 13d16b4723 | |||
| ddacfd7d5f | |||
| 932207b106 | |||
| 2c39f3515b | |||
| 8e53b2d507 | |||
| 9bd7141359 | |||
| e534997bf9 | |||
| db9de34993 | |||
| 6f95f51da2 | |||
| a67743b5cd | |||
| 2a56e70110 | |||
| eaedb14942 | |||
| c7cd084e24 | |||
| 685a2c088b | |||
| be7111f007 | |||
| 59c28c0f76 | |||
| 27331cb379 | |||
| 52b5fff537 | |||
| 6fbd9fb8f8 | |||
| 5996fcbc83 | |||
| e34eb151ca | |||
| 4ee1987af4 | |||
| 91652e1174 | |||
| cbf22201e6 | |||
| 040b99b2ff | |||
| c4eecbb380 | |||
| d235180547 | |||
| a42b560c24 | |||
| 2894d87ff8 | |||
| b15e101b20 | |||
| 6cf52a7fb7 | |||
| 8cf20a6996 | |||
| 24432018ec | |||
| 5ec38f84c5 | |||
| 40ffe2a306 | |||
| b1eceb03dc | |||
| dde69f8da4 | |||
| a525d5267b | |||
| f7951aa57c | |||
| a63e058fa5 | |||
| 09327eae75 | |||
| edd48d71ae | |||
| 2faf8bc57b | |||
| aac3d7a559 | |||
| d914ae2a62 | |||
| 2710d40403 | |||
| d327d4923f | |||
| dd0bed9bff | |||
| ff78a5b075 | |||
| 856370f522 | |||
| 041d3f5c4c | |||
| 3969c71932 | |||
| 133bf0cedb | |||
| f168aafc33 | |||
| d237b3448c | |||
| bbaf908bb2 | |||
| 9d947d994e | |||
| e2ecff5e23 | |||
| decae9e34c | |||
| 4896741f0c | |||
| c360ccc62b | |||
| 913c002ee4 | |||
| 59c405d846 | |||
| a9826653e1 | |||
| b47d52d919 | |||
| 7422f0ab1b | |||
| 18c6c84d35 | |||
| 7bcf92e55a | |||
| ee7d4003de | |||
| 79e50084a9 | |||
| 73a70d430f | |||
| 503b4ce2a4 | |||
| 094ccbc1f2 | |||
| 434ab5174b | |||
| 1b85810735 | |||
| 0c75a4fd9c | |||
| d3f2798472 | |||
| c88c18c042 | |||
| cb7d4c8638 | |||
| 4a9d0ab4d3 | |||
| ac029d300a | |||
| 8fe0b7fb7b | |||
| c6c58ebc3e | |||
| 32ac99fd3e | |||
| 175a8b6968 | |||
| 6708388c29 | |||
| 958b19bd83 | |||
| e40dc5c4a6 | |||
| 12ff54c0bd | |||
| 83040d13c7 | |||
| ebc9a6bf51 | |||
| c8ad232c31 | |||
| cfd918977b | |||
| e7efaeaf17 | |||
| e849fc45ff | |||
| 9054c7a120 | |||
| 60c042bd81 | |||
| 495ba3571e | |||
| b8776425fd | |||
| 693fd43449 | |||
| 71f80809c0 | |||
| db13a40f0a | |||
| edf7e06b8d | |||
| 442abece14 | |||
| 5c143bfc6e | |||
| 51354f2326 | |||
| 1177508a45 | |||
| 4bbffd3589 | |||
| 2266c794b4 | |||
| 562ee58506 | |||
| fa96adc2ce | |||
| c46088e89a | |||
| 131ae0f9f7 | |||
| 49828b9681 | |||
| 141430ab0a | |||
| 807b4b223b | |||
| 89246f213a | |||
| a6fa2ff30a | |||
| 7f32c9a3f7 | |||
| 18b2433a99 | |||
| 51b9964f7e | |||
| 9084122a5c | |||
| 9ff07e0fc2 | |||
| 7ba47840d8 | |||
| 327e8476dd | |||
| 18eaec374c | |||
| 430a36ac42 | |||
| 508ca12be9 | |||
| adf7e17fce | |||
| 9c675f387a | |||
| 5770366c00 | |||
| f2581e8d96 | |||
| d7d678c082 | |||
| 44181457c5 | |||
| f9b27aecf5 | |||
| ddbb0ae1db | |||
| fec2567283 | |||
| ad8a020c29 | |||
| 06c04779bf | |||
| 1a047a8e14 | |||
| 0cf8666286 | |||
| 7c02b7e431 | |||
| 6c55cff603 | |||
| c64895a621 | |||
| 9dc3f2c909 | |||
| 1dc2ee743e | |||
| 1f7967d17f | |||
| 916729fbd5 | |||
| 1922536927 | |||
| de89f90700 | |||
| 09f1dff502 | |||
| 9a0414da6f | |||
| 119fc7f4f2 | |||
| 481e0b8b6c | |||
| 1b69f2db46 | |||
| 1b877c76b9 | |||
| 1fa791fc7a | |||
| e8a4867ff7 | |||
| 629717caea | |||
| 0d6253555b | |||
| 63d9edcc40 | |||
| bc2f217e7c | |||
| 7381bd09b1 | |||
| 379bd852d2 | |||
| a9ee6e5d43 | |||
| 2bef377e99 | |||
| 7f326421d7 | |||
| 3546f21af7 | |||
| 441dcfb56a | |||
| 42d9ef397d | |||
| 10eb89f078 | |||
| 8b2482af22 | |||
| a2ca59bf05 | |||
| 91f11868ea | |||
| 2c19e6a6a4 | |||
| e7ebe0a5c4 | |||
| 95ec0d8162 | |||
| 0a4f5a365a | |||
| b6b6b6d12b | |||
| 9f194ff4df | |||
| ed6ca9cd06 | |||
| 08971562cd | |||
| 263ff21cc1 | |||
| 99b08826dd | |||
| 417e00b938 | |||
| f8bb40c48f | |||
| 01b75c4393 | |||
| 9f1ffeee25 | |||
| c55faac0a9 | |||
| aaa50bae90 | |||
| b0c4910815 | |||
| 654f84a26c | |||
| ff10ea601c | |||
| 88bfba9fb2 | |||
| f11168df8e | |||
| 4ce056180c | |||
| 8718828869 | |||
| edfcc134ec | |||
| 6a34b88f79 | |||
| e596bf6ef9 | |||
| b369a1085c | |||
| 2e7e90a8aa | |||
| eae80ca46d | |||
| fe7505745d | |||
| 2ee3ab8577 | |||
| 3521b96611 | |||
| 7abfd45baf | |||
| 4141b456db | |||
| f86dc6b0a6 | |||
| 87be5af1ec | |||
| 12b9f232c2 | |||
| 19995df367 | |||
| 97a671cb49 | |||
| 9acea88101 | |||
| b29c0ca2f7 | |||
| a4a3577163 | |||
| 9dfaa8a4e5 | |||
| 661b09ab1c | |||
| e238292075 | |||
| 9fd52f600e | |||
| c75e692269 | |||
| 6770570f13 | |||
| 9875b069bc | |||
| 9399e00033 | |||
| 67d5d997c9 | |||
| 40c11410f0 | |||
| 307108ec6c | |||
| 0bb173b646 | |||
| 6538da22a6 | |||
| c79db992d9 | |||
| 89ab0becc2 | |||
| 58892be6f7 | |||
| 2aaa025d72 | |||
| 1474aa2116 | |||
| 2de8046f99 | |||
| a58af721f1 | |||
| 3a0bce0618 | |||
| 658dc8e9c3 | |||
| 7a87c22c7d | |||
| e36eaa56cb | |||
| 84a74d68cf | |||
| 5946590a66 | |||
| 268a3649b6 | |||
| 3e67766d1a | |||
| 1038684014 | |||
| 43acb99f86 | |||
| 8dccc8e07c | |||
| 3c800b00f5 | |||
| cb0f531b9a | |||
| 5e61c7b38a | |||
| 57f85e1720 | |||
| f4ced3b078 | |||
| 9553c46030 | |||
| 14e73e0c63 | |||
| 5c5c6e77fd | |||
| e9678a15f1 | |||
| f0135adb62 | |||
| 58fe92a41b | |||
| 5689fbf7cc | |||
| af052c79a7 | |||
| f431bb6396 | |||
| e21cc17a7b | |||
| 1247e40e88 | |||
| 6159209d49 | |||
| d8263a1fcd | |||
| 5e3b88f42d | |||
| a0e4d8b582 | |||
| ff80545285 | |||
| 3462d99675 | |||
| 11ec0c579d | |||
| 0de9f54e3c | |||
| 75e499004d | |||
| 11a817c442 | |||
| 8db843a57c | |||
| 08dd51a12f | |||
| 3f869ec191 | |||
| 0fba8ba402 | |||
| 7756f4b945 | |||
| 832e7113f7 | |||
| aa46e3d26f | |||
| d48719ab1c | |||
| 0c40a1ef92 | |||
| bad0504e1d | |||
| 01fdd83c6c | |||
| 0a92b6b681 | |||
| 167467339a | |||
| efd3329c50 | |||
| a140787252 | |||
| d09c4010f6 | |||
| e2f1a245b0 | |||
| 682045ef16 | |||
| dc6e825edd | |||
| 481e444ffe | |||
| 5193fa698f | |||
| b8d2bd6c30 | |||
| 33fde29acb | |||
| 6934b83acc | |||
| 330988ad16 | |||
| 058ef0a5a8 | |||
| 003c101f14 | |||
| 98d602628a | |||
| 46efc52a22 | |||
| f78891b600 | |||
| 05e3bbde45 | |||
| 4dc4a022ab | |||
| 226ae374c1 | |||
| fbfe1c7224 | |||
| 53f8ae3055 | |||
| 1634b3acfc | |||
| 3067323564 | |||
| c410b79af0 | |||
| f09fc23fdc | |||
| a9262b18c2 | |||
| ef129f9491 | |||
| fc90a3c2ba | |||
| 382a06028c |
+1
-1
@@ -1 +1 @@
|
||||
v0.10.21
|
||||
v0.10.33
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
2.7.6
|
||||
+18
-9
@@ -2,7 +2,7 @@
|
||||
|
||||
Atom is a hackable text editor for the 21st century, built on [atom-shell](http://github.com/atom/atom-shell), and based on everything we love about our favorite editors. We designed it to be deeply customizable, but still approachable using the default configuration.
|
||||
|
||||
Visit [atom.io](https://atom.io) to learn more.
|
||||
Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https://discuss.atom.io).
|
||||
|
||||
Visit [issue #3684](https://github.com/atom/atom/issues/3684) to learn more
|
||||
about the Atom 1.0 roadmap.
|
||||
@@ -17,16 +17,25 @@ Atom will automatically update when a new release is available.
|
||||
|
||||
### Windows
|
||||
|
||||
Install the [Atom chocolatey package](https://chocolatey.org/packages/Atom).
|
||||
Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
|
||||
|
||||
1. Install [chocolatey](https://chocolatey.org).
|
||||
2. Close and reopen your command prompt or PowerShell window.
|
||||
3. Run `cinst Atom`
|
||||
4. In the future run `cup Atom` to upgrade to the latest release.
|
||||
Atom will automatically update when a new release is available.
|
||||
|
||||
You can also download a `.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The Windows version does not currently automatically update so you will need to
|
||||
manually upgrade to future releases by re-downloading the `.zip` file.
|
||||
You can also download an `atom-windows.zip` file from the [releases page](https://github.com/atom/atom/releases/latest).
|
||||
The `.zip` version will not automatically update.
|
||||
|
||||
#### Uninstalling Chocolatey Version
|
||||
|
||||
The recommended installation of Atom on Windows used to be using [Chocolatey](https://chocolatey.org/packages/Atom/).
|
||||
This is no longer recommended now that the Atom Windows installer & auto-updater
|
||||
exists.
|
||||
|
||||
To switch from Chocolatey to the new installer:
|
||||
* Upgrade to Atom 0.155 or above by running `cup Atom`
|
||||
* Run `cuninst Atom` to uninstall the Chocolatey version of Atom
|
||||
* This will not delete any of your installed packages or Atom config files.
|
||||
* Download the latest [AtomSetup.exe installer](https://github.com/atom/atom/releases/latest).
|
||||
* Double-click the downloaded file to install Atom
|
||||
|
||||
### Debian Linux (Ubuntu)
|
||||
|
||||
|
||||
+1
-1
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "0.109.0"
|
||||
"atom-package-manager": "0.113.0"
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -45,12 +45,12 @@ if [ $REDIRECT_STDERR ]; then
|
||||
fi
|
||||
|
||||
if [ $OS == 'Mac' ]; then
|
||||
ATOM_PATH=${ATOM_PATH:-/Applications} # Set ATOM_PATH unless it is already set
|
||||
ATOM_PATH="${ATOM_PATH:-/Applications}" # Set ATOM_PATH unless it is already set
|
||||
ATOM_APP_NAME=Atom.app
|
||||
|
||||
# If ATOM_PATH isn't a executable file, use spotlight to search for Atom
|
||||
if [ ! -x "$ATOM_PATH/$ATOM_APP_NAME" ]; then
|
||||
ATOM_PATH=$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs dirname)
|
||||
ATOM_PATH="$(mdfind "kMDItemCFBundleIdentifier == 'com.github.atom'" | grep -v ShipIt | head -1 | xargs -0 dirname)"
|
||||
fi
|
||||
|
||||
# Exit if Atom can't be found
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
require '../spec/spec-helper'
|
||||
|
||||
path = require 'path'
|
||||
{$, Point} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
{Point} = require 'atom'
|
||||
_ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Project = require '../src/project'
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
require './benchmark-helper'
|
||||
{$, _, WorkspaceView} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
_ = require 'underscore-plus'
|
||||
{WorkspaceView} = require 'atom'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
|
||||
describe "editorView.", ->
|
||||
|
||||
@@ -6,7 +6,6 @@ os = require 'os'
|
||||
# modules work under node v0.11.x.
|
||||
require 'vm-compatibility-layer'
|
||||
|
||||
fm = require 'json-front-matter'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
packageJson = require '../package.json'
|
||||
@@ -22,9 +21,9 @@ module.exports = (grunt) ->
|
||||
grunt.loadNpmTasks('grunt-contrib-csslint')
|
||||
grunt.loadNpmTasks('grunt-contrib-coffee')
|
||||
grunt.loadNpmTasks('grunt-contrib-less')
|
||||
grunt.loadNpmTasks('grunt-markdown')
|
||||
grunt.loadNpmTasks('grunt-shell')
|
||||
grunt.loadNpmTasks('grunt-download-atom-shell')
|
||||
grunt.loadNpmTasks('grunt-atom-shell-installer')
|
||||
grunt.loadNpmTasks('grunt-peg')
|
||||
grunt.loadTasks('tasks')
|
||||
|
||||
@@ -194,32 +193,19 @@ module.exports = (grunt) ->
|
||||
'static/**/*.less'
|
||||
]
|
||||
|
||||
markdown:
|
||||
guides:
|
||||
files: [
|
||||
expand: true
|
||||
cwd: 'docs'
|
||||
src: '**/*.md'
|
||||
dest: 'docs/output/'
|
||||
ext: '.html'
|
||||
]
|
||||
options:
|
||||
template: 'docs/template.jst'
|
||||
templateContext:
|
||||
tag: "v#{major}.#{minor}"
|
||||
markdownOptions:
|
||||
gfm: true
|
||||
preCompile: (src, context) ->
|
||||
parsed = fm.parse(src)
|
||||
_.extend(context, parsed.attributes)
|
||||
parsed.body
|
||||
|
||||
'download-atom-shell':
|
||||
version: packageJson.atomShellVersion
|
||||
outputDir: 'atom-shell'
|
||||
downloadDir: atomShellDownloadDir
|
||||
rebuild: true # rebuild native modules after atom-shell is updated
|
||||
|
||||
'create-windows-installer':
|
||||
appDirectory: shellAppDir
|
||||
outputDirectory: path.join(buildDir, 'installer')
|
||||
authors: 'GitHub Inc.'
|
||||
loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif')
|
||||
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico'
|
||||
|
||||
shell:
|
||||
'kill-atom':
|
||||
command: killCommand
|
||||
@@ -237,6 +223,7 @@ module.exports = (grunt) ->
|
||||
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
|
||||
ciTasks.push('set-version', 'check-licenses', 'lint')
|
||||
ciTasks.push('mkdeb') if process.platform is 'linux'
|
||||
ciTasks.push('create-windows-installer') if process.platform is 'win32'
|
||||
ciTasks.push('test') if process.platform is 'darwin'
|
||||
ciTasks.push('codesign')
|
||||
ciTasks.push('publish-build')
|
||||
|
||||
@@ -7,11 +7,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "~0.2.9",
|
||||
"donna": "1.0.6",
|
||||
"donna": "1.0.7",
|
||||
"formidable": "~1.0.14",
|
||||
"fs-plus": "2.x",
|
||||
"github-releases": "~0.2.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-atom-shell-installer": "^0.13.0",
|
||||
"grunt-cli": "~0.1.9",
|
||||
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
|
||||
"grunt-contrib-coffee": "~0.9.0",
|
||||
@@ -20,21 +21,17 @@
|
||||
"grunt-cson": "0.10.0",
|
||||
"grunt-download-atom-shell": "~0.10.0",
|
||||
"grunt-lesslint": "0.13.0",
|
||||
"grunt-markdown": "~0.4.0",
|
||||
"grunt-peg": "~1.1.0",
|
||||
"grunt-shell": "~0.3.1",
|
||||
"harmony-collections": "~0.3.8",
|
||||
"json-front-matter": "~0.1.3",
|
||||
"legal-eagle": "~0.4.0",
|
||||
"legal-eagle": "~0.6.0",
|
||||
"minidump": "~0.8",
|
||||
"normalize-package-data": "0.2.12",
|
||||
"npm": "~1.4.5",
|
||||
"rcedit": "~0.1.2",
|
||||
"read-package-json": "1.1.8",
|
||||
"rcedit": "~0.3.0",
|
||||
"request": "~2.27.0",
|
||||
"rimraf": "~2.2.2",
|
||||
"runas": "~1.0.1",
|
||||
"tello": "1.0.3",
|
||||
"tello": "1.0.4",
|
||||
"temp": "~0.8.1",
|
||||
"underscore-plus": "1.x",
|
||||
"unzip": "~0.1.9",
|
||||
|
||||
@@ -11,6 +11,7 @@ module.exports = (grunt) ->
|
||||
appDir = grunt.config.get('atom.appDir')
|
||||
|
||||
rm shellAppDir
|
||||
rm path.join(buildDir, 'installer')
|
||||
mkdir path.dirname(buildDir)
|
||||
|
||||
if process.platform is 'darwin'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
module.exports = (grunt) ->
|
||||
grunt.registerTask 'check-licenses', 'Report the licenses of all dependencies', ->
|
||||
legalEagle = require 'legal-eagle'
|
||||
@@ -13,7 +12,7 @@ module.exports = (grunt) ->
|
||||
legalEagle options, (err, summary) ->
|
||||
if err?
|
||||
console.error(err)
|
||||
exit 1
|
||||
process.exit 1
|
||||
|
||||
for key of summary
|
||||
delete summary[key] if key.match /^atom@/
|
||||
|
||||
@@ -36,7 +36,7 @@ module.exports = (grunt) ->
|
||||
spawn {cmd, args}, (error) ->
|
||||
return callback(error) if error?
|
||||
|
||||
setupExePath = path.join(grunt.config.get('atom.shellAppDir'), '..', 'Releases', 'setup.exe')
|
||||
setupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
|
||||
if fs.isFileSync(setupExePath)
|
||||
args = [setupExePath]
|
||||
spawn {cmd, args}, (error) -> callback(error)
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports = (grunt) ->
|
||||
{spawn, rm} = require('./task-helpers')(grunt)
|
||||
|
||||
grunt.registerTask 'create-installer', 'Create the Windows installer', ->
|
||||
return unless process.platform is 'win32'
|
||||
|
||||
done = @async()
|
||||
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
atomDir = path.join(buildDir, 'Atom')
|
||||
releasesDir = path.join(buildDir, 'Releases')
|
||||
atomGitHubToken = process.env.ATOM_ACCESS_TOKEN
|
||||
|
||||
packageInfo = grunt.file.readJSON(path.join(atomDir, 'resources', 'app', 'package.json'))
|
||||
inputTemplate = grunt.file.read(path.join('build', 'windows', 'atom.nuspec.erb'))
|
||||
|
||||
# NB: Build server has some sort of stamp on the version number
|
||||
packageInfo.version = packageInfo.version.replace(/-.*$/, '')
|
||||
|
||||
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
|
||||
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
|
||||
|
||||
# We use the previous releases to build deltas for the current release,
|
||||
# sync down the existing releases directory by rolling through GitHub releases
|
||||
cmd = 'build/windows/SyncGitHubReleases.exe'
|
||||
args = ['-r', releasesDir, '-u', 'https://github.com/atom/atom', '-t', atomGitHubToken]
|
||||
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
if error?
|
||||
grunt.log.error "ATOM_ACCESS_TOKEN environment variable not set or invalid, can't download old releases; continuing anyways"
|
||||
|
||||
cmd = 'build/windows/nuget.exe'
|
||||
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
|
||||
|
||||
spawn {cmd, args}, (error, result, code) ->
|
||||
return done(error) if error?
|
||||
|
||||
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
|
||||
|
||||
cmd = 'build/windows/update.com'
|
||||
args = ['--releasify', path.join(buildDir, pkgs), '-r', releasesDir, '-g', 'build/windows/install-spinner.gif']
|
||||
spawn {cmd, args}, (error, result, code) -> done(error)
|
||||
@@ -6,12 +6,17 @@ _ = require 'underscore-plus'
|
||||
donna = require 'donna'
|
||||
tello = require 'tello'
|
||||
|
||||
moduleBlacklist = [
|
||||
'space-pen'
|
||||
]
|
||||
|
||||
module.exports = (grunt) ->
|
||||
getClassesToInclude = ->
|
||||
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
|
||||
classes = {}
|
||||
fs.traverseTreeSync modulesPath, (modulePath) ->
|
||||
return false if modulePath.match(/node_modules/g).length > 1 # dont need the dependencies of the dependencies
|
||||
return false if path.basename(modulePath) in moduleBlacklist
|
||||
return true unless path.basename(modulePath) is 'package.json'
|
||||
return true unless fs.isFileSync(modulePath)
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@ module.exports = (gruntObject) ->
|
||||
uploadAssets(release, buildDir, assets, done)
|
||||
|
||||
getAssets = ->
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
|
||||
{version} = grunt.file.readJSON('package.json')
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
|
||||
switch process.platform
|
||||
when 'darwin'
|
||||
[
|
||||
@@ -62,16 +67,16 @@ getAssets = ->
|
||||
{assetName: 'atom-api.json', sourcePath: 'atom-api.json'}
|
||||
]
|
||||
when 'win32'
|
||||
[
|
||||
{assetName: 'atom-windows.zip', sourcePath: 'Atom'}
|
||||
]
|
||||
assets = [{assetName: 'atom-windows.zip', sourcePath: 'Atom'}]
|
||||
for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg"]
|
||||
cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset)
|
||||
assets.push({assetName: squirrelAsset, sourcePath: assetName})
|
||||
assets
|
||||
when 'linux'
|
||||
buildDir = grunt.config.get('atom.buildDir')
|
||||
if process.arch is 'ia32'
|
||||
arch = 'i386'
|
||||
else
|
||||
arch = 'amd64'
|
||||
{version} = grunt.file.readJSON('package.json')
|
||||
|
||||
# Check for a Debian build
|
||||
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
|
||||
@@ -87,7 +92,6 @@ getAssets = ->
|
||||
arch = 'x86_64'
|
||||
assetName = "atom.#{arch}.rpm"
|
||||
|
||||
{cp} = require('./task-helpers')(grunt)
|
||||
cp sourcePath, path.join(buildDir, assetName)
|
||||
|
||||
[
|
||||
@@ -123,10 +127,22 @@ getAtomDraftRelease = (callback) ->
|
||||
logError('Fetching atom/atom releases failed', error, releases)
|
||||
callback(error)
|
||||
else
|
||||
for release in releases when release.draft
|
||||
callback(null, release)
|
||||
return
|
||||
callback(new Error('No draft release in atom/atom repo'))
|
||||
[firstDraft] = releases.filter ({draft}) -> draft
|
||||
if firstDraft?
|
||||
options =
|
||||
uri: firstDraft.assets_url
|
||||
method: 'GET'
|
||||
headers: defaultHeaders
|
||||
json: true
|
||||
request options, (error, response, assets=[]) ->
|
||||
if error? or response.statusCode isnt 200
|
||||
logError('Fetching draft release assets failed', error, assets)
|
||||
callback(error ? new Error(response.statusCode))
|
||||
else
|
||||
firstDraft.assets = assets
|
||||
callback(null, firstDraft)
|
||||
else
|
||||
callback(new Error('No draft release in atom/atom repo'))
|
||||
|
||||
deleteRelease = (release) ->
|
||||
options =
|
||||
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id><%= name %></id>
|
||||
<version><%= version %></version>
|
||||
<authors>The Atom Community</authors>
|
||||
<owners>The Atom Community</owners>
|
||||
<iconUrl>https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description><%= description %></description>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="locales\**" target="lib\net45\locales" />
|
||||
<file src="resources\**" target="lib\net45\resources" />
|
||||
<file src="*.pak" target="lib\net45" />
|
||||
|
||||
<file src="atom.exe" target="lib\net45\atom.exe" />
|
||||
<file src="atom.exe.gui" target="lib\net45\atom.exe.gui" />
|
||||
<file src="chromiumcontent.dll" target="lib\net45\chromiumcontent.dll" />
|
||||
<file src="d3dcompiler_43.dll" target="lib\net45\d3dcompiler_43.dll" />
|
||||
<file src="ffmpegsumo.dll" target="lib\net45\ffmpegsumo.dll" />
|
||||
<file src="icudtl.dat" target="lib\net45\icudtl.dat" />
|
||||
<file src="libEGL.dll" target="lib\net45\libEGL.dll" />
|
||||
<file src="libGLESv2.dll" target="lib\net45\libGLESv2.dll" />
|
||||
<file src="LICENSE" target="lib\net45\LICENSE" />
|
||||
<file src="msvcp120.dll" target="lib\net45\msvcp120.dll" />
|
||||
<file src="msvcr120.dll" target="lib\net45\msvcr120.dll" />
|
||||
<file src="vccorlib120.dll" target="lib\net45\vccorlib120.dll" />
|
||||
<file src="version" target="lib\net45\version" />
|
||||
<file src="xinput1_3.dll" target="lib\net45\xinput1_3.dll" />
|
||||
</files>
|
||||
</package>
|
||||
Arquivo binário não exibido.
|
Antes Largura: | Altura: | Tamanho: 43 KiB |
+2
-57
@@ -1,60 +1,5 @@
|
||||
# Welcome to the Atom API Documentation
|
||||
# Welcome to the Atom Docs
|
||||
|
||||

|
||||
|
||||
## FAQ
|
||||
|
||||
### Where do I start?
|
||||
|
||||
Check out [EditorView][EditorView] and [Editor][Editor] classes for a good
|
||||
overview of the main editor API.
|
||||
|
||||
### How do I access these classes?
|
||||
|
||||
Check out the [Atom][Atom] class docs to see what globals are available and
|
||||
what they provide.
|
||||
|
||||
You can also require many of these classes in your package via:
|
||||
|
||||
```coffee
|
||||
{EditorView} = require 'atom'
|
||||
```
|
||||
|
||||
The classes available from `require 'atom'` are:
|
||||
* [BufferedProcess][BufferedProcess]
|
||||
* [BufferedNodeProcess][BufferedNodeProcess]
|
||||
* [EditorView][EditorView]
|
||||
* [Git][Git]
|
||||
* [Point][Point]
|
||||
* [Range][Range]
|
||||
* [ScrollView][ScrollView]
|
||||
* [SelectListView][SelectListView]
|
||||
* [View][View]
|
||||
* [WorkspaceView][WorkspaceView]
|
||||
* [Workspace][Workspace]
|
||||
|
||||
### How do I create a package?
|
||||
|
||||
You probably want to read the [creating a package][creating-a-package]
|
||||
doc first and come back here when you are done.
|
||||
|
||||
### Where are the node docs?
|
||||
|
||||
Atom ships with node 0.11.10 and the comprehensive node API docs are available
|
||||
[here][node-docs].
|
||||
|
||||
[Atom]: ../classes/Atom.html
|
||||
[BufferedProcess]: ../classes/BufferedProcess.html
|
||||
[BufferedNodeProcess]: ../classes/BufferedNodeProcess.html
|
||||
[Editor]: ../classes/Editor.html
|
||||
[EditorView]: ../classes/EditorView.html
|
||||
[Git]: ../classes/Git.html
|
||||
[Point]: ../classes/Point.html
|
||||
[Range]: ../classes/Range.html
|
||||
[ScrollView]: ../classes/ScrollView.html
|
||||
[SelectListView]: ../classes/SelectListView.html
|
||||
[View]: ../classes/View.html
|
||||
[WorkspaceView]: ../classes/WorkspaceView.html
|
||||
[Workspace]: ../classes/Workspace.html
|
||||
[creating-a-package]: https://atom.io/docs/latest/creating-a-package
|
||||
[node-docs]: http://nodejs.org/docs/v0.11.10/api
|
||||
TODO: Write when docs move to a dedicated repo.
|
||||
|
||||
@@ -11,32 +11,34 @@ value of a namespaced config key with `atom.config.get`:
|
||||
@showInvisibles() if atom.config.get "editor.showInvisibles"
|
||||
```
|
||||
|
||||
Or you can use the `::subscribe` with `atom.config.observe` to track changes
|
||||
from any view object.
|
||||
Or you can subscribe via `atom.config.observe` to track changes from any view
|
||||
object.
|
||||
|
||||
```coffeescript
|
||||
{View} = require 'space-pen'
|
||||
|
||||
class MyView extends View
|
||||
initialize: ->
|
||||
@subscribe atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
attached: ->
|
||||
@fontSizeObserveSubscription =
|
||||
atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
|
||||
detached: ->
|
||||
@fontSizeObserveSubscription.dispose()
|
||||
```
|
||||
|
||||
The `atom.config.observe` method will call the given callback immediately with
|
||||
the current value for the specified key path, and it will also call it in the
|
||||
future whenever the value of that key path changes.
|
||||
future whenever the value of that key path changes. If you only want to invoke
|
||||
the callback when the next time the value changes, use `atom.config.onDidChange`
|
||||
instead.
|
||||
|
||||
Subscriptions made with `::subscribe` are automatically canceled when the
|
||||
view is removed. You can cancel config subscriptions manually via the
|
||||
`off` method on the subscription object that `atom.config.observe` returns.
|
||||
|
||||
```coffeescript
|
||||
fontSizeSubscription = atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
|
||||
@adjustFontSize()
|
||||
|
||||
# ... later on
|
||||
|
||||
fontSizeSubscription.off() # Stop observing
|
||||
```
|
||||
Subscription methods return *disposable* subscription objects. Note in the
|
||||
example above how we save the subscription to the `@fontSizeObserveSubscription`
|
||||
instance variable and dispose of it when the view is detached. To group multiple
|
||||
subscriptions together, you can add them all to a
|
||||
[`CompositeDisposable`][composite-disposable] that you dispose when the view is
|
||||
detached.
|
||||
|
||||
### Writing Config Settings
|
||||
|
||||
@@ -48,10 +50,9 @@ but you can programmatically write to it with `atom.config.set`:
|
||||
atom.config.set("core.showInvisibles", true)
|
||||
```
|
||||
|
||||
You can also use `setDefaults`, which will assign default values for keys that
|
||||
are always overridden by values assigned with `set`. Defaults are not written
|
||||
out to the the `config.json` file to prevent it from becoming cluttered.
|
||||
If you're exposing package configuration via specific key paths, you'll want to
|
||||
associate them with a schema in your package's main module. Read more about
|
||||
schemas in the [config API docs][config-api].
|
||||
|
||||
```coffeescript
|
||||
atom.config.setDefaults("editor", fontSize: 18, showInvisibles: true)
|
||||
```
|
||||
[composite-disposable]: https://atom.io/docs/api/latest/CompositeDisposable
|
||||
[config-api]: https://atom.io/docs/api/latest/Config
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# Globals
|
||||
|
||||
Atom exposes several services through singleton objects accessible via the
|
||||
`atom` global:
|
||||
|
||||
* atom
|
||||
* workspace:
|
||||
Manipulate and query the state of the user interface for the current
|
||||
window. Open editors, manipulate panes.
|
||||
* workspaceView:
|
||||
Similar to workspace, but provides access to the root of all views in the
|
||||
current window.
|
||||
* project:
|
||||
Access the directory associated with the current window. Load editors,
|
||||
perform project-wide searches, register custom openers for special file
|
||||
types.
|
||||
* config:
|
||||
Read, write, and observe user configuration settings.
|
||||
* keymap:
|
||||
Add and query the currently active keybindings.
|
||||
* deserializers:
|
||||
Deserialize instances from their state objects and register deserializers.
|
||||
* packages:
|
||||
Activate, deactivate, and query user packages.
|
||||
* themes:
|
||||
Activate, deactivate, and query user themes.
|
||||
* contextMenu:
|
||||
Register context menus.
|
||||
* menu:
|
||||
Register application menus.
|
||||
* pasteboard:
|
||||
Read from and write to the system pasteboard.
|
||||
* syntax:
|
||||
Assign and query syntactically-scoped properties.
|
||||
@@ -16,7 +16,7 @@ keystrokes pass through `atom-text-editor` elements:
|
||||
'ctrl-shift-e': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
|
||||
'atom-text-editor:not(.mini)'
|
||||
'atom-text-editor:not([mini])'
|
||||
'cmd-alt-[': 'editor:fold-current-row'
|
||||
'cmd-alt-]': 'editor:unfold-current-row'
|
||||
```
|
||||
@@ -27,8 +27,8 @@ patterns* to *commands*. When an element with the `atom-text-editor` class is fo
|
||||
`editor:delete-to-beginning-of-line` is emitted on the `atom-text-editor` element.
|
||||
|
||||
The second selector group also targets editors, but only if they don't have the
|
||||
`.mini` class. In this example, the commands for code folding don't really make
|
||||
sense on mini-editors, so the selector restricts them to regular editors.
|
||||
`mini` attribute. In this example, the commands for code folding don't really
|
||||
make sense on mini-editors, so the selector restricts them to regular editors.
|
||||
|
||||
### Keystroke Patterns
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
## Atom's View System
|
||||
|
||||
### SpacePen Basics
|
||||
|
||||
Atom's view system is built around the [SpacePen] view framework. SpacePen
|
||||
view objects inherit from the jQuery prototype, and wrap DOM nodes
|
||||
|
||||
View objects are actually jQuery wrappers around DOM fragments, supporting all
|
||||
the typical jQuery traversal and manipulation methods. In addition, view objects
|
||||
have methods that are view-specific. For example, you could call both general
|
||||
and view-specific on the global `atom.workspaceView` instance:
|
||||
|
||||
```coffeescript
|
||||
atom.workspaceView.find('atom-text-editor.active') # standard jQuery method
|
||||
atom.workspaceView.getActiveEditor() # view-specific method
|
||||
```
|
||||
|
||||
If you retrieve a jQuery wrapper for an element associated with a view, use the
|
||||
`.view()` method to retrieve the element's view object:
|
||||
|
||||
```coffeescript
|
||||
# this is a plain jQuery object; you can't call view-specific methods
|
||||
editorElement = atom.workspaceView.find('atom-text-editor.active')
|
||||
|
||||
# get the view object by calling `.view()` to call view-specific methods
|
||||
editorView = editorElement.view()
|
||||
editorView.setCursorBufferPosition([1, 2])
|
||||
```
|
||||
|
||||
Refer to the [SpacePen] documentation for more details.
|
||||
|
||||
### WorkspaceView
|
||||
|
||||
The root of Atom's view hierarchy is a global called `atom.workspaceView`, which is a
|
||||
singleton instance of the `WorkspaceView` view class. The root view fills the entire
|
||||
window, and contains every other view. If you open Atom's inspector with
|
||||
`alt-cmd-i`, you can see the internal structure of `WorkspaceView`:
|
||||
|
||||
![WorkspaceView in the inspector][workspaceview-inspector]
|
||||
|
||||
#### Panes
|
||||
|
||||
The `WorkspaceView` contains `prependToBottom/Top/Left/Right` and
|
||||
`appendToBottom/Top/Left/Right` methods, which are used to add Tool Panels. Tool
|
||||
panels are elements that take up screen real estate not devoted to text editing.
|
||||
In the example above, the `TreeView` is appended to the left, and the
|
||||
`CommandPanel` is appended to the top.
|
||||
|
||||
```coffeescript
|
||||
# place a view to the left of the panes
|
||||
atom.workspaceView.appendToLeft(new MyView)
|
||||
|
||||
# place a view below the panes
|
||||
atom.workspaceView.appendToBottom(new MyOtherView)
|
||||
```
|
||||
|
||||
[spacepen]: http://github.com/nathansobo/space-pen
|
||||
[workspaceView-inspector]: https://f.cloud.github.com/assets/1424/1091631/1932c2d6-166b-11e3-8adf-9690fe82d3b8.png
|
||||
@@ -30,6 +30,8 @@ All requests that take parameters require `application/json`.
|
||||
Parameters:
|
||||
|
||||
- **page** (optional)
|
||||
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
|
||||
- **direction** (optional, values: `asc`, `desc`)
|
||||
|
||||
Returns a list of all packages in the following format:
|
||||
```json
|
||||
@@ -57,6 +59,20 @@ Link: <https://www.atom.io/api/packages?page=1>; rel="self",
|
||||
<https://www.atom.io/api/packages?page=2>; rel="next"
|
||||
```
|
||||
|
||||
By default, results are sorted by download count, descending.
|
||||
|
||||
#### GET /api/packages/search
|
||||
|
||||
Parameters:
|
||||
|
||||
- **q** String query to search
|
||||
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
|
||||
- **direction** (optional, values: `asc`, `desc`)
|
||||
|
||||
Returns a list of all packages in the same format as `/api/packages`.
|
||||
|
||||
By default, results sorted by relevance to search query.
|
||||
|
||||
### Showing package details
|
||||
|
||||
#### GET /api/packages/:package_name
|
||||
|
||||
@@ -29,6 +29,10 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
|
||||
* `sudo pacman -S base-devel git nodejs libgnome-keyring python2`
|
||||
* `export PYTHON=/usr/bin/python2` before building Atom.
|
||||
|
||||
### Slackware
|
||||
|
||||
* `sbopkg -k -i node -i atom`
|
||||
|
||||
## Instructions
|
||||
|
||||
If you have problems with permissions don't forget to prefix with `sudo`
|
||||
@@ -43,7 +47,7 @@ If you have problems with permissions don't forget to prefix with `sudo`
|
||||
2. Checkout the latest Atom release:
|
||||
|
||||
```sh
|
||||
git fetch
|
||||
git fetch -p
|
||||
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
```
|
||||
|
||||
@@ -121,6 +125,15 @@ have Node.js installed, or node isn't identified as Node.js on your machine.
|
||||
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
|
||||
your terminal may fix the issue.
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
Alternatives so that changes to the binary paths can be fixed or altered easily:
|
||||
|
||||
```sh
|
||||
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
|
||||
```
|
||||
|
||||
### AttributeError: 'module' object has no attribute 'script_main'
|
||||
|
||||
If you get following error with a big traceback while building Atom:
|
||||
@@ -137,15 +150,6 @@ On Fedora you would do the following:
|
||||
sudo yum remove gyp
|
||||
```
|
||||
|
||||
#### You can also use Alternatives
|
||||
|
||||
On some variants (mostly Debian based distros) it's preferable for you to use
|
||||
Alternatives so that changes to the binary paths can be fixed or altered easily:
|
||||
|
||||
```sh
|
||||
sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 1 --slave /usr/bin/js js /usr/bin/nodejs
|
||||
```
|
||||
|
||||
### Linux build error reports in atom/atom
|
||||
* Use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Alinux&type=Issues)
|
||||
to get a list of reports about build errors on Linux.
|
||||
|
||||
@@ -40,7 +40,7 @@ package.json files have their own additions.
|
||||
- `main` (**Required**): the path to the CoffeeScript file that's the entry point
|
||||
to your package
|
||||
- `stylesheets` (**Optional**): an Array of Strings identifying the order of the
|
||||
stylesheets your package needs to load. If not specified, stylesheets in the
|
||||
style sheets your package needs to load. If not specified, style sheets in the
|
||||
_stylesheets_ directory are added alphabetically.
|
||||
- `keymaps`(**Optional**): an Array of Strings identifying the order of the
|
||||
key mappings your package needs to load. If not specified, mappings in the
|
||||
@@ -119,27 +119,27 @@ Also, please collaborate with us if you need an API that doesn't exist. Our goal
|
||||
is to build out Atom's API organically based on the needs of package authors
|
||||
like you.
|
||||
|
||||
## Stylesheets
|
||||
## Style Sheets
|
||||
|
||||
Stylesheets for your package should be placed in the _stylesheets_ directory.
|
||||
Any stylesheets in this directory will be loaded and attached to the DOM when
|
||||
your package is activated. Stylesheets can be written as CSS or [LESS] (but LESS
|
||||
is recommended).
|
||||
Style sheets for your package should be placed in the _stylesheets_ directory.
|
||||
Any style sheets in this directory will be loaded and attached to the DOM when
|
||||
your package is activated. Style sheets can be written as CSS or [LESS] (but
|
||||
LESS is recommended).
|
||||
|
||||
Ideally, you won't need much in the way of styling. We've provided a standard
|
||||
set of components which define both the colors and UI elements for any package
|
||||
that fits into Atom seamlessly. You can view all of Atom's UI components by opening
|
||||
the styleguide: open the command palette (`cmd-shift-P`) and search for _styleguide_,
|
||||
or just type `cmd-ctrl-shift-G`.
|
||||
that fits into Atom seamlessly. You can view all of Atom's UI components by
|
||||
opening the styleguide: open the command palette (`cmd-shift-P`) and search for
|
||||
_styleguide_, or just type `cmd-ctrl-shift-G`.
|
||||
|
||||
If you _do_ need special styling, try to keep only structural styles in the package
|
||||
stylesheets. If you _must_ specify colors and sizing, these should be taken from
|
||||
the active theme's [ui-variables.less][ui-variables]. For more information, see the
|
||||
[theme variables docs][theme-variables]. If you follow this guideline, your package
|
||||
will look good out of the box with any theme!
|
||||
If you _do_ need special styling, try to keep only structural styles in the
|
||||
package style sheets. If you _must_ specify colors and sizing, these should be
|
||||
taken from the active theme's [ui-variables.less][ui-variables]. For more
|
||||
information, see the [theme variables docs][theme-variables]. If you follow this
|
||||
guideline, your package will look good out of the box with any theme!
|
||||
|
||||
An optional `stylesheets` array in your _package.json_ can list the stylesheets
|
||||
by name to specify a loading order; otherwise, stylesheets are loaded
|
||||
An optional `stylesheets` array in your _package.json_ can list the style sheets
|
||||
by name to specify a loading order; otherwise, style sheets are loaded
|
||||
alphabetically.
|
||||
|
||||
## Keymaps
|
||||
@@ -157,9 +157,9 @@ loaded in alphabetical order. An optional `keymaps` array in your _package.json_
|
||||
can specify which keymaps to load and in what order.
|
||||
|
||||
|
||||
Keybindings are executed by determining which element the keypress occurred on. In
|
||||
the example above, `changer:magic` command is executed when pressing `ctrl-V` on
|
||||
the `.tree-view-scroller` element.
|
||||
Keybindings are executed by determining which element the keypress occurred on.
|
||||
In the example above, `changer:magic` command is executed when pressing `ctrl-V`
|
||||
on the `.tree-view-scroller` element.
|
||||
|
||||
See the [main keymaps documentation][keymaps] for more detailed information on
|
||||
how keymaps work.
|
||||
@@ -195,7 +195,8 @@ with your package that aren't tied to a specific element:
|
||||
```
|
||||
|
||||
To add your own item to the application menu, simply create a top level `menu`
|
||||
key in any menu configuration file in _menus_. This can be a JSON or [CSON] file.
|
||||
key in any menu configuration file in _menus_. This can be a JSON or [CSON]
|
||||
file.
|
||||
|
||||
The menu templates you specify are merged with all other templates provided
|
||||
by other packages in the order which they were loaded.
|
||||
|
||||
@@ -63,7 +63,7 @@ built-in keymaps:
|
||||
'atom-text-editor':
|
||||
'enter': 'editor:newline'
|
||||
|
||||
'atom-text-editor.mini input':
|
||||
'atom-text-editor[mini] input':
|
||||
'enter': 'core:confirm'
|
||||
```
|
||||
|
||||
@@ -118,7 +118,6 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
|
||||
- `cr`: Carriage return (for Microsoft-style line endings)
|
||||
- `eol`: `\n` characters
|
||||
- `space`: Leading and trailing space characters
|
||||
- `normalizeIndentOnPaste`: Enable/disable conversion of pasted tabs to spaces
|
||||
- `preferredLineLength`: Identifies the length of a line (defaults to `80`)
|
||||
- `showInvisibles`: Whether to render placeholders for invisible characters (defaults to `false`)
|
||||
- `showIndentGuide`: Show/hide indent indicators within the editor
|
||||
|
||||
+5
-1
@@ -18,5 +18,9 @@
|
||||
* [Developing Node Modules](advanced/node-modules.md)
|
||||
* [Keymaps](advanced/keymaps.md)
|
||||
* [Serialization](advanced/serialization.md)
|
||||
* [View System](advanced/view-system.md)
|
||||
* [Scopes and Scope Descriptors](advanced/scopes-and-scope-descriptors.md)
|
||||
|
||||
### Upgrading to 1.0 APIs
|
||||
|
||||
* [Upgrading Your UI Theme Or Package Selectors](upgrading/upgrading-your-ui-theme.md)
|
||||
* [Upgrading Your Syntax Theme](upgrading/upgrading-your-syntax-theme.md)
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css">
|
||||
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../assets/js/html5shiv.js"></script>
|
||||
<script src="../../assets/js/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<title>Atom - <%= title %></title>
|
||||
<style>
|
||||
/*github.com style (c) Vasily Polovnyov <vast@whiteants.net>*/
|
||||
pre code {
|
||||
display: block; padding: 0.5em;
|
||||
color: #333;
|
||||
background: #f8f8ff
|
||||
}
|
||||
pre .comment,
|
||||
pre .template_comment,
|
||||
pre .diff .header,
|
||||
pre .javadoc {
|
||||
color: #998;
|
||||
font-style: italic
|
||||
}
|
||||
pre .keyword,
|
||||
pre .css .rule .keyword,
|
||||
pre .winutils,
|
||||
pre .javascript .title,
|
||||
pre .nginx .title,
|
||||
pre .subst,
|
||||
pre .request,
|
||||
pre .status {
|
||||
color: #333;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .number,
|
||||
pre .hexcolor,
|
||||
pre .ruby .constant {
|
||||
color: #099;
|
||||
}
|
||||
pre .string,
|
||||
pre .tag .value,
|
||||
pre .phpdoc,
|
||||
pre .tex .formula {
|
||||
color: #d14
|
||||
}
|
||||
pre .title,
|
||||
pre .id {
|
||||
color: #900;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .javascript .title,
|
||||
pre .lisp .title,
|
||||
pre .clojure .title,
|
||||
pre .subst {
|
||||
font-weight: normal
|
||||
}
|
||||
pre .class .title,
|
||||
pre .haskell .type,
|
||||
pre .vhdl .literal,
|
||||
pre .tex .command {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .tag,
|
||||
pre .tag .title,
|
||||
pre .rules .property,
|
||||
pre .django .tag .keyword {
|
||||
color: #000080;
|
||||
font-weight: normal
|
||||
}
|
||||
pre .attribute,
|
||||
pre .variable,
|
||||
pre .lisp .body {
|
||||
color: #008080
|
||||
}
|
||||
pre .regexp {
|
||||
color: #009926
|
||||
}
|
||||
pre .class {
|
||||
color: #458;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .symbol,
|
||||
pre .ruby .symbol .string,
|
||||
pre .lisp .keyword,
|
||||
pre .tex .special,
|
||||
pre .prompt {
|
||||
color: #990073
|
||||
}
|
||||
pre .built_in,
|
||||
pre .lisp .title,
|
||||
pre .clojure .built_in {
|
||||
color: #0086b3
|
||||
}
|
||||
pre .preprocessor,
|
||||
pre .pi,
|
||||
pre .doctype,
|
||||
pre .shebang,
|
||||
pre .cdata {
|
||||
color: #999;
|
||||
font-weight: bold
|
||||
}
|
||||
pre .deletion {
|
||||
background: #fdd
|
||||
}
|
||||
pre .addition {
|
||||
background: #dfd
|
||||
}
|
||||
pre .diff .change {
|
||||
background: #0086b3
|
||||
}
|
||||
pre .chunk {
|
||||
color: #aaa
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/<%= tag %>/index.html">Atom Documentation</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="/docs/api/<%= tag %>/api/index.html">API</a></li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<%= content %>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
# Upgrading Your Syntax Theme
|
||||
|
||||
Text editor content is now rendered in the shadow DOM, which shields it from being styled by global style sheets to protect against accidental style pollution. For more background on the shadow DOM, check out the [Shadow DOM 101][shadow-dom-101] on HTML 5 Rocks.
|
||||
|
||||
Syntax themes are specifically intended to style only text editor content, so they are automatically loaded directly into the text editor's shadow DOM when it is enabled. This happens automatically when the the theme's `package.json` contains a `theme: "syntax"` declaration, so you don't need to change anything to target the appropriate context.
|
||||
|
||||
When theme style sheets are loaded into the text editor's shadow DOM, selectors intended to target the editor from the *outside* no longer make sense. Styles targeting the `.editor` and `.editor-colors` classes instead need to target the `:host` pseudo-element, which matches against the containing `atom-text-editor` node. Check out the [Shadow DOM 201][host-pseudo-element] article for more information about the `:host` pseudo-element.
|
||||
|
||||
Here's an example from Atom's light syntax theme. Note that the previous selectors intended to target the editor from the outside have been retained to allow the theme to keep working during the transition phase when it is possible to disable the shadow DOM.
|
||||
|
||||
```css
|
||||
.editor-colors, :host { /* :host added */
|
||||
background-color: @syntax-background-color;
|
||||
color: @syntax-text-color;
|
||||
}
|
||||
|
||||
.editor, :host { /* :host added */
|
||||
.invisible-character {
|
||||
color: @syntax-invisible-character-color;
|
||||
}
|
||||
|
||||
/* more nested selectors... */
|
||||
}
|
||||
```
|
||||
|
||||
[shadow-dom-101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom
|
||||
[host-pseudo-element]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201#toc-style-host
|
||||
@@ -0,0 +1,137 @@
|
||||
# Upgrading Your UI Theme Or Package Selectors
|
||||
|
||||
In addition to changes in Atom's scripting API, we'll also be making some breaking changes to Atom's DOM structure, requiring stylesheets and keymaps in both packages and themes to be updated.
|
||||
|
||||
## Deprecation Cop
|
||||
|
||||
Deprecation cop will list usages of deprecated selector patterns to guide you. You can access it via the command palette (`cmd-shift-p`, then search for `Deprecation`). It breaks the deprecations down by package:
|
||||
|
||||

|
||||
|
||||
## Custom Tags
|
||||
|
||||
Rather than adding classes to standard HTML elements to indicate their role, Atom now uses custom element names. For example, `<div class="workspace">` has now been replaced with `<atom-workspace>`. Selectors should be updated accordingly. Note that tag names have lower specificity than classes in CSS, so you'll need to take care in converting things.
|
||||
|
||||
Old Selector | New Selector
|
||||
--------------------|--------------------------------
|
||||
`.editor` | `atom-text-editor`
|
||||
`.editor.mini` | `atom-text-editor[mini]`
|
||||
`.workspace` | `atom-workspace`
|
||||
`.horizontal` | `atom-workspace-axis.horizontal`
|
||||
`.vertical` | `atom-workspace-axis.vertical`
|
||||
`.pane-container` | `atom-pane-conatiner`
|
||||
`.pane` | `atom-pane`
|
||||
`.tool-panel` | `atom-panel`
|
||||
`.panel-top` | `atom-panel.top`
|
||||
`.panel-bottom` | `atom-panel.bottom`
|
||||
`.panel-left` | `atom-panel.left`
|
||||
`.panel-right` | `atom-panel.right`
|
||||
`.overlay` | `atom-panel.modal`
|
||||
|
||||
## Supporting the Shadow DOM
|
||||
|
||||
Text editor content is now rendered in the shadow DOM, which shields it from being styled by global style sheets to protect against accidental style pollution. For more background on the shadow DOM, check out the [Shadow DOM 101][shadow-dom-101] on HTML 5 Rocks. If you need to style text editor content in a UI theme, you'll need to circumvent this protection for any rules that target the text editor's content. Some examples of the kinds of UI theme styles needing to be updated:
|
||||
|
||||
* Highlight decorations
|
||||
* Gutter decorations
|
||||
* Line decorations
|
||||
* Scrollbar styling
|
||||
* Anything targeting a child selector of `.editor`
|
||||
|
||||
During a transition phase, it will be possible to enable or disable the text editor's shadow DOM in the settings, so themes will need to be compatible with both approaches.
|
||||
|
||||
### Shadow DOM Selectors
|
||||
|
||||
Chromium provides two tools for bypassing shadow boundaries, the `::shadow` pseudo-element and the `/deep/` combinator. For an in-depth explanation of styling the shadow DOM, see the [Shadow DOM 201][shadow-dom-201] article on HTML 5 Rocks.
|
||||
|
||||
#### ::shadow
|
||||
|
||||
The `::shadow` pseudo-element allows you to bypass a single shadow root. For example, say you want to update a highlight decoration for a linter package. Initially, the style looks as follows:
|
||||
|
||||
```css
|
||||
// Without shadow DOM support
|
||||
atom-text-editor .highlight.my-linter {
|
||||
background: hotpink;
|
||||
}
|
||||
```
|
||||
|
||||
In order for this style to apply with the shadow DOM enabled, you will need to add a second selector with the `::shadow` pseudo-element. You should leave the original selector in place so your theme continues to work with the shadow DOM disabled during the transition period.
|
||||
|
||||
```css
|
||||
// With shadow DOM support
|
||||
atom-text-editor .highlight.my-linter,
|
||||
atom-text-editor::shadow .highlight.my-linter {
|
||||
background: hotpink;
|
||||
}
|
||||
```
|
||||
|
||||
Check out the [find-and-replace][find-and-replace] package for another example of using `::shadow` to pierce the shadow DOM.
|
||||
|
||||
#### /deep/
|
||||
|
||||
The `/deep/` combinator overrides *all* shadow boundaries, making it useful for rules you want to apply globally such as scrollbar styling. Here's a snippet containing scrollbar styling for the Atom Dark UI theme before shadow DOM support:
|
||||
|
||||
```css
|
||||
// Without shadow DOM support
|
||||
.scrollbars-visible-always {
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-corner {
|
||||
background: @scrollbar-background-color;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: @scrollbar-color;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 1px black inset;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To style scrollbars even inside of the shadow DOM, each rule needs to be prefixed with `/deep/`. We use `/deep/` instead of `::shadow` because we don't care about the selector of the host element in this case. We just want our styling to apply everywhere.
|
||||
|
||||
```css
|
||||
// With shadow DOM support using /deep/
|
||||
.scrollbars-visible-always {
|
||||
/deep/ ::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
/deep/ ::-webkit-scrollbar-track,
|
||||
/deep/ ::-webkit-scrollbar-corner {
|
||||
background: @scrollbar-background-color;
|
||||
}
|
||||
|
||||
/deep/ ::-webkit-scrollbar-thumb {
|
||||
background: @scrollbar-color;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 1px black inset;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Context-Targeted Style Sheets
|
||||
|
||||
The selector features discussed above allow you to target shadow DOM content with specific selectors, but Atom also allows you to target a specific shadow DOM context with an entire style sheet. The context into which a style sheet is loaded is based on the file name. If you want to load a style sheet into the editor, name it with the `.atom-text-editor.less` or `.atom-text-editor.css` extensions.
|
||||
|
||||
```
|
||||
my-ui-theme/
|
||||
stylesheets/
|
||||
index.less # loaded globally
|
||||
index.atom-text-editor.less # loaded in the text editor shadow DOM
|
||||
```
|
||||
|
||||
Check out this [style sheet](https://github.com/atom/decoration-example/blob/master/stylesheets/decoration-example.atom-text-editor.less) from the decoration-example package for an example of context-targeting.
|
||||
|
||||
Inside a context-targeted style sheet, there's no need to use the `::shadow` or `/deep/` expressions. If you want to refer to the element containing the shadow root, you can use the `::host` pseudo-element.
|
||||
|
||||
During the transition phase, style sheets targeting the `atom-text-editor` context will *also* be loaded globally. Make sure you update your selectors in a way that maintains compatibility with the shadow DOM being disabled. That means if you use a `::host` pseudo element, you should also include the same style rule matches against `atom-text-editor`.
|
||||
|
||||
[shadow-dom-101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom
|
||||
[shadow-dom-201]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201#toc-style-cat-hat
|
||||
[find-and-replace]: https://github.com/atom/find-and-replace/blob/95351f261bc384960a69b66bf12eae8002da63f9/stylesheets/find-and-replace.less#L10
|
||||
@@ -72,7 +72,7 @@ Writing Asynchronous specs can be tricky at first. Some examples.
|
||||
atom.workspace.open 'c.coffee'
|
||||
|
||||
it "should be opened in an editor", ->
|
||||
expect(atom.workspace.getActiveEditor().getPath()).toContain 'c.coffee'
|
||||
expect(atom.workspace.getActiveTextEditor().getPath()).toContain 'c.coffee'
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ Register the command in _lib/ascii-art.coffee_:
|
||||
```coffeescript
|
||||
module.exports =
|
||||
activate: ->
|
||||
atom.workspaceView.command "ascii-art:convert", => @convert()
|
||||
atom.commands.add 'atom-workspace', "ascii-art:convert", => @convert()
|
||||
|
||||
convert: ->
|
||||
# This assumes the active pane item is an editor
|
||||
@@ -57,10 +57,10 @@ module.exports =
|
||||
editor.insertText('Hello, World!')
|
||||
```
|
||||
|
||||
The `atom.workspaceView.command` method takes a command name and a callback. The
|
||||
callback executes when the command is triggered. In this case, when the command
|
||||
is triggered the callback will call the `convert` method and insert 'Hello,
|
||||
World!'.
|
||||
The `atom.commands.add` method takes a selector, command name, and a callback.
|
||||
The callback executes when the command is triggered on an element matching the
|
||||
selector. In this case, when the command is triggered the callback will call the
|
||||
`convert` method and insert 'Hello, World!'.
|
||||
|
||||
## Reload the Package
|
||||
|
||||
@@ -95,13 +95,13 @@ you don't need it anymore. When finished, the file will look like this:
|
||||
'cmd-alt-a': 'ascii-art:convert'
|
||||
```
|
||||
|
||||
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors *scope* key
|
||||
bindings so they only apply to specific elements. In this case, our binding is
|
||||
only active for elements matching the `atom-text-editor` selector. If the Tree View has
|
||||
focus, pressing `cmd-alt-a` won't trigger the `ascii-art:convert` command. But
|
||||
if the editor has focus, the `ascii-art:convert` method *will* be triggered.
|
||||
More information on key bindings can be found in the
|
||||
[keymaps](advanced/keymaps.html) documentation.
|
||||
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors
|
||||
*scope* key bindings so they only apply to specific elements. In this case, our
|
||||
binding is only active for elements matching the `atom-text-editor` selector. If
|
||||
the Tree View has focus, pressing `cmd-alt-a` won't trigger the
|
||||
`ascii-art:convert` command. But if the editor has focus, the
|
||||
`ascii-art:convert` method *will* be triggered. More information on key bindings
|
||||
can be found in the [keymaps](advanced/keymaps.html) documentation.
|
||||
|
||||
Now reload the window and verify that the key binding works! You can also verify
|
||||
that it **doesn't** work when the Tree View is focused.
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
# after packages are loaded/activated and after the previous editor state
|
||||
# has been restored.
|
||||
#
|
||||
# An example hack to make opened Markdown files always be soft wrapped:
|
||||
# An example hack to log to the console when each text editor is saved.
|
||||
#
|
||||
# path = require 'path'
|
||||
#
|
||||
# atom.workspaceView.eachEditorView (editorView) ->
|
||||
# editor = editorView.getEditor()
|
||||
# if path.extname(editor.getPath()) is '.md'
|
||||
# editor.setSoftWrapped(true)
|
||||
# atom.workspace.observeTextEditors (editor) ->
|
||||
# editor.onDidSave ->
|
||||
# console.log "Saved! #{editor.getPath()}"
|
||||
|
||||
+108
-16
@@ -1,35 +1,127 @@
|
||||
{Point, Range} = require 'text-buffer'
|
||||
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
|
||||
{deprecate} = require 'grim'
|
||||
|
||||
module.exports =
|
||||
BufferedNodeProcess: require '../src/buffered-node-process'
|
||||
BufferedProcess: require '../src/buffered-process'
|
||||
GitRepository: require '../src/git-repository'
|
||||
Notification: require '../src/notification'
|
||||
Point: Point
|
||||
Range: Range
|
||||
Emitter: Emitter
|
||||
Disposable: Disposable
|
||||
CompositeDisposable: CompositeDisposable
|
||||
|
||||
# The following classes can't be used from a Task handler and should therefore
|
||||
# only be exported when not running as a child node process
|
||||
unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
|
||||
module.exports.Task = require '../src/task'
|
||||
module.exports.TextEditor = require '../src/text-editor'
|
||||
|
||||
{$, $$, $$$, View} = require '../src/space-pen-extensions'
|
||||
|
||||
module.exports.$ = $
|
||||
module.exports.$$ = $$
|
||||
module.exports.$$$ = $$$
|
||||
module.exports.TextEditorView = require '../src/text-editor-view'
|
||||
module.exports.ScrollView = require '../src/scroll-view'
|
||||
module.exports.SelectListView = require '../src/select-list-view'
|
||||
module.exports.Task = require '../src/task'
|
||||
module.exports.View = View
|
||||
module.exports.WorkspaceView = require '../src/workspace-view'
|
||||
module.exports.Workspace = require '../src/workspace'
|
||||
module.exports.React = require 'react-atom-fork'
|
||||
module.exports.Reactionary = require 'reactionary-atom-fork'
|
||||
Object.defineProperty module.exports, 'Workspace', get: ->
|
||||
deprecate """
|
||||
Requiring `Workspace` from `atom` is no longer supported.
|
||||
If you need this, please open an issue on
|
||||
https://github.com/atom/atom/issues/new
|
||||
And let us know what you are using it for.
|
||||
"""
|
||||
require '../src/workspace'
|
||||
|
||||
Object.defineProperty module.exports, 'WorkspaceView', get: ->
|
||||
deprecate """
|
||||
Requiring `WorkspaceView` from `atom` is no longer supported.
|
||||
Use `atom.views.getView(atom.workspace)` instead.
|
||||
"""
|
||||
require '../src/workspace-view'
|
||||
|
||||
Object.defineProperty module.exports, '$', get: ->
|
||||
deprecate """
|
||||
Requiring `$` from `atom` is no longer supported.
|
||||
If you are using `space-pen`, please require `$` from `space-pen`. Otherwise require `jquery` instead:
|
||||
`{$} = require 'space-pen'`
|
||||
or
|
||||
`$ = require 'jquery'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
Or add `"jquery": "^2"` to your package dependencies.
|
||||
"""
|
||||
$
|
||||
|
||||
Object.defineProperty module.exports, '$$', get: ->
|
||||
deprecate """
|
||||
Requiring `$$` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{$$} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
"""
|
||||
$$
|
||||
|
||||
Object.defineProperty module.exports, '$$$', get: ->
|
||||
deprecate """
|
||||
Requiring `$$$` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{$$$} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
"""
|
||||
$$$
|
||||
|
||||
Object.defineProperty module.exports, 'View', get: ->
|
||||
deprecate """
|
||||
Requiring `View` from `atom` is no longer supported.
|
||||
Please require `space-pen` instead:
|
||||
`{View} = require 'space-pen'`
|
||||
Add `"space-pen": "^4"` to your package dependencies.
|
||||
"""
|
||||
View
|
||||
|
||||
Object.defineProperty module.exports, 'EditorView', get: ->
|
||||
deprecate """
|
||||
Requiring `EditorView` from `atom` is no longer supported.
|
||||
Please require `TextEditorView` from `atom-space-pen-view` instead:
|
||||
`{TextEditorView} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/text-editor-view'
|
||||
|
||||
Object.defineProperty module.exports, 'TextEditorView', get: ->
|
||||
deprecate """
|
||||
Requiring `TextEditorView` from `atom` is no longer supported.
|
||||
Please require `TextEditorView` from `atom-space-pen-view` instead:
|
||||
`{TextEditorView} = require 'atom-space-pen-views'`
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/text-editor-view'
|
||||
|
||||
Object.defineProperty module.exports, 'ScrollView', get: ->
|
||||
deprecate """
|
||||
Requiring `ScrollView` from `atom` is no longer supported.
|
||||
Please require `ScrollView` from `atom-space-pen-view` instead:
|
||||
`{ScrollView} = require 'atom-space-pen-views'`
|
||||
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/scroll-view'
|
||||
|
||||
Object.defineProperty module.exports, 'SelectListView', get: ->
|
||||
deprecate """
|
||||
Requiring `SelectListView` from `atom` is no longer supported.
|
||||
Please require `SelectListView` from `atom-space-pen-view` instead:
|
||||
`{SelectListView} = require 'atom-space-pen-views'`
|
||||
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
|
||||
Add `"atom-space-pen-views": "^0"` to your package dependencies.
|
||||
"""
|
||||
require '../src/select-list-view'
|
||||
|
||||
Object.defineProperty module.exports, 'React', get: ->
|
||||
deprecate "Please require `react-atom-fork` instead: `React = require 'react-atom-fork'`. Add `\"react-atom-fork\": \"^0.11\"` to your package dependencies."
|
||||
require 'react-atom-fork'
|
||||
|
||||
Object.defineProperty module.exports, 'Reactionary', get: ->
|
||||
deprecate "Please require `reactionary-atom-fork` instead: `Reactionary = require 'reactionary-atom-fork'`. Add `\"reactionary-atom-fork\": \"^0.9\"` to your package dependencies."
|
||||
require 'reactionary-atom-fork'
|
||||
|
||||
Object.defineProperty module.exports, 'Git', get: ->
|
||||
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
|
||||
module.exports.GitRepository
|
||||
|
||||
Object.defineProperty module.exports, 'EditorView', get: ->
|
||||
deprecate "Please require `TextEditorView` instead of `EditorView`: `{TextEditorView} = require 'atom'`"
|
||||
module.exports.TextEditorView
|
||||
|
||||
+3
-3
@@ -5,7 +5,7 @@
|
||||
'shift-home': 'editor:select-to-first-character-of-line'
|
||||
'shift-end': 'editor:select-to-end-of-line'
|
||||
|
||||
'atom-text-editor:not(.mini)':
|
||||
'atom-text-editor:not([mini])':
|
||||
# Atom Specific
|
||||
'ctrl-C': 'editor:copy-path'
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
|
||||
'.select-list atom-text-editor.mini':
|
||||
'.select-list atom-text-editor[mini]':
|
||||
'enter': 'core:confirm'
|
||||
|
||||
'.tool-panel.panel-left, .tool-panel.panel-right':
|
||||
'escape': 'tool-panel:unfocus'
|
||||
|
||||
'atom-text-editor !important, atom-text-editor.mini !important':
|
||||
'atom-text-editor !important, atom-text-editor[mini] !important':
|
||||
'escape': 'editor:consolidate-selections'
|
||||
|
||||
# allow standard input fields to work correctly
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
'ctrl-alt-cmd-l': 'window:reload'
|
||||
'alt-cmd-i': 'window:toggle-dev-tools'
|
||||
'cmd-alt-ctrl-p': 'window:run-package-specs'
|
||||
'ctrl-shift-left': 'pane:move-item-left'
|
||||
'ctrl-shift-right': 'pane:move-item-right'
|
||||
|
||||
# Sublime Parity
|
||||
'cmd-,': 'application:show-settings'
|
||||
@@ -110,7 +112,7 @@
|
||||
# Apple Specific
|
||||
'cmd-backspace': 'editor:delete-to-beginning-of-line'
|
||||
'cmd-shift-backspace': 'editor:delete-to-beginning-of-line'
|
||||
'cmd-delete': 'editor:delete-to-beginning-of-line'
|
||||
'cmd-delete': 'editor:delete-to-end-of-line'
|
||||
'ctrl-A': 'editor:select-to-first-character-of-line'
|
||||
'ctrl-E': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
@@ -134,7 +136,7 @@
|
||||
'cmd-l': 'editor:select-line'
|
||||
'ctrl-t': 'editor:transpose'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-cmd-z': 'editor:checkout-head-revision'
|
||||
'cmd-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'ctrl-alt-o': 'application:open-dev'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'ctrl-shift-pageup': 'pane:move-item-left'
|
||||
'ctrl-shift-pagedown': 'pane:move-item-right'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
@@ -99,7 +101,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
'ctrl-alt-s': 'application:run-all-specs'
|
||||
'ctrl-alt-o': 'application:open-dev'
|
||||
'ctrl-shift-o': 'application:open-folder'
|
||||
'ctrl-shift-left': 'pane:move-item-left'
|
||||
'ctrl-shift-right': 'pane:move-item-right'
|
||||
'F11': 'window:toggle-full-screen'
|
||||
|
||||
# Sublime Parity
|
||||
@@ -96,7 +98,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
submenu: [
|
||||
{ label: '&Reload', command: 'window:reload' }
|
||||
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
|
||||
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
|
||||
{
|
||||
label: 'Developer'
|
||||
submenu: [
|
||||
|
||||
+6
-2
@@ -93,6 +93,7 @@
|
||||
submenu: [
|
||||
{ label: '&Reload', command: 'window:reload' }
|
||||
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
|
||||
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
|
||||
{
|
||||
label: 'Panes'
|
||||
submenu: [
|
||||
@@ -109,7 +110,7 @@
|
||||
{ label: 'Focus Pane On Left', command: 'window:focus-pane-on-left' }
|
||||
{ label: 'Focus Pane On Right', command: 'window:focus-pane-on-right' }
|
||||
{ type: 'separator' }
|
||||
{ label: 'Close pane', command: 'pane:close' }
|
||||
{ label: 'Close Pane', command: 'pane:close' }
|
||||
]
|
||||
}
|
||||
{
|
||||
@@ -162,7 +163,10 @@
|
||||
submenu: [
|
||||
{ label: 'View &Terms of Use', command: 'application:open-terms-of-use' }
|
||||
{ label: 'View &License', command: 'application:open-license' }
|
||||
{ label: "VERSION", enabled: false }
|
||||
{ label: 'VERSION', enabled: false }
|
||||
{ label: 'Restart and Install Update', command: 'application:install-update', visible: false}
|
||||
{ label: 'Check for Update', command: 'application:check-for-update', visible: false}
|
||||
{ label: 'Downloading Update', enabled: false, visible: false}
|
||||
{ type: 'separator' }
|
||||
{ label: '&Documentation', command: 'application:open-documentation' }
|
||||
{ label: 'Roadmap', command: 'application:open-roadmap' }
|
||||
|
||||
+80
-75
@@ -1,7 +1,7 @@
|
||||
{
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "0.143.0",
|
||||
"version": "0.157.0",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/browser/main.js",
|
||||
"repository": {
|
||||
@@ -17,19 +17,19 @@
|
||||
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"atomShellVersion": "0.19.1",
|
||||
"atomShellVersion": "0.19.4",
|
||||
"dependencies": {
|
||||
"async": "0.2.6",
|
||||
"atom-keymap": "^2.2.2",
|
||||
"atom-keymap": "^2.3.0",
|
||||
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
|
||||
"clear-cut": "0.4.0",
|
||||
"coffee-script": "1.7.0",
|
||||
"coffeestack": "0.7.0",
|
||||
"delegato": "^1",
|
||||
"emissary": "^1.3.1",
|
||||
"event-kit": "0.7.2",
|
||||
"event-kit": "0.8.1",
|
||||
"first-mate": "^2.2.0",
|
||||
"fs-plus": "^2.3.1",
|
||||
"fs-plus": "^2.3.2",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"git-utils": "^2.1.5",
|
||||
@@ -37,13 +37,15 @@
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.17.0",
|
||||
"jquery": "^2.1.1",
|
||||
"less-cache": "0.19.0",
|
||||
"marked": "^0.3",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "^1.0.1",
|
||||
"oniguruma": "^3.0.4",
|
||||
"optimist": "0.4.0",
|
||||
"pathwatcher": "^2.3.2",
|
||||
"pathwatcher": "^2.3.5",
|
||||
"property-accessors": "^1",
|
||||
"q": "^1.0.1",
|
||||
"random-words": "0.0.1",
|
||||
@@ -56,91 +58,94 @@
|
||||
"season": "^1.0.2",
|
||||
"semver": "2.2.1",
|
||||
"serializable": "^1",
|
||||
"space-pen": "3.8.1",
|
||||
"service-hub": "^0.1.0",
|
||||
"space-pen": "3.8.2",
|
||||
"temp": "0.7.0",
|
||||
"text-buffer": "^3.6.0",
|
||||
"text-buffer": "^3.8.2",
|
||||
"theorist": "^1.0.2",
|
||||
"underscore-plus": "^1.6.1",
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.20.0",
|
||||
"atom-dark-ui": "0.35.0",
|
||||
"atom-light-syntax": "0.21.0",
|
||||
"atom-light-ui": "0.30.0",
|
||||
"base16-tomorrow-dark-theme": "0.21.0",
|
||||
"base16-tomorrow-light-theme": "0.4.0",
|
||||
"solarized-dark-syntax": "0.22.0",
|
||||
"solarized-light-syntax": "0.12.0",
|
||||
"archive-view": "0.37.0",
|
||||
"autocomplete": "0.33.0",
|
||||
"autoflow": "0.18.0",
|
||||
"autosave": "0.18.0",
|
||||
"background-tips": "0.17.0",
|
||||
"bookmarks": "0.28.0",
|
||||
"bracket-matcher": "0.62.0",
|
||||
"command-palette": "0.27.0",
|
||||
"deprecation-cop": "0.11.0",
|
||||
"atom-dark-syntax": "0.23.0",
|
||||
"atom-dark-ui": "0.42.0",
|
||||
"atom-light-syntax": "0.22.0",
|
||||
"atom-light-ui": "0.36.0",
|
||||
"base16-tomorrow-dark-theme": "0.22.0",
|
||||
"base16-tomorrow-light-theme": "0.5.0",
|
||||
"solarized-dark-syntax": "0.26.0",
|
||||
"solarized-light-syntax": "0.13.0",
|
||||
"archive-view": "0.40.0",
|
||||
"autocomplete": "0.34.0",
|
||||
"autoflow": "0.19.0",
|
||||
"autosave": "0.19.0",
|
||||
"background-tips": "0.18.0",
|
||||
"bookmarks": "0.31.0",
|
||||
"bracket-matcher": "0.64.0",
|
||||
"command-palette": "0.30.0",
|
||||
"deprecation-cop": "0.18.0",
|
||||
"dev-live-reload": "0.35.0",
|
||||
"encoding-selector": "0.5.0",
|
||||
"exception-reporting": "0.20.0",
|
||||
"find-and-replace": "0.144.0",
|
||||
"fuzzy-finder": "0.60.0",
|
||||
"git-diff": "0.42.0",
|
||||
"go-to-line": "0.26.0",
|
||||
"encoding-selector": "0.10.0",
|
||||
"exception-reporting": "0.21.0",
|
||||
"find-and-replace": "0.152.0",
|
||||
"fuzzy-finder": "0.62.0",
|
||||
"git-diff": "0.45.0",
|
||||
"go-to-line": "0.27.0",
|
||||
"grammar-selector": "0.37.0",
|
||||
"image-view": "0.40.0",
|
||||
"incompatible-packages": "0.10.0",
|
||||
"keybinding-resolver": "0.20.0",
|
||||
"link": "0.26.0",
|
||||
"markdown-preview": "0.109.0",
|
||||
"metrics": "0.38.0",
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.32.0",
|
||||
"image-view": "0.43.0",
|
||||
"incompatible-packages": "0.15.0",
|
||||
"keybinding-resolver": "0.23.0",
|
||||
"link": "0.28.0",
|
||||
"markdown-preview": "0.112.0",
|
||||
"metrics": "0.39.0",
|
||||
"notifications": "0.13.0",
|
||||
"open-on-github": "0.31.0",
|
||||
"package-generator": "0.33.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.155.0",
|
||||
"snippets": "0.56.0",
|
||||
"spell-check": "0.43.0",
|
||||
"status-bar": "0.46.0",
|
||||
"styleguide": "0.30.0",
|
||||
"symbols-view": "0.67.0",
|
||||
"tabs": "0.55.0",
|
||||
"timecop": "0.23.0",
|
||||
"tree-view": "0.132.0",
|
||||
"update-package-dependencies": "0.6.0",
|
||||
"welcome": "0.19.0",
|
||||
"whitespace": "0.26.0",
|
||||
"wrap-guide": "0.23.0",
|
||||
"language-c": "0.30.0",
|
||||
"language-coffee-script": "0.37.0",
|
||||
"language-css": "0.21.0",
|
||||
"language-gfm": "0.53.0",
|
||||
"settings-view": "0.161.0",
|
||||
"snippets": "0.58.0",
|
||||
"spell-check": "0.44.0",
|
||||
"status-bar": "0.53.0",
|
||||
"styleguide": "0.34.0",
|
||||
"symbols-view": "0.70.0",
|
||||
"tabs": "0.57.0",
|
||||
"timecop": "0.24.0",
|
||||
"tree-view": "0.137.0",
|
||||
"update-package-dependencies": "0.7.0",
|
||||
"welcome": "0.21.0",
|
||||
"whitespace": "0.27.0",
|
||||
"wrap-guide": "0.26.0",
|
||||
"language-c": "0.33.0",
|
||||
"language-clojure": "0.9.0",
|
||||
"language-coffee-script": "0.38.1",
|
||||
"language-css": "0.23.1",
|
||||
"language-gfm": "0.55.0",
|
||||
"language-git": "0.9.0",
|
||||
"language-go": "0.19.0",
|
||||
"language-html": "0.26.0",
|
||||
"language-hyperlink": "0.12.0",
|
||||
"language-java": "0.11.0",
|
||||
"language-javascript": "0.43.0",
|
||||
"language-json": "0.8.0",
|
||||
"language-less": "0.18.0",
|
||||
"language-go": "0.19.1",
|
||||
"language-html": "0.26.1",
|
||||
"language-hyperlink": "0.12.2",
|
||||
"language-java": "0.13.0",
|
||||
"language-javascript": "0.48.0",
|
||||
"language-json": "0.10.0",
|
||||
"language-less": "0.21.0",
|
||||
"language-make": "0.12.0",
|
||||
"language-mustache": "0.10.0",
|
||||
"language-objective-c": "0.11.0",
|
||||
"language-mustache": "0.11.0",
|
||||
"language-objective-c": "0.12.0",
|
||||
"language-perl": "0.9.0",
|
||||
"language-php": "0.18.0",
|
||||
"language-property-list": "0.7.0",
|
||||
"language-python": "0.22.0",
|
||||
"language-ruby": "0.41.0",
|
||||
"language-python": "0.26.0",
|
||||
"language-ruby": "0.44.0",
|
||||
"language-ruby-on-rails": "0.18.0",
|
||||
"language-sass": "0.24.0",
|
||||
"language-shellscript": "0.9.0",
|
||||
"language-sass": "0.28.0",
|
||||
"language-shellscript": "0.10.1",
|
||||
"language-source": "0.8.0",
|
||||
"language-sql": "0.11.0",
|
||||
"language-text": "0.6.0",
|
||||
"language-todo": "0.13.0",
|
||||
"language-toml": "0.14.0",
|
||||
"language-xml": "0.24.0",
|
||||
"language-yaml": "0.19.0"
|
||||
"language-todo": "0.14.0",
|
||||
"language-toml": "0.14.1",
|
||||
"language-xml": "0.25.0",
|
||||
"language-yaml": "0.21.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
Package: <%= name %>
|
||||
Version: <%= version %>
|
||||
Depends: python (>= 2.6), libc6
|
||||
Depends: gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
|
||||
Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0
|
||||
Section: <%= section %>
|
||||
Priority: optional
|
||||
Architecture: <%= arch %>
|
||||
|
||||
Arquivo binário não exibido.
|
Depois Largura: | Altura: | Tamanho: 274 KiB |
@@ -34,6 +34,9 @@ exports.safeSpawn = function(command, args, options, callback) {
|
||||
var child = childProcess.spawn(command, args, options);
|
||||
child.stderr.pipe(process.stderr);
|
||||
child.stdout.pipe(process.stdout);
|
||||
child.on('error', function(error) {
|
||||
console.error('Command \'' + command + '\' failed: ' + error.message);
|
||||
});
|
||||
child.on('exit', function(code) {
|
||||
if (code != 0)
|
||||
process.exit(code);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe '"atom" protocol URL', ->
|
||||
it 'sends the file relative in the package as response', ->
|
||||
|
||||
@@ -3,6 +3,7 @@ _ = require 'underscore-plus'
|
||||
{convertStackTrace} = require 'coffeestack'
|
||||
{View, $, $$} = require '../src/space-pen-extensions'
|
||||
grim = require 'grim'
|
||||
marked = require 'marked'
|
||||
|
||||
sourceMaps = {}
|
||||
formatStackTrace = (spec, message='', stackTrace) ->
|
||||
@@ -37,7 +38,8 @@ module.exports =
|
||||
class AtomReporter extends View
|
||||
@content: ->
|
||||
@div class: 'spec-reporter', =>
|
||||
@div outlet: "suites"
|
||||
@div class: 'padded pull-right', =>
|
||||
@button outlet: 'reloadButton', class: 'btn btn-small reload-button', 'Reload Specs'
|
||||
@div outlet: 'coreArea', class: 'symbol-area', =>
|
||||
@div outlet: 'coreHeader', class: 'symbol-header'
|
||||
@ul outlet: 'coreSummary', class: 'symbol-summary list-unstyled'
|
||||
@@ -79,6 +81,8 @@ class AtomReporter extends View
|
||||
@on 'click', '.stack-trace', ->
|
||||
$(this).toggleClass('expanded')
|
||||
|
||||
@reloadButton.on 'click', -> require('ipc').send('call-window-method', 'restart')
|
||||
|
||||
reportRunnerResults: (runner) ->
|
||||
@updateSpecCounts()
|
||||
@status.addClass('alert-success').removeClass('alert-info') if @failedCount is 0
|
||||
@@ -110,7 +114,8 @@ class AtomReporter extends View
|
||||
for deprecation in deprecations
|
||||
@deprecationList.append $$ ->
|
||||
@div class: 'padded', =>
|
||||
@div class: 'result-message fail deprecation-message', deprecation.message
|
||||
@div class: 'result-message fail deprecation-message', =>
|
||||
@raw marked(deprecation.message)
|
||||
|
||||
for stack in deprecation.stacks
|
||||
fullStack = stack.map ({functionName, location}) ->
|
||||
|
||||
+82
-10
@@ -1,13 +1,10 @@
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
Exec = require('child_process').exec
|
||||
path = require 'path'
|
||||
Package = require '../src/package'
|
||||
ThemeManager = require '../src/theme-manager'
|
||||
|
||||
describe "the `atom` global", ->
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
|
||||
describe 'window sizing methods', ->
|
||||
describe '::getPosition and ::setPosition', ->
|
||||
it 'sets the position of the window, and can retrieve the position just set', ->
|
||||
@@ -33,10 +30,16 @@ describe "the `atom` global", ->
|
||||
version = '36b5518'
|
||||
expect(atom.isReleasedVersion()).toBe false
|
||||
|
||||
describe "window:update-available", ->
|
||||
it "is triggered when the auto-updater sends the update-downloaded event", ->
|
||||
describe "when an update becomes available", ->
|
||||
subscription = null
|
||||
|
||||
afterEach ->
|
||||
subscription?.dispose()
|
||||
|
||||
it "invokes onUpdateAvailable listeners", ->
|
||||
updateAvailableHandler = jasmine.createSpy("update-available-handler")
|
||||
atom.workspaceView.on 'window:update-available', updateAvailableHandler
|
||||
subscription = atom.onUpdateAvailable updateAvailableHandler
|
||||
|
||||
autoUpdater = require('remote').require('auto-updater')
|
||||
autoUpdater.emit 'update-downloaded', null, "notes", "version"
|
||||
|
||||
@@ -44,11 +47,80 @@ describe "the `atom` global", ->
|
||||
updateAvailableHandler.callCount > 0
|
||||
|
||||
runs ->
|
||||
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
|
||||
expect(notes).toBe 'notes'
|
||||
expect(version).toBe 'version'
|
||||
{releaseVersion, releaseNotes} = updateAvailableHandler.mostRecentCall.args[0]
|
||||
expect(releaseVersion).toBe 'version'
|
||||
expect(releaseNotes).toBe 'notes'
|
||||
|
||||
describe "loading default config", ->
|
||||
it 'loads the default core config', ->
|
||||
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
|
||||
describe "window onerror handler", ->
|
||||
beforeEach ->
|
||||
spyOn atom, 'openDevTools'
|
||||
spyOn atom, 'executeJavaScriptInDevTools'
|
||||
|
||||
it "will open the dev tools when an error is triggered", ->
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
|
||||
expect(atom.openDevTools).toHaveBeenCalled()
|
||||
expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled()
|
||||
|
||||
describe "::onWillThrowError", ->
|
||||
willThrowSpy = null
|
||||
beforeEach ->
|
||||
willThrowSpy = jasmine.createSpy()
|
||||
|
||||
it "is called when there is an error", ->
|
||||
error = null
|
||||
atom.onWillThrowError(willThrowSpy)
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
error = e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
|
||||
delete willThrowSpy.mostRecentCall.args[0].preventDefault
|
||||
expect(willThrowSpy).toHaveBeenCalledWith
|
||||
message: error.toString()
|
||||
url: 'abc'
|
||||
line: 2
|
||||
column: 3
|
||||
originalError: error
|
||||
|
||||
it "will not show the devtools when preventDefault() is called", ->
|
||||
willThrowSpy.andCallFake (errorObject) -> errorObject.preventDefault()
|
||||
atom.onWillThrowError(willThrowSpy)
|
||||
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
|
||||
expect(willThrowSpy).toHaveBeenCalled()
|
||||
expect(atom.openDevTools).not.toHaveBeenCalled()
|
||||
expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled()
|
||||
|
||||
describe "::onDidThrowError", ->
|
||||
didThrowSpy = null
|
||||
beforeEach ->
|
||||
didThrowSpy = jasmine.createSpy()
|
||||
|
||||
it "is called when there is an error", ->
|
||||
error = null
|
||||
atom.onDidThrowError(didThrowSpy)
|
||||
try
|
||||
a + 1
|
||||
catch e
|
||||
error = e
|
||||
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
|
||||
expect(didThrowSpy).toHaveBeenCalledWith
|
||||
message: error.toString()
|
||||
url: 'abc'
|
||||
line: 2
|
||||
column: 3
|
||||
originalError: error
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
BufferedProcess = require '../src/buffered-process'
|
||||
|
||||
describe "BufferedProcess", ->
|
||||
describe "when a bad command is specified", ->
|
||||
[oldOnError] = []
|
||||
beforeEach ->
|
||||
oldOnError = window.onerror
|
||||
window.onerror = jasmine.createSpy()
|
||||
|
||||
afterEach ->
|
||||
window.onerror = oldOnError
|
||||
|
||||
describe "when there is an error handler specified", ->
|
||||
it "calls the error handler and does not throw an exception", ->
|
||||
process = new BufferedProcess
|
||||
command: 'bad-command-nope'
|
||||
args: ['nothing']
|
||||
options: {}
|
||||
|
||||
errorSpy = jasmine.createSpy().andCallFake (error) -> error.handle()
|
||||
process.onWillThrowError(errorSpy)
|
||||
|
||||
waitsFor -> errorSpy.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(window.onerror).not.toHaveBeenCalled()
|
||||
expect(errorSpy).toHaveBeenCalled()
|
||||
expect(errorSpy.mostRecentCall.args[0].error.message).toContain 'spawn bad-command-nope ENOENT'
|
||||
|
||||
describe "when there is not an error handler specified", ->
|
||||
it "calls the error handler and does not throw an exception", ->
|
||||
process = new BufferedProcess
|
||||
command: 'bad-command-nope'
|
||||
args: ['nothing']
|
||||
options: {}
|
||||
|
||||
waitsFor -> window.onerror.callCount > 0
|
||||
|
||||
runs ->
|
||||
expect(window.onerror).toHaveBeenCalled()
|
||||
expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope`'
|
||||
expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError'
|
||||
@@ -1,4 +1,5 @@
|
||||
CommandRegistry = require '../src/command-registry'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
describe "CommandRegistry", ->
|
||||
[registry, parent, child, grandchild] = []
|
||||
@@ -154,8 +155,15 @@ describe "CommandRegistry", ->
|
||||
registry.add '.grandchild', 'namespace:command-3', ->
|
||||
registry.add '.grandchild.no-match', 'namespace:command-4', ->
|
||||
|
||||
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
|
||||
registry.add grandchild, 'namespace:inline-command-1', ->
|
||||
registry.add child, 'namespace:inline-command-2', ->
|
||||
|
||||
commands = registry.findCommands(target: grandchild)
|
||||
nonJqueryCommands = _.reject commands, (cmd) -> cmd.jQuery
|
||||
expect(nonJqueryCommands).toEqual [
|
||||
{name: 'namespace:inline-command-1', displayName: 'Namespace: Inline Command 1'}
|
||||
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
|
||||
{name: 'namespace:inline-command-2', displayName: 'Namespace: Inline Command 2'}
|
||||
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
|
||||
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
|
||||
]
|
||||
|
||||
@@ -128,6 +128,12 @@ describe "Config", ->
|
||||
expect(atom.config.get("foo")).toEqual 'a\\.b': 1, b: 2
|
||||
|
||||
describe ".toggle(keyPath)", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "negates the boolean value of the current key path value", ->
|
||||
atom.config.set('foo.a', 1)
|
||||
atom.config.toggle('foo.a')
|
||||
@@ -195,6 +201,52 @@ describe "Config", ->
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.save.callCount).toBe 1
|
||||
|
||||
it "does not call ::save or add a scoped property when no value has been set", ->
|
||||
# see https://github.com/atom/atom/issues/4175
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
|
||||
|
||||
expect(atom.config.save).not.toHaveBeenCalled()
|
||||
|
||||
scopedProperties = atom.config.scopedSettingsStore.propertiesForSource('user-config')
|
||||
expect(scopedProperties['.coffee.source']).toBeUndefined()
|
||||
|
||||
it "removes the scoped value when it was the only set value on the object", ->
|
||||
spyOn(CSON, 'writeFileSync')
|
||||
jasmine.unspy atom.config, 'save'
|
||||
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
atom.config.set('.source.coffee', 'foo.bar.zfoo', 20)
|
||||
CSON.writeFileSync.reset()
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
|
||||
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.zfoo')).toBe 20
|
||||
expect(CSON.writeFileSync).toHaveBeenCalled()
|
||||
properties = CSON.writeFileSync.mostRecentCall.args[1]
|
||||
expect(properties['.coffee.source']).toEqual
|
||||
foo:
|
||||
bar:
|
||||
zfoo: 20
|
||||
|
||||
CSON.writeFileSync.reset()
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.zfoo')
|
||||
expect(CSON.writeFileSync).toHaveBeenCalled()
|
||||
properties = CSON.writeFileSync.mostRecentCall.args[1]
|
||||
expect(properties['.coffee.source']).toBeUndefined()
|
||||
|
||||
it "does not call ::save when the value is already at the default", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
|
||||
atom.config.save.reset()
|
||||
|
||||
atom.config.restoreDefault('.source.coffee', 'foo.bar.ok')
|
||||
expect(atom.config.save).not.toHaveBeenCalled()
|
||||
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
|
||||
|
||||
describe ".getSettings()", ->
|
||||
it "returns all settings including defaults", ->
|
||||
atom.config.setDefaults("foo", bar: baz: 10)
|
||||
@@ -252,6 +304,12 @@ describe "Config", ->
|
||||
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
|
||||
|
||||
describe ".getPositiveInt(keyPath, defaultValue)", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "returns the proper coerced value", ->
|
||||
atom.config.set('editor.preferredLineLength', 0)
|
||||
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
|
||||
@@ -424,7 +482,7 @@ describe "Config", ->
|
||||
|
||||
it "does not fire the callback once the observe subscription is off'ed", ->
|
||||
observeHandler.reset() # clear the initial call
|
||||
observeSubscription.off()
|
||||
observeSubscription.dispose()
|
||||
atom.config.set('foo.bar.baz', "value 2")
|
||||
expect(observeHandler).not.toHaveBeenCalled()
|
||||
|
||||
@@ -508,11 +566,13 @@ describe "Config", ->
|
||||
describe "when the config file contains invalid cson", ->
|
||||
beforeEach ->
|
||||
spyOn(console, 'error')
|
||||
spyOn(atom.notifications, 'addError')
|
||||
fs.writeFileSync(atom.config.configFilePath, "{{{{{")
|
||||
|
||||
it "logs an error to the console and does not overwrite the config file on a subsequent save", ->
|
||||
atom.config.loadUserConfig()
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
expect(atom.notifications.addError.callCount).toBe 1
|
||||
atom.config.set("hair", "blonde") # trigger a save
|
||||
expect(atom.config.save).not.toHaveBeenCalled()
|
||||
|
||||
@@ -646,7 +706,6 @@ describe "Config", ->
|
||||
expect(atom.config.get(['.source.ruby'], 'foo.bar')).toBe 'baz'
|
||||
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe true
|
||||
|
||||
|
||||
describe "when the config file changes to omit a setting with a default", ->
|
||||
it "resets the setting back to the default", ->
|
||||
fs.writeFileSync(atom.config.configFilePath, "foo: { baz: 'new'}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$$} = require 'atom'
|
||||
{$$} = require '../src/space-pen-extensions'
|
||||
|
||||
ContextMenuManager = require '../src/context-menu-manager'
|
||||
|
||||
@@ -151,24 +151,31 @@ describe "ContextMenuManager", ->
|
||||
shouldDisplay = false
|
||||
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
|
||||
|
||||
it "allows items to be specified in the legacy format for now", ->
|
||||
contextMenu.add '.parent':
|
||||
'A': 'a'
|
||||
'Separator 1': '-'
|
||||
'B':
|
||||
'C': 'c'
|
||||
'Separator 2': '-'
|
||||
'D': 'd'
|
||||
describe "when the menus are specified in a legacy format", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
expect(contextMenu.templateForElement(parent)).toEqual [
|
||||
{label: 'A', command: 'a'}
|
||||
{type: 'separator'}
|
||||
{
|
||||
label: 'B'
|
||||
submenu: [
|
||||
{label: 'C', command: 'c'}
|
||||
{type: 'separator'}
|
||||
{label: 'D', command: 'd'}
|
||||
]
|
||||
}
|
||||
]
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "allows items to be specified in the legacy format for now", ->
|
||||
contextMenu.add '.parent':
|
||||
'A': 'a'
|
||||
'Separator 1': '-'
|
||||
'B':
|
||||
'C': 'c'
|
||||
'Separator 2': '-'
|
||||
'D': 'd'
|
||||
|
||||
expect(contextMenu.templateForElement(parent)).toEqual [
|
||||
{label: 'A', command: 'a'}
|
||||
{type: 'separator'}
|
||||
{
|
||||
label: 'B'
|
||||
submenu: [
|
||||
{label: 'C', command: 'c'}
|
||||
{type: 'separator'}
|
||||
{label: 'D', command: 'd'}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1085,6 +1085,12 @@ describe "DisplayBuffer", ->
|
||||
expect(oldProperties).toEqual decorationProperties
|
||||
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
|
||||
|
||||
describe "::getDecorations(properties)", ->
|
||||
it "returns decorations matching the given optional properties", ->
|
||||
expect(displayBuffer.getDecorations()).toEqual [decoration]
|
||||
expect(displayBuffer.getDecorations(class: 'two').length).toEqual 0
|
||||
expect(displayBuffer.getDecorations(class: 'one').length).toEqual 1
|
||||
|
||||
describe "::setScrollTop", ->
|
||||
beforeEach ->
|
||||
displayBuffer.manageScrollPosition = true
|
||||
|
||||
@@ -9,5 +9,6 @@ module.exports =
|
||||
atom.commands.add 'atom-workspace', 'activation-command', =>
|
||||
@activationCommandCallCount++
|
||||
|
||||
atom.workspaceView.getActiveView()?.command 'activation-command', =>
|
||||
editorView = atom.views.getView(atom.workspace.getActiveTextEditor())?.__spacePenView
|
||||
editorView?.command 'activation-command', =>
|
||||
@legacyActivationCommandCallCount++
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1':
|
||||
'Menu item 1': 'command-1'
|
||||
'.test-1': [
|
||||
{label: 'Menu item 1', command: 'command-1'}
|
||||
]
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
]
|
||||
|
||||
'context-menu':
|
||||
'.test-1':
|
||||
'Menu item 2': 'command-2'
|
||||
'.test-1': [
|
||||
{label: 'Menu item 2', command: 'command-2'}
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'context-menu':
|
||||
'.test-1':
|
||||
'Menu item 3': 'command-3'
|
||||
'.test-1': [
|
||||
{label: 'Menu item 3', command: 'command-3'}
|
||||
]
|
||||
|
||||
+3
@@ -1,3 +1,6 @@
|
||||
'.source.omg':
|
||||
'editor':
|
||||
'increaseIndentPattern': '^a'
|
||||
'decreaseIndentPattern': '^z'
|
||||
'commentStart': '/*'
|
||||
'commentEnd': '*/'
|
||||
|
||||
@@ -132,7 +132,7 @@ describe "GitRepository", ->
|
||||
atom.workspace.open(filePath)
|
||||
|
||||
runs ->
|
||||
editor = atom.workspace.getActiveEditor()
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
|
||||
it "displays a confirmation dialog by default", ->
|
||||
spyOn(atom, 'confirm').andCallFake ({buttons}) -> buttons.OK()
|
||||
|
||||
@@ -96,12 +96,13 @@ describe "LanguageMode", ->
|
||||
buffer.setText("//this is a single line comment")
|
||||
expect(languageMode.rowRangeForCommentAtBufferRow(0)).toBeUndefined()
|
||||
|
||||
describe "suggestedIndentForBufferRow", ->
|
||||
it "returns the suggested indentation based on auto-indent/outdent rules", ->
|
||||
describe ".suggestedIndentForBufferRow", ->
|
||||
it "bases indentation off of the previous non-blank line", ->
|
||||
expect(languageMode.suggestedIndentForBufferRow(0)).toBe 0
|
||||
expect(languageMode.suggestedIndentForBufferRow(1)).toBe 1
|
||||
expect(languageMode.suggestedIndentForBufferRow(2)).toBe 2
|
||||
expect(languageMode.suggestedIndentForBufferRow(9)).toBe 1
|
||||
expect(languageMode.suggestedIndentForBufferRow(11)).toBe 1
|
||||
|
||||
describe "rowRangeForParagraphAtBufferRow", ->
|
||||
describe "with code and comments", ->
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
NotificationManager = require '../src/notification-manager'
|
||||
|
||||
describe "NotificationManager", ->
|
||||
[manager] = []
|
||||
|
||||
beforeEach ->
|
||||
manager = new NotificationManager
|
||||
|
||||
describe "the atom global", ->
|
||||
it "has a notifications instance", ->
|
||||
expect(atom.notifications instanceof NotificationManager).toBe true
|
||||
|
||||
describe "adding events", ->
|
||||
addSpy = null
|
||||
|
||||
beforeEach ->
|
||||
addSpy = jasmine.createSpy()
|
||||
manager.onDidAddNotification(addSpy)
|
||||
|
||||
it "emits an event when a notification has been added", ->
|
||||
manager.add('error', 'Some error!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'error'
|
||||
expect(notification.getMessage()).toBe 'Some error!'
|
||||
expect(notification.getIcon()).toBe 'someIcon'
|
||||
|
||||
it "emits a fatal error ::addFatalError has been called", ->
|
||||
manager.addFatalError('Some error!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'fatal'
|
||||
|
||||
it "emits an error ::addError has been called", ->
|
||||
manager.addError('Some error!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'error'
|
||||
|
||||
it "emits a warning notification ::addWarning has been called", ->
|
||||
manager.addWarning('Something!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'warning'
|
||||
|
||||
it "emits an info notification ::addInfo has been called", ->
|
||||
manager.addInfo('Something!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'info'
|
||||
|
||||
it "emits a success notification ::addSuccess has been called", ->
|
||||
manager.addSuccess('Something!', icon: 'someIcon')
|
||||
expect(addSpy).toHaveBeenCalled()
|
||||
notification = addSpy.mostRecentCall.args[0]
|
||||
expect(notification.getType()).toBe 'success'
|
||||
@@ -0,0 +1,47 @@
|
||||
Notification = require '../src/notification'
|
||||
|
||||
describe "Notification", ->
|
||||
[notification] = []
|
||||
|
||||
describe "::getTimestamp()", ->
|
||||
it "returns a Date object", ->
|
||||
notification = new Notification('error', 'message!')
|
||||
expect(notification.getTimestamp() instanceof Date).toBe true
|
||||
|
||||
describe "::getIcon()", ->
|
||||
it "returns a default when no icon specified", ->
|
||||
notification = new Notification('error', 'message!')
|
||||
expect(notification.getIcon()).toBe 'flame'
|
||||
|
||||
it "returns the icon specified", ->
|
||||
notification = new Notification('error', 'message!', icon: 'my-icon')
|
||||
expect(notification.getIcon()).toBe 'my-icon'
|
||||
|
||||
describe "dismissing notifications", ->
|
||||
describe "when the notfication is dismissable", ->
|
||||
it "calls a callback when the notification is dismissed", ->
|
||||
dismissedSpy = jasmine.createSpy()
|
||||
notification = new Notification('error', 'message', dismissable: true)
|
||||
notification.onDidDismiss dismissedSpy
|
||||
|
||||
expect(notification.isDismissable()).toBe true
|
||||
expect(notification.isDismissed()).toBe false
|
||||
|
||||
notification.dismiss()
|
||||
|
||||
expect(dismissedSpy).toHaveBeenCalled()
|
||||
expect(notification.isDismissed()).toBe true
|
||||
|
||||
describe "when the notfication is not dismissable", ->
|
||||
it "does nothing when ::dismiss() is called", ->
|
||||
dismissedSpy = jasmine.createSpy()
|
||||
notification = new Notification('error', 'message')
|
||||
notification.onDidDismiss dismissedSpy
|
||||
|
||||
expect(notification.isDismissable()).toBe false
|
||||
expect(notification.isDismissed()).toBe true
|
||||
|
||||
notification.dismiss()
|
||||
|
||||
expect(dismissedSpy).not.toHaveBeenCalled()
|
||||
expect(notification.isDismissed()).toBe true
|
||||
@@ -1,9 +1,12 @@
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
Grim = require 'grim'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
Package = require '../src/package'
|
||||
|
||||
describe "PackageManager", ->
|
||||
workspaceElement = null
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
spyOn(Grim, 'deprecate') # suppress deprecation warnings due to comment strings
|
||||
|
||||
describe "::loadPackage(name)", ->
|
||||
it "continues if the package has an invalid package.json", ->
|
||||
@@ -97,21 +100,29 @@ describe "PackageManager", ->
|
||||
expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true
|
||||
expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10
|
||||
|
||||
it "still assigns configDefaults from the module though deprecated", ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
describe "when a package has configDefaults", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
it "still assigns configDefaults from the module though deprecated", ->
|
||||
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('package-with-config-defaults')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
|
||||
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
|
||||
|
||||
describe "when the package metadata includes `activationCommands`", ->
|
||||
[mainModule, promise, workspaceCommandListener] = []
|
||||
|
||||
beforeEach ->
|
||||
atom.workspaceView.attachToDom()
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
mainModule = require './fixtures/packages/package-with-activation-commands/index'
|
||||
mainModule.legacyActivationCommandCallCount = 0
|
||||
mainModule.activationCommandCallCount = 0
|
||||
@@ -125,29 +136,29 @@ describe "PackageManager", ->
|
||||
|
||||
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
|
||||
expect(promise.isFulfilled()).not.toBeTruthy()
|
||||
atom.workspaceView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
workspaceElement.dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
|
||||
waitsForPromise ->
|
||||
promise
|
||||
|
||||
it "triggers the activation event on all handlers registered during activation", ->
|
||||
waitsForPromise ->
|
||||
atom.workspaceView.open()
|
||||
atom.workspace.open()
|
||||
|
||||
runs ->
|
||||
editorView = atom.workspaceView.getActiveView()
|
||||
editorView = atom.views.getView(atom.workspace.getActiveTextEditor()).__spacePenView
|
||||
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
|
||||
editorView.command 'activation-command', legacyCommandListener
|
||||
editorCommandListener = jasmine.createSpy("editorCommandListener")
|
||||
atom.commands.add 'atom-text-editor', 'activation-command', editorCommandListener
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
atom.commands.dispatch(editorView[0], 'activation-command')
|
||||
expect(mainModule.activate.callCount).toBe 1
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 1
|
||||
expect(mainModule.activationCommandCallCount).toBe 1
|
||||
expect(legacyCommandListener.callCount).toBe 1
|
||||
expect(editorCommandListener.callCount).toBe 1
|
||||
expect(workspaceCommandListener.callCount).toBe 1
|
||||
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
|
||||
atom.commands.dispatch(editorView[0], 'activation-command')
|
||||
expect(mainModule.legacyActivationCommandCallCount).toBe 2
|
||||
expect(mainModule.activationCommandCallCount).toBe 2
|
||||
expect(legacyCommandListener.callCount).toBe 2
|
||||
@@ -294,16 +305,18 @@ describe "PackageManager", ->
|
||||
it "loads all stylesheets from the stylesheets directory", ->
|
||||
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
|
||||
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
|
||||
|
||||
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.test-context.css")
|
||||
four = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/4.css")
|
||||
|
||||
one = atom.themes.stringToId(one)
|
||||
two = atom.themes.stringToId(two)
|
||||
three = atom.themes.stringToId(three)
|
||||
four = atom.themes.stringToId(four)
|
||||
|
||||
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(four)).toBeNull()
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
@@ -312,6 +325,7 @@ describe "PackageManager", ->
|
||||
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
|
||||
expect(atom.themes.stylesheetElementForId(four)).not.toBeNull()
|
||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||
|
||||
it "assigns the stylesheet's context based on the filename", ->
|
||||
@@ -319,8 +333,26 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage("package-with-stylesheets")
|
||||
|
||||
runs ->
|
||||
element = atom.styles.getStyleElements().find (element) -> element.context is 'test-context'
|
||||
expect(element).toBeDefined()
|
||||
count = 0
|
||||
|
||||
for styleElement in atom.styles.getStyleElements()
|
||||
if styleElement.sourcePath.match /1.css/
|
||||
expect(styleElement.context).toBe undefined
|
||||
count++
|
||||
|
||||
if styleElement.sourcePath.match /2.less/
|
||||
expect(styleElement.context).toBe undefined
|
||||
count++
|
||||
|
||||
if styleElement.sourcePath.match /3.test-context.css/
|
||||
expect(styleElement.context).toBe 'test-context'
|
||||
count++
|
||||
|
||||
if styleElement.sourcePath.match /4.css/
|
||||
expect(styleElement.context).toBe undefined
|
||||
count++
|
||||
|
||||
expect(count).toBe 4
|
||||
|
||||
describe "grammar loading", ->
|
||||
it "loads the package's grammars", ->
|
||||
@@ -328,8 +360,8 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage('package-with-grammars')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Alot'
|
||||
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Alittle'
|
||||
|
||||
describe "scoped-property loading", ->
|
||||
it "loads the scoped properties", ->
|
||||
@@ -337,17 +369,41 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
expect(atom.config.get ['.source.omg'], 'editor.indent.increasePattern').toBe '^a'
|
||||
|
||||
it "combines 'editor.commentStart' and 'editor.commentEnd' strings under the 'editor.comment' key path", ->
|
||||
if atom.packages.isPackageLoaded("package-with-scoped-properties")
|
||||
atom.packages.unloadPackage("package-with-scoped-properties")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get ['.source.omg'], 'editor.comment.start').toBe '/*'
|
||||
expect(atom.config.get ['.source.omg'], 'editor.comment.end').toBe '*/'
|
||||
expect(Grim.deprecate).toHaveBeenCalled()
|
||||
|
||||
it "combines 'editor.increaseIndentPattern' and 'editor.decreaseIndentPattern' strings under the 'editor.indent' key path", ->
|
||||
if atom.packages.isPackageLoaded("package-with-scoped-properties")
|
||||
atom.packages.unloadPackage("package-with-scoped-properties")
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get ['.source.omg'], 'editor.indent.increasePattern').toBe '^a'
|
||||
expect(atom.config.get ['.source.omg'], 'editor.indent.decreasePattern').toBe '^z'
|
||||
expect(Grim.deprecate).toHaveBeenCalled()
|
||||
|
||||
describe "converted textmate packages", ->
|
||||
it "loads the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
|
||||
it "loads the translated scoped properties", ->
|
||||
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
|
||||
@@ -356,7 +412,7 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBe '# '
|
||||
expect(atom.config.get(['.source.ruby'], 'editor.comment.start')).toBe '# '
|
||||
|
||||
describe "::deactivatePackage(id)", ->
|
||||
afterEach ->
|
||||
@@ -433,8 +489,8 @@ describe "PackageManager", ->
|
||||
|
||||
runs ->
|
||||
atom.packages.deactivatePackage('package-with-grammars')
|
||||
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Null Grammar'
|
||||
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Null Grammar'
|
||||
|
||||
it "removes the package's keymaps", ->
|
||||
waitsForPromise ->
|
||||
@@ -463,21 +519,21 @@ describe "PackageManager", ->
|
||||
atom.packages.activatePackage("package-with-scoped-properties")
|
||||
|
||||
runs ->
|
||||
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBe '^a'
|
||||
expect(atom.config.get ['.source.omg'], 'editor.indent.increasePattern').toBe '^a'
|
||||
atom.packages.deactivatePackage("package-with-scoped-properties")
|
||||
expect(atom.config.get ['.source.omg'], 'editor.increaseIndentPattern').toBeUndefined()
|
||||
expect(atom.config.get ['.source.omg'], 'editor.indent.increasePattern').toBeUndefined()
|
||||
|
||||
describe "textmate packages", ->
|
||||
it "removes the package's grammars", ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-ruby')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
|
||||
atom.packages.deactivatePackage('language-ruby')
|
||||
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
|
||||
|
||||
it "removes the package's scoped properties", ->
|
||||
waitsForPromise ->
|
||||
@@ -492,6 +548,7 @@ describe "PackageManager", ->
|
||||
themeActivator = null
|
||||
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
spyOn(console, 'warn')
|
||||
atom.packages.loadPackages()
|
||||
|
||||
@@ -505,8 +562,9 @@ describe "PackageManager", ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
Syntax = require '../src/syntax'
|
||||
atom.syntax = window.syntax = new Syntax()
|
||||
GrammarRegistry = require '../src/grammar-registry'
|
||||
atom.grammars = window.syntax = new GrammarRegistry()
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "activates all the packages, and none of the themes", ->
|
||||
atom.packages.activate()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$} = require 'atom'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
Package = require '../src/package'
|
||||
ThemePackage = require '../src/theme-package'
|
||||
|
||||
@@ -33,6 +33,13 @@ describe "PaneContainer", ->
|
||||
[pane1B, pane2B, pane3B] = containerB.getPanes()
|
||||
expect(containerB.getActivePane()).toBe pane3B
|
||||
|
||||
it "makes the first pane active if no pane exists for the activePaneId", ->
|
||||
pane3A.activate()
|
||||
state = containerA.serialize()
|
||||
state.activePaneId = -22
|
||||
containerB = atom.deserializers.deserialize(state)
|
||||
expect(containerB.getActivePane()).toBe containerB.getPanes()[0]
|
||||
|
||||
it "does not allow the root pane to be destroyed", ->
|
||||
container = new PaneContainer
|
||||
container.getRoot().destroy()
|
||||
@@ -141,3 +148,57 @@ describe "PaneContainer", ->
|
||||
saved = container.confirmClose()
|
||||
expect(saved).toBeFalsy()
|
||||
expect(atom.confirm).toHaveBeenCalled()
|
||||
|
||||
describe "::onDidAddPane(callback)", ->
|
||||
it "invokes the given callback when panes are added", ->
|
||||
container = new PaneContainer
|
||||
events = []
|
||||
container.onDidAddPane (event) -> events.push(event)
|
||||
|
||||
pane1 = container.getActivePane()
|
||||
pane2 = pane1.splitRight()
|
||||
pane3 = pane2.splitDown()
|
||||
|
||||
expect(events).toEqual [{pane: pane2}, {pane: pane3}]
|
||||
|
||||
describe "::onDidDestroyPane(callback)", ->
|
||||
it "invokes the given callback when panes are destroyed", ->
|
||||
container = new PaneContainer
|
||||
events = []
|
||||
container.onDidDestroyPane (event) -> events.push(event)
|
||||
|
||||
pane1 = container.getActivePane()
|
||||
pane2 = pane1.splitRight()
|
||||
pane3 = pane2.splitDown()
|
||||
|
||||
pane2.destroy()
|
||||
pane3.destroy()
|
||||
|
||||
expect(events).toEqual [{pane: pane2}, {pane: pane3}]
|
||||
|
||||
describe "::onWillDestroyPaneItem() and ::onDidDestroyPaneItem", ->
|
||||
it "invokes the given callbacks when an item will be destroyed on any pane", ->
|
||||
container = new PaneContainer
|
||||
pane1 = container.getRoot()
|
||||
item1 = new Object
|
||||
item2 = new Object
|
||||
item3 = new Object
|
||||
|
||||
pane1.addItem(item1)
|
||||
events = []
|
||||
container.onWillDestroyPaneItem (event) -> events.push(['will', event])
|
||||
container.onDidDestroyPaneItem (event) -> events.push(['did', event])
|
||||
pane2 = pane1.splitRight(items: [item2, item3])
|
||||
|
||||
pane1.destroyItem(item1)
|
||||
pane2.destroyItem(item3)
|
||||
pane2.destroyItem(item2)
|
||||
|
||||
expect(events).toEqual [
|
||||
['will', {item: item1, pane: pane1, index: 0}]
|
||||
['did', {item: item1, pane: pane1, index: 0}]
|
||||
['will', {item: item3, pane: pane2, index: 1}]
|
||||
['did', {item: item3, pane: pane2, index: 1}]
|
||||
['will', {item: item2, pane: pane2, index: 0}]
|
||||
['did', {item: item2, pane: pane2, index: 0}]
|
||||
]
|
||||
|
||||
@@ -3,7 +3,8 @@ temp = require 'temp'
|
||||
PaneContainer = require '../src/pane-container'
|
||||
PaneContainerView = require '../src/pane-container-view'
|
||||
PaneView = require '../src/pane-view'
|
||||
{$, View, $$} = require 'atom'
|
||||
{Disposable} = require 'event-kit'
|
||||
{$, View, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "PaneContainerView", ->
|
||||
[TestView, container, pane1, pane2, pane3, deserializerDisposable] = []
|
||||
@@ -18,6 +19,8 @@ describe "PaneContainerView", ->
|
||||
getUri: -> path.join(temp.dir, @name)
|
||||
save: -> @saved = true
|
||||
isEqual: (other) -> @name is other?.name
|
||||
onDidChangeTitle: -> new Disposable(->)
|
||||
onDidChangeModified: -> new Disposable(->)
|
||||
|
||||
container = atom.views.getView(atom.workspace.paneContainer).__spacePenView
|
||||
pane1 = container.getRoot()
|
||||
|
||||
@@ -146,6 +146,24 @@ describe "Pane", ->
|
||||
pane.activateNextItem()
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
|
||||
describe "::moveItemRight() and ::moveItemLeft()", ->
|
||||
it "moves the active item to the right and left, without looping around at either end", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
[item1, item2, item3] = pane.getItems()
|
||||
|
||||
pane.activateItemAtIndex(0)
|
||||
expect(pane.getActiveItem()).toBe item1
|
||||
pane.moveItemLeft()
|
||||
expect(pane.getItems()).toEqual [item1, item2, item3]
|
||||
pane.moveItemRight()
|
||||
expect(pane.getItems()).toEqual [item2, item1, item3]
|
||||
pane.moveItemLeft()
|
||||
expect(pane.getItems()).toEqual [item1, item2, item3]
|
||||
pane.activateItemAtIndex(2)
|
||||
expect(pane.getActiveItem()).toBe item3
|
||||
pane.moveItemRight()
|
||||
expect(pane.getItems()).toEqual [item1, item2, item3]
|
||||
|
||||
describe "::activateItemAtIndex(index)", ->
|
||||
it "activates the item at the given index", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
|
||||
@@ -565,6 +583,37 @@ describe "Pane", ->
|
||||
expect(pane1.isActive()).toBe false
|
||||
expect(pane2.isActive()).toBe true
|
||||
|
||||
describe "::close()", ->
|
||||
it "prompts to save unsaved items before destroying the pane", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
[item1, item2] = pane.getItems()
|
||||
|
||||
item1.shouldPromptToSave = -> true
|
||||
item1.getUri = -> "/test/path"
|
||||
item1.save = jasmine.createSpy("save")
|
||||
|
||||
spyOn(atom, 'confirm').andReturn(0)
|
||||
pane.close()
|
||||
|
||||
expect(atom.confirm).toHaveBeenCalled()
|
||||
expect(item1.save).toHaveBeenCalled()
|
||||
expect(pane.isDestroyed()).toBe true
|
||||
|
||||
it "does not destroy the pane if cancel is called", ->
|
||||
pane = new Pane(items: [new Item("A"), new Item("B")])
|
||||
[item1, item2] = pane.getItems()
|
||||
|
||||
item1.shouldPromptToSave = -> true
|
||||
item1.getUri = -> "/test/path"
|
||||
item1.save = jasmine.createSpy("save")
|
||||
|
||||
spyOn(atom, 'confirm').andReturn(1)
|
||||
pane.close()
|
||||
|
||||
expect(atom.confirm).toHaveBeenCalled()
|
||||
expect(item1.save).not.toHaveBeenCalled()
|
||||
expect(pane.isDestroyed()).toBe false
|
||||
|
||||
describe "::destroy()", ->
|
||||
[container, pane1, pane2] = []
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
PaneContainer = require '../src/pane-container'
|
||||
PaneView = require '../src/pane-view'
|
||||
fs = require 'fs-plus'
|
||||
{Emitter} = require 'event-kit'
|
||||
{$, View} = require 'atom'
|
||||
{Emitter, Disposable} = require 'event-kit'
|
||||
{$, View} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
|
||||
@@ -21,8 +21,11 @@ describe "PaneView", ->
|
||||
@emitter.emit 'did-change-title', 'title'
|
||||
onDidChangeTitle: (callback) ->
|
||||
@emitter.on 'did-change-title', callback
|
||||
onDidChangeModified: -> new Disposable(->)
|
||||
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
deserializerDisposable = atom.deserializers.add(TestView)
|
||||
container = atom.views.getView(new PaneContainer).__spacePenView
|
||||
containerModel = container.model
|
||||
@@ -41,6 +44,7 @@ describe "PaneView", ->
|
||||
|
||||
afterEach ->
|
||||
deserializerDisposable.dispose()
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
describe "when the active pane item changes", ->
|
||||
it "hides all item views except the active one", ->
|
||||
@@ -144,22 +148,30 @@ describe "PaneView", ->
|
||||
|
||||
describe "when an item is moved to another pane", ->
|
||||
it "detaches the item's view rather than removing it", ->
|
||||
container.attachToDom()
|
||||
expect(view1.is(':visible')).toBe true
|
||||
paneModel2 = paneModel.splitRight()
|
||||
view1.data('preservative', 1234)
|
||||
paneModel.moveItemToPane(view1, paneModel2, 1)
|
||||
expect(view1.data('preservative')).toBe 1234
|
||||
paneModel2.activateItemAtIndex(1)
|
||||
expect(view1.data('preservative')).toBe 1234
|
||||
expect(view1.is(':visible')).toBe true
|
||||
|
||||
describe "when the title of the active item changes", ->
|
||||
describe 'when there is no onDidChangeTitle method', ->
|
||||
describe 'when there is no onDidChangeTitle method (deprecated)', ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
view1.onDidChangeTitle = null
|
||||
view2.onDidChangeTitle = null
|
||||
|
||||
pane.activateItem(view2)
|
||||
pane.activateItem(view1)
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "emits pane:active-item-title-changed", ->
|
||||
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
|
||||
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
|
||||
@@ -217,7 +229,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
pane2Model = paneModel.splitRight() # Can't destroy the last pane, so we add another
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane2 = atom.views.getView(pane2Model).__spacePenView
|
||||
|
||||
it "triggers a 'pane:removed' event with the pane", ->
|
||||
removedHandler = jasmine.createSpy("removedHandler")
|
||||
@@ -250,7 +262,7 @@ describe "PaneView", ->
|
||||
|
||||
beforeEach ->
|
||||
pane2Model = paneModel.splitRight(items: [pane.copyActiveItem()])
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane2 = atom.views.getView(pane2Model).__spacePenView
|
||||
expect(pane2Model.isActive()).toBe true
|
||||
|
||||
it "adds or removes the .active class as appropriate", ->
|
||||
@@ -297,8 +309,8 @@ describe "PaneView", ->
|
||||
pane2Model = pane1Model.splitRight(items: [pane1Model.copyActiveItem()])
|
||||
pane3Model = pane2Model.splitDown(items: [pane2Model.copyActiveItem()])
|
||||
pane2 = pane2Model._view
|
||||
pane2 = containerModel.getView(pane2Model).__spacePenView
|
||||
pane3 = containerModel.getView(pane3Model).__spacePenView
|
||||
pane2 = atom.views.getView(pane2Model).__spacePenView
|
||||
pane3 = atom.views.getView(pane3Model).__spacePenView
|
||||
|
||||
expect(container.find('> atom-pane-axis.horizontal > atom-pane').toArray()).toEqual [pane1[0]]
|
||||
expect(container.find('> atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').toArray()).toEqual [pane2[0], pane3[0]]
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelElement = require '../src/panel-element'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
PanelContainerElement = require '../src/panel-container-element'
|
||||
|
||||
describe "PanelContainerElement", ->
|
||||
[jasmineContent, element, container, viewRegistry] = []
|
||||
[jasmineContent, element, container] = []
|
||||
|
||||
class TestPanelContainerItem
|
||||
constructior: ->
|
||||
@@ -13,29 +12,27 @@ describe "PanelContainerElement", ->
|
||||
class TestPanelContainerItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
setModel: (@model) ->
|
||||
initialize: (@model) ->
|
||||
this
|
||||
|
||||
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
viewRegistry = new ViewRegistry
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: Panel
|
||||
viewConstructor: PanelElement
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: PanelContainer
|
||||
viewConstructor: PanelContainerElement
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: TestPanelContainerItem
|
||||
viewConstructor: TestPanelContainerItemElement
|
||||
atom.views.addViewProvider Panel, (model) ->
|
||||
new PanelElement().initialize(model)
|
||||
atom.views.addViewProvider PanelContainer, (model) ->
|
||||
new PaneContainerElement().initialize(model)
|
||||
atom.views.addViewProvider TestPanelContainerItem, (model) ->
|
||||
new TestPanelContainerItemElement().initialize(model)
|
||||
|
||||
container = new PanelContainer({viewRegistry, location: 'left'})
|
||||
element = container.getView()
|
||||
container = new PanelContainer({location: 'left'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it 'has a location attribute with value from the model', ->
|
||||
expect(element.getAttribute('location')).toBe 'left'
|
||||
it 'has a location class with value from the model', ->
|
||||
expect(element).toHaveClass 'left'
|
||||
|
||||
it 'removes the element when the container is destroyed', ->
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
@@ -43,23 +40,38 @@ describe "PanelContainerElement", ->
|
||||
expect(element.parentNode).not.toBe jasmineContent
|
||||
|
||||
describe "adding and removing panels", ->
|
||||
it "allows panels to be inserted at any position", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
|
||||
panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
|
||||
|
||||
container.addPanel(panel1)
|
||||
container.addPanel(panel2)
|
||||
container.addPanel(panel3)
|
||||
|
||||
expect(element.childNodes[2].getModel()).toBe(panel1)
|
||||
expect(element.childNodes[1].getModel()).toBe(panel3)
|
||||
expect(element.childNodes[0].getModel()).toBe(panel2)
|
||||
|
||||
describe "when the container is at the left location", ->
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0].getAttribute('location')).toBe 'left'
|
||||
expect(element.childNodes[0]).toHaveClass 'left'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-left' # legacy selector support
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(panel2.getView().style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
@@ -69,24 +81,26 @@ describe "PanelContainerElement", ->
|
||||
|
||||
describe "when the container is at the bottom location", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({viewRegistry, location: 'bottom'})
|
||||
element = container.getView()
|
||||
container = new PanelContainer({location: 'bottom'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'one'})
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0].getAttribute('location')).toBe 'bottom'
|
||||
expect(element.childNodes[0]).toHaveClass 'bottom'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
expect(panel1.getView()).toHaveClass 'one'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'one'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
expect(panel2.getView()).toHaveClass 'two'
|
||||
expect(atom.views.getView(panel2)).toHaveClass 'two'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
@@ -96,23 +110,34 @@ describe "PanelContainerElement", ->
|
||||
|
||||
describe "when the container is modal", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({viewRegistry, location: 'modal'})
|
||||
element = container.getView()
|
||||
container = new PanelContainer({location: 'modal'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "allows only one panel to be visible at a time", ->
|
||||
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
|
||||
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(panel1.getView().style.display).toBe 'none'
|
||||
expect(panel2.getView().style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(panel1.getView().style.display).not.toBe 'none'
|
||||
expect(panel2.getView().style.display).toBe 'none'
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).toBe 'none'
|
||||
|
||||
it "adds the 'modal' class to panels", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'modal'
|
||||
|
||||
# legacy selector support
|
||||
expect(atom.views.getView(panel1)).not.toHaveClass 'tool-panel'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'overlay'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'from-top'
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainer", ->
|
||||
[container, viewRegistry] = []
|
||||
[container] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
|
||||
beforeEach ->
|
||||
viewRegistry = new ViewRegistry
|
||||
container = new PanelContainer({viewRegistry})
|
||||
container = new PanelContainer
|
||||
|
||||
describe "::addPanel(panel)", ->
|
||||
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
|
||||
@@ -46,7 +44,7 @@ describe "PanelContainer", ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({viewRegistry, location: 'left'})
|
||||
container = new PanelContainer({location: 'left'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
@@ -75,7 +73,7 @@ describe "PanelContainer", ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({viewRegistry, location: 'right'})
|
||||
container = new PanelContainer({location: 'right'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
ViewRegistry = require '../src/view-registry'
|
||||
Panel = require '../src/panel'
|
||||
PanelElement = require '../src/panel-element'
|
||||
|
||||
describe "PanelElement", ->
|
||||
[jasmineContent, element, panel, viewRegistry] = []
|
||||
[jasmineContent, element, panel] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructior: ->
|
||||
@@ -11,23 +10,22 @@ describe "PanelElement", ->
|
||||
class TestPanelItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
setModel: (@model) ->
|
||||
initialize: (@model) ->
|
||||
this
|
||||
|
||||
TestPanelItemElement = document.registerElement 'atom-test-item-element', prototype: TestPanelItemElement.prototype
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
viewRegistry = new ViewRegistry
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: Panel
|
||||
viewConstructor: PanelElement
|
||||
viewRegistry.addViewProvider
|
||||
modelConstructor: TestPanelItem
|
||||
viewConstructor: TestPanelItemElement
|
||||
atom.views.addViewProvider Panel, (model) ->
|
||||
new PanelElement().initialize(model)
|
||||
atom.views.addViewProvider TestPanelItem, (model) ->
|
||||
new TestPanelItemElement().initialize(model)
|
||||
|
||||
it 'removes the element when the panel is destroyed', ->
|
||||
panel = new Panel({viewRegistry, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
@@ -36,15 +34,15 @@ describe "PanelElement", ->
|
||||
|
||||
describe "changing panel visibility", ->
|
||||
it 'initially renders panel created with visibile: false', ->
|
||||
panel = new Panel({viewRegistry, visible: false, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({visible: false, item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.style.display).toBe 'none'
|
||||
|
||||
it 'hides and shows the panel element when Panel::hide() and Panel::show() are called', ->
|
||||
panel = new Panel({viewRegistry, item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element.style.display).not.toBe 'none'
|
||||
@@ -57,8 +55,8 @@ describe "PanelElement", ->
|
||||
|
||||
describe "when a class name is specified", ->
|
||||
it 'initially renders panel created with visibile: false', ->
|
||||
panel = new Panel({viewRegistry, className: 'some classes', item: new TestPanelItem})
|
||||
element = panel.getView()
|
||||
panel = new Panel({className: 'some classes', item: new TestPanelItem})
|
||||
element = atom.views.getView(panel)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
expect(element).toHaveClass 'some'
|
||||
|
||||
@@ -21,3 +21,7 @@ describe "Panel", ->
|
||||
panel.show()
|
||||
expect(panel.isVisible()).toBe true
|
||||
expect(spy).toHaveBeenCalledWith(true)
|
||||
|
||||
panel.destroy()
|
||||
expect(panel.isVisible()).toBe false
|
||||
expect(spy).toHaveBeenCalledWith(false)
|
||||
|
||||
@@ -170,30 +170,30 @@ describe "Project", ->
|
||||
absolutePath = fs.absolute(__dirname)
|
||||
expect(atom.project.resolve(absolutePath)).toBe absolutePath
|
||||
|
||||
describe ".setPath(path)", ->
|
||||
describe ".setPaths(path)", ->
|
||||
describe "when path is a file", ->
|
||||
it "sets its path to the files parent directory and updates the root directory", ->
|
||||
atom.project.setPaths([require.resolve('./fixtures/dir/a')])
|
||||
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
|
||||
describe "when path is a directory", ->
|
||||
it "sets its path to the directory and updates the root directory", ->
|
||||
directory = fs.absolute(path.join(__dirname, 'fixtures', 'dir', 'a-dir'))
|
||||
atom.project.setPaths([directory])
|
||||
expect(atom.project.getPaths()[0]).toEqual directory
|
||||
expect(atom.project.getRootDirectory().path).toEqual directory
|
||||
expect(atom.project.getDirectories()[0].path).toEqual directory
|
||||
|
||||
describe "when path is null", ->
|
||||
it "sets its path and root directory to null", ->
|
||||
atom.project.setPaths([])
|
||||
expect(atom.project.getPaths()[0]?).toBeFalsy()
|
||||
expect(atom.project.getRootDirectory()?).toBeFalsy()
|
||||
expect(atom.project.getDirectories()[0]?).toBeFalsy()
|
||||
|
||||
it "normalizes the path to remove consecutive slashes, ., and .. segments", ->
|
||||
atom.project.setPaths(["#{require.resolve('./fixtures/dir/a')}#{path.sep}b#{path.sep}#{path.sep}.."])
|
||||
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
|
||||
|
||||
describe ".replace()", ->
|
||||
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
SelectListView = require '../src/select-list-view'
|
||||
{$, $$} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "SelectListView", ->
|
||||
[selectList, items, list, filterEditorView] = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{View, $, $$} = require 'atom'
|
||||
{View, $, $$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "SpacePen extensions", ->
|
||||
class TestView extends View
|
||||
|
||||
@@ -9,12 +9,17 @@ _ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Grim = require 'grim'
|
||||
KeymapManager = require '../src/keymap-extensions'
|
||||
{$, WorkspaceView, Workspace} = require 'atom'
|
||||
|
||||
# FIXME: Remove jquery from this
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
|
||||
Config = require '../src/config'
|
||||
{Point} = require 'text-buffer'
|
||||
Project = require '../src/project'
|
||||
Workspace = require '../src/workspace'
|
||||
TextEditor = require '../src/text-editor'
|
||||
TextEditorView = require '../src/text-editor-view'
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
TokenizedBuffer = require '../src/tokenized-buffer'
|
||||
TextEditorComponent = require '../src/text-editor-component'
|
||||
pathwatcher = require 'pathwatcher'
|
||||
@@ -76,13 +81,15 @@ beforeEach ->
|
||||
atom.commands.restoreSnapshot(commandsToRestore)
|
||||
atom.styles.restoreSnapshot(styleElementsToRestore)
|
||||
|
||||
atom.workspaceViewParentSelector = '#jasmine-content'
|
||||
|
||||
window.resetTimeouts()
|
||||
atom.packages.packageStates = {}
|
||||
|
||||
serializedWindowState = null
|
||||
|
||||
spyOn(atom, 'saveSync')
|
||||
atom.syntax.clearGrammarOverrides()
|
||||
atom.grammars.clearGrammarOverrides()
|
||||
|
||||
spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) ->
|
||||
if specPackageName and packageName is specPackageName
|
||||
@@ -111,8 +118,7 @@ beforeEach ->
|
||||
config.save.reset()
|
||||
|
||||
# make editor display updates synchronous
|
||||
spyOn(TextEditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
||||
TextEditorComponent.performSyncUpdates = true
|
||||
TextEditorElement::setUpdatedSynchronously(true)
|
||||
|
||||
spyOn(atom, "setRepresentedFilename")
|
||||
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
|
||||
@@ -135,8 +141,9 @@ afterEach ->
|
||||
atom.menu.template = []
|
||||
atom.contextMenu.clear()
|
||||
|
||||
atom.workspaceView?.remove?()
|
||||
atom.workspaceView = null
|
||||
atom.workspace?.destroy()
|
||||
atom.workspace = null
|
||||
atom.__workspaceView = null
|
||||
delete atom.state.workspace
|
||||
|
||||
atom.project?.destroy()
|
||||
@@ -150,7 +157,7 @@ afterEach ->
|
||||
|
||||
jasmine.unspy(atom, 'saveSync')
|
||||
ensureNoPathSubscriptions()
|
||||
atom.syntax.clearObservers()
|
||||
atom.grammars.clearObservers()
|
||||
waits(0) # yield to ui thread to make screen update more frequently
|
||||
|
||||
ensureNoPathSubscriptions = ->
|
||||
@@ -191,6 +198,17 @@ jasmine.unspy = (object, methodName) ->
|
||||
throw new Error("Not a spy") unless object[methodName].hasOwnProperty('originalValue')
|
||||
object[methodName] = object[methodName].originalValue
|
||||
|
||||
jasmine.attachToDOM = (element) ->
|
||||
jasmineContent = document.querySelector('#jasmine-content')
|
||||
jasmineContent.appendChild(element) unless jasmineContent.contains(element)
|
||||
|
||||
deprecationsSnapshot = null
|
||||
jasmine.snapshotDeprecations = ->
|
||||
deprecationsSnapshot = Grim.getDeprecations() # suppress deprecations!!
|
||||
|
||||
jasmine.restoreDeprecationsSnapshot = ->
|
||||
Grim.grimDeprecations = deprecationsSnapshot
|
||||
|
||||
addCustomMatchers = (spec) ->
|
||||
spec.addMatchers
|
||||
toBeInstanceOf: (expected) ->
|
||||
|
||||
@@ -59,8 +59,9 @@ describe "StylesElement", ->
|
||||
atom.styles.addStyleSheet("a {color: red;}", context: 'test-context')
|
||||
atom.styles.addStyleSheet("a {color: green;}")
|
||||
|
||||
expect(element.children.length).toBe initialChildCount + 1
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: green;}"
|
||||
expect(element.children.length).toBe initialChildCount + 2
|
||||
expect(element.children[initialChildCount].textContent).toBe "a {color: red;}"
|
||||
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: green;}"
|
||||
|
||||
element.setAttribute('context', 'test-context')
|
||||
|
||||
@@ -73,3 +74,39 @@ describe "StylesElement", ->
|
||||
expect(element.children.length).toBe 2
|
||||
expect(element.children[0].textContent).toBe "a {color: red;}"
|
||||
expect(element.children[1].textContent).toBe "a {color: blue;}"
|
||||
|
||||
describe "atom-text-editor shadow DOM selector upgrades", ->
|
||||
beforeEach ->
|
||||
element.setAttribute('context', 'atom-text-editor')
|
||||
spyOn(console, 'warn')
|
||||
|
||||
it "upgrades selectors containing .editor-colors", ->
|
||||
atom.styles.addStyleSheet(".editor-colors {background: black;}", context: 'atom-text-editor')
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
|
||||
it "upgrades selectors containing .editor", ->
|
||||
atom.styles.addStyleSheet """
|
||||
.editor {background: black;}
|
||||
.editor.mini {background: black;}
|
||||
.editor:focus {background: black;}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
expect(element.firstChild.sheet.cssRules[1].selectorText).toBe ':host(.mini)'
|
||||
expect(element.firstChild.sheet.cssRules[2].selectorText).toBe ':host(:focus)'
|
||||
|
||||
it "defers selector upgrade until the element is attached", ->
|
||||
element = new StylesElement
|
||||
element.setAttribute('context', 'atom-text-editor')
|
||||
element.initialize()
|
||||
|
||||
atom.styles.addStyleSheet ".editor {background: black;}", context: 'atom-text-editor'
|
||||
expect(element.firstChild.sheet).toBeNull()
|
||||
|
||||
document.querySelector('#jasmine-content').appendChild(element)
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
|
||||
it "does not throw exceptions on rules with no selectors", ->
|
||||
atom.styles.addStyleSheet """
|
||||
@media screen {font-size: 10px;}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
+29
-56
@@ -23,10 +23,10 @@ describe "the `syntax` global", ->
|
||||
describe "serialization", ->
|
||||
it "remembers grammar overrides by path", ->
|
||||
filePath = '/foo/bar/file.js'
|
||||
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
syntax2 = atom.deserializers.deserialize(atom.syntax.serialize())
|
||||
syntax2.addGrammar(grammar) for grammar in atom.syntax.grammars when grammar isnt atom.syntax.nullGrammar
|
||||
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
syntax2 = atom.deserializers.deserialize(atom.grammars.serialize())
|
||||
syntax2.addGrammar(grammar) for grammar in atom.grammars.grammars when grammar isnt atom.grammars.nullGrammar
|
||||
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
|
||||
describe ".selectGrammar(filePath)", ->
|
||||
@@ -35,15 +35,15 @@ describe "the `syntax` global", ->
|
||||
atom.packages.activatePackage('language-git')
|
||||
|
||||
runs ->
|
||||
expect(atom.syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
|
||||
expect(atom.syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
|
||||
expect(atom.syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
|
||||
expect(atom.syntax.selectGrammar("curb").name).toBe "Null Grammar"
|
||||
expect(atom.syntax.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
|
||||
expect(atom.grammars.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
|
||||
expect(atom.grammars.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
|
||||
expect(atom.grammars.selectGrammar("curb").name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
|
||||
|
||||
it "uses the filePath's shebang line if the grammar cannot be determined by the extension or basename", ->
|
||||
filePath = require.resolve("./fixtures/shebang")
|
||||
expect(atom.syntax.selectGrammar(filePath).name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar(filePath).name).toBe "Ruby"
|
||||
|
||||
it "uses the number of newlines in the first line regex to determine the number of lines to test against", ->
|
||||
waitsForPromise ->
|
||||
@@ -51,28 +51,28 @@ describe "the `syntax` global", ->
|
||||
|
||||
runs ->
|
||||
fileContent = "first-line\n<html>"
|
||||
expect(atom.syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
|
||||
expect(atom.grammars.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
|
||||
|
||||
fileContent = '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
|
||||
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
|
||||
|
||||
fileContent += '\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
|
||||
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
|
||||
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
|
||||
|
||||
it "doesn't read the file when the file contents are specified", ->
|
||||
filePath = require.resolve("./fixtures/shebang")
|
||||
filePathContents = fs.readFileSync(filePath, 'utf8')
|
||||
spyOn(fs, 'read').andCallThrough()
|
||||
expect(atom.syntax.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
|
||||
expect(atom.grammars.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
|
||||
expect(fs.read).not.toHaveBeenCalled()
|
||||
|
||||
it "allows the default grammar to be overridden for a path", ->
|
||||
filePath = '/foo/bar/file.js'
|
||||
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
expect(atom.syntax.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
atom.syntax.clearGrammarOverrideForPath(filePath)
|
||||
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
|
||||
expect(atom.grammars.selectGrammar(filePath).name).toBe 'Ruby'
|
||||
atom.grammars.clearGrammarOverrideForPath(filePath)
|
||||
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
|
||||
|
||||
describe "when multiple grammars have matching fileTypes", ->
|
||||
it "selects the grammar with the longest fileType match", ->
|
||||
@@ -82,8 +82,8 @@ describe "the `syntax` global", ->
|
||||
scopeName: 'source1'
|
||||
fileTypes: ['test']
|
||||
)
|
||||
grammar1 = atom.syntax.loadGrammarSync(grammarPath1)
|
||||
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar1
|
||||
grammar1 = atom.grammars.loadGrammarSync(grammarPath1)
|
||||
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar1
|
||||
|
||||
grammarPath2 = temp.path(suffix: '.json')
|
||||
fs.writeFileSync grammarPath2, JSON.stringify(
|
||||
@@ -91,44 +91,17 @@ describe "the `syntax` global", ->
|
||||
scopeName: 'source2'
|
||||
fileTypes: ['test', 'more.test']
|
||||
)
|
||||
grammar2 = atom.syntax.loadGrammarSync(grammarPath2)
|
||||
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar2
|
||||
grammar2 = atom.grammars.loadGrammarSync(grammarPath2)
|
||||
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar2
|
||||
|
||||
describe "when there is no file path", ->
|
||||
it "does not throw an exception (regression)", ->
|
||||
expect(-> atom.syntax.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
|
||||
expect(-> atom.syntax.selectGrammar(null, '')).not.toThrow()
|
||||
expect(-> atom.syntax.selectGrammar(null, null)).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, '')).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, null)).not.toThrow()
|
||||
|
||||
describe ".removeGrammar(grammar)", ->
|
||||
it "removes the grammar, so it won't be returned by selectGrammar", ->
|
||||
grammar = atom.syntax.selectGrammar('foo.js')
|
||||
atom.syntax.removeGrammar(grammar)
|
||||
expect(atom.syntax.selectGrammar('foo.js').name).not.toBe grammar.name
|
||||
|
||||
describe ".getProperty(scopeDescriptor)", ->
|
||||
it "returns the property with the most specific scope selector", ->
|
||||
atom.syntax.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.syntax.addProperties(".source .string.quoted.double", foo: bar: baz: 22)
|
||||
atom.syntax.addProperties(".source", foo: bar: baz: 11)
|
||||
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
|
||||
expect(atom.syntax.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
|
||||
expect(atom.syntax.getProperty([".text"], "foo.bar.baz")).toBeUndefined()
|
||||
|
||||
it "favors the most recently added properties in the event of a specificity tie", ->
|
||||
atom.syntax.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42)
|
||||
atom.syntax.addProperties(".source.coffee .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
|
||||
|
||||
describe ".removeProperties(name)", ->
|
||||
it "allows properties to be removed by name", ->
|
||||
atom.syntax.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
|
||||
atom.syntax.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22)
|
||||
|
||||
atom.syntax.removeProperties("b")
|
||||
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
|
||||
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
|
||||
grammar = atom.grammars.selectGrammar('foo.js')
|
||||
atom.grammars.removeGrammar(grammar)
|
||||
expect(atom.grammars.selectGrammar('foo.js').name).not.toBe grammar.name
|
||||
|
||||
@@ -37,9 +37,9 @@ describe "TextEditorComponent", ->
|
||||
wrapperView = new TextEditorView(editor, {lineOverdrawMargin})
|
||||
wrapperView.attachToDom()
|
||||
wrapperNode = wrapperView.element
|
||||
wrapperNode.setUpdatedSynchronously(false)
|
||||
|
||||
{component} = wrapperView
|
||||
component.performSyncUpdates = false
|
||||
component.setFontFamily('monospace')
|
||||
component.setLineHeight(1.3)
|
||||
component.setFontSize(20)
|
||||
@@ -302,7 +302,7 @@ describe "TextEditorComponent", ->
|
||||
|
||||
it "interleaves invisible line-ending characters with indent guides on empty lines", ->
|
||||
component.setShowIndentGuide(true)
|
||||
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", false)
|
||||
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", normalizeLineEndings: false)
|
||||
nextAnimationFrame()
|
||||
expect(component.lineNodeForScreenRow(10).innerHTML).toBe '<span class="indent-guide"><span class="invisible-character">C</span><span class="invisible-character">E</span></span>'
|
||||
|
||||
@@ -1131,6 +1131,13 @@ describe "TextEditorComponent", ->
|
||||
regions = componentNode.querySelectorAll('.test-highlight .region')
|
||||
expect(regions.length).toBe 2
|
||||
|
||||
it "renders classes on the regions directly if 'deprecatedRegionClass' option is defined", ->
|
||||
decoration = editor.decorateMarker(marker, type: 'highlight', class: 'test-highlight', deprecatedRegionClass: 'test-highlight-region')
|
||||
nextAnimationFrame()
|
||||
|
||||
regions = componentNode.querySelectorAll('.test-highlight .region.test-highlight-region')
|
||||
expect(regions.length).toBe 2
|
||||
|
||||
describe "when flashing a decoration via Decoration::flash()", ->
|
||||
highlightNode = null
|
||||
beforeEach ->
|
||||
@@ -1196,6 +1203,232 @@ describe "TextEditorComponent", ->
|
||||
expect(componentNode.querySelector('.test-highlight')).toBeFalsy()
|
||||
expect(componentNode.querySelector('.new-test-highlight')).toBeTruthy()
|
||||
|
||||
describe "overlay decoration rendering", ->
|
||||
[item] = []
|
||||
beforeEach ->
|
||||
item = document.createElement('div')
|
||||
item.classList.add 'overlay-test'
|
||||
|
||||
describe "when the marker is empty", ->
|
||||
it "renders an overlay decoration when added and removes the overlay when the decoration is destroyed", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 13], [2, 13]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay .overlay-test')
|
||||
expect(overlay).toBe item
|
||||
|
||||
decoration.destroy()
|
||||
nextAnimationFrame()
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay .overlay-test')
|
||||
expect(overlay).toBe null
|
||||
|
||||
it "renders in the correct position on initial display and when the marker moves", ->
|
||||
editor.setCursorBufferPosition([2, 5])
|
||||
|
||||
marker = editor.getLastCursor().getMarker()
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 5])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.moveRight()
|
||||
editor.moveRight()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 7])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
describe "when the marker is not empty", ->
|
||||
it "renders at the head of the marker by default", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 10])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "renders at the head of the marker when the marker is reversed", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never', reversed: true)
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 5])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "renders at the tail of the marker when the 'position' option is 'tail'", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 5])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
describe "positioning the overlay when near the edge of the editor", ->
|
||||
[itemWidth, itemHeight] = []
|
||||
beforeEach ->
|
||||
itemWidth = 4 * editor.getDefaultCharWidth()
|
||||
itemHeight = 4 * editor.getLineHeightInPixels()
|
||||
|
||||
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
|
||||
windowWidth = gutterWidth + 30 * editor.getDefaultCharWidth()
|
||||
windowHeight = 9 * editor.getLineHeightInPixels()
|
||||
|
||||
item.style.width = itemWidth + 'px'
|
||||
item.style.height = itemHeight + 'px'
|
||||
|
||||
wrapperNode.style.width = windowWidth + 'px'
|
||||
wrapperNode.style.height = windowHeight + 'px'
|
||||
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
it "flips horizontally when near the right edge", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[0, 26], [0, 26]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 26])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertText('a')
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 27])
|
||||
|
||||
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "flips vertically when near the bottom edge", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[4, 0], [4, 0]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([4, 0])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertNewline()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([5, 0])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
|
||||
|
||||
describe "when the editor is very small", ->
|
||||
beforeEach ->
|
||||
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
|
||||
windowWidth = gutterWidth + 6 * editor.getDefaultCharWidth()
|
||||
windowHeight = 6 * editor.getLineHeightInPixels()
|
||||
|
||||
wrapperNode.style.width = windowWidth + 'px'
|
||||
wrapperNode.style.height = windowHeight + 'px'
|
||||
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
it "does not flip horizontally and force the overlay to have a negative left", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[0, 2], [0, 2]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 2])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertText('a')
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 3])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "does not flip vertically and force the overlay to have a negative top", ->
|
||||
marker = editor.displayBuffer.markBufferRange([[1, 0], [1, 0]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([1, 0])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertNewline()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([2, 0])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
|
||||
describe "when editor scroll position is not 0", ->
|
||||
it "flips horizontally when near the right edge", ->
|
||||
editor.setScrollLeft(2 * editor.getDefaultCharWidth())
|
||||
marker = editor.displayBuffer.markBufferRange([[0, 28], [0, 28]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 28])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertText('a')
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([0, 29])
|
||||
|
||||
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
it "flips vertically when near the bottom edge", ->
|
||||
editor.setScrollTop(2 * editor.getLineHeightInPixels())
|
||||
marker = editor.displayBuffer.markBufferRange([[6, 0], [6, 0]], invalidate: 'never')
|
||||
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([6, 0])
|
||||
|
||||
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
|
||||
|
||||
editor.insertNewline()
|
||||
nextAnimationFrame()
|
||||
|
||||
position = editor.pixelPositionForBufferPosition([7, 0])
|
||||
|
||||
expect(overlay.style.left).toBe position.left + 'px'
|
||||
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
|
||||
|
||||
describe "hidden input field", ->
|
||||
it "renders the hidden input field at the position of the last cursor if the cursor is on screen and the editor is focused", ->
|
||||
editor.setVerticalScrollMargin(0)
|
||||
@@ -1675,7 +1908,8 @@ describe "TextEditorComponent", ->
|
||||
}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
nextAnimationFrame()
|
||||
nextAnimationFrame() # handle stylesheet change event
|
||||
nextAnimationFrame() # perform requested update
|
||||
|
||||
scrollbarCornerNode = componentNode.querySelector('.scrollbar-corner')
|
||||
expect(verticalScrollbarNode.offsetWidth).toBe 8
|
||||
@@ -2310,7 +2544,7 @@ describe "TextEditorComponent", ->
|
||||
describe "grammar data attributes", ->
|
||||
it "adds and updates the grammar data attribute based on the current grammar", ->
|
||||
expect(wrapperNode.dataset.grammar).toBe 'source js'
|
||||
editor.setGrammar(atom.syntax.nullGrammar)
|
||||
editor.setGrammar(atom.grammars.nullGrammar)
|
||||
expect(wrapperNode.dataset.grammar).toBe 'text plain null-grammar'
|
||||
|
||||
describe "encoding data attributes", ->
|
||||
@@ -2462,6 +2696,28 @@ describe "TextEditorComponent", ->
|
||||
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe false
|
||||
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
|
||||
|
||||
describe "middle mouse paste on Linux", ->
|
||||
it "pastes the previously selected text", ->
|
||||
spyOn(require('ipc'), 'send').andCallFake (eventName, selectedText) ->
|
||||
if eventName is 'write-text-to-selection-clipboard'
|
||||
require('clipboard').writeText(selectedText, 'selection')
|
||||
|
||||
atom.clipboard.write('')
|
||||
component.listenForMiddleMousePaste()
|
||||
|
||||
editor.setCursorBufferPosition([10, 0])
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
|
||||
|
||||
expect(atom.clipboard.read()).toBe ''
|
||||
expect(editor.lineTextForBufferRow(10)).toBe ''
|
||||
|
||||
editor.setSelectedBufferRange([[1, 6], [1, 10]])
|
||||
editor.setCursorBufferPosition([10, 0])
|
||||
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
|
||||
|
||||
expect(atom.clipboard.read()).toBe 'sort'
|
||||
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
|
||||
|
||||
buildMouseEvent = (type, properties...) ->
|
||||
properties = extend({bubbles: true, cancelable: true}, properties...)
|
||||
properties.detail ?= 1
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
TextEditor = require '../src/text-editor'
|
||||
|
||||
# The rest of text-editor-component-spec will be moved to this file when React
|
||||
# is eliminated. This covers only concerns related to the wrapper element for now
|
||||
@@ -19,6 +20,18 @@ describe "TextEditorElement", ->
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().getPlaceholderText()).toBe 'testing'
|
||||
|
||||
it "honors the text content", ->
|
||||
jasmineContent.innerHTML = "<atom-text-editor>testing</atom-text-editor>"
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().getText()).toBe 'testing'
|
||||
|
||||
describe "when the model is assigned", ->
|
||||
it "adds the 'mini' attribute if .isMini() returns true on the model", ->
|
||||
element = new TextEditorElement
|
||||
model = new TextEditor(mini: true)
|
||||
element.setModel(model)
|
||||
expect(element.hasAttribute('mini')).toBe true
|
||||
|
||||
describe "focus and blur handling", ->
|
||||
describe "when the editor.useShadowDOM config option is true", ->
|
||||
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
|
||||
@@ -40,9 +53,6 @@ describe "TextEditorElement", ->
|
||||
expect(blurCalled).toBe true
|
||||
|
||||
describe "when the editor.useShadowDOM config option is false", ->
|
||||
afterEach ->
|
||||
document.head.querySelector('atom-styles[context="atom-text-editor"]').remove()
|
||||
|
||||
it "proxies focus/blur events to/from the hidden input", ->
|
||||
atom.config.set('editor.useShadowDOM', false)
|
||||
|
||||
@@ -59,3 +69,89 @@ describe "TextEditorElement", ->
|
||||
|
||||
document.body.focus()
|
||||
expect(blurCalled).toBe true
|
||||
|
||||
describe "when the themes finish loading", ->
|
||||
[themeReloadCallback, initialThemeLoadComplete, element] = []
|
||||
|
||||
beforeEach ->
|
||||
themeReloadCallback = null
|
||||
initialThemeLoadComplete = false
|
||||
|
||||
spyOn(atom.themes, 'isInitialLoadComplete').andCallFake ->
|
||||
initialThemeLoadComplete
|
||||
spyOn(atom.themes, 'onDidReloadAll').andCallFake (fn) ->
|
||||
themeReloadCallback = fn
|
||||
|
||||
atom.config.set("editor.useShadowDOM", false)
|
||||
|
||||
element = new TextEditorElement()
|
||||
element.style.height = '200px'
|
||||
element.getModel().setText [0..20].join("\n")
|
||||
|
||||
it "re-renders the scrollbar", ->
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
atom.styles.addStyleSheet """
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
"""
|
||||
|
||||
initialThemeLoadComplete = true
|
||||
themeReloadCallback()
|
||||
|
||||
verticalScrollbarNode = element.querySelector(".vertical-scrollbar")
|
||||
scrollbarWidth = verticalScrollbarNode.offsetWidth - verticalScrollbarNode.clientWidth
|
||||
expect(scrollbarWidth).toEqual(8)
|
||||
|
||||
describe "::onDidAttach and ::onDidDetach", ->
|
||||
it "invokes callbacks when the element is attached and detached", ->
|
||||
element = new TextEditorElement
|
||||
|
||||
attachedCallback = jasmine.createSpy("attachedCallback")
|
||||
detachedCallback = jasmine.createSpy("detachedCallback")
|
||||
|
||||
element.onDidAttach(attachedCallback)
|
||||
element.onDidDetach(detachedCallback)
|
||||
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
expect(attachedCallback).toHaveBeenCalled()
|
||||
expect(detachedCallback).not.toHaveBeenCalled()
|
||||
|
||||
attachedCallback.reset()
|
||||
element.remove()
|
||||
|
||||
expect(attachedCallback).not.toHaveBeenCalled()
|
||||
expect(detachedCallback).toHaveBeenCalled()
|
||||
|
||||
describe "::setUpdatedSynchronously", ->
|
||||
it "controls whether the text editor is updated synchronously", ->
|
||||
spyOn(window, 'requestAnimationFrame').andCallFake (fn) -> fn()
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
element.setUpdatedSynchronously(false)
|
||||
expect(element.isUpdatedSynchronously()).toBe false
|
||||
|
||||
element.getModel().setText("hello")
|
||||
expect(window.requestAnimationFrame).toHaveBeenCalled()
|
||||
|
||||
expect(element.shadowRoot.textContent).toContain "hello"
|
||||
|
||||
window.requestAnimationFrame.reset()
|
||||
element.setUpdatedSynchronously(true)
|
||||
element.getModel().setText("goodbye")
|
||||
expect(window.requestAnimationFrame).not.toHaveBeenCalled()
|
||||
expect(element.shadowRoot.textContent).toContain "goodbye"
|
||||
|
||||
describe "::getDefaultCharacterWidth", ->
|
||||
it "returns null before the element is attached", ->
|
||||
element = new TextEditorElement
|
||||
expect(element.getDefaultCharacterWidth()).toBeNull()
|
||||
|
||||
it "returns the width of a character in the root scope", ->
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
expect(element.getDefaultCharacterWidth()).toBeGreaterThan(0)
|
||||
|
||||
+358
-259
@@ -98,12 +98,13 @@ describe "TextEditor", ->
|
||||
expect(editor2.isFoldedAtBufferRow(4)).not.toBe editor.isFoldedAtBufferRow(4)
|
||||
|
||||
describe "config defaults", ->
|
||||
it "uses the `editor.tabLength`, `editor.softWrap`, and `editor.softTabs` config values", ->
|
||||
it "uses the `editor.tabLength`, `editor.softWrap`, and `editor.softTabs`, and `core.fileEncoding` config values", ->
|
||||
editor1 = null
|
||||
editor2 = null
|
||||
atom.config.set('editor.tabLength', 4)
|
||||
atom.config.set('editor.softWrap', true)
|
||||
atom.config.set('editor.softTabs', false)
|
||||
atom.config.set('core.fileEncoding', 'utf16le')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('a').then (o) -> editor1 = o
|
||||
@@ -112,10 +113,12 @@ describe "TextEditor", ->
|
||||
expect(editor1.getTabLength()).toBe 4
|
||||
expect(editor1.isSoftWrapped()).toBe true
|
||||
expect(editor1.getSoftTabs()).toBe false
|
||||
expect(editor1.getEncoding()).toBe 'utf16le'
|
||||
|
||||
atom.config.set('editor.tabLength', 8)
|
||||
atom.config.set('editor.softWrap', false)
|
||||
atom.config.set('editor.softTabs', true)
|
||||
atom.config.set('core.fileEncoding', 'macroman')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('b').then (o) -> editor2 = o
|
||||
@@ -124,6 +127,7 @@ describe "TextEditor", ->
|
||||
expect(editor2.getTabLength()).toBe 8
|
||||
expect(editor2.isSoftWrapped()).toBe false
|
||||
expect(editor2.getSoftTabs()).toBe true
|
||||
expect(editor2.getEncoding()).toBe 'macroman'
|
||||
|
||||
describe "title", ->
|
||||
describe ".getTitle()", ->
|
||||
@@ -188,12 +192,18 @@ describe "TextEditor", ->
|
||||
expect(editor.getCursorBufferPosition()).toEqual [1, 1]
|
||||
|
||||
it "emits an event with the old position, new position, and the cursor that moved", ->
|
||||
editor.onDidChangeCursorPosition positionChangedHandler = jasmine.createSpy()
|
||||
cursorCallback = jasmine.createSpy('cursor-changed-position')
|
||||
editorCallback = jasmine.createSpy('editor-changed-cursor-position')
|
||||
|
||||
editor.getLastCursor().onDidChangePosition(cursorCallback)
|
||||
editor.onDidChangeCursorPosition(editorCallback)
|
||||
|
||||
editor.setCursorBufferPosition([2, 4])
|
||||
|
||||
expect(positionChangedHandler).toHaveBeenCalled()
|
||||
eventObject = positionChangedHandler.mostRecentCall.args[0]
|
||||
expect(editorCallback).toHaveBeenCalled()
|
||||
expect(cursorCallback).toHaveBeenCalled()
|
||||
eventObject = editorCallback.mostRecentCall.args[0]
|
||||
expect(cursorCallback.mostRecentCall.args[0]).toEqual(eventObject)
|
||||
|
||||
expect(eventObject.oldBufferPosition).toEqual [0, 0]
|
||||
expect(eventObject.oldScreenPosition).toEqual [0, 0]
|
||||
@@ -612,7 +622,7 @@ describe "TextEditor", ->
|
||||
describe "when invisible characters are enabled with hard tabs", ->
|
||||
it "moves to the first character of the current line without being confused by the invisible characters", ->
|
||||
atom.config.set('editor.showInvisibles', true)
|
||||
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', false)
|
||||
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', normalizeLineEndings: false)
|
||||
|
||||
editor.setCursorScreenPosition [1,7]
|
||||
editor.moveToFirstCharacterOfLine()
|
||||
@@ -1158,6 +1168,21 @@ describe "TextEditor", ->
|
||||
editor.selectLinesContainingCursors()
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0,0], [2,0]]
|
||||
|
||||
it "autoscrolls to the selection", ->
|
||||
editor.manageScrollPosition = true
|
||||
editor.setLineHeightInPixels(10)
|
||||
editor.setDefaultCharWidth(10)
|
||||
editor.setHeight(50)
|
||||
editor.setWidth(50)
|
||||
editor.setHorizontalScrollbarHeight(0)
|
||||
editor.setCursorScreenPosition([5, 6])
|
||||
|
||||
editor.scrollToTop()
|
||||
expect(editor.getScrollTop()).toBe 0
|
||||
|
||||
editor.selectLinesContainingCursors()
|
||||
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
|
||||
|
||||
describe ".selectToBeginningOfWord()", ->
|
||||
it "selects text from cusor position to beginning of word", ->
|
||||
editor.setCursorScreenPosition [0,13]
|
||||
@@ -2458,17 +2483,33 @@ describe "TextEditor", ->
|
||||
expect(editor.getCursorScreenPosition()).toEqual [0, editor.getTabLength() * 2]
|
||||
|
||||
describe "clipboard operations", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
|
||||
describe ".cutSelectedText()", ->
|
||||
it "removes the selected text from the buffer and places it on the clipboard", ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
editor.cutSelectedText()
|
||||
expect(buffer.lineForRow(0)).toBe "var = function () {"
|
||||
expect(buffer.lineForRow(1)).toBe " var = function(items) {"
|
||||
|
||||
expect(clipboard.readText()).toBe 'quicksort\nsort'
|
||||
|
||||
describe "when no text is selected", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([
|
||||
[[0, 0], [0, 0]],
|
||||
[[5, 0], [5, 0]],
|
||||
])
|
||||
|
||||
it "cuts the lines on which there are cursors", ->
|
||||
editor.cutSelectedText()
|
||||
expect(buffer.getLineCount()).toBe(11)
|
||||
expect(buffer.lineForRow(1)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(buffer.lineForRow(4)).toBe(" current < pivot ? left.push(current) : right.push(current);")
|
||||
expect(atom.clipboard.read()).toEqual """
|
||||
var quicksort = function () {
|
||||
|
||||
current = items.shift();
|
||||
|
||||
"""
|
||||
|
||||
describe ".cutToEndOfLine()", ->
|
||||
describe "when soft wrap is on", ->
|
||||
it "cuts up to the end of the line", ->
|
||||
@@ -2507,37 +2548,165 @@ describe "TextEditor", ->
|
||||
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
|
||||
expect(buffer.lineForRow(2)).toBe " if (items.length <= 1) return items;"
|
||||
expect(clipboard.readText()).toBe 'quicksort\nsort\nitems'
|
||||
expect(atom.clipboard.readWithMetadata().metadata.selections).toEqual([
|
||||
'quicksort'
|
||||
'sort'
|
||||
'items'
|
||||
])
|
||||
expect(atom.clipboard.read()).toEqual """
|
||||
quicksort
|
||||
sort
|
||||
items
|
||||
"""
|
||||
|
||||
describe "when no text is selected", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([
|
||||
[[1, 5], [1, 5]],
|
||||
[[5, 8], [5, 8]]
|
||||
])
|
||||
|
||||
it "copies the lines on which there are cursors", ->
|
||||
editor.copySelectedText()
|
||||
expect(atom.clipboard.read()).toEqual([
|
||||
" var sort = function(items) {\n"
|
||||
" current = items.shift();\n"
|
||||
].join("\n"))
|
||||
expect(editor.getSelectedBufferRanges()).toEqual([
|
||||
[[1, 5], [1, 5]],
|
||||
[[5, 8], [5, 8]]
|
||||
])
|
||||
|
||||
describe ".pasteText()", ->
|
||||
copyText = (text, {startColumn, textEditor}={}) ->
|
||||
startColumn ?= 0
|
||||
textEditor ?= editor
|
||||
textEditor.setCursorBufferPosition([0, 0])
|
||||
textEditor.insertText(text)
|
||||
numberOfNewlines = text.match(/\n/g)?.length
|
||||
endColumn = text.match(/[^\n]*$/)[0]?.length
|
||||
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
|
||||
textEditor.cutSelectedText()
|
||||
|
||||
it "pastes text into the buffer", ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
atom.clipboard.write('first')
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var first = function () {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var first = function(items) {"
|
||||
|
||||
describe "when `autoIndentOnPaste` is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndentOnPaste", true)
|
||||
|
||||
describe "when only whitespace precedes the cursor", ->
|
||||
it "auto-indents the lines spanned by the pasted text", ->
|
||||
atom.clipboard.write("console.log(x);\nconsole.log(y);\n")
|
||||
editor.setCursorBufferPosition([5, 2])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(5)).toBe(" console.log(x);")
|
||||
expect(editor.lineTextForBufferRow(6)).toBe(" console.log(y);")
|
||||
|
||||
describe "when non-whitespace characters precede the cursor", ->
|
||||
it "does not auto-indent the first line being pasted", ->
|
||||
editor.setText """
|
||||
if (x) {
|
||||
y();
|
||||
}
|
||||
"""
|
||||
|
||||
atom.clipboard.write(" z();")
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(" y(); z();")
|
||||
|
||||
describe "when `autoIndentOnPaste` is false", ->
|
||||
beforeEach ->
|
||||
atom.config.set('editor.autoIndentOnPaste', false)
|
||||
|
||||
describe "when the cursor is indented further than the original copied text", ->
|
||||
it "increases the indentation of the copied lines to match", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [3, 0]])
|
||||
editor.copySelectedText()
|
||||
|
||||
editor.setCursorBufferPosition([5, 6])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " var sort = function(items) {"
|
||||
expect(editor.lineTextForBufferRow(6)).toBe " if (items.length <= 1) return items;"
|
||||
|
||||
describe "when the cursor is indented less far than the original copied text", ->
|
||||
it "decreases the indentation of the copied lines to match", ->
|
||||
editor.setSelectedBufferRange([[6, 6], [8, 0]])
|
||||
editor.copySelectedText()
|
||||
|
||||
editor.setCursorBufferPosition([1, 2])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " current < pivot ? left.push(current) : right.push(current);"
|
||||
expect(editor.lineTextForBufferRow(2)).toBe "}"
|
||||
|
||||
describe "when the first copied line has leading whitespace", ->
|
||||
it "preserves the line's leading whitespace", ->
|
||||
editor.setSelectedBufferRange([[4, 0], [6, 0]])
|
||||
editor.copySelectedText()
|
||||
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(0)).toBe " while(items.length > 0) {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " current = items.shift();"
|
||||
|
||||
describe 'when the clipboard has many selections', ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndentOnPaste", false)
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
|
||||
editor.copySelectedText()
|
||||
|
||||
it "pastes each selection separately into the buffer", ->
|
||||
atom.clipboard.write('first\nsecond', {selections: ['first', 'second'] })
|
||||
editor.copySelectedText()
|
||||
editor.moveRight()
|
||||
editor.insertText("_")
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var first = function () {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var second = function(items) {"
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var quicksort_quicksort = function () {"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var sort_sort = function(items) {"
|
||||
|
||||
describe 'and the selections count does not match', ->
|
||||
it "pastes the whole text into the buffer", ->
|
||||
atom.clipboard.write('first\nsecond\nthird', {selections: ['first', 'second', 'third'] })
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var first"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe "second"
|
||||
expect(editor.lineTextForBufferRow(2)).toBe "third = function () {"
|
||||
beforeEach ->
|
||||
editor.setSelectedBufferRanges([[[0, 4], [0, 13]]])
|
||||
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " var first"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe "second"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe "third = function(items) {"
|
||||
it "pastes the whole text into the buffer", ->
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(0)).toBe "var quicksort"
|
||||
expect(editor.lineTextForBufferRow(1)).toBe "sort = function () {"
|
||||
|
||||
describe "when a full line was cut", ->
|
||||
beforeEach ->
|
||||
editor.setCursorBufferPosition([2, 13])
|
||||
editor.cutSelectedText()
|
||||
editor.setCursorBufferPosition([2, 13])
|
||||
|
||||
it "pastes the line above the cursor and retains the cursor's column", ->
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(" var pivot = items.shift(), current, left = [], right = [];")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([3, 13])
|
||||
|
||||
describe "when a full line was copied", ->
|
||||
beforeEach ->
|
||||
editor.setCursorBufferPosition([2, 13])
|
||||
editor.copySelectedText()
|
||||
|
||||
describe "when there is a selection", ->
|
||||
it "overwrites the selection as with any copied text", ->
|
||||
editor.setSelectedBufferRange([[1, 2], [1, Infinity]])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(1)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(" ")
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([2, 2])
|
||||
|
||||
describe "when there is no selection", ->
|
||||
it "pastes the line above the cursor and retains the cursor's column", ->
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([3, 13])
|
||||
|
||||
describe ".indentSelectedRows()", ->
|
||||
describe "when nothing is selected", ->
|
||||
@@ -2668,6 +2837,18 @@ describe "TextEditor", ->
|
||||
|
||||
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [3, 0]]
|
||||
|
||||
describe ".autoIndentSelectedRows", ->
|
||||
it "auto-indents the selection", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText("function() {\ninside=true\n}\n i=1\n")
|
||||
editor.getLastSelection().setBufferRange([[2,0], [6,0]])
|
||||
editor.autoIndentSelectedRows()
|
||||
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " function() {"
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " inside=true"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
|
||||
|
||||
describe ".toggleLineCommentsInSelection()", ->
|
||||
it "toggles comments on the selected lines", ->
|
||||
editor.setSelectedBufferRange([[4, 5], [7, 5]])
|
||||
@@ -2839,18 +3020,16 @@ describe "TextEditor", ->
|
||||
expect(editor.isFoldedAtBufferRow(1)).toBeFalsy()
|
||||
expect(editor.isFoldedAtBufferRow(2)).toBeTruthy()
|
||||
|
||||
describe "begin/commitTransaction()", ->
|
||||
describe "::transact", ->
|
||||
it "restores the selection when the transaction is undone/redone", ->
|
||||
buffer.setText('1234')
|
||||
editor.setSelectedBufferRange([[0, 1], [0, 3]])
|
||||
editor.beginTransaction()
|
||||
|
||||
editor.delete()
|
||||
editor.moveToEndOfLine()
|
||||
editor.insertText('5')
|
||||
expect(buffer.getText()).toBe '145'
|
||||
|
||||
editor.commitTransaction()
|
||||
editor.transact ->
|
||||
editor.delete()
|
||||
editor.moveToEndOfLine()
|
||||
editor.insertText('5')
|
||||
expect(buffer.getText()).toBe '145'
|
||||
|
||||
editor.undo()
|
||||
expect(buffer.getText()).toBe '1234'
|
||||
@@ -3157,251 +3336,158 @@ describe "TextEditor", ->
|
||||
it "switches to the better-matched grammar and re-tokenizes the buffer", ->
|
||||
editor.destroy()
|
||||
|
||||
jsGrammar = atom.syntax.selectGrammar('a.js')
|
||||
atom.syntax.removeGrammar(jsGrammar)
|
||||
jsGrammar = atom.grammars.selectGrammar('a.js')
|
||||
atom.grammars.removeGrammar(jsGrammar)
|
||||
|
||||
waitsForPromise ->
|
||||
atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.getGrammar()).toBe atom.syntax.nullGrammar
|
||||
expect(editor.getGrammar()).toBe atom.grammars.nullGrammar
|
||||
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBe 1
|
||||
|
||||
atom.syntax.addGrammar(jsGrammar)
|
||||
atom.grammars.addGrammar(jsGrammar)
|
||||
expect(editor.getGrammar()).toBe jsGrammar
|
||||
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBeGreaterThan 1
|
||||
|
||||
describe "auto-indent", ->
|
||||
copyText = (text, {startColumn, textEditor}={}) ->
|
||||
startColumn ?= 0
|
||||
textEditor ?= editor
|
||||
textEditor.setCursorBufferPosition([0, 0])
|
||||
textEditor.insertText(text)
|
||||
numberOfNewlines = text.match(/\n/g)?.length
|
||||
endColumn = text.match(/[^\n]*$/)[0]?.length
|
||||
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
|
||||
textEditor.cutSelectedText()
|
||||
|
||||
describe "editor.autoIndent", ->
|
||||
describe "when editor.autoIndent is false (default)", ->
|
||||
describe "when `indent` is triggered", ->
|
||||
it "does not auto-indent the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", false)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
describe "when editor.autoIndent is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
|
||||
describe "when `indent` is triggered", ->
|
||||
it "auto-indents the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
describe "when a newline is added", ->
|
||||
describe "when the line preceding the newline adds a new level of indentation", ->
|
||||
it "indents the newline to one additional level of indentation beyond the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
describe "when the line preceding the newline does't add a level of indentation", ->
|
||||
it "indents the new line to the same level a as the preceding line", ->
|
||||
editor.setCursorBufferPosition([5, 14])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
|
||||
|
||||
describe "when the line preceding the newline is a comment", ->
|
||||
it "maintains the indent of the commented line", ->
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.insertText(' //')
|
||||
editor.setCursorBufferPosition([0, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 2
|
||||
|
||||
it "does not indent the line preceding the newline", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText(' var this-line-should-be-indented-more\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.setCursorBufferPosition([2, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
expect(editor.indentationForBufferRow(2)).toBe 1
|
||||
|
||||
describe "when the cursor is before whitespace", ->
|
||||
it "retains the whitespace following the cursor on the new line", ->
|
||||
editor.setText(" var sort = function() {}")
|
||||
editor.setCursorScreenPosition([0, 23])
|
||||
editor.insertNewline()
|
||||
|
||||
expect(buffer.lineForRow(0)).toBe ' var sort = function()'
|
||||
expect(buffer.lineForRow(1)).toBe ' {}'
|
||||
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
||||
|
||||
describe "when inserted text matches a decrease indent pattern", ->
|
||||
describe "when the preceding line matches an increase indent pattern", ->
|
||||
it "decreases the indentation to match that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1)
|
||||
|
||||
describe "when the preceding line doesn't match an increase indent pattern", ->
|
||||
it "decreases the indentation to be one level below that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([3, Infinity])
|
||||
editor.insertText('\n ')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3)
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3) - 1
|
||||
|
||||
it "doesn't break when decreasing the indentation on a row that has no indentation", ->
|
||||
editor.setCursorBufferPosition([12, Infinity])
|
||||
editor.insertText("\n}; # too many closing brackets!")
|
||||
expect(editor.lineTextForBufferRow(13)).toBe "}; # too many closing brackets!"
|
||||
|
||||
describe "when inserted text does not match a decrease indent pattern", ->
|
||||
it "does not decrease the indentation", ->
|
||||
editor.setCursorBufferPosition([12, 0])
|
||||
editor.insertText(' ')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' };'
|
||||
editor.insertText('\t\t')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' \t\t};'
|
||||
|
||||
describe "when the current line does not match a decrease indent pattern", ->
|
||||
it "leaves the line unchanged", ->
|
||||
editor.setCursorBufferPosition([2, 4])
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('foo')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
|
||||
runs ->
|
||||
atom.config.set('.source.js', 'editor.autoIndent', true)
|
||||
atom.config.set('.source.coffee', 'editor.autoIndent', false)
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it "does not auto-indent the line for javascript files", ->
|
||||
describe "editor.autoIndent", ->
|
||||
describe "when editor.autoIndent is false (default)", ->
|
||||
describe "when `indent` is triggered", ->
|
||||
it "does not auto-indent the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n")
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", false)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
describe "when editor.autoIndent is true", ->
|
||||
beforeEach ->
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
|
||||
describe "when `indent` is triggered", ->
|
||||
it "auto-indents the line", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.indent()
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
coffeeEditor.setCursorBufferPosition([1, 18])
|
||||
coffeeEditor.insertText("\n")
|
||||
expect(coffeeEditor.lineTextForBufferRow(2)).toBe ""
|
||||
|
||||
describe "editor.normalizeIndentOnPaste", ->
|
||||
beforeEach ->
|
||||
atom.config.set('editor.normalizeIndentOnPaste', true)
|
||||
|
||||
it "does not normalize the indentation level of the text when editor.normalizeIndentOnPaste is false", ->
|
||||
copyText(" function() {\nvar cool = 1;\n }\n")
|
||||
atom.config.set('editor.normalizeIndentOnPaste', false)
|
||||
editor.setCursorBufferPosition([5, 2])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " function() {"
|
||||
expect(editor.lineTextForBufferRow(6)).toBe "var cool = 1;"
|
||||
expect(editor.lineTextForBufferRow(7)).toBe " }"
|
||||
|
||||
describe "when the inserted text contains no newlines", ->
|
||||
it "does not adjust the indentation level of the text", ->
|
||||
editor.setCursorBufferPosition([5, 2])
|
||||
editor.insertText("foo", indentBasis: 5)
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " foo current = items.shift();"
|
||||
|
||||
it "does not adjust the whitespace if there are preceding characters", ->
|
||||
copyText(" foo")
|
||||
editor.setCursorBufferPosition([5, 30])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " current = items.shift(); foo"
|
||||
|
||||
describe "when the inserted text contains newlines", ->
|
||||
describe "when the cursor is preceded only by whitespace characters", ->
|
||||
it "normalizes indented lines to the cursor's current indentation level", ->
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2})
|
||||
editor.setCursorBufferPosition([3, 4])
|
||||
editor.pasteText()
|
||||
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " foo();"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(6)).toBe "var pivot = items.shift(), current, left = [], right = [];"
|
||||
|
||||
describe "when the cursor is preceded by non-whitespace characters", ->
|
||||
it "normalizes the indentation level of all lines based on the level of the existing first line", ->
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 0})
|
||||
describe "when a newline is added", ->
|
||||
describe "when the line preceding the newline adds a new level of indentation", ->
|
||||
it "indents the newline to one additional level of indentation beyond the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.pasteText()
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
expect(editor.lineTextForBufferRow(1)).toBe " var sort = function(items) {while (true) {"
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " foo();"
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe ""
|
||||
describe "when the line preceding the newline does't add a level of indentation", ->
|
||||
it "indents the new line to the same level a as the preceding line", ->
|
||||
editor.setCursorBufferPosition([5, 14])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
describe "when the line preceding the newline is a comment", ->
|
||||
it "maintains the indent of the commented line", ->
|
||||
editor.setCursorBufferPosition([0, 0])
|
||||
editor.insertText(' //')
|
||||
editor.setCursorBufferPosition([0, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 2
|
||||
|
||||
runs ->
|
||||
atom.config.set('.source.js', 'editor.normalizeIndentOnPaste', true)
|
||||
atom.config.set('.source.coffee', 'editor.normalizeIndentOnPaste', false)
|
||||
describe "when the line preceding the newline contains only whitespace", ->
|
||||
it "bases the new line's indentation on only the preceding line", ->
|
||||
editor.setCursorBufferPosition([6, Infinity])
|
||||
editor.insertText("\n ")
|
||||
expect(editor.getCursorBufferPosition()).toEqual([7, 2])
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
editor.insertNewline()
|
||||
expect(editor.lineTextForBufferRow(8)).toBe(" ")
|
||||
|
||||
it "normalizes the indentation level based on scoped settings", ->
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2, textEditor: coffeeEditor})
|
||||
coffeeEditor.setCursorBufferPosition([4, 4])
|
||||
coffeeEditor.pasteText()
|
||||
expect(coffeeEditor.lineTextForBufferRow(4)).toBe " while (true) {"
|
||||
expect(coffeeEditor.lineTextForBufferRow(5)).toBe " foo();"
|
||||
expect(coffeeEditor.lineTextForBufferRow(6)).toBe " }"
|
||||
it "does not indent the line preceding the newline", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText(' var this-line-should-be-indented-more\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
|
||||
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2})
|
||||
editor.setCursorBufferPosition([3, 4])
|
||||
editor.pasteText()
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " while (true) {"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " foo();"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " }"
|
||||
atom.config.set("editor.autoIndent", true)
|
||||
editor.setCursorBufferPosition([2, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(1)).toBe 1
|
||||
expect(editor.indentationForBufferRow(2)).toBe 1
|
||||
|
||||
it "autoIndentSelectedRows auto-indents the selection", ->
|
||||
editor.setCursorBufferPosition([2, 0])
|
||||
editor.insertText("function() {\ninside=true\n}\n i=1\n")
|
||||
editor.getLastSelection().setBufferRange([[2,0], [6,0]])
|
||||
editor.autoIndentSelectedRows()
|
||||
describe "when the cursor is before whitespace", ->
|
||||
it "retains the whitespace following the cursor on the new line", ->
|
||||
editor.setText(" var sort = function() {}")
|
||||
editor.setCursorScreenPosition([0, 23])
|
||||
editor.insertNewline()
|
||||
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " function() {"
|
||||
expect(editor.lineTextForBufferRow(3)).toBe " inside=true"
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " }"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
|
||||
expect(buffer.lineForRow(0)).toBe ' var sort = function()'
|
||||
expect(buffer.lineForRow(1)).toBe ' {}'
|
||||
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
|
||||
|
||||
describe "when inserted text matches a decrease indent pattern", ->
|
||||
describe "when the preceding line matches an increase indent pattern", ->
|
||||
it "decreases the indentation to match that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([1, Infinity])
|
||||
editor.insertText('\n')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1)
|
||||
|
||||
describe "when the preceding line doesn't match an increase indent pattern", ->
|
||||
it "decreases the indentation to be one level below that of the preceding line", ->
|
||||
editor.setCursorBufferPosition([3, Infinity])
|
||||
editor.insertText('\n ')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3)
|
||||
editor.insertText('}')
|
||||
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3) - 1
|
||||
|
||||
it "doesn't break when decreasing the indentation on a row that has no indentation", ->
|
||||
editor.setCursorBufferPosition([12, Infinity])
|
||||
editor.insertText("\n}; # too many closing brackets!")
|
||||
expect(editor.lineTextForBufferRow(13)).toBe "}; # too many closing brackets!"
|
||||
|
||||
describe "when inserted text does not match a decrease indent pattern", ->
|
||||
it "does not decrease the indentation", ->
|
||||
editor.setCursorBufferPosition([12, 0])
|
||||
editor.insertText(' ')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' };'
|
||||
editor.insertText('\t\t')
|
||||
expect(editor.lineTextForBufferRow(12)).toBe ' \t\t};'
|
||||
|
||||
describe "when the current line does not match a decrease indent pattern", ->
|
||||
it "leaves the line unchanged", ->
|
||||
editor.setCursorBufferPosition([2, 4])
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
editor.insertText('foo')
|
||||
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
|
||||
|
||||
describe 'when scoped settings are used', ->
|
||||
coffeeEditor = null
|
||||
beforeEach ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
waitsForPromise ->
|
||||
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
|
||||
|
||||
runs ->
|
||||
atom.config.set('.source.js', 'editor.autoIndent', true)
|
||||
atom.config.set('.source.coffee', 'editor.autoIndent', false)
|
||||
|
||||
afterEach: ->
|
||||
atom.packages.deactivatePackages()
|
||||
atom.packages.unloadPackages()
|
||||
|
||||
it "does not auto-indent the line for javascript files", ->
|
||||
editor.setCursorBufferPosition([1, 30])
|
||||
editor.insertText("\n")
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " "
|
||||
|
||||
coffeeEditor.setCursorBufferPosition([1, 18])
|
||||
coffeeEditor.insertText("\n")
|
||||
expect(coffeeEditor.lineTextForBufferRow(2)).toBe ""
|
||||
|
||||
describe "soft and hard tabs", ->
|
||||
afterEach ->
|
||||
@@ -3423,6 +3509,19 @@ describe "TextEditor", ->
|
||||
runs ->
|
||||
expect(editor.softTabs).toBe false
|
||||
|
||||
it "uses hard tabs in Makefile files", ->
|
||||
# FIXME remove once this is handled by a scoped setting in the
|
||||
# language-make package
|
||||
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-make')
|
||||
|
||||
waitsForPromise ->
|
||||
atom.project.open('Makefile').then (o) -> editor = o
|
||||
|
||||
runs ->
|
||||
expect(editor.softTabs).toBe false
|
||||
|
||||
describe ".destroy()", ->
|
||||
it "destroys all markers associated with the edit session", ->
|
||||
expect(buffer.getMarkerCount()).toBeGreaterThan 0
|
||||
@@ -3666,7 +3765,7 @@ describe "TextEditor", ->
|
||||
|
||||
it "updates the grammar based on grammar overrides", ->
|
||||
expect(editor.getGrammar().name).toBe 'JavaScript'
|
||||
atom.syntax.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
|
||||
atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
|
||||
editor.reloadGrammar()
|
||||
expect(editor.getGrammar().name).toBe 'CoffeeScript'
|
||||
|
||||
@@ -3684,7 +3783,7 @@ describe "TextEditor", ->
|
||||
atom.packages.activatePackage('language-hyperlink')
|
||||
|
||||
runs ->
|
||||
grammar = atom.syntax.selectGrammar("text.js")
|
||||
grammar = atom.grammars.selectGrammar("text.js")
|
||||
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
|
||||
|
||||
expect(tokens[0].value).toBe "var"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
path = require 'path'
|
||||
|
||||
{$, $$, WorkspaceView} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
fs = require 'fs-plus'
|
||||
temp = require 'temp'
|
||||
|
||||
@@ -20,8 +20,12 @@ describe "ThemeManager", ->
|
||||
|
||||
describe "theme getters and setters", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
atom.packages.loadPackages()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it 'getLoadedThemes get all the loaded themes', ->
|
||||
themes = themeManager.getLoadedThemes()
|
||||
expect(themes.length).toBeGreaterThan(2)
|
||||
@@ -70,7 +74,7 @@ describe "ThemeManager", ->
|
||||
describe "when the core.themes config value changes", ->
|
||||
it "add/removes stylesheets to reflect the new config value", ->
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
|
||||
spyOn(atom.styles, 'getUserStyleSheetPath').andCallFake -> null
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
@@ -92,7 +96,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style[group=theme]')).toHaveLength 1
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
|
||||
atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-ui'])
|
||||
|
||||
@@ -111,7 +115,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
reloadHandler.reset()
|
||||
expect($('style[group=theme]')).toHaveLength 1
|
||||
expect($('style[group=theme]')).toHaveLength 2
|
||||
# atom-dark-ui has an directory path, the syntax one doesn't
|
||||
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
|
||||
|
||||
@@ -130,15 +134,24 @@ describe "ThemeManager", ->
|
||||
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
|
||||
|
||||
describe "::requireStylesheet(path)", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
||||
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
|
||||
cssPath = atom.project.resolve('css.css')
|
||||
lengthBefore = $('head style').length
|
||||
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($('head style').length).toBe lengthBefore + 1
|
||||
|
||||
expect(styleElementAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
@@ -148,8 +161,10 @@ describe "ThemeManager", ->
|
||||
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
|
||||
|
||||
# doesn't append twice
|
||||
styleElementAddedHandler.reset()
|
||||
themeManager.requireStylesheet(cssPath)
|
||||
expect($('head style').length).toBe lengthBefore + 1
|
||||
expect(styleElementAddedHandler).not.toHaveBeenCalled()
|
||||
|
||||
$('head style[id*="css.css"]').remove()
|
||||
|
||||
@@ -192,6 +207,7 @@ describe "ThemeManager", ->
|
||||
disposable = themeManager.requireStylesheet(cssPath)
|
||||
expect($(document.body).css('font-weight')).toBe("bold")
|
||||
|
||||
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
|
||||
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
|
||||
@@ -199,6 +215,7 @@ describe "ThemeManager", ->
|
||||
|
||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||
|
||||
expect(styleElementRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
stylesheet = stylesheetRemovedHandler.argsForCall[0][0]
|
||||
expect(stylesheet instanceof CSSStyleSheet).toBe true
|
||||
@@ -207,14 +224,20 @@ describe "ThemeManager", ->
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
describe "base stylesheet loading", ->
|
||||
workspaceElement = null
|
||||
beforeEach ->
|
||||
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
|
||||
atom.workspaceView.append $('<atom-text-editor>')
|
||||
atom.workspaceView.attachToDom()
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
workspaceElement.appendChild document.createElement('atom-text-editor')
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
beforeEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "loads the correct values from the theme's ui-variables file", ->
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
@@ -224,7 +247,7 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
# an override loaded in the base css
|
||||
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
|
||||
|
||||
# from within the theme itself
|
||||
expect($("atom-text-editor").css("padding-top")).toBe "150px"
|
||||
@@ -241,14 +264,14 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
# an override loaded in the base css
|
||||
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
|
||||
|
||||
# from within the theme itself
|
||||
expect($("atom-text-editor").css("background-color")).toBe "rgb(0, 152, 255)"
|
||||
|
||||
describe "theme classes on the workspace", ->
|
||||
it 'adds theme-* classes to the workspace for each active theme', ->
|
||||
expect(atom.workspaceView).toHaveClass 'theme-atom-dark-ui'
|
||||
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
|
||||
|
||||
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
|
||||
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
|
||||
@@ -258,22 +281,32 @@ describe "ThemeManager", ->
|
||||
|
||||
runs ->
|
||||
# `theme-` twice as it prefixes the name with `theme-`
|
||||
expect(atom.workspaceView).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(atom.workspaceView).toHaveClass 'theme-theme-with-syntax-variables'
|
||||
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-ui'
|
||||
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-syntax'
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
|
||||
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
|
||||
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
|
||||
|
||||
describe "when the user stylesheet changes", ->
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
it "reloads it", ->
|
||||
[styleElementAddedHandler, styleElementRemovedHandler] = []
|
||||
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
|
||||
userStylesheetPath = path.join(temp.mkdirSync("atom"), 'styles.less')
|
||||
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
|
||||
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
|
||||
spyOn(atom.styles, 'getUserStyleSheetPath').andReturn userStylesheetPath
|
||||
|
||||
waitsForPromise ->
|
||||
themeManager.activateThemes()
|
||||
|
||||
runs ->
|
||||
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
|
||||
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
|
||||
|
||||
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
|
||||
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
|
||||
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
|
||||
@@ -288,14 +321,19 @@ describe "ThemeManager", ->
|
||||
runs ->
|
||||
expect($(document.body).css('border-style')).toBe 'dashed'
|
||||
|
||||
expect(styleElementRemovedHandler).toHaveBeenCalled()
|
||||
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dotted'
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted'
|
||||
|
||||
expect(styleElementAddedHandler).toHaveBeenCalled()
|
||||
expect(styleElementAddedHandler.argsForCall[0][0].textContent).toContain 'dashed'
|
||||
expect(stylesheetAddedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
|
||||
|
||||
expect(stylesheetsChangedHandler).toHaveBeenCalled()
|
||||
|
||||
styleElementRemovedHandler.reset()
|
||||
stylesheetRemovedHandler.reset()
|
||||
stylesheetsChangedHandler.reset()
|
||||
fs.removeSync(userStylesheetPath)
|
||||
@@ -304,6 +342,8 @@ describe "ThemeManager", ->
|
||||
themeManager.loadUserStylesheet.callCount is 2
|
||||
|
||||
runs ->
|
||||
expect(styleElementRemovedHandler).toHaveBeenCalled()
|
||||
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dashed'
|
||||
expect(stylesheetRemovedHandler).toHaveBeenCalled()
|
||||
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
|
||||
expect($(document.body).css('border-style')).toBe 'none'
|
||||
|
||||
@@ -522,7 +522,7 @@ describe "TokenizedBuffer", ->
|
||||
buffer = atom.project.bufferForPathSync()
|
||||
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
|
||||
tokenizedBuffer = new TokenizedBuffer({buffer})
|
||||
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
|
||||
tokenizedBuffer.setGrammar(atom.grammars.selectGrammar('test.erb'))
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
TooltipManager = require '../src/tooltip-manager'
|
||||
{$} = require '../src/space-pen-extensions'
|
||||
|
||||
describe "TooltipManager", ->
|
||||
[manager, element] = []
|
||||
|
||||
beforeEach ->
|
||||
manager = new TooltipManager
|
||||
element = document.createElement('div')
|
||||
element.classList.add('foo')
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
hover = (element, fn) ->
|
||||
$(element).trigger 'mouseenter'
|
||||
advanceClock(manager.defaults.delay.show)
|
||||
fn()
|
||||
$(element).trigger 'mouseleave'
|
||||
advanceClock(manager.defaults.delay.hide)
|
||||
|
||||
describe "::add(target, options)", ->
|
||||
describe "when the target is an element", ->
|
||||
it "creates a tooltip based on the given options when hovering over the target element", ->
|
||||
manager.add element, title: "Title"
|
||||
hover element, ->
|
||||
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
|
||||
|
||||
describe "when a keyBindingCommand is specified", ->
|
||||
describe "when a title is specified", ->
|
||||
it "appends the key binding corresponding to the command to the title", ->
|
||||
atom.keymaps.add 'test',
|
||||
'.foo': 'ctrl-x ctrl-y': 'test-command'
|
||||
'.bar': 'ctrl-x ctrl-z': 'test-command'
|
||||
|
||||
manager.add element, title: "Title", keyBindingCommand: 'test-command'
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement).toHaveText "Title ⌃X ⌃Y"
|
||||
|
||||
describe "when no title is specified", ->
|
||||
it "shows the key binding corresponding to the command alone", ->
|
||||
atom.keymaps.add 'test', '.foo': 'ctrl-x ctrl-y': 'test-command'
|
||||
|
||||
manager.add element, keyBindingCommand: 'test-command'
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement).toHaveText "⌃X ⌃Y"
|
||||
|
||||
describe "when a keyBindingTarget is specified", ->
|
||||
it "looks up the key binding relative to the target", ->
|
||||
atom.keymaps.add 'test',
|
||||
'.bar': 'ctrl-x ctrl-z': 'test-command'
|
||||
'.foo': 'ctrl-x ctrl-y': 'test-command'
|
||||
|
||||
manager.add element, keyBindingCommand: 'test-command', keyBindingTarget: element
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement).toHaveText "⌃X ⌃Y"
|
||||
|
||||
it "does not display the keybinding if there is nothing mapped to the specified keyBindingCommand", ->
|
||||
manager.add element, title: 'A Title', keyBindingCommand: 'test-command', keyBindingTarget: element
|
||||
|
||||
hover element, ->
|
||||
tooltipElement = document.body.querySelector(".tooltip")
|
||||
expect(tooltipElement.textContent).toBe "A Title"
|
||||
|
||||
describe "when .dispose() is called on the returned disposable", ->
|
||||
it "no longer displays the tooltip on hover", ->
|
||||
disposable = manager.add element, title: "Title"
|
||||
|
||||
hover element, ->
|
||||
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
|
||||
|
||||
disposable.dispose()
|
||||
|
||||
hover element, ->
|
||||
expect(document.body.querySelector(".tooltip")).toBeNull()
|
||||
@@ -25,47 +25,27 @@ describe "ViewRegistry", ->
|
||||
|
||||
describe "when passed a model object", ->
|
||||
describe "when a view provider is registered matching the object's constructor", ->
|
||||
describe "when the provider has a viewConstructor property", ->
|
||||
it "constructs a view element and assigns the model on it", ->
|
||||
class TestModel
|
||||
it "constructs a view element and assigns the model on it", ->
|
||||
class TestModel
|
||||
|
||||
class TestModelSubclass extends TestModel
|
||||
class TestModelSubclass extends TestModel
|
||||
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
class TestView
|
||||
initialize: (@model) -> this
|
||||
|
||||
model = new TestModel
|
||||
model = new TestModel
|
||||
|
||||
registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
viewConstructor: TestView
|
||||
registry.addViewProvider TestModel, (model) ->
|
||||
new TestView().initialize(model)
|
||||
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
|
||||
subclassModel = new TestModelSubclass
|
||||
view2 = registry.getView(subclassModel)
|
||||
expect(view2 instanceof TestView).toBe true
|
||||
expect(view2.model).toBe subclassModel
|
||||
|
||||
describe "when the provider has a createView method", ->
|
||||
it "constructs a view element by calling the createView method with the model", ->
|
||||
class TestModel
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
|
||||
registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
createView: (model) ->
|
||||
view = new TestView
|
||||
view.setModel(model)
|
||||
view
|
||||
|
||||
model = new TestModel
|
||||
view = registry.getView(model)
|
||||
expect(view instanceof TestView).toBe true
|
||||
expect(view.model).toBe model
|
||||
subclassModel = new TestModelSubclass
|
||||
view2 = registry.getView(subclassModel)
|
||||
expect(view2 instanceof TestView).toBe true
|
||||
expect(view2.model).toBe subclassModel
|
||||
|
||||
describe "when no view provider is registered for the object's constructor", ->
|
||||
describe "when the object has a .getViewClass() method", ->
|
||||
@@ -97,10 +77,10 @@ describe "ViewRegistry", ->
|
||||
it "returns a disposable that can be used to remove the provider", ->
|
||||
class TestModel
|
||||
class TestView
|
||||
setModel: (@model) ->
|
||||
disposable = registry.addViewProvider
|
||||
modelConstructor: TestModel
|
||||
viewConstructor: TestView
|
||||
initialize: (@model) -> this
|
||||
|
||||
disposable = registry.addViewProvider TestModel, (model) ->
|
||||
new TestView().initialize(model)
|
||||
|
||||
expect(registry.getView(new TestModel) instanceof TestView).toBe true
|
||||
disposable.dispose()
|
||||
|
||||
+15
-18
@@ -1,4 +1,4 @@
|
||||
{$, $$} = require 'atom'
|
||||
{$, $$} = require '../src/space-pen-extensions'
|
||||
path = require 'path'
|
||||
TextEditor = require '../src/text-editor'
|
||||
WindowEventHandler = require '../src/window-event-handler'
|
||||
@@ -95,13 +95,13 @@ describe "Window", ->
|
||||
describe ".unloadEditorWindow()", ->
|
||||
it "saves the serialized state of the window so it can be deserialized after reload", ->
|
||||
workspaceState = atom.workspace.serialize()
|
||||
syntaxState = atom.syntax.serialize()
|
||||
syntaxState = atom.grammars.serialize()
|
||||
projectState = atom.project.serialize()
|
||||
|
||||
atom.unloadEditorWindow()
|
||||
|
||||
expect(atom.state.workspace).toEqual workspaceState
|
||||
expect(atom.state.syntax).toEqual syntaxState
|
||||
expect(atom.state.grammars).toEqual syntaxState
|
||||
expect(atom.state.project).toEqual projectState
|
||||
expect(atom.saveSync).toHaveBeenCalled()
|
||||
|
||||
@@ -112,9 +112,9 @@ describe "Window", ->
|
||||
|
||||
runs ->
|
||||
buffer = atom.workspace.getActivePaneItem().buffer
|
||||
pane = atom.workspaceView.getActivePaneView()
|
||||
pane.splitRight(pane.copyActiveItem())
|
||||
expect(atom.workspaceView.find('atom-text-editor').length).toBe 2
|
||||
pane = atom.workspace.getActivePane()
|
||||
pane.splitRight(copyActiveItem: true)
|
||||
expect(atom.workspace.getTextEditors().length).toBe 2
|
||||
|
||||
atom.removeEditorWindow()
|
||||
|
||||
@@ -128,17 +128,15 @@ describe "Window", ->
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
|
||||
event = $.Event(type)
|
||||
event.originalEvent = { dataTransfer }
|
||||
event.preventDefault = ->
|
||||
event.stopPropagation = ->
|
||||
event = new CustomEvent("drop")
|
||||
event.dataTransfer = dataTransfer
|
||||
event
|
||||
|
||||
describe "when a file is dragged to window", ->
|
||||
it "opens it", ->
|
||||
spyOn(atom, "open")
|
||||
event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ])
|
||||
$(document).trigger(event)
|
||||
document.dispatchEvent(event)
|
||||
expect(atom.open.callCount).toBe 1
|
||||
expect(atom.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2']
|
||||
|
||||
@@ -146,7 +144,7 @@ describe "Window", ->
|
||||
it "does nothing", ->
|
||||
spyOn(atom, "open")
|
||||
event = buildDragEvent("drop", [])
|
||||
$(document).trigger(event)
|
||||
document.dispatchEvent(event)
|
||||
expect(atom.open).not.toHaveBeenCalled()
|
||||
|
||||
describe "when a link is clicked", ->
|
||||
@@ -259,24 +257,23 @@ describe "Window", ->
|
||||
|
||||
describe "when the opened path exists", ->
|
||||
it "sets the project path to the opened path", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
|
||||
|
||||
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
|
||||
expect(atom.project.getPaths()[0]).toBe __dirname
|
||||
|
||||
describe "when the opened path does not exist but its parent directory does", ->
|
||||
it "sets the project path to the opened path's parent directory", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: path.join(__dirname, 'this-path-does-not-exist.txt')}])
|
||||
|
||||
pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
|
||||
atom.getCurrentWindow().send 'message', 'open-path', {pathToOpen}
|
||||
expect(atom.project.getPaths()[0]).toBe __dirname
|
||||
|
||||
describe "when the opened path is a file", ->
|
||||
it "opens it in the workspace", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
|
||||
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
|
||||
|
||||
expect(atom.workspace.open.mostRecentCall.args[0]).toBe __filename
|
||||
|
||||
describe "when the opened path is a directory", ->
|
||||
it "does not open it in the workspace", ->
|
||||
$(window).trigger('window:open-path', [{pathToOpen: __dirname}])
|
||||
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __dirname
|
||||
|
||||
expect(atom.workspace.open.callCount).toBe 0
|
||||
|
||||
@@ -356,7 +356,7 @@ describe "Workspace", ->
|
||||
atom.workspace.open('sample.coffee')
|
||||
|
||||
runs ->
|
||||
atom.workspace.getActiveEditor().setText """
|
||||
atom.workspace.getActiveTextEditor().setText """
|
||||
i = /test/; #FIXME
|
||||
"""
|
||||
|
||||
@@ -375,7 +375,7 @@ describe "Workspace", ->
|
||||
describe "document.title", ->
|
||||
describe "when the project has no path", ->
|
||||
it "sets the title to 'untitled'", ->
|
||||
atom.project.setPath(undefined)
|
||||
atom.project.setPaths([])
|
||||
expect(document.title).toBe 'untitled - Atom'
|
||||
|
||||
describe "when the project has a path", ->
|
||||
@@ -458,46 +458,98 @@ describe "Workspace", ->
|
||||
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
|
||||
|
||||
describe "adding panels", ->
|
||||
class TestPanel
|
||||
constructior: ->
|
||||
class TestItem
|
||||
|
||||
class TestItemElement extends HTMLElement
|
||||
constructor: ->
|
||||
initialize: (@model) -> this
|
||||
getModel: -> @model
|
||||
|
||||
beforeEach ->
|
||||
atom.views.addViewProvider TestItem, (model) ->
|
||||
new TestItemElement().initialize(model)
|
||||
|
||||
describe '::addLeftPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getLeftPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addLeftPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addLeftPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getLeftPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addRightPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getRightPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addRightPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addRightPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getRightPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addTopPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getTopPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addTopPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addTopPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getTopPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addBottomPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getBottomPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addBottomPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addBottomPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getBottomPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe '::addModalPanel(model)', ->
|
||||
it 'adds a panel to the correct panel container', ->
|
||||
expect(atom.workspace.getModalPanels().length).toBe(0)
|
||||
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = atom.workspace.addModalPanel(item: new TestPanel())
|
||||
|
||||
model = new TestItem
|
||||
panel = atom.workspace.addModalPanel(item: model)
|
||||
|
||||
expect(panel).toBeDefined()
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(panel.getClassName()).toBe 'overlay from-top' # the default
|
||||
|
||||
itemView = atom.views.getView(atom.workspace.getModalPanels()[0].getItem())
|
||||
expect(itemView instanceof TestItemElement).toBe(true)
|
||||
expect(itemView.getModel()).toBe(model)
|
||||
|
||||
describe "::panelForItem(item)", ->
|
||||
it "returns the panel associated with the item", ->
|
||||
item = new TestItem
|
||||
panel = atom.workspace.addLeftPanel(item: item)
|
||||
|
||||
itemWithNoPanel = new TestItem
|
||||
|
||||
expect(atom.workspace.panelForItem(item)).toBe panel
|
||||
expect(atom.workspace.panelForItem(itemWithNoPanel)).toBe null
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{$, $$, WorkspaceView, View} = require 'atom'
|
||||
{$, $$, View} = require '../src/space-pen-extensions'
|
||||
Q = require 'q'
|
||||
path = require 'path'
|
||||
temp = require 'temp'
|
||||
@@ -10,6 +10,8 @@ describe "WorkspaceView", ->
|
||||
pathToOpen = null
|
||||
|
||||
beforeEach ->
|
||||
jasmine.snapshotDeprecations()
|
||||
|
||||
atom.project.setPaths([atom.project.resolve('dir')])
|
||||
pathToOpen = atom.project.resolve('a')
|
||||
atom.workspace = new Workspace
|
||||
@@ -20,6 +22,9 @@ describe "WorkspaceView", ->
|
||||
waitsForPromise ->
|
||||
atom.workspace.open(pathToOpen)
|
||||
|
||||
afterEach ->
|
||||
jasmine.restoreDeprecationsSnapshot()
|
||||
|
||||
describe "@deserialize()", ->
|
||||
viewState = null
|
||||
|
||||
@@ -277,15 +282,15 @@ describe "WorkspaceView", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
it 'inserts panel container elements in the correct places in the DOM', ->
|
||||
leftContainer = workspaceElement.querySelector('atom-panel-container[location="left"]')
|
||||
rightContainer = workspaceElement.querySelector('atom-panel-container[location="right"]')
|
||||
leftContainer = workspaceElement.querySelector('atom-panel-container.left')
|
||||
rightContainer = workspaceElement.querySelector('atom-panel-container.right')
|
||||
expect(leftContainer.nextSibling).toBe workspaceElement.verticalAxis
|
||||
expect(rightContainer.previousSibling).toBe workspaceElement.verticalAxis
|
||||
|
||||
topContainer = workspaceElement.querySelector('atom-panel-container[location="top"]')
|
||||
bottomContainer = workspaceElement.querySelector('atom-panel-container[location="bottom"]')
|
||||
topContainer = workspaceElement.querySelector('atom-panel-container.top')
|
||||
bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
|
||||
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
|
||||
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
|
||||
|
||||
modalContainer = workspaceElement.querySelector('atom-panel-container[location="modal"]')
|
||||
modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
|
||||
expect(modalContainer.parentNode).toBe workspaceElement
|
||||
|
||||
+112
-20
@@ -11,6 +11,7 @@ _ = require 'underscore-plus'
|
||||
{Emitter} = require 'event-kit'
|
||||
{Model} = require 'theorist'
|
||||
fs = require 'fs-plus'
|
||||
{convertStackTrace, convertLine} = require 'coffeestack'
|
||||
|
||||
{$} = require './space-pen-extensions'
|
||||
WindowEventHandler = require './window-event-handler'
|
||||
@@ -33,6 +34,23 @@ class Atom extends Model
|
||||
startTime = Date.now()
|
||||
atom = @deserialize(@loadState(mode)) ? new this({mode, @version})
|
||||
atom.deserializeTimings.atom = Date.now() - startTime
|
||||
|
||||
workspaceViewDeprecationMessage = """
|
||||
atom.workspaceView is no longer available.
|
||||
In most cases you will not need the view. See the Workspace docs for
|
||||
alternatives: https://atom.io/docs/api/latest/Workspace.
|
||||
If you do need the view, please use `atom.views.getView(atom.workspace)`,
|
||||
which returns an HTMLElement.
|
||||
"""
|
||||
|
||||
Object.defineProperty atom, 'workspaceView',
|
||||
get: ->
|
||||
deprecate(workspaceViewDeprecationMessage)
|
||||
atom.__workspaceView
|
||||
set: (newValue) ->
|
||||
deprecate(workspaceViewDeprecationMessage)
|
||||
atom.__workspaceView = newValue
|
||||
|
||||
atom
|
||||
|
||||
# Deserializes the Atom environment from a state object
|
||||
@@ -116,6 +134,9 @@ class Atom extends Model
|
||||
# Public: A {Clipboard} instance
|
||||
clipboard: null
|
||||
|
||||
# A {ServiceHub} instance
|
||||
services: null
|
||||
|
||||
# Public: A {ContextMenuManager} instance
|
||||
contextMenu: null
|
||||
|
||||
@@ -125,11 +146,17 @@ class Atom extends Model
|
||||
# Public: A {KeymapManager} instance
|
||||
keymaps: null
|
||||
|
||||
# Public: A {TooltipManager} instance
|
||||
tooltips: null
|
||||
|
||||
# Experimental: A {NotificationManager} instance
|
||||
notifications: null
|
||||
|
||||
# Public: A {Project} instance
|
||||
project: null
|
||||
|
||||
# Public: A {Syntax} instance
|
||||
syntax: null
|
||||
# Public: A {GrammarRegistry} instance
|
||||
grammars: null
|
||||
|
||||
# Public: A {PackageManager} instance
|
||||
packages: null
|
||||
@@ -137,6 +164,9 @@ class Atom extends Model
|
||||
# Public: A {ThemeManager} instance
|
||||
themes: null
|
||||
|
||||
# Public: A {StyleManager} instance
|
||||
styles: null
|
||||
|
||||
# Public: A {DeserializerManager} instance
|
||||
deserializers: null
|
||||
|
||||
@@ -146,9 +176,6 @@ class Atom extends Model
|
||||
# Public: A {Workspace} instance
|
||||
workspace: null
|
||||
|
||||
# Public: A {WorkspaceView} instance
|
||||
workspaceView: null
|
||||
|
||||
###
|
||||
Section: Construction and Destruction
|
||||
###
|
||||
@@ -172,12 +199,29 @@ class Atom extends Model
|
||||
unless @inDevMode() or @inSpecMode()
|
||||
require('grim').deprecate = ->
|
||||
|
||||
sourceMapCache = {}
|
||||
|
||||
window.onerror = =>
|
||||
@openDevTools()
|
||||
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
|
||||
@lastUncaughtError = Array::slice.call(arguments)
|
||||
[message, url, line, column, originalError] = @lastUncaughtError
|
||||
|
||||
convertedLine = convertLine(url, line, column, sourceMapCache)
|
||||
{line, column} = convertedLine if convertedLine?
|
||||
originalError.stack = convertStackTrace(originalError.stack, sourceMapCache) if originalError
|
||||
|
||||
eventObject = {message, url, line, column, originalError}
|
||||
|
||||
openDevTools = true
|
||||
eventObject.preventDefault = -> openDevTools = false
|
||||
|
||||
@emitter.emit 'will-throw-error', eventObject
|
||||
|
||||
if openDevTools
|
||||
@openDevTools()
|
||||
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
|
||||
|
||||
@emit 'uncaught-error', arguments...
|
||||
@emitter.emit 'did-throw-error', arguments...
|
||||
@emitter.emit 'did-throw-error', {message, url, line, column, originalError}
|
||||
|
||||
@unsubscribe()
|
||||
@setBodyPlatformClass()
|
||||
@@ -188,9 +232,12 @@ class Atom extends Model
|
||||
KeymapManager = require './keymap-extensions'
|
||||
ViewRegistry = require './view-registry'
|
||||
CommandRegistry = require './command-registry'
|
||||
TooltipManager = require './tooltip-manager'
|
||||
NotificationManager = require './notification-manager'
|
||||
PackageManager = require './package-manager'
|
||||
Clipboard = require './clipboard'
|
||||
Syntax = require './syntax'
|
||||
ServiceHub = require './service-hub'
|
||||
GrammarRegistry = require './grammar-registry'
|
||||
ThemeManager = require './theme-manager'
|
||||
StyleManager = require './style-manager'
|
||||
ContextMenuManager = require './context-menu-manager'
|
||||
@@ -213,6 +260,9 @@ class Atom extends Model
|
||||
@config = new Config({configDirPath, resourcePath})
|
||||
@keymaps = new KeymapManager({configDirPath, resourcePath})
|
||||
@keymap = @keymaps # Deprecated
|
||||
@keymaps.subscribeToFileReadFailure()
|
||||
@tooltips = new TooltipManager
|
||||
@notifications = new NotificationManager
|
||||
@commands = new CommandRegistry
|
||||
@views = new ViewRegistry
|
||||
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
|
||||
@@ -222,8 +272,13 @@ class Atom extends Model
|
||||
@contextMenu = new ContextMenuManager({resourcePath, devMode})
|
||||
@menu = new MenuManager({resourcePath})
|
||||
@clipboard = new Clipboard()
|
||||
@services = new ServiceHub
|
||||
|
||||
@syntax = @deserializers.deserialize(@state.syntax) ? new Syntax()
|
||||
@grammars = @deserializers.deserialize(@state.grammars ? @state.syntax) ? new GrammarRegistry()
|
||||
|
||||
Object.defineProperty this, 'syntax', get: ->
|
||||
deprecate "The atom.syntax global is deprecated. Use atom.grammars instead."
|
||||
@grammars
|
||||
|
||||
@subscribe @packages.onDidActivateAll => @watchThemes()
|
||||
|
||||
@@ -248,10 +303,31 @@ class Atom extends Model
|
||||
onDidBeep: (callback) ->
|
||||
@emitter.on 'did-beep', callback
|
||||
|
||||
# Extended: Invoke the given callback when there is an unhandled error, but
|
||||
# before the devtools pop open
|
||||
#
|
||||
# * `callback` {Function} to be called whenever there is an unhandled error
|
||||
# * `event` {Object}
|
||||
# * `originalError` {Object} the original error object
|
||||
# * `message` {String} the original error object
|
||||
# * `url` {String} Url to the file where the error originated.
|
||||
# * `line` {Number}
|
||||
# * `column` {Number}
|
||||
# * `preventDefault` {Function} call this to avoid popping up the dev tools.
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onWillThrowError: (callback) ->
|
||||
@emitter.on 'will-throw-error', callback
|
||||
|
||||
# Extended: Invoke the given callback whenever there is an unhandled error.
|
||||
#
|
||||
# * `callback` {Function} to be called whenever there is an unhandled error
|
||||
# * `errorMessage` {String}
|
||||
# * `event` {Object}
|
||||
# * `originalError` {Object} the original error object
|
||||
# * `message` {String} the original error object
|
||||
# * `url` {String} Url to the file where the error originated.
|
||||
# * `line` {Number}
|
||||
# * `column` {Number}
|
||||
#
|
||||
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
|
||||
onDidThrowError: (callback) ->
|
||||
@@ -503,15 +579,19 @@ class Atom extends Model
|
||||
@packages.activate()
|
||||
@keymaps.loadUserKeymap()
|
||||
@requireUserInitScript() unless safeMode
|
||||
|
||||
@menu.update()
|
||||
@subscribe @config.onDidChange 'core.autoHideMenuBar', ({newValue}) =>
|
||||
@setAutoHideMenuBar(newValue)
|
||||
@setAutoHideMenuBar(true) if @config.get('core.autoHideMenuBar')
|
||||
|
||||
maximize = dimensions?.maximized and process.platform isnt 'darwin'
|
||||
@displayWindow({maximize})
|
||||
|
||||
unloadEditorWindow: ->
|
||||
return if not @project and not @workspaceView
|
||||
return if not @project
|
||||
|
||||
@state.syntax = @syntax.serialize()
|
||||
@state.grammars = @grammars.serialize()
|
||||
@state.project = @project.serialize()
|
||||
@state.workspace = @workspace.serialize()
|
||||
@packages.deactivatePackages()
|
||||
@@ -520,10 +600,10 @@ class Atom extends Model
|
||||
@windowState = null
|
||||
|
||||
removeEditorWindow: ->
|
||||
return if not @project and not @workspaceView
|
||||
return if not @project
|
||||
|
||||
@workspaceView?.remove()
|
||||
@workspaceView = null
|
||||
@workspace?.destroy()
|
||||
@workspace = null
|
||||
@project?.destroy()
|
||||
@project = null
|
||||
|
||||
@@ -536,7 +616,7 @@ class Atom extends Model
|
||||
# Essential: Visually and audibly trigger a beep.
|
||||
beep: ->
|
||||
shell.beep() if @config.get('core.audioBeep')
|
||||
@workspaceView.trigger 'beep'
|
||||
@__workspaceView?.trigger 'beep'
|
||||
@emitter.emit 'did-beep'
|
||||
|
||||
# Essential: A flexible way to open a dialog akin to an alert dialog.
|
||||
@@ -612,11 +692,13 @@ class Atom extends Model
|
||||
|
||||
startTime = Date.now()
|
||||
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
|
||||
@workspaceView = @views.getView(@workspace).__spacePenView
|
||||
|
||||
workspaceElement = @views.getView(@workspace)
|
||||
@__workspaceView = workspaceElement.__spacePenView
|
||||
@deserializeTimings.workspace = Date.now() - startTime
|
||||
|
||||
@keymaps.defaultTarget = @workspaceView[0]
|
||||
$(@workspaceViewParentSelector).append(@workspaceView)
|
||||
@keymaps.defaultTarget = workspaceElement
|
||||
document.querySelector(@workspaceViewParentSelector).appendChild(workspaceElement)
|
||||
|
||||
deserializePackageStates: ->
|
||||
@packages.packageStates = @state.packageStates ? {}
|
||||
@@ -713,6 +795,12 @@ class Atom extends Model
|
||||
else
|
||||
window[key] = value
|
||||
|
||||
onUpdateAvailable: (callback) ->
|
||||
@emitter.on 'update-available', callback
|
||||
|
||||
updateAvailable: (details) ->
|
||||
@emitter.emit 'update-available', details
|
||||
|
||||
# Deprecated: Callers should be converted to use atom.deserializers
|
||||
registerRepresentationClass: ->
|
||||
deprecate("Callers should be converted to use atom.deserializers")
|
||||
@@ -723,3 +811,7 @@ class Atom extends Model
|
||||
|
||||
setBodyPlatformClass: ->
|
||||
document.body.classList.add("platform-#{process.platform}")
|
||||
|
||||
setAutoHideMenuBar: (autoHide) ->
|
||||
ipc.send('call-window-method', 'setAutoHideMenuBar', autoHide)
|
||||
ipc.send('call-window-method', 'setMenuBarVisibility', !autoHide)
|
||||
|
||||
@@ -238,6 +238,11 @@ class AtomApplication
|
||||
win = BrowserWindow.fromWebContents(event.sender)
|
||||
win[method](args...)
|
||||
|
||||
clipboard = null
|
||||
ipc.on 'write-text-to-selection-clipboard', (event, selectedText) ->
|
||||
clipboard ?= require 'clipboard'
|
||||
clipboard.writeText(selectedText, 'selection')
|
||||
|
||||
# Public: Executes the given command.
|
||||
#
|
||||
# If it isn't handled globally, delegate to the currently focused window.
|
||||
|
||||
@@ -58,7 +58,7 @@ class AtomWindow
|
||||
@browserWindow.loadUrl @getUrl(loadSettings)
|
||||
@browserWindow.focusOnWebView() if @isSpec
|
||||
|
||||
@openPath(pathToOpen, initialLine, initialColumn)
|
||||
@openPath(pathToOpen, initialLine, initialColumn) unless @isSpecWindow()
|
||||
|
||||
getUrl: (loadSettingsObj) ->
|
||||
# Ignore the windowState when passing loadSettings via URL, since it could
|
||||
@@ -143,10 +143,13 @@ class AtomWindow
|
||||
openPath: (pathToOpen, initialLine, initialColumn) ->
|
||||
if @loaded
|
||||
@focus()
|
||||
@sendCommand('window:open-path', {pathToOpen, initialLine, initialColumn})
|
||||
@sendMessage 'open-path', {pathToOpen, initialLine, initialColumn}
|
||||
else
|
||||
@browserWindow.once 'window:loaded', => @openPath(pathToOpen, initialLine, initialColumn)
|
||||
|
||||
sendMessage: (message, detail) ->
|
||||
@browserWindow.webContents.send 'message', message, detail
|
||||
|
||||
sendCommand: (command, args...) ->
|
||||
if @isSpecWindow()
|
||||
unless global.atomApplication.sendCommandToFirstResponder(command)
|
||||
@@ -154,7 +157,6 @@ class AtomWindow
|
||||
when 'window:reload' then @reload()
|
||||
when 'window:toggle-dev-tools' then @toggleDevTools()
|
||||
when 'window:close' then @close()
|
||||
when 'window:update-available' then @sendCommandToBrowserWindow(command, args...) # For spec testing
|
||||
else if @isWebViewFocused()
|
||||
@sendCommandToBrowserWindow(command, args...)
|
||||
else
|
||||
|
||||
Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais
Referência em uma Nova Issue
Bloquear um usuário