styles.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /**
  2. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. import StyleProxy from '../../src/view/styles';
  6. describe( 'Styles', () => {
  7. let styleProxy;
  8. beforeEach( () => {
  9. styleProxy = new StyleProxy();
  10. } );
  11. describe( 'getStyleNames()', () => {
  12. it( 'should output custom style names', () => {
  13. styleProxy.setStyle( 'foo: 2;bar: baz;foo-bar-baz:none;' );
  14. expect( styleProxy.getStyleNames() ).to.deep.equal( [ 'bar', 'foo', 'foo-bar-baz' ] );
  15. } );
  16. it( 'should output full names for shorthand', () => {
  17. styleProxy.setStyle( 'margin: 1px;margin-left: 2em;' );
  18. expect( styleProxy.getStyleNames() ).to.deep.equal( [ 'margin' ] );
  19. } );
  20. } );
  21. describe( 'styles rules', () => {
  22. describe( 'border', () => {
  23. it( 'should parse border shorthand', () => {
  24. styleProxy.setStyle( 'border:1px solid blue;' );
  25. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  26. top: { color: 'blue', style: 'solid', width: '1px' },
  27. right: { color: 'blue', style: 'solid', width: '1px' },
  28. bottom: { color: 'blue', style: 'solid', width: '1px' },
  29. left: { color: 'blue', style: 'solid', width: '1px' }
  30. } );
  31. } );
  32. it( 'should parse border shorthand with other shorthands', () => {
  33. styleProxy.setStyle( 'border:1px solid blue;border-left:#665511 dashed 2.7em;border-top:7px dotted #ccc;' );
  34. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  35. top: { color: '#ccc', style: 'dotted', width: '7px' },
  36. right: { color: 'blue', style: 'solid', width: '1px' },
  37. bottom: { color: 'blue', style: 'solid', width: '1px' },
  38. left: { color: '#665511', style: 'dashed', width: '2.7em' }
  39. } );
  40. } );
  41. it( 'should output inline shorthand rules', () => {
  42. styleProxy.setStyle( 'border:1px solid blue;' );
  43. expect( styleProxy.getInlineStyle() ).to.equal( 'border:1px solid blue;' );
  44. expect( styleProxy.getInlineRule( 'border' ) ).to.equal( '1px solid blue' );
  45. expect( styleProxy.getInlineRule( 'border-top' ) ).to.equal( '1px solid blue' );
  46. expect( styleProxy.getInlineRule( 'border-right' ) ).to.equal( '1px solid blue' );
  47. expect( styleProxy.getInlineRule( 'border-bottom' ) ).to.equal( '1px solid blue' );
  48. expect( styleProxy.getInlineRule( 'border-left' ) ).to.equal( '1px solid blue' );
  49. } );
  50. it( 'should output inline shorthand rules', () => {
  51. styleProxy.setStyle( 'border:1px solid blue;border-left:#665511 dashed 2.7em;border-top:7px dotted #ccc;' );
  52. expect( styleProxy.getInlineStyle() ).to.equal(
  53. 'border-top:7px dotted #ccc;border-right:1px solid blue;border-bottom:1px solid blue;border-left:2.7em dashed #665511;'
  54. );
  55. expect( styleProxy.getInlineRule( 'border' ) ).to.be.undefined;
  56. expect( styleProxy.getInlineRule( 'border-top' ) ).to.equal( '7px dotted #ccc' );
  57. expect( styleProxy.getInlineRule( 'border-right' ) ).to.equal( '1px solid blue' );
  58. expect( styleProxy.getInlineRule( 'border-bottom' ) ).to.equal( '1px solid blue' );
  59. expect( styleProxy.getInlineRule( 'border-left' ) ).to.equal( '2.7em dashed #665511' );
  60. } );
  61. it( 'should merge rules on insert other shorthand', () => {
  62. styleProxy.setStyle( 'border:1px solid blue;' );
  63. styleProxy.insertRule( 'border-left', '#665511 dashed 2.7em' );
  64. styleProxy.insertRule( 'border-top', '7px dotted #ccc' );
  65. expect( styleProxy.getInlineStyle() ).to.equal(
  66. 'border-top:7px dotted #ccc;border-right:1px solid blue;border-bottom:1px solid blue;border-left:2.7em dashed #665511;'
  67. );
  68. expect( styleProxy.getInlineRule( 'border' ) ).to.be.undefined;
  69. expect( styleProxy.getInlineRule( 'border-top' ) ).to.equal( '7px dotted #ccc' );
  70. expect( styleProxy.getInlineRule( 'border-right' ) ).to.equal( '1px solid blue' );
  71. expect( styleProxy.getInlineRule( 'border-bottom' ) ).to.equal( '1px solid blue' );
  72. expect( styleProxy.getInlineRule( 'border-left' ) ).to.equal( '2.7em dashed #665511' );
  73. } );
  74. it( 'should output', () => {
  75. styleProxy.setStyle( 'border:1px solid blue;' );
  76. styleProxy.removeRule( 'border-top' );
  77. expect( styleProxy.getInlineStyle() ).to.equal(
  78. 'border-right:1px solid blue;border-bottom:1px solid blue;border-left:1px solid blue;'
  79. );
  80. expect( styleProxy.getInlineRule( 'border' ) ).to.be.undefined;
  81. expect( styleProxy.getInlineRule( 'border-top' ) ).to.be.undefined;
  82. expect( styleProxy.getInlineRule( 'border-right' ) ).to.equal( '1px solid blue' );
  83. expect( styleProxy.getInlineRule( 'border-bottom' ) ).to.equal( '1px solid blue' );
  84. expect( styleProxy.getInlineRule( 'border-left' ) ).to.equal( '1px solid blue' );
  85. } );
  86. describe( 'border-color', () => {
  87. it( 'should set all border colors (1 value defined)', () => {
  88. styleProxy.setStyle( 'border-color:cyan;' );
  89. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  90. top: { color: 'cyan' },
  91. left: { color: 'cyan' },
  92. bottom: { color: 'cyan' },
  93. right: { color: 'cyan' }
  94. } );
  95. } );
  96. it( 'should set all border colors (2 values defined)', () => {
  97. styleProxy.setStyle( 'border-color:cyan magenta;' );
  98. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  99. top: { color: 'cyan' },
  100. right: { color: 'magenta' },
  101. bottom: { color: 'cyan' },
  102. left: { color: 'magenta' }
  103. } );
  104. } );
  105. it( 'should set all border colors (3 values defined)', () => {
  106. styleProxy.setStyle( 'border-color:cyan magenta pink;' );
  107. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  108. top: { color: 'cyan' },
  109. right: { color: 'magenta' },
  110. bottom: { color: 'pink' },
  111. left: { color: 'magenta' }
  112. } );
  113. } );
  114. it( 'should set all border colors (4 values defined)', () => {
  115. styleProxy.setStyle( 'border-color:cyan magenta pink beige;' );
  116. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  117. top: { color: 'cyan' },
  118. right: { color: 'magenta' },
  119. bottom: { color: 'pink' },
  120. left: { color: 'beige' }
  121. } );
  122. } );
  123. it( 'should merge with border shorthand', () => {
  124. styleProxy.setStyle( 'border:1px solid blue;border-color:cyan black;' );
  125. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  126. top: { color: 'cyan', style: 'solid', width: '1px' },
  127. right: { color: 'black', style: 'solid', width: '1px' },
  128. bottom: { color: 'cyan', style: 'solid', width: '1px' },
  129. left: { color: 'black', style: 'solid', width: '1px' }
  130. } );
  131. } );
  132. } );
  133. describe( 'border-style', () => {
  134. it( 'should set all border styles (1 value defined)', () => {
  135. styleProxy.setStyle( 'border-style:solid;' );
  136. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  137. top: { style: 'solid' },
  138. right: { style: 'solid' },
  139. bottom: { style: 'solid' },
  140. left: { style: 'solid' }
  141. } );
  142. } );
  143. it( 'should set all border styles (2 values defined)', () => {
  144. styleProxy.setStyle( 'border-style:solid dotted;' );
  145. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  146. top: { style: 'solid' },
  147. right: { style: 'dotted' },
  148. bottom: { style: 'solid' },
  149. left: { style: 'dotted' }
  150. } );
  151. } );
  152. it( 'should set all border styles (3 values defined)', () => {
  153. styleProxy.setStyle( 'border-style:solid dotted dashed;' );
  154. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  155. top: { style: 'solid' },
  156. right: { style: 'dotted' },
  157. bottom: { style: 'dashed' },
  158. left: { style: 'dotted' }
  159. } );
  160. } );
  161. it( 'should set all border styles (4 values defined)', () => {
  162. styleProxy.setStyle( 'border-style:solid dotted dashed ridge;' );
  163. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  164. top: { style: 'solid' },
  165. right: { style: 'dotted' },
  166. bottom: { style: 'dashed' },
  167. left: { style: 'ridge' }
  168. } );
  169. } );
  170. } );
  171. describe( 'border-width', () => {
  172. it( 'should set all border widths (1 value defined)', () => {
  173. styleProxy.setStyle( 'border-width:1px;' );
  174. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  175. top: { width: '1px' },
  176. right: { width: '1px' },
  177. bottom: { width: '1px' },
  178. left: { width: '1px' }
  179. } );
  180. } );
  181. it( 'should set all border widths (2 values defined)', () => {
  182. styleProxy.setStyle( 'border-width:1px .34cm;' );
  183. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  184. top: { width: '1px' },
  185. right: { width: '.34cm' },
  186. bottom: { width: '1px' },
  187. left: { width: '.34cm' }
  188. } );
  189. } );
  190. it( 'should set all border widths (3 values defined)', () => {
  191. styleProxy.setStyle( 'border-width:1px .34cm 90.1rem;' );
  192. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  193. top: { width: '1px' },
  194. right: { width: '.34cm' },
  195. bottom: { width: '90.1rem' },
  196. left: { width: '.34cm' }
  197. } );
  198. } );
  199. it( 'should set all border widths (4 values defined)', () => {
  200. styleProxy.setStyle( 'border-width:1px .34cm 90.1rem thick;' );
  201. expect( styleProxy.getModel( 'border' ) ).to.deep.equal( {
  202. top: { width: '1px' },
  203. right: { width: '.34cm' },
  204. bottom: { width: '90.1rem' },
  205. left: { width: 'thick' }
  206. } );
  207. } );
  208. } );
  209. } );
  210. describe( 'margin', () => {
  211. it( 'should set all margins (1 value defined)', () => {
  212. styleProxy.setStyle( 'margin:1px;' );
  213. expect( styleProxy.getModel( 'margin' ) ).to.deep.equal( {
  214. top: '1px',
  215. right: '1px',
  216. bottom: '1px',
  217. left: '1px'
  218. } );
  219. } );
  220. it( 'should set all margins (2 values defined)', () => {
  221. styleProxy.setStyle( 'margin:1px .34cm;' );
  222. expect( styleProxy.getModel( 'margin' ) ).to.deep.equal( {
  223. top: '1px',
  224. right: '.34cm',
  225. bottom: '1px',
  226. left: '.34cm'
  227. } );
  228. } );
  229. it( 'should set all margins (3 values defined)', () => {
  230. styleProxy.setStyle( 'margin:1px .34cm 90.1rem;' );
  231. expect( styleProxy.getModel( 'margin' ) ).to.deep.equal( {
  232. top: '1px',
  233. right: '.34cm',
  234. bottom: '90.1rem',
  235. left: '.34cm'
  236. } );
  237. } );
  238. it( 'should set all margins (4 values defined)', () => {
  239. styleProxy.setStyle( 'margin:1px .34cm 90.1rem thick;' );
  240. expect( styleProxy.getModel( 'margin' ) ).to.deep.equal( {
  241. top: '1px',
  242. right: '.34cm',
  243. bottom: '90.1rem',
  244. left: 'thick'
  245. } );
  246. } );
  247. it( 'should output inline style (1 value defined)', () => {
  248. styleProxy.setStyle( 'margin:1px;' );
  249. expect( styleProxy.getInlineStyle() ).to.equal( 'margin:1px;' );
  250. expect( styleProxy.getInlineRule( 'margin' ) ).to.equal( '1px' );
  251. expect( styleProxy.getInlineRule( 'margin-top' ) ).to.equal( '1px' );
  252. expect( styleProxy.getInlineRule( 'margin-right' ) ).to.equal( '1px' );
  253. expect( styleProxy.getInlineRule( 'margin-bottom' ) ).to.equal( '1px' );
  254. expect( styleProxy.getInlineRule( 'margin-left' ) ).to.equal( '1px' );
  255. } );
  256. it( 'should output inline style (2 values defined)', () => {
  257. styleProxy.setStyle( 'margin:1px .34cm;' );
  258. expect( styleProxy.getInlineStyle() ).to.equal( 'margin:1px .34cm;' );
  259. expect( styleProxy.getInlineRule( 'margin' ) ).to.equal( '1px .34cm' );
  260. expect( styleProxy.getInlineRule( 'margin-top' ) ).to.equal( '1px' );
  261. expect( styleProxy.getInlineRule( 'margin-right' ) ).to.equal( '.34cm' );
  262. expect( styleProxy.getInlineRule( 'margin-bottom' ) ).to.equal( '1px' );
  263. expect( styleProxy.getInlineRule( 'margin-left' ) ).to.equal( '.34cm' );
  264. } );
  265. it( 'should output inline style (3 values defined)', () => {
  266. styleProxy.setStyle( 'margin:1px .34cm 90.1rem;' );
  267. expect( styleProxy.getInlineStyle() ).to.equal( 'margin:1px .34cm 90.1rem;' );
  268. expect( styleProxy.getInlineRule( 'margin' ) ).to.equal( '1px .34cm 90.1rem' );
  269. expect( styleProxy.getInlineRule( 'margin-top' ) ).to.equal( '1px' );
  270. expect( styleProxy.getInlineRule( 'margin-right' ) ).to.equal( '.34cm' );
  271. expect( styleProxy.getInlineRule( 'margin-bottom' ) ).to.equal( '90.1rem' );
  272. expect( styleProxy.getInlineRule( 'margin-left' ) ).to.equal( '.34cm' );
  273. } );
  274. it( 'should output inline style (3 values defined, only last different)', () => {
  275. styleProxy.setStyle( 'margin:1px 1px 90.1rem;' );
  276. expect( styleProxy.getInlineStyle() ).to.equal( 'margin:1px 1px 90.1rem;' );
  277. expect( styleProxy.getInlineRule( 'margin' ) ).to.equal( '1px 1px 90.1rem' );
  278. expect( styleProxy.getInlineRule( 'margin-top' ) ).to.equal( '1px' );
  279. expect( styleProxy.getInlineRule( 'margin-right' ) ).to.equal( '1px' );
  280. expect( styleProxy.getInlineRule( 'margin-bottom' ) ).to.equal( '90.1rem' );
  281. expect( styleProxy.getInlineRule( 'margin-left' ) ).to.equal( '1px' );
  282. } );
  283. it( 'should output inline style (4 values defined)', () => {
  284. styleProxy.setStyle( 'margin:1px .34cm 90.1rem thick;' );
  285. expect( styleProxy.getInlineStyle() ).to.equal( 'margin:1px .34cm 90.1rem thick;' );
  286. expect( styleProxy.getInlineRule( 'margin' ) ).to.equal( '1px .34cm 90.1rem thick' );
  287. expect( styleProxy.getInlineRule( 'margin-top' ) ).to.equal( '1px' );
  288. expect( styleProxy.getInlineRule( 'margin-right' ) ).to.equal( '.34cm' );
  289. expect( styleProxy.getInlineRule( 'margin-bottom' ) ).to.equal( '90.1rem' );
  290. expect( styleProxy.getInlineRule( 'margin-left' ) ).to.equal( 'thick' );
  291. } );
  292. it( 'should output inline style (4 values defined, only last different)', () => {
  293. styleProxy.setStyle( 'margin:1px 1px 1px thick;' );
  294. expect( styleProxy.getInlineStyle() ).to.equal( 'margin:1px 1px 1px thick;' );
  295. expect( styleProxy.getInlineRule( 'margin' ) ).to.equal( '1px 1px 1px thick' );
  296. expect( styleProxy.getInlineRule( 'margin-top' ) ).to.equal( '1px' );
  297. expect( styleProxy.getInlineRule( 'margin-right' ) ).to.equal( '1px' );
  298. expect( styleProxy.getInlineRule( 'margin-bottom' ) ).to.equal( '1px' );
  299. expect( styleProxy.getInlineRule( 'margin-left' ) ).to.equal( 'thick' );
  300. } );
  301. describe( 'margin-*', () => {
  302. it( 'should set proper margin', () => {
  303. styleProxy.setStyle( 'margin-top:1px;' );
  304. expect( styleProxy.getModel( 'margin' ) ).to.deep.equal( { top: '1px' } );
  305. expect( styleProxy.getModel( 'margin-top' ) ).to.equal( '1px' );
  306. } );
  307. it( 'should set proper margin with margin shorthand', () => {
  308. styleProxy.setStyle( 'margin: 2em;margin-top:1px;' );
  309. expect( styleProxy.getModel( 'margin' ) ).to.deep.equal( {
  310. top: '1px',
  311. right: '2em',
  312. bottom: '2em',
  313. left: '2em'
  314. } );
  315. expect( styleProxy.getModel( 'margin-top' ) ).to.equal( '1px' );
  316. expect( styleProxy.getModel( 'margin-right' ) ).to.equal( '2em' );
  317. expect( styleProxy.getModel( 'margin-bottom' ) ).to.equal( '2em' );
  318. expect( styleProxy.getModel( 'margin-left' ) ).to.equal( '2em' );
  319. } );
  320. } );
  321. } );
  322. describe( 'padding', () => {
  323. it( 'should set all paddings (1 value defined)', () => {
  324. styleProxy.setStyle( 'padding:1px;' );
  325. expect( styleProxy.getModel( 'padding' ) ).to.deep.equal( {
  326. top: '1px',
  327. right: '1px',
  328. bottom: '1px',
  329. left: '1px'
  330. } );
  331. } );
  332. it( 'should set all paddings (2 values defined)', () => {
  333. styleProxy.setStyle( 'padding:1px .34cm;' );
  334. expect( styleProxy.getModel( 'padding' ) ).to.deep.equal( {
  335. top: '1px',
  336. right: '.34cm',
  337. bottom: '1px',
  338. left: '.34cm'
  339. } );
  340. } );
  341. it( 'should set all paddings (3 values defined)', () => {
  342. styleProxy.setStyle( 'padding:1px .34cm 90.1rem;' );
  343. expect( styleProxy.getModel( 'padding' ) ).to.deep.equal( {
  344. top: '1px',
  345. right: '.34cm',
  346. bottom: '90.1rem',
  347. left: '.34cm'
  348. } );
  349. } );
  350. it( 'should set all paddings (4 values defined)', () => {
  351. styleProxy.setStyle( 'padding:1px .34cm 90.1rem thick;' );
  352. expect( styleProxy.getModel( 'padding' ) ).to.deep.equal( {
  353. top: '1px',
  354. right: '.34cm',
  355. bottom: '90.1rem',
  356. left: 'thick'
  357. } );
  358. } );
  359. describe( 'padding-*', () => {
  360. it( 'should set proper padding', () => {
  361. styleProxy.setStyle( 'padding-top:1px;' );
  362. expect( styleProxy.getModel( 'padding' ) ).to.deep.equal( {
  363. top: '1px'
  364. } );
  365. } );
  366. it( 'should set proper padding with padding shorthand', () => {
  367. styleProxy.setStyle( 'padding: 2em;padding-top:1px;' );
  368. expect( styleProxy.getModel( 'padding' ) ).to.deep.equal( {
  369. top: '1px',
  370. right: '2em',
  371. bottom: '2em',
  372. left: '2em'
  373. } );
  374. } );
  375. } );
  376. } );
  377. describe( 'unknown rules', () => {
  378. it( 'should left rules untouched', () => {
  379. styleProxy.setStyle( 'foo-bar:baz 1px abc;baz: 2px 3em;' );
  380. expect( styleProxy.getInlineStyle() ).to.equal( 'baz:2px 3em;foo-bar:baz 1px abc;' );
  381. expect( styleProxy.getInlineRule( 'foo-bar' ) ).to.equal( 'baz 1px abc' );
  382. expect( styleProxy.getInlineRule( 'baz' ) ).to.equal( '2px 3em' );
  383. } );
  384. } );
  385. } );
  386. } );