emojipicker_test.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. // Copyright 2007 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.ui.emoji.EmojiPickerTest');
  15. goog.setTestOnly('goog.ui.emoji.EmojiPickerTest');
  16. goog.require('goog.dom.TagName');
  17. goog.require('goog.dom.classlist');
  18. goog.require('goog.events.EventHandler');
  19. goog.require('goog.style');
  20. goog.require('goog.testing.events');
  21. goog.require('goog.testing.jsunit');
  22. goog.require('goog.ui.Component');
  23. goog.require('goog.ui.emoji.Emoji');
  24. goog.require('goog.ui.emoji.EmojiPicker');
  25. goog.require('goog.ui.emoji.SpriteInfo');
  26. var handler;
  27. function setUp() {
  28. handler = new goog.events.EventHandler();
  29. }
  30. function tearDown() {
  31. handler.removeAll();
  32. }
  33. // 26 emoji
  34. var emojiGroup1 = [
  35. 'Emoji 1',
  36. [
  37. ['../../demos/emoji/200.gif', 'std.200'],
  38. ['../../demos/emoji/201.gif', 'std.201'],
  39. ['../../demos/emoji/202.gif', 'std.202'],
  40. ['../../demos/emoji/203.gif', 'std.203'],
  41. ['../../demos/emoji/204.gif', 'std.204'],
  42. ['../../demos/emoji/200.gif', 'std.200'],
  43. ['../../demos/emoji/201.gif', 'std.201'],
  44. ['../../demos/emoji/202.gif', 'std.202'],
  45. ['../../demos/emoji/203.gif', 'std.203'],
  46. ['../../demos/emoji/204.gif', 'std.204'],
  47. ['../../demos/emoji/200.gif', 'std.200'],
  48. ['../../demos/emoji/201.gif', 'std.201'],
  49. ['../../demos/emoji/202.gif', 'std.202'],
  50. ['../../demos/emoji/203.gif', 'std.203'],
  51. ['../../demos/emoji/204.gif', 'std.204'],
  52. ['../../demos/emoji/200.gif', 'std.200'],
  53. ['../../demos/emoji/201.gif', 'std.201'],
  54. ['../../demos/emoji/202.gif', 'std.202'],
  55. ['../../demos/emoji/203.gif', 'std.203'],
  56. ['../../demos/emoji/204.gif', 'std.204'],
  57. ['../../demos/emoji/200.gif', 'std.200'],
  58. ['../../demos/emoji/201.gif', 'std.201'],
  59. ['../../demos/emoji/202.gif', 'std.202'],
  60. ['../../demos/emoji/203.gif', 'std.203'],
  61. ['../../demos/emoji/204.gif', 'std.204'],
  62. ['../../demos/emoji/200.gif', 'std.200']
  63. ]
  64. ];
  65. // 20 emoji
  66. var emojiGroup2 = [
  67. 'Emoji 2',
  68. [
  69. ['../../demos/emoji/200.gif', 'std.200'],
  70. ['../../demos/emoji/201.gif', 'std.201'],
  71. ['../../demos/emoji/202.gif', 'std.202'],
  72. ['../../demos/emoji/203.gif', 'std.203'],
  73. ['../../demos/emoji/204.gif', 'std.204'],
  74. ['../../demos/emoji/200.gif', 'std.200'],
  75. ['../../demos/emoji/201.gif', 'std.201'],
  76. ['../../demos/emoji/202.gif', 'std.202'],
  77. ['../../demos/emoji/203.gif', 'std.203'],
  78. ['../../demos/emoji/204.gif', 'std.204'],
  79. ['../../demos/emoji/200.gif', 'std.200'],
  80. ['../../demos/emoji/201.gif', 'std.201'],
  81. ['../../demos/emoji/202.gif', 'std.202'],
  82. ['../../demos/emoji/203.gif', 'std.203'],
  83. ['../../demos/emoji/204.gif', 'std.204'],
  84. ['../../demos/emoji/200.gif', 'std.200'],
  85. ['../../demos/emoji/201.gif', 'std.201'],
  86. ['../../demos/emoji/202.gif', 'std.202'],
  87. ['../../demos/emoji/203.gif', 'std.203'],
  88. ['../../demos/emoji/204.gif', 'std.204']
  89. ]
  90. ];
  91. // 20 emoji
  92. var emojiGroup3 = [
  93. 'Emoji 3',
  94. [
  95. ['../../demos/emoji/200.gif', 'std.200'],
  96. ['../../demos/emoji/201.gif', 'std.201'],
  97. ['../../demos/emoji/202.gif', 'std.202'],
  98. ['../../demos/emoji/203.gif', 'std.203'],
  99. ['../../demos/emoji/204.gif', 'std.204'],
  100. ['../../demos/emoji/200.gif', 'std.200'],
  101. ['../../demos/emoji/201.gif', 'std.201'],
  102. ['../../demos/emoji/202.gif', 'std.202'],
  103. ['../../demos/emoji/203.gif', 'std.203'],
  104. ['../../demos/emoji/204.gif', 'std.204'],
  105. ['../../demos/emoji/200.gif', 'std.200'],
  106. ['../../demos/emoji/201.gif', 'std.201'],
  107. ['../../demos/emoji/202.gif', 'std.202'],
  108. ['../../demos/emoji/203.gif', 'std.203'],
  109. ['../../demos/emoji/204.gif', 'std.204'],
  110. ['../../demos/emoji/200.gif', 'std.200'],
  111. ['../../demos/emoji/201.gif', 'std.201'],
  112. ['../../demos/emoji/202.gif', 'std.202'],
  113. ['../../demos/emoji/203.gif', 'std.203'],
  114. ['../../demos/emoji/204.gif', 'std.204']
  115. ]
  116. ];
  117. var sprite = '../../demos/emoji/sprite.png';
  118. var sprite2 = '../../demos/emoji/sprite2.png';
  119. /**
  120. * Creates a SpriteInfo object with the specified properties. If the image is
  121. * sprited via CSS, then only the first parameter needs a value. If the image
  122. * is sprited via metadata, then the first parameter should be left null.
  123. *
  124. * @param {?string} cssClass CSS class to properly display the sprited image.
  125. * @param {string=} opt_url Url of the sprite image.
  126. * @param {number=} opt_width Width of the image being sprited.
  127. * @param {number=} opt_height Height of the image being sprited.
  128. * @param {number=} opt_xOffset Positive x offset of the image being sprited
  129. * within the sprite.
  130. * @param {number=} opt_yOffset Positive y offset of the image being sprited
  131. * within the sprite.
  132. * @param {boolean=} opt_animated Whether the sprite info is for an animated
  133. * emoji.
  134. */
  135. function si(
  136. cssClass, opt_url, opt_width, opt_height, opt_xOffset, opt_yOffset,
  137. opt_animated) {
  138. return new goog.ui.emoji.SpriteInfo(
  139. cssClass, opt_url, opt_width, opt_height, opt_xOffset, opt_yOffset,
  140. opt_animated);
  141. }
  142. // Contains a mix of sprited emoji via css, sprited emoji via metadata, and
  143. // non-sprited emoji
  144. var spritedEmoji1 = [
  145. 'Emoji 1',
  146. [
  147. ['../../demos/emoji/200.gif', 'std.200', si('SPRITE_200')],
  148. ['../../demos/emoji/201.gif', 'std.201', si('SPRITE_201')],
  149. ['../../demos/emoji/202.gif', 'std.202', si('SPRITE_202')],
  150. ['../../demos/emoji/203.gif', 'std.203', si('SPRITE_203')],
  151. ['../../demos/emoji/204.gif', 'std.204', si('SPRITE_204')],
  152. ['../../demos/emoji/200.gif', 'std.200', si('SPRITE_200')],
  153. ['../../demos/emoji/201.gif', 'std.201', si('SPRITE_201')],
  154. ['../../demos/emoji/202.gif', 'std.202', si('SPRITE_202')],
  155. ['../../demos/emoji/203.gif', 'std.203', si('SPRITE_203')],
  156. ['../../demos/emoji/2BE.gif', 'std.2BE', si(null, sprite, 18, 18, 36, 54)],
  157. ['../../demos/emoji/2BF.gif', 'std.2BF', si(null, sprite, 18, 18, 0, 126)],
  158. ['../../demos/emoji/2C0.gif', 'std.2C0', si(null, sprite, 18, 18, 18, 305)],
  159. ['../../demos/emoji/2C1.gif', 'std.2C1', si(null, sprite, 18, 18, 0, 287)],
  160. ['../../demos/emoji/2C2.gif', 'std.2C2', si(null, sprite, 18, 18, 18, 126)],
  161. ['../../demos/emoji/2C3.gif', 'std.2C3', si(null, sprite, 18, 18, 36, 234)],
  162. ['../../demos/emoji/2C4.gif', 'std.2C4', si(null, sprite, 18, 18, 36, 72)],
  163. ['../../demos/emoji/2C5.gif', 'std.2C5', si(null, sprite, 18, 18, 54, 54)],
  164. ['../../demos/emoji/200.gif', 'std.200'],
  165. ['../../demos/emoji/201.gif', 'std.201'],
  166. ['../../demos/emoji/202.gif', 'std.202'],
  167. ['../../demos/emoji/203.gif', 'std.203'],
  168. ['../../demos/emoji/204.gif', 'std.204'],
  169. ['../../demos/emoji/200.gif', 'std.200'],
  170. ['../../demos/emoji/201.gif', 'std.201'],
  171. ['../../demos/emoji/202.gif', 'std.202'],
  172. ['../../demos/emoji/203.gif', 'std.203']
  173. ]
  174. ];
  175. // This group contains a mix of sprited emoji via css, sprited emoji via
  176. // metadata, and non-sprited emoji.
  177. var spritedEmoji2 = [
  178. 'Emoji 1',
  179. [
  180. ['../../demos/emoji/200.gif', 'std.200', si('SPRITE_200')],
  181. ['../../demos/emoji/201.gif', 'std.201', si('SPRITE_201')],
  182. ['../../demos/emoji/202.gif', 'std.202', si('SPRITE_202')],
  183. ['../../demos/emoji/203.gif', 'std.203', si('SPRITE_203')],
  184. ['../../demos/emoji/204.gif', 'std.204', si('SPRITE_204')],
  185. ['../../demos/emoji/200.gif', 'std.200', si('SPRITE_200')],
  186. ['../../demos/emoji/201.gif', 'std.201', si('SPRITE_201')],
  187. ['../../demos/emoji/202.gif', 'std.202', si('SPRITE_202')],
  188. ['../../demos/emoji/203.gif', 'std.203', si('SPRITE_203')],
  189. ['../../demos/emoji/2BE.gif', 'std.2BE', si(null, sprite, 18, 18, 36, 54)],
  190. ['../../demos/emoji/2BF.gif', 'std.2BF', si(null, sprite, 18, 18, 0, 126)],
  191. ['../../demos/emoji/2C0.gif', 'std.2C0', si(null, sprite, 18, 18, 18, 305)],
  192. ['../../demos/emoji/2C1.gif', 'std.2C1', si(null, sprite, 18, 18, 0, 287)],
  193. ['../../demos/emoji/2C2.gif', 'std.2C2', si(null, sprite, 18, 18, 18, 126)],
  194. ['../../demos/emoji/2C3.gif', 'std.2C3', si(null, sprite, 18, 18, 36, 234)],
  195. ['../../demos/emoji/2C4.gif', 'std.2C4', si(null, sprite, 18, 18, 36, 72)],
  196. ['../../demos/emoji/2C5.gif', 'std.2C5', si(null, sprite, 18, 18, 54, 54)],
  197. ['../../demos/emoji/2C6.gif', 'std.2C6'],
  198. ['../../demos/emoji/2C7.gif', 'std.2C7'],
  199. ['../../demos/emoji/2C8.gif', 'std.2C8'],
  200. ['../../demos/emoji/2C9.gif', 'std.2C9'],
  201. [
  202. '../../demos/emoji/2CA.gif', 'std.2CA',
  203. si(null, sprite2, 18, 20, 36, 72, 1)
  204. ],
  205. [
  206. '../../demos/emoji/2E3.gif', 'std.2E3', si(null, sprite2, 18, 18, 0, 0, 1)
  207. ],
  208. [
  209. '../../demos/emoji/2EF.gif', 'std.2EF',
  210. si(null, sprite2, 18, 20, 0, 300, 1)
  211. ],
  212. [
  213. '../../demos/emoji/2F1.gif', 'std.2F1',
  214. si(null, sprite2, 18, 18, 0, 320, 1)
  215. ]
  216. ]
  217. ];
  218. var emojiGroups = [emojiGroup1, emojiGroup2, emojiGroup3];
  219. function testConstructAndRenderOnePageEmojiPicker() {
  220. var picker = new goog.ui.emoji.EmojiPicker('../../demos/emoji/none.gif');
  221. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  222. picker.render();
  223. picker.dispose();
  224. }
  225. function testConstructAndRenderMultiPageEmojiPicker() {
  226. var picker = new goog.ui.emoji.EmojiPicker('../../demos/emoji/none.gif');
  227. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  228. picker.addEmojiGroup(emojiGroup2[0], emojiGroup2[1]);
  229. picker.addEmojiGroup(emojiGroup3[0], emojiGroup3[1]);
  230. picker.render();
  231. picker.dispose();
  232. }
  233. function testExitDocumentCleansUpProperlyForSinglePageEmojiPicker() {
  234. var picker = new goog.ui.emoji.EmojiPicker('../../demos/emoji/none.gif');
  235. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  236. picker.render();
  237. picker.enterDocument();
  238. picker.exitDocument();
  239. picker.dispose();
  240. }
  241. function testExitDocumentCleansUpProperlyForMultiPageEmojiPicker() {
  242. var picker = new goog.ui.emoji.EmojiPicker('../../demos/emoji/none.gif');
  243. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  244. picker.addEmojiGroup(emojiGroup2[0], emojiGroup2[1]);
  245. picker.render();
  246. picker.enterDocument();
  247. picker.exitDocument();
  248. picker.dispose();
  249. }
  250. function testNumGroups() {
  251. var picker = new goog.ui.emoji.EmojiPicker('../../demos/emoji/none.gif');
  252. for (var i = 0; i < emojiGroups.length; i++) {
  253. picker.addEmojiGroup(emojiGroups[i][0], emojiGroups[i][1]);
  254. }
  255. assertTrue(picker.getNumEmojiGroups() == emojiGroups.length);
  256. }
  257. function testAdjustNumRowsIfNecessaryIsCorrect() {
  258. var picker = new goog.ui.emoji.EmojiPicker('../../demos/emoji/none.gif');
  259. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  260. picker.setAutoSizeByColumnCount(true);
  261. picker.setNumColumns(5);
  262. assertEquals(5, picker.getNumColumns());
  263. assertEquals(goog.ui.emoji.EmojiPicker.DEFAULT_NUM_ROWS, picker.getNumRows());
  264. picker.adjustNumRowsIfNecessary_();
  265. // The emojiGroup has 26 emoji. ceil(26/5) should give 6 rows.
  266. assertEquals(6, picker.getNumRows());
  267. // Change col count to 10, should give 3 rows.
  268. picker.setNumColumns(10);
  269. picker.adjustNumRowsIfNecessary_();
  270. assertEquals(3, picker.getNumRows());
  271. // Add another gruop, with 20 emoji. Deliberately set the number of rows too
  272. // low. It should adjust it to three to accommodate the emoji in the first
  273. // group.
  274. picker.addEmojiGroup(emojiGroup2[0], emojiGroup2[1]);
  275. picker.setNumColumns(10);
  276. picker.setNumRows(2);
  277. picker.adjustNumRowsIfNecessary_();
  278. assertEquals(3, picker.getNumRows());
  279. }
  280. /**
  281. * Helper for testDelayedLoad. Returns true if the two paths end with the same
  282. * file.
  283. *
  284. * E.g., ('../../cool.gif', 'file:///home/usr/somewhere/cool.gif') --> true
  285. *
  286. * @param {string} path1 First url
  287. * @param {string} path2 Second url
  288. */
  289. function checkPathsEndWithSameFile(path1, path2) {
  290. var pieces1 = path1.split('/');
  291. var file1 = pieces1[pieces1.length - 1];
  292. var pieces2 = path2.split('/');
  293. var file2 = pieces2[pieces2.length - 1];
  294. return file1 == file2;
  295. }
  296. /**
  297. * Gets the emoji URL from a palette element. Palette elements are divs or
  298. * imgs wrapped in an outer div. The returns the background-image if it's a div,
  299. * or the src attribute if it's an image.
  300. *
  301. * @param {Element} element Element to get the image url for
  302. * @return {string}
  303. */
  304. function getImageUrl(element) {
  305. element = element.firstChild; // get the wrapped element
  306. if (element.tagName == goog.dom.TagName.IMG) {
  307. return element.src;
  308. } else {
  309. var url = goog.style.getStyle(element, 'background-image');
  310. url = url.replace(/url\(/, '');
  311. url = url.replace(/\)/, '');
  312. return url;
  313. }
  314. }
  315. /**
  316. * Checks that the content of an emojipicker page is all images pointing to
  317. * the default img.
  318. *
  319. * @param {goog.ui.emoji.EmojiPalette} page The page of the picker to check
  320. * @param {string} defaultImgUrl The url of the default img
  321. */
  322. function checkContentIsDefaultImg(page, defaultImgUrl) {
  323. var content = page.getContent();
  324. for (var i = 0; i < content.length; i++) {
  325. var url = getImageUrl(content[i]);
  326. assertTrue(
  327. 'img src should be ' + defaultImgUrl + ' but is ' + url,
  328. checkPathsEndWithSameFile(url, defaultImgUrl));
  329. }
  330. }
  331. /**
  332. * Checks that the content of an emojipicker page is the specified emoji and
  333. * the default img after the emoji are all used.
  334. *
  335. * @param {goog.ui.emoji.EmojiPalette} page The page of the picker to check
  336. * @param {Array<Array<string>>} emojiList List of emoji that should be in the
  337. * palette
  338. * @param {string} defaultImgUrl The url of the default img
  339. */
  340. function checkContentIsEmojiImages(page, emojiList, defaultImg) {
  341. var content = page.getContent();
  342. for (var i = 0; i < content.length; i++) {
  343. var url = getImageUrl(content[i]);
  344. if (i < emojiList.length) {
  345. assertTrue(
  346. 'Paths should end with the same file: ' + url + ', ' +
  347. emojiList[i][0],
  348. checkPathsEndWithSameFile(url, emojiList[i][0]));
  349. } else {
  350. assertTrue(
  351. 'Paths should end with the same file: ' + url + ', ' + defaultImg,
  352. checkPathsEndWithSameFile(url, defaultImg));
  353. }
  354. }
  355. }
  356. function testNonDelayedLoadPaletteCreationForSinglePagePicker() {
  357. var defaultImg = '../../demos/emoji/none.gif';
  358. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  359. picker.setDelayedLoad(false);
  360. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  361. picker.render();
  362. var page = picker.getPage(0);
  363. assertTrue('Page should be in the document but is not', page.isInDocument());
  364. // The content should be the actual emoji images now, with the remainder set
  365. // to the default img
  366. checkContentIsEmojiImages(page, emojiGroup1[1], defaultImg);
  367. picker.dispose();
  368. }
  369. function testNonDelayedLoadPaletteCreationForMultiPagePicker() {
  370. var defaultImg = '../../demos/emoji/none.gif';
  371. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  372. picker.setDelayedLoad(false);
  373. for (var i = 0; i < emojiGroups.length; i++) {
  374. picker.addEmojiGroup(emojiGroups[i][0], emojiGroups[i][1]);
  375. }
  376. picker.render();
  377. for (var i = 0; i < emojiGroups.length; i++) {
  378. var page = picker.getPage(i);
  379. assertTrue(
  380. 'Page ' + i + ' should be in the document but is not',
  381. page.isInDocument());
  382. checkContentIsEmojiImages(page, emojiGroups[i][1], defaultImg);
  383. }
  384. picker.dispose();
  385. }
  386. function testDelayedLoadPaletteCreationForSinglePagePicker() {
  387. var defaultImg = '../../demos/emoji/none.gif';
  388. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  389. picker.setDelayedLoad(true);
  390. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  391. picker.render();
  392. // At this point the picker should have pages filled with the default img
  393. checkContentIsDefaultImg(picker.getPage(0), defaultImg);
  394. // Now load the images
  395. picker.loadImages();
  396. var page = picker.getPage(0);
  397. assertTrue('Page should be in the document but is not', page.isInDocument());
  398. // The content should be the actual emoji images now, with the remainder set
  399. // to the default img
  400. checkContentIsEmojiImages(page, emojiGroup1[1], defaultImg);
  401. picker.dispose();
  402. }
  403. function testGetSelectedEmoji() {
  404. var defaultImg = '../../demos/emoji/none.gif';
  405. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  406. picker.setDelayedLoad(false);
  407. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  408. picker.render();
  409. var palette = picker.getPage(0);
  410. // No emoji should be selected yet
  411. assertUndefined(palette.getSelectedEmoji());
  412. // Artificially select the first emoji
  413. palette.setSelectedIndex(0);
  414. // Now we should get the first emoji back. See emojiGroup1 above.
  415. var emoji = palette.getSelectedEmoji();
  416. assertEquals(emoji.getId(), 'std.200');
  417. assertEquals(emoji.getUrl(), '../../demos/emoji/200.gif');
  418. picker.dispose();
  419. }
  420. function testGetSelectedEmoji_click() {
  421. var defaultImg = '../../demos/emoji/none.gif';
  422. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  423. picker.setDelayedLoad(false);
  424. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  425. picker.render();
  426. var palette = picker.getPage(0);
  427. // Artificially select the an emoji
  428. palette.setSelectedIndex(2);
  429. var element = palette.getSelectedItem();
  430. palette.setSelectedIndex(0); // Select a different emoji.
  431. var eventSent;
  432. handler.listen(picker, goog.ui.Component.EventType.ACTION, function(e) {
  433. eventSent = e;
  434. });
  435. goog.testing.events.fireClickSequence(
  436. element, undefined, undefined, {shiftKey: false});
  437. // Now we should get the first emoji back. See emojiGroup1 above.
  438. var emoji = picker.getSelectedEmoji();
  439. assertEquals(emoji.getId(), 'std.202');
  440. assertEquals(emoji.getUrl(), '../../demos/emoji/202.gif');
  441. assertFalse(eventSent.shiftKey);
  442. picker.dispose();
  443. }
  444. function testGetSelectedEmoji_shiftClick() {
  445. var defaultImg = '../../demos/emoji/none.gif';
  446. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  447. picker.setDelayedLoad(false);
  448. picker.addEmojiGroup(emojiGroup1[0], emojiGroup1[1]);
  449. picker.render();
  450. var palette = picker.getPage(0);
  451. // Artificially select the an emoji
  452. palette.setSelectedIndex(3);
  453. var element = palette.getSelectedItem();
  454. palette.setSelectedIndex(0); // Select a different emoji.
  455. var eventSent;
  456. handler.listen(picker, goog.ui.Component.EventType.ACTION, function(e) {
  457. eventSent = e;
  458. });
  459. goog.testing.events.fireClickSequence(
  460. element, undefined, undefined, {shiftKey: true});
  461. // Now we should get the first emoji back. See emojiGroup1 above.
  462. var emoji = picker.getSelectedEmoji();
  463. assertEquals(emoji.getId(), 'std.203');
  464. assertEquals(emoji.getUrl(), '../../demos/emoji/203.gif');
  465. assertTrue(eventSent.shiftKey);
  466. picker.dispose();
  467. }
  468. /**
  469. * Checks and verifies the structure of a non-progressively-rendered
  470. * emojipicker.
  471. *
  472. * @param {goog.ui.emoji.EmojiPalette} palette Emoji palette to check.
  473. * @param {Array<Array<string>>} emoji Emoji that should be in the palette.
  474. */
  475. function checkStructureForNonProgressivePicker(palette, emoji) {
  476. // We can hackily check the items by selecting an item and then getting the
  477. // selected item.
  478. for (var i = 0; i < emoji[1].length; i++) {
  479. palette.setSelectedIndex(i);
  480. var emojiInfo = emoji[1][i];
  481. var cell = palette.getSelectedItem();
  482. var inner = /** @type {Element} */ (cell.firstChild);
  483. // Check that the cell is a div wrapped around something else, and that the
  484. // outer div contains the goomoji attribute
  485. assertEquals(
  486. 'The palette item should be a div wrapped around something',
  487. cell.tagName, 'DIV');
  488. assertNotNull('The outer div is not wrapped around another element', inner);
  489. assertEquals(
  490. 'The palette item should have the goomoji attribute',
  491. cell.getAttribute(goog.ui.emoji.Emoji.ATTRIBUTE), emojiInfo[1]);
  492. assertEquals(
  493. 'The palette item should have the data-goomoji attribute',
  494. cell.getAttribute(goog.ui.emoji.Emoji.DATA_ATTRIBUTE), emojiInfo[1]);
  495. // Now check the contents of the cells
  496. var spriteInfo = emojiInfo[2];
  497. if (spriteInfo) {
  498. assertEquals(inner.tagName, 'DIV');
  499. var cssClass = spriteInfo.getCssClass();
  500. if (cssClass) {
  501. assertTrue(
  502. 'Sprite should have its CSS class set',
  503. goog.dom.classlist.contains(inner, cssClass));
  504. } else {
  505. checkPathsEndWithSameFile(
  506. goog.style.getStyle(inner, 'background-image'),
  507. spriteInfo.getUrl());
  508. assertEquals(
  509. spriteInfo.getWidthCssValue(), goog.style.getStyle(inner, 'width'));
  510. assertEquals(
  511. spriteInfo.getHeightCssValue(),
  512. goog.style.getStyle(inner, 'height'));
  513. assertEquals(
  514. (spriteInfo.getXOffsetCssValue() + ' ' +
  515. spriteInfo.getYOffsetCssValue())
  516. .replace(/px/g, '')
  517. .replace(/pt/g, ''),
  518. goog.style.getStyle(inner, 'background-position')
  519. .replace(/px/g, '')
  520. .replace(/pt/g, ''));
  521. }
  522. } else {
  523. // A non-sprited emoji is just an img
  524. assertEquals(inner.tagName, 'IMG');
  525. checkPathsEndWithSameFile(inner.src, emojiInfo[0]);
  526. }
  527. }
  528. }
  529. /**
  530. * Checks and verifies the structure of a progressively-rendered emojipicker.
  531. *
  532. * @param {goog.ui.emoji.EmojiPalette} palette Emoji palette to check.
  533. * @param {Array<Array<string>>} emoji Emoji that should be in the palette.
  534. */
  535. function checkStructureForProgressivePicker(palette, emoji) {
  536. // We can hackily check the items by selecting an item and then getting the
  537. // selected item.
  538. for (var i = 0; i < emoji[1].length; i++) {
  539. palette.setSelectedIndex(i);
  540. var emojiInfo = emoji[1][i];
  541. var cell = palette.getSelectedItem();
  542. var inner = /** @type {Element} */ (cell.firstChild);
  543. // Check that the cell is a div wrapped around something else, and that the
  544. // outer div contains the goomoji attribute
  545. assertEquals(
  546. 'The palette item should be a div wrapped around something',
  547. cell.tagName, 'DIV');
  548. assertNotNull('The outer div is not wrapped around another element', inner);
  549. assertEquals(
  550. 'The palette item should have the goomoji attribute',
  551. cell.getAttribute(goog.ui.emoji.Emoji.ATTRIBUTE), emojiInfo[1]);
  552. assertEquals(
  553. 'The palette item should have the data-goomoji attribute',
  554. cell.getAttribute(goog.ui.emoji.Emoji.DATA_ATTRIBUTE), emojiInfo[1]);
  555. // Now check the contents of the cells
  556. var spriteInfo = emojiInfo[2];
  557. if (spriteInfo) {
  558. var cssClass = spriteInfo.getCssClass();
  559. if (cssClass) {
  560. assertEquals('DIV', inner.tagName);
  561. assertTrue(
  562. 'Sprite should have its CSS class set',
  563. goog.dom.classlist.contains(inner, cssClass));
  564. } else {
  565. // There's an inner div wrapping an img tag
  566. assertEquals('DIV', inner.tagName);
  567. var img = inner.firstChild;
  568. assertNotNull('Div should be wrapping something', img);
  569. assertEquals('IMG', img.tagName);
  570. checkPathsEndWithSameFile(img.src, spriteInfo.getUrl());
  571. assertEquals(
  572. spriteInfo.getWidthCssValue(), goog.style.getStyle(inner, 'width'));
  573. assertEquals(
  574. spriteInfo.getHeightCssValue(),
  575. goog.style.getStyle(inner, 'height'));
  576. assertEquals(
  577. spriteInfo.getXOffsetCssValue().replace(/px/, '').replace(/pt/, ''),
  578. goog.style.getStyle(img, 'left')
  579. .replace(/px/, '')
  580. .replace(/pt/, ''));
  581. assertEquals(
  582. spriteInfo.getYOffsetCssValue().replace(/px/, '').replace(/pt/, ''),
  583. goog.style.getStyle(img, 'top')
  584. .replace(/px/, '')
  585. .replace(/pt/, ''));
  586. }
  587. } else {
  588. // A non-sprited emoji is just an img
  589. assertEquals(inner.tagName, 'IMG');
  590. checkPathsEndWithSameFile(inner.src, emojiInfo[0]);
  591. }
  592. }
  593. }
  594. /**
  595. * Checks and verifies the structure of a non-progressive fast-loading picker
  596. * after the animated emoji have loaded.
  597. *
  598. * @param {goog.ui.emoji.EmojiPalette} palette Emoji palette to check.
  599. * @param {Array<Array<string>>} emoji Emoji that should be in the palette.
  600. */
  601. function checkPostLoadStructureForFastLoadNonProgressivePicker(palette, emoji) {
  602. for (var i = 0; i < emoji[1].length; i++) {
  603. palette.setSelectedIndex(i);
  604. var emojiInfo = emoji[1][i];
  605. var cell = palette.getSelectedItem();
  606. var inner = /** @type {Element} */ (cell.firstChild);
  607. // Check that the cell is a div wrapped around something else, and that the
  608. // outer div contains the goomoji attribute
  609. assertEquals(
  610. 'The palette item should be a div wrapped around something',
  611. cell.tagName, 'DIV');
  612. assertNotNull('The outer div is not wrapped around another element', inner);
  613. assertEquals(
  614. 'The palette item should have the goomoji attribute',
  615. cell.getAttribute(goog.ui.emoji.Emoji.ATTRIBUTE), emojiInfo[1]);
  616. assertEquals(
  617. 'The palette item should have the data-goomoji attribute',
  618. cell.getAttribute(goog.ui.emoji.Emoji.DATA_ATTRIBUTE), emojiInfo[1]);
  619. // Now check the contents of the cells
  620. var url = emojiInfo[0]; // url of the animated emoji
  621. var spriteInfo = emojiInfo[2];
  622. if (spriteInfo) {
  623. assertEquals(inner.tagName, 'DIV');
  624. if (spriteInfo.isAnimated()) {
  625. var img = new Image();
  626. img.src = url;
  627. checkPathsEndWithSameFile(
  628. goog.style.getStyle(inner, 'background-image'), url);
  629. assertEquals(
  630. String(img.width), goog.style.getStyle(inner, 'width')
  631. .replace(/px/g, '')
  632. .replace(/pt/g, ''));
  633. assertEquals(
  634. String(img.height), goog.style.getStyle(inner, 'height')
  635. .replace(/px/g, '')
  636. .replace(/pt/g, ''));
  637. assertEquals(
  638. '0 0', goog.style.getStyle(inner, 'background-position')
  639. .replace(/px/g, '')
  640. .replace(/pt/g, ''));
  641. } else {
  642. var cssClass = spriteInfo.getCssClass();
  643. if (cssClass) {
  644. assertTrue(
  645. 'Sprite should have its CSS class set',
  646. goog.dom.classlist.contains(inner, cssClass));
  647. } else {
  648. checkPathsEndWithSameFile(
  649. goog.style.getStyle(inner, 'background-image'),
  650. spriteInfo.getUrl());
  651. assertEquals(
  652. spriteInfo.getWidthCssValue(),
  653. goog.style.getStyle(inner, 'width'));
  654. assertEquals(
  655. spriteInfo.getHeightCssValue(),
  656. goog.style.getStyle(inner, 'height'));
  657. assertEquals(
  658. (spriteInfo.getXOffsetCssValue() + ' ' +
  659. spriteInfo.getYOffsetCssValue())
  660. .replace(/px/g, '')
  661. .replace(/pt/g, ''),
  662. goog.style.getStyle(inner, 'background-position')
  663. .replace(/px/g, '')
  664. .replace(/pt/g, ''));
  665. }
  666. }
  667. } else {
  668. // A non-sprited emoji is just an img
  669. assertEquals(inner.tagName, 'IMG');
  670. checkPathsEndWithSameFile(inner.src, emojiInfo[0]);
  671. }
  672. }
  673. }
  674. /**
  675. * Checks and verifies the structure of a progressive fast-loading picker
  676. * after the animated emoji have loaded.
  677. *
  678. * @param {goog.ui.emoji.EmojiPalette} palette Emoji palette to check.
  679. * @param {Array<Array<string>>} emoji Emoji that should be in the palette.
  680. */
  681. function checkPostLoadStructureForFastLoadProgressivePicker(palette, emoji) {
  682. for (var i = 0; i < emoji[1].length; i++) {
  683. palette.setSelectedIndex(i);
  684. var emojiInfo = emoji[1][i];
  685. var cell = palette.getSelectedItem();
  686. var inner = /** @type {Element} */ (cell.firstChild);
  687. // Check that the cell is a div wrapped around something else, and that the
  688. // outer div contains the goomoji attribute
  689. assertEquals(
  690. 'The palette item should be a div wrapped around something',
  691. cell.tagName, 'DIV');
  692. assertNotNull('The outer div is not wrapped around another element', inner);
  693. assertEquals(
  694. 'The palette item should have the goomoji attribute',
  695. cell.getAttribute(goog.ui.emoji.Emoji.ATTRIBUTE), emojiInfo[1]);
  696. assertEquals(
  697. 'The palette item should have the data-goomoji attribute',
  698. cell.getAttribute(goog.ui.emoji.Emoji.DATA_ATTRIBUTE), emojiInfo[1]);
  699. // Now check the contents of the cells
  700. var url = emojiInfo[0]; // url of the animated emoji
  701. var spriteInfo = emojiInfo[2];
  702. if (spriteInfo) {
  703. if (spriteInfo.isAnimated()) {
  704. var testImg = new Image();
  705. testImg.src = url;
  706. var img = inner.firstChild;
  707. checkPathsEndWithSameFile(img.src, url);
  708. assertEquals(testImg.width, img.width);
  709. assertEquals(testImg.height, img.height);
  710. assertEquals(
  711. '0', goog.style.getStyle(img, 'left')
  712. .replace(/px/g, '')
  713. .replace(/pt/g, ''));
  714. assertEquals(
  715. '0', goog.style.getStyle(img, 'top')
  716. .replace(/px/g, '')
  717. .replace(/pt/g, ''));
  718. } else {
  719. var cssClass = spriteInfo.getCssClass();
  720. if (cssClass) {
  721. assertEquals('DIV', inner.tagName);
  722. assertTrue(
  723. 'Sprite should have its CSS class set',
  724. goog.dom.classlist.contains(inner, cssClass));
  725. } else {
  726. // There's an inner div wrapping an img tag
  727. assertEquals('DIV', inner.tagName);
  728. var img = inner.firstChild;
  729. assertNotNull('Div should be wrapping something', img);
  730. assertEquals('IMG', img.tagName);
  731. checkPathsEndWithSameFile(img.src, spriteInfo.getUrl());
  732. assertEquals(
  733. spriteInfo.getWidthCssValue(),
  734. goog.style.getStyle(inner, 'width'));
  735. assertEquals(
  736. spriteInfo.getHeightCssValue(),
  737. goog.style.getStyle(inner, 'height'));
  738. assertEquals(
  739. spriteInfo.getXOffsetCssValue().replace(/px/, '').replace(
  740. /pt/, ''),
  741. goog.style.getStyle(img, 'left')
  742. .replace(/px/, '')
  743. .replace(/pt/, ''));
  744. assertEquals(
  745. spriteInfo.getYOffsetCssValue().replace(/px/, '').replace(
  746. /pt/, ''),
  747. goog.style.getStyle(img, 'top')
  748. .replace(/px/, '')
  749. .replace(/pt/, ''));
  750. }
  751. }
  752. } else {
  753. // A non-sprited emoji is just an img
  754. assertEquals(inner.tagName, 'IMG');
  755. checkPathsEndWithSameFile(inner.src, emojiInfo[0]);
  756. }
  757. }
  758. }
  759. function testPreLoadCellConstructionForFastLoadingNonProgressive() {
  760. var defaultImg = '../../demos/emoji/none.gif';
  761. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  762. picker.setDelayedLoad(false);
  763. picker.setManualLoadOfAnimatedEmoji(true);
  764. picker.setProgressiveRender(false);
  765. picker.addEmojiGroup(spritedEmoji2[0], spritedEmoji2[1]);
  766. picker.render();
  767. var palette = picker.getPage(0);
  768. checkStructureForNonProgressivePicker(palette, spritedEmoji2);
  769. picker.dispose();
  770. }
  771. function testPreLoadCellConstructionForFastLoadingProgressive() {
  772. var defaultImg = '../../demos/emoji/none.gif';
  773. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  774. picker.setDelayedLoad(false);
  775. picker.setManualLoadOfAnimatedEmoji(true);
  776. picker.setProgressiveRender(true);
  777. picker.addEmojiGroup(spritedEmoji2[0], spritedEmoji2[1]);
  778. picker.render();
  779. var palette = picker.getPage(0);
  780. checkStructureForProgressivePicker(palette, spritedEmoji2);
  781. picker.dispose();
  782. }
  783. function testCellConstructionForNonProgressiveRenderingSpriting() {
  784. var defaultImg = '../../demos/emoji/none.gif';
  785. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  786. picker.setDelayedLoad(false);
  787. picker.addEmojiGroup(spritedEmoji1[0], spritedEmoji1[1]);
  788. picker.render();
  789. var palette = picker.getPage(0);
  790. checkStructureForNonProgressivePicker(palette, spritedEmoji1);
  791. picker.dispose();
  792. }
  793. function testCellConstructionForProgressiveRenderingSpriting() {
  794. var defaultImg = '../../demos/emoji/none.gif';
  795. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  796. picker.setDelayedLoad(false);
  797. picker.setProgressiveRender(true);
  798. picker.addEmojiGroup(spritedEmoji1[0], spritedEmoji1[1]);
  799. picker.render();
  800. var palette = picker.getPage(0);
  801. checkStructureForProgressivePicker(palette, spritedEmoji1);
  802. picker.dispose();
  803. }
  804. function testDelayedLoadPaletteCreationForMultiPagePicker() {
  805. var defaultImg = '../../demos/emoji/none.gif';
  806. var picker = new goog.ui.emoji.EmojiPicker(defaultImg);
  807. picker.setDelayedLoad(true);
  808. for (var i = 0; i < emojiGroups.length; i++) {
  809. picker.addEmojiGroup(emojiGroups[i][0], emojiGroups[i][1]);
  810. }
  811. picker.render();
  812. // At this point the picker should have pages filled with the default img
  813. for (var i = 0; i < emojiGroups.length; i++) {
  814. checkContentIsDefaultImg(picker.getPage(i), defaultImg);
  815. }
  816. // Now load the images
  817. picker.loadImages();
  818. // The first page should be loaded
  819. var page = picker.getPage(0);
  820. assertTrue(
  821. 'Page ' + i + ' should be in the document but is not',
  822. page.isInDocument());
  823. checkContentIsEmojiImages(page, emojiGroups[0][1], defaultImg);
  824. // The other pages should all be filled with the default img since they are
  825. // lazily loaded
  826. for (var i = 1; i < 3; i++) {
  827. checkContentIsDefaultImg(picker.getPage(i), defaultImg);
  828. }
  829. // Activate the other two pages so that their images get loaded, and check
  830. // that they're now loaded correctly
  831. var tabPane = picker.getTabPane();
  832. for (var i = 1; i < 3; i++) {
  833. tabPane.setSelectedIndex(i);
  834. page = picker.getPage(i);
  835. assertTrue(page.isInDocument());
  836. checkContentIsEmojiImages(page, emojiGroups[i][1], defaultImg);
  837. }
  838. picker.dispose();
  839. }