style_test.js 91 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692
  1. // Copyright 2011 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 Licensegg 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. /**
  15. * @fileoverview Shared unit tests for styles.
  16. */
  17. goog.provide('goog.style_test');
  18. goog.require('goog.array');
  19. goog.require('goog.color');
  20. goog.require('goog.dom');
  21. goog.require('goog.dom.TagName');
  22. goog.require('goog.events.BrowserEvent');
  23. goog.require('goog.html.testing');
  24. goog.require('goog.labs.userAgent.util');
  25. goog.require('goog.math.Box');
  26. goog.require('goog.math.Coordinate');
  27. goog.require('goog.math.Rect');
  28. goog.require('goog.math.Size');
  29. goog.require('goog.object');
  30. goog.require('goog.style');
  31. goog.require('goog.testing.ExpectedFailures');
  32. goog.require('goog.testing.MockUserAgent');
  33. goog.require('goog.testing.TestCase');
  34. goog.require('goog.testing.asserts');
  35. goog.require('goog.testing.jsunit');
  36. goog.require('goog.userAgent');
  37. goog.require('goog.userAgentTestUtil');
  38. goog.require('goog.userAgentTestUtil.UserAgents');
  39. goog.setTestOnly('goog.style_test');
  40. // IE before version 6 will always be border box in compat mode.
  41. var isBorderBox = goog.dom.isCss1CompatMode() ?
  42. (goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('6')) :
  43. true;
  44. var EPSILON = 2;
  45. var expectedFailures = new goog.testing.ExpectedFailures();
  46. var $ = goog.dom.getElement;
  47. var mockUserAgent;
  48. function setUpPage() {
  49. // TODO(b/25875505): Fix unreported assertions (go/failonunreportedasserts).
  50. goog.testing.TestCase.getActiveTestCase().failOnUnreportedAsserts = false;
  51. var viewportSize = goog.dom.getViewportSize();
  52. // When the window is too short or not wide enough, some tests, especially
  53. // those for off-screen elements, fail. Oddly, the most reliable
  54. // indicator is a width of zero (which is of course erroneous), since
  55. // height sometimes includes a scroll bar. We can make no assumptions on
  56. // window size on the Selenium farm.
  57. if (goog.userAgent.IE && viewportSize.width < 300) {
  58. // Move to origin, since IE won't resize outside the screen.
  59. window.moveTo(0, 0);
  60. window.resizeTo(640, 480);
  61. }
  62. }
  63. function setUp() {
  64. window.scrollTo(0, 0);
  65. goog.userAgentTestUtil.reinitializeUserAgent();
  66. mockUserAgent = new goog.testing.MockUserAgent();
  67. mockUserAgent.install();
  68. }
  69. function tearDown() {
  70. expectedFailures.handleTearDown();
  71. var testVisibleDiv2 = goog.dom.getElement('test-visible2');
  72. testVisibleDiv2.setAttribute('style', '');
  73. goog.dom.removeChildren(testVisibleDiv2);
  74. var testViewport = goog.dom.getElement('test-viewport');
  75. testViewport.setAttribute('style', '');
  76. goog.dom.removeChildren(testViewport);
  77. goog.dispose(mockUserAgent);
  78. // Prevent multiple vendor prefixed mock elements from poisoning the cache.
  79. goog.style.styleNameCache_ = {};
  80. }
  81. function testSetStyle() {
  82. var el = $('span1');
  83. goog.style.setStyle(el, 'textDecoration', 'underline');
  84. assertEquals('Should be underline', 'underline', el.style.textDecoration);
  85. }
  86. function testSetStyleMap() {
  87. var el = $('span6');
  88. var styles =
  89. {'background-color': 'blue', 'font-size': '100px', textAlign: 'center'};
  90. goog.style.setStyle(el, styles);
  91. var answers = {
  92. backgroundColor: 'blue',
  93. fontSize: '100px',
  94. textAlign: 'center'
  95. };
  96. goog.object.forEach(answers, function(value, style) {
  97. assertEquals('Should be ' + value, value, el.style[style]);
  98. });
  99. }
  100. function testSetStyleWithNonCamelizedString() {
  101. var el = $('span5');
  102. goog.style.setStyle(el, 'text-decoration', 'underline');
  103. assertEquals('Should be underline', 'underline', el.style.textDecoration);
  104. }
  105. function testGetStyle() {
  106. var el = goog.dom.getElement('styleTest3');
  107. goog.style.setStyle(el, 'width', '80px');
  108. goog.style.setStyle(el, 'textDecoration', 'underline');
  109. assertEquals('80px', goog.style.getStyle(el, 'width'));
  110. assertEquals('underline', goog.style.getStyle(el, 'textDecoration'));
  111. assertEquals('underline', goog.style.getStyle(el, 'text-decoration'));
  112. // Non set properties are always empty strings.
  113. assertEquals('', goog.style.getStyle(el, 'border'));
  114. }
  115. function testGetStyleMsFilter() {
  116. // Element with -ms-filter style set.
  117. var e = goog.dom.getElement('msFilter');
  118. if (goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(8) &&
  119. !goog.userAgent.isDocumentModeOrHigher(10)) {
  120. // Only IE8/9 supports -ms-filter and returns it as value for the "filter"
  121. // property. When in compatibility mode, -ms-filter is not supported
  122. // and IE8 behaves as IE7 so the other case will apply.
  123. assertEquals('alpha(opacity=0)', goog.style.getStyle(e, 'filter'));
  124. } else {
  125. // Any other browser does not support ms-filter so it returns empty string.
  126. assertEquals('', goog.style.getStyle(e, 'filter'));
  127. }
  128. }
  129. function testGetStyleFilter() {
  130. // Element with filter style set.
  131. var e = goog.dom.getElement('filter');
  132. if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {
  133. // Filter supported.
  134. assertEquals('alpha(opacity=0)', goog.style.getStyle(e, 'filter'));
  135. } else {
  136. assertEquals('', goog.style.getStyle(e, 'filter'));
  137. }
  138. }
  139. function testGetComputedStyleMsFilter() {
  140. // Element with -ms-filter style set.
  141. var e = goog.dom.getElement('msFilter');
  142. if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {
  143. if (goog.userAgent.isDocumentModeOrHigher(9)) {
  144. // IE 9 returns the value.
  145. assertEquals(
  146. 'alpha(opacity=0)', goog.style.getComputedStyle(e, 'filter'));
  147. } else {
  148. // Older IE always returns empty string for computed styles.
  149. assertEquals('', goog.style.getComputedStyle(e, 'filter'));
  150. }
  151. } else {
  152. // Non IE returns 'none' for filter as it is an SVG property
  153. assertEquals('none', goog.style.getComputedStyle(e, 'filter'));
  154. }
  155. }
  156. function testGetComputedStyleFilter() {
  157. // Element with filter style set.
  158. var e = goog.dom.getElement('filter');
  159. if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {
  160. if (goog.userAgent.isDocumentModeOrHigher(9)) {
  161. // IE 9 returns the value.
  162. assertEquals(
  163. 'alpha(opacity=0)', goog.style.getComputedStyle(e, 'filter'));
  164. } else {
  165. // Older IE always returns empty string for computed styles.
  166. assertEquals('', goog.style.getComputedStyle(e, 'filter'));
  167. }
  168. } else {
  169. // Non IE returns 'none' for filter as it is an SVG property
  170. assertEquals('none', goog.style.getComputedStyle(e, 'filter'));
  171. }
  172. }
  173. function testGetComputedBoxSizing() {
  174. if (!goog.userAgent.IE || goog.userAgent.isVersionOrHigher(8)) {
  175. var defaultBoxSizing =
  176. goog.dom.isCss1CompatMode() ? 'content-box' : 'border-box';
  177. var el = goog.dom.getElement('box-sizing-unset');
  178. assertEquals(defaultBoxSizing, goog.style.getComputedBoxSizing(el));
  179. el = goog.dom.getElement('box-sizing-border-box');
  180. assertEquals('border-box', goog.style.getComputedBoxSizing(el));
  181. } else {
  182. // IE7 and below don't support box-sizing.
  183. assertNull(
  184. goog.style.getComputedBoxSizing(
  185. goog.dom.getElement('box-sizing-border-box')));
  186. }
  187. }
  188. function testGetComputedPosition() {
  189. assertEquals(
  190. 'position not set', 'static',
  191. goog.style.getComputedPosition($('position-unset')));
  192. assertEquals(
  193. 'position:relative in style attribute', 'relative',
  194. goog.style.getComputedPosition($('style-position-relative')));
  195. if (goog.userAgent.IE && !goog.dom.isCss1CompatMode() &&
  196. !goog.userAgent.isVersionOrHigher(10)) {
  197. assertEquals(
  198. 'position:fixed in style attribute', 'static',
  199. goog.style.getComputedPosition($('style-position-fixed')));
  200. } else {
  201. assertEquals(
  202. 'position:fixed in style attribute', 'fixed',
  203. goog.style.getComputedPosition($('style-position-fixed')));
  204. }
  205. assertEquals(
  206. 'position:absolute in css', 'absolute',
  207. goog.style.getComputedPosition($('css-position-absolute')));
  208. }
  209. function testGetComputedOverflowXAndY() {
  210. assertEquals(
  211. 'overflow-x:scroll in style attribute', 'scroll',
  212. goog.style.getComputedOverflowX($('style-overflow-scroll')));
  213. assertEquals(
  214. 'overflow-y:scroll in style attribute', 'scroll',
  215. goog.style.getComputedOverflowY($('style-overflow-scroll')));
  216. assertEquals(
  217. 'overflow-x:hidden in css', 'hidden',
  218. goog.style.getComputedOverflowX($('css-overflow-hidden')));
  219. assertEquals(
  220. 'overflow-y:hidden in css', 'hidden',
  221. goog.style.getComputedOverflowY($('css-overflow-hidden')));
  222. }
  223. function testGetComputedZIndex() {
  224. assertEquals(
  225. 'z-index:200 in style attribute', '200',
  226. '' + goog.style.getComputedZIndex($('style-z-index-200')));
  227. assertEquals(
  228. 'z-index:200 in css', '200',
  229. '' + goog.style.getComputedZIndex($('css-z-index-200')));
  230. }
  231. function testGetComputedTextAlign() {
  232. assertEquals(
  233. 'text-align:right in style attribute', 'right',
  234. goog.style.getComputedTextAlign($('style-text-align-right')));
  235. assertEquals(
  236. 'text-align:right inherited from parent', 'right',
  237. goog.style.getComputedTextAlign($('style-text-align-right-inner')));
  238. assertEquals(
  239. 'text-align:center in css', 'center',
  240. goog.style.getComputedTextAlign($('css-text-align-center')));
  241. }
  242. function testGetComputedCursor() {
  243. assertEquals(
  244. 'cursor:move in style attribute', 'move',
  245. goog.style.getComputedCursor($('style-cursor-move')));
  246. assertEquals(
  247. 'cursor:move inherited from parent', 'move',
  248. goog.style.getComputedCursor($('style-cursor-move-inner')));
  249. assertEquals(
  250. 'cursor:poiner in css', 'pointer',
  251. goog.style.getComputedCursor($('css-cursor-pointer')));
  252. }
  253. function testGetBackgroundColor() {
  254. var dest = $('bgcolorDest');
  255. for (var i = 0; $('bgcolorTest' + i); i++) {
  256. var src = $('bgcolorTest' + i);
  257. var bgColor = goog.style.getBackgroundColor(src);
  258. dest.style.backgroundColor = bgColor;
  259. assertEquals(
  260. 'Background colors should be equal', goog.style.getBackgroundColor(src),
  261. goog.style.getBackgroundColor(dest));
  262. try {
  263. // goog.color.parse throws a generic exception if handed input it
  264. // doesn't understand.
  265. var c = goog.color.parse(bgColor);
  266. assertEquals('rgb(255,0,0)', goog.color.hexToRgbStyle(c.hex));
  267. } catch (e) {
  268. // Internet Explorer is unable to parse colors correctly after test 4.
  269. // Other browsers may vary, but all should be able to handle straight
  270. // hex input.
  271. assertFalse('Should be able to parse color "' + bgColor + '"', i < 5);
  272. }
  273. }
  274. }
  275. function testSetPosition() {
  276. var el = $('testEl');
  277. goog.style.setPosition(el, 100, 100);
  278. assertEquals('100px', el.style.left);
  279. assertEquals('100px', el.style.top);
  280. goog.style.setPosition(el, '50px', '25px');
  281. assertEquals('50px', el.style.left);
  282. assertEquals('25px', el.style.top);
  283. goog.style.setPosition(el, '10ex', '25px');
  284. assertEquals('10ex', el.style.left);
  285. assertEquals('25px', el.style.top);
  286. goog.style.setPosition(el, '10%', '25%');
  287. assertEquals('10%', el.style.left);
  288. assertEquals('25%', el.style.top);
  289. // ignores stupid units
  290. goog.style.setPosition(el, 0, 0);
  291. // TODO(user): IE errors if you set these values. Should we make setStyle
  292. // catch these? Or leave it up to the app. Fixing the tests for now.
  293. // goog.style.setPosition(el, '10rainbows', '25rainbows');
  294. assertEquals('0px', el.style.left);
  295. assertEquals('0px', el.style.top);
  296. goog.style.setPosition(el, new goog.math.Coordinate(20, 40));
  297. assertEquals('20px', el.style.left);
  298. assertEquals('40px', el.style.top);
  299. }
  300. function testGetClientPositionAbsPositionElement() {
  301. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  302. div.style.position = 'absolute';
  303. div.style.left = '100px';
  304. div.style.top = '200px';
  305. document.body.appendChild(div);
  306. var pos = goog.style.getClientPosition(div);
  307. assertEquals(100, pos.x);
  308. assertEquals(200, pos.y);
  309. }
  310. function testGetClientPositionNestedElements() {
  311. var innerDiv = goog.dom.createDom(goog.dom.TagName.DIV);
  312. innerDiv.style.position = 'relative';
  313. innerDiv.style.left = '-10px';
  314. innerDiv.style.top = '-10px';
  315. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  316. div.style.position = 'absolute';
  317. div.style.left = '150px';
  318. div.style.top = '250px';
  319. div.appendChild(innerDiv);
  320. document.body.appendChild(div);
  321. var pos = goog.style.getClientPosition(innerDiv);
  322. assertEquals(140, pos.x);
  323. assertEquals(240, pos.y);
  324. }
  325. function testGetClientPositionOfOffscreenElement() {
  326. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  327. div.style.position = 'absolute';
  328. div.style.left = '2000px';
  329. div.style.top = '2000px';
  330. div.style.width = '10px';
  331. div.style.height = '10px';
  332. document.body.appendChild(div);
  333. try {
  334. window.scroll(0, 0);
  335. var pos = goog.style.getClientPosition(div);
  336. assertEquals(2000, pos.x);
  337. assertEquals(2000, pos.y);
  338. // The following tests do not work in Gecko 1.8 and below, due to an
  339. // obscure off-by-one bug in goog.style.getPageOffset. Same for IE.
  340. if (!goog.userAgent.IE &&
  341. !(goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9'))) {
  342. window.scroll(1, 1);
  343. var pos = goog.style.getClientPosition(div);
  344. assertEquals(1999, pos.x);
  345. assertRoughlyEquals(1999, pos.y, 0.5);
  346. window.scroll(2, 2);
  347. pos = goog.style.getClientPosition(div);
  348. assertEquals(1998, pos.x);
  349. assertRoughlyEquals(1998, pos.y, 0.5);
  350. window.scroll(100, 100);
  351. pos = goog.style.getClientPosition(div);
  352. assertEquals(1900, pos.x);
  353. assertRoughlyEquals(1900, pos.y, 0.5);
  354. }
  355. } finally {
  356. window.scroll(0, 0);
  357. document.body.removeChild(div);
  358. }
  359. }
  360. function testGetClientPositionOfOrphanElement() {
  361. var orphanElem = goog.dom.createElement(goog.dom.TagName.DIV);
  362. var pos = goog.style.getClientPosition(orphanElem);
  363. assertEquals(0, pos.x);
  364. assertEquals(0, pos.y);
  365. }
  366. function testGetClientPositionEvent() {
  367. var mockEvent = {};
  368. mockEvent.clientX = 100;
  369. mockEvent.clientY = 200;
  370. var pos = goog.style.getClientPosition(mockEvent);
  371. assertEquals(100, pos.x);
  372. assertEquals(200, pos.y);
  373. }
  374. function testGetClientPositionTouchEvent() {
  375. var mockTouchEvent = {};
  376. mockTouchEvent.changedTouches = [{}];
  377. mockTouchEvent.changedTouches[0].clientX = 100;
  378. mockTouchEvent.changedTouches[0].clientY = 200;
  379. var pos = goog.style.getClientPosition(mockTouchEvent);
  380. assertEquals(100, pos.x);
  381. assertEquals(200, pos.y);
  382. }
  383. function testGetClientPositionEmptyTouchList() {
  384. var mockTouchEvent = {};
  385. mockTouchEvent.touches = [];
  386. mockTouchEvent.changedTouches = [{}];
  387. mockTouchEvent.changedTouches[0].clientX = 100;
  388. mockTouchEvent.changedTouches[0].clientY = 200;
  389. var pos = goog.style.getClientPosition(mockTouchEvent);
  390. assertEquals(100, pos.x);
  391. assertEquals(200, pos.y);
  392. }
  393. function testGetClientPositionAbstractedTouchEvent() {
  394. var mockTouchEvent = {};
  395. mockTouchEvent.changedTouches = [{}];
  396. mockTouchEvent.changedTouches[0].clientX = 100;
  397. mockTouchEvent.changedTouches[0].clientY = 200;
  398. var e = new goog.events.BrowserEvent(mockTouchEvent);
  399. var pos = goog.style.getClientPosition(e);
  400. assertEquals(100, pos.x);
  401. assertEquals(200, pos.y);
  402. }
  403. function testGetPageOffsetAbsPositionedElement() {
  404. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  405. div.style.position = 'absolute';
  406. div.style.left = '100px';
  407. div.style.top = '200px';
  408. document.body.appendChild(div);
  409. var pos = goog.style.getPageOffset(div);
  410. assertEquals(100, pos.x);
  411. assertEquals(200, pos.y);
  412. }
  413. function testGetPageOffsetNestedElements() {
  414. var innerDiv = goog.dom.createDom(goog.dom.TagName.DIV);
  415. innerDiv.style.position = 'relative';
  416. innerDiv.style.left = '-10px';
  417. innerDiv.style.top = '-10px';
  418. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  419. div.style.position = 'absolute';
  420. div.style.left = '150px';
  421. div.style.top = '250px';
  422. div.appendChild(innerDiv);
  423. document.body.appendChild(div);
  424. var pos = goog.style.getPageOffset(innerDiv);
  425. assertRoughlyEquals(140, pos.x, 0.1);
  426. assertRoughlyEquals(240, pos.y, 0.1);
  427. }
  428. function testGetPageOffsetWithBodyPadding() {
  429. document.body.style.margin = '40px';
  430. document.body.style.padding = '60px';
  431. document.body.style.borderWidth = '70px';
  432. try {
  433. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  434. div.style.position = 'absolute';
  435. div.style.left = '100px';
  436. div.style.top = '200px';
  437. // Margin will affect position, but padding and borders should not.
  438. div.style.margin = '1px';
  439. div.style.padding = '2px';
  440. div.style.borderWidth = '3px';
  441. document.body.appendChild(div);
  442. var pos = goog.style.getPageOffset(div);
  443. assertRoughlyEquals(101, pos.x, 0.1);
  444. assertRoughlyEquals(201, pos.y, 0.1);
  445. } finally {
  446. document.body.removeChild(div);
  447. document.body.style.margin = '';
  448. document.body.style.padding = '';
  449. document.body.style.borderWidth = '';
  450. }
  451. }
  452. function testGetPageOffsetWithDocumentElementPadding() {
  453. document.documentElement.style.margin = '40px';
  454. document.documentElement.style.padding = '60px';
  455. document.documentElement.style.borderWidth = '70px';
  456. try {
  457. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  458. div.style.position = 'absolute';
  459. div.style.left = '100px';
  460. div.style.top = '200px';
  461. // Margin will affect position, but padding and borders should not.
  462. div.style.margin = '1px';
  463. div.style.padding = '2px';
  464. div.style.borderWidth = '3px';
  465. document.body.appendChild(div);
  466. var pos = goog.style.getPageOffset(div);
  467. // FF3 (but not beyond) gets confused by document margins.
  468. if (goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9') &&
  469. !goog.userAgent.isVersionOrHigher('1.9.1')) {
  470. assertEquals(141, pos.x);
  471. assertEquals(241, pos.y);
  472. } else {
  473. assertRoughlyEquals(101, pos.x, 0.1);
  474. assertRoughlyEquals(201, pos.y, 0.1);
  475. }
  476. } finally {
  477. document.body.removeChild(div);
  478. document.documentElement.style.margin = '';
  479. document.documentElement.style.padding = '';
  480. document.documentElement.style.borderWidth = '';
  481. }
  482. }
  483. function testGetPageOffsetElementOffscreen() {
  484. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  485. div.style.position = 'absolute';
  486. div.style.left = '10000px';
  487. div.style.top = '20000px';
  488. document.body.appendChild(div);
  489. window.scroll(0, 0);
  490. try {
  491. var pos = goog.style.getPageOffset(div);
  492. assertEquals(10000, pos.x);
  493. assertEquals(20000, pos.y);
  494. // The following tests do not work in Gecko 1.8 and below, due to an
  495. // obscure off-by-one bug in goog.style.getPageOffset. Same for IE.
  496. if (!(goog.userAgent.IE) &&
  497. !(goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9'))) {
  498. window.scroll(1, 1);
  499. pos = goog.style.getPageOffset(div);
  500. assertEquals(10000, pos.x);
  501. assertRoughlyEquals(20000, pos.y, 0.5);
  502. window.scroll(1000, 2000);
  503. pos = goog.style.getPageOffset(div);
  504. assertEquals(10000, pos.x);
  505. assertRoughlyEquals(20000, pos.y, 1);
  506. window.scroll(10000, 20000);
  507. pos = goog.style.getPageOffset(div);
  508. assertEquals(10000, pos.x);
  509. assertRoughlyEquals(20000, pos.y, 1);
  510. }
  511. }
  512. // Undo changes.
  513. finally {
  514. document.body.removeChild(div);
  515. window.scroll(0, 0);
  516. }
  517. }
  518. function testGetPageOffsetFixedPositionElements() {
  519. // Skip these tests in certain browsers.
  520. // position:fixed is not supported in IE before version 7
  521. if (!goog.userAgent.IE || !goog.userAgent.isVersionOrHigher('6')) {
  522. // Test with a position fixed element
  523. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  524. div.style.position = 'fixed';
  525. div.style.top = '10px';
  526. div.style.left = '10px';
  527. document.body.appendChild(div);
  528. var pos = goog.style.getPageOffset(div);
  529. assertEquals(10, pos.x);
  530. assertEquals(10, pos.y);
  531. // Test with a position fixed element as parent
  532. var innerDiv = goog.dom.createDom(goog.dom.TagName.DIV);
  533. div = goog.dom.createDom(goog.dom.TagName.DIV);
  534. div.style.position = 'fixed';
  535. div.style.top = '10px';
  536. div.style.left = '10px';
  537. div.style.padding = '5px';
  538. div.appendChild(innerDiv);
  539. document.body.appendChild(div);
  540. pos = goog.style.getPageOffset(innerDiv);
  541. assertEquals(15, pos.x);
  542. assertEquals(15, pos.y);
  543. }
  544. }
  545. function testGetPositionTolerantToNoDocumentElementBorder() {
  546. // In IE, removing the border on the document element undoes the normal
  547. // 2-pixel offset. Ensure that we're correctly compensating for both cases.
  548. try {
  549. document.documentElement.style.borderWidth = '0';
  550. var div = goog.dom.createDom(goog.dom.TagName.DIV);
  551. div.style.position = 'absolute';
  552. div.style.left = '100px';
  553. div.style.top = '200px';
  554. document.body.appendChild(div);
  555. // Test all major positioning methods.
  556. // Disabled for IE9 and below - IE8 returns dimensions multiplied by 100.
  557. // IE9 is flaky. See b/22873770.
  558. expectedFailures.expectFailureFor(
  559. goog.userAgent.IE && !goog.userAgent.isVersionOrHigher(10));
  560. try {
  561. // Test all major positioning methods.
  562. var pos = goog.style.getClientPosition(div);
  563. assertEquals(100, pos.x);
  564. assertRoughlyEquals(200, pos.y, .1);
  565. var offset = goog.style.getPageOffset(div);
  566. assertEquals(100, offset.x);
  567. assertRoughlyEquals(200, offset.y, .1);
  568. } catch (e) {
  569. expectedFailures.handleException(e);
  570. }
  571. } finally {
  572. document.documentElement.style.borderWidth = '';
  573. }
  574. }
  575. function testSetSize() {
  576. var el = $('testEl');
  577. goog.style.setSize(el, 100, 100);
  578. assertEquals('100px', el.style.width);
  579. assertEquals('100px', el.style.height);
  580. goog.style.setSize(el, '50px', '25px');
  581. assertEquals('should be "50px"', '50px', el.style.width);
  582. assertEquals('should be "25px"', '25px', el.style.height);
  583. goog.style.setSize(el, '10ex', '25px');
  584. assertEquals('10ex', el.style.width);
  585. assertEquals('25px', el.style.height);
  586. goog.style.setSize(el, '10%', '25%');
  587. assertEquals('10%', el.style.width);
  588. assertEquals('25%', el.style.height);
  589. // ignores stupid units
  590. goog.style.setSize(el, 0, 0);
  591. // TODO(user): IE errors if you set these values. Should we make setStyle
  592. // catch these? Or leave it up to the app. Fixing the tests for now.
  593. // goog.style.setSize(el, '10rainbows', '25rainbows');
  594. assertEquals('0px', el.style.width);
  595. assertEquals('0px', el.style.height);
  596. goog.style.setSize(el, new goog.math.Size(20, 40));
  597. assertEquals('20px', el.style.width);
  598. assertEquals('40px', el.style.height);
  599. }
  600. function testSetWidthAndHeight() {
  601. var el = $('testEl');
  602. // Replicate all of the setSize tests above.
  603. goog.style.setWidth(el, 100);
  604. goog.style.setHeight(el, 100);
  605. assertEquals('100px', el.style.width);
  606. assertEquals('100px', el.style.height);
  607. goog.style.setWidth(el, '50px');
  608. goog.style.setHeight(el, '25px');
  609. assertEquals('should be "50px"', '50px', el.style.width);
  610. assertEquals('should be "25px"', '25px', el.style.height);
  611. goog.style.setWidth(el, '10ex');
  612. goog.style.setHeight(el, '25px');
  613. assertEquals('10ex', el.style.width);
  614. assertEquals('25px', el.style.height);
  615. goog.style.setWidth(el, '10%');
  616. goog.style.setHeight(el, '25%');
  617. assertEquals('10%', el.style.width);
  618. assertEquals('25%', el.style.height);
  619. goog.style.setWidth(el, 0);
  620. goog.style.setHeight(el, 0);
  621. assertEquals('0px', el.style.width);
  622. assertEquals('0px', el.style.height);
  623. goog.style.setWidth(el, 20);
  624. goog.style.setHeight(el, 40);
  625. assertEquals('20px', el.style.width);
  626. assertEquals('40px', el.style.height);
  627. // Additional tests testing each separately.
  628. goog.style.setWidth(el, '');
  629. goog.style.setHeight(el, '');
  630. assertEquals('', el.style.width);
  631. assertEquals('', el.style.height);
  632. goog.style.setHeight(el, 20);
  633. assertEquals('', el.style.width);
  634. assertEquals('20px', el.style.height);
  635. goog.style.setWidth(el, 40);
  636. assertEquals('40px', el.style.width);
  637. assertEquals('20px', el.style.height);
  638. }
  639. function testGetSize() {
  640. var el = $('testEl');
  641. goog.style.setSize(el, 100, 100);
  642. var dims = goog.style.getSize(el);
  643. assertEquals(100, dims.width);
  644. assertEquals(100, dims.height);
  645. goog.style.setStyle(el, 'display', 'none');
  646. dims = goog.style.getSize(el);
  647. assertEquals(100, dims.width);
  648. assertEquals(100, dims.height);
  649. el = $('testEl5');
  650. goog.style.setSize(el, 100, 100);
  651. dims = goog.style.getSize(el);
  652. assertEquals(100, dims.width);
  653. assertEquals(100, dims.height);
  654. el = $('span0');
  655. dims = goog.style.getSize(el);
  656. assertNotEquals(0, dims.width);
  657. assertNotEquals(0, dims.height);
  658. el = $('table1');
  659. dims = goog.style.getSize(el);
  660. assertNotEquals(0, dims.width);
  661. assertNotEquals(0, dims.height);
  662. el = $('td1');
  663. dims = goog.style.getSize(el);
  664. assertNotEquals(0, dims.width);
  665. assertNotEquals(0, dims.height);
  666. el = $('li1');
  667. dims = goog.style.getSize(el);
  668. assertNotEquals(0, dims.width);
  669. assertNotEquals(0, dims.height);
  670. el = goog.dom.getElementsByTagNameAndClass(goog.dom.TagName.HTML)[0];
  671. dims = goog.style.getSize(el);
  672. assertNotEquals(0, dims.width);
  673. assertNotEquals(0, dims.height);
  674. el = goog.dom.getElementsByTagNameAndClass(goog.dom.TagName.BODY)[0];
  675. dims = goog.style.getSize(el);
  676. assertNotEquals(0, dims.width);
  677. assertNotEquals(0, dims.height);
  678. }
  679. function testGetSizeSvgElements() {
  680. var svgEl = document.createElementNS &&
  681. document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  682. if (!svgEl || svgEl.getAttribute('transform') == '' ||
  683. (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher(534.8))) {
  684. // SVG not supported, or getBoundingClientRect not supported on SVG
  685. // elements.
  686. return;
  687. }
  688. document.body.appendChild(svgEl);
  689. var el = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  690. el.setAttribute('x', 10);
  691. el.setAttribute('y', 10);
  692. el.setAttribute('width', 32);
  693. el.setAttribute('height', 21);
  694. el.setAttribute('fill', '#000');
  695. svgEl.appendChild(el);
  696. // The bounding size in 1 larger than the SVG element in IE.
  697. var expectedWidth = (goog.userAgent.EDGE_OR_IE) ? 33 : 32;
  698. var expectedHeight = (goog.userAgent.EDGE_OR_IE) ? 22 : 21;
  699. var dims = goog.style.getSize(el);
  700. assertEquals(expectedWidth, dims.width);
  701. assertRoughlyEquals(expectedHeight, dims.height, 0.01);
  702. dims = goog.style.getSize(svgEl);
  703. // The size of the <svg> will be the viewport size on all browsers. This used
  704. // to not be true for Firefox, but they fixed the glitch in Firefox 33.
  705. // https://bugzilla.mozilla.org/show_bug.cgi?id=530985
  706. assertTrue(dims.width >= expectedWidth);
  707. assertTrue(dims.height >= expectedHeight);
  708. el.style.visibility = 'none';
  709. dims = goog.style.getSize(el);
  710. assertEquals(expectedWidth, dims.width);
  711. assertRoughlyEquals(expectedHeight, dims.height, 0.01);
  712. dims = goog.style.getSize(svgEl);
  713. assertTrue(dims.width >= expectedWidth);
  714. assertTrue(dims.height >= expectedHeight);
  715. }
  716. function testGetSizeSvgDocument() {
  717. var svgEl = document.createElementNS &&
  718. document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  719. if (!svgEl || svgEl.getAttribute('transform') == '' ||
  720. (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher(534.8))) {
  721. // SVG not supported, or getBoundingClientRect not supported on SVG
  722. // elements.
  723. return;
  724. }
  725. var frame = goog.dom.getElement('svg-frame');
  726. var doc = goog.dom.getFrameContentDocument(frame);
  727. var rect = doc.getElementById('rect');
  728. var dims = goog.style.getSize(rect);
  729. if (goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher(53)) {
  730. // Firefox >= 53 auto-scales iframe SVG content to fit the frame
  731. // b/38432885 | https://bugzilla.mozilla.org/show_bug.cgi?id=1366126
  732. assertEquals(75, dims.width);
  733. assertEquals(75, dims.height);
  734. } else if (!goog.userAgent.EDGE_OR_IE) {
  735. assertEquals(50, dims.width);
  736. assertEquals(50, dims.height);
  737. } else {
  738. assertEquals(51, dims.width);
  739. assertEquals(51, dims.height);
  740. }
  741. }
  742. function testGetSizeInlineBlock() {
  743. var el = $('height-test-inner');
  744. var dims = goog.style.getSize(el);
  745. assertNotEquals(0, dims.height);
  746. }
  747. function testGetSizeTransformedRotated() {
  748. if (!hasWebkitTransform()) return;
  749. var el = $('rotated');
  750. goog.style.setSize(el, 300, 200);
  751. var noRotateDims = goog.style.getTransformedSize(el);
  752. assertEquals(300, noRotateDims.width);
  753. assertEquals(200, noRotateDims.height);
  754. el.style.webkitTransform = 'rotate(180deg)';
  755. var rotate180Dims = goog.style.getTransformedSize(el);
  756. assertEquals(300, rotate180Dims.width);
  757. assertEquals(200, rotate180Dims.height);
  758. el.style.webkitTransform = 'rotate(90deg)';
  759. var rotate90ClockwiseDims = goog.style.getTransformedSize(el);
  760. assertEquals(200, rotate90ClockwiseDims.width);
  761. assertEquals(300, rotate90ClockwiseDims.height);
  762. el.style.webkitTransform = 'rotate(-90deg)';
  763. var rotate90CounterClockwiseDims = goog.style.getTransformedSize(el);
  764. assertEquals(200, rotate90CounterClockwiseDims.width);
  765. assertEquals(300, rotate90CounterClockwiseDims.height);
  766. }
  767. function testGetSizeTransformedScaled() {
  768. if (!hasWebkitTransform()) return;
  769. var el = $('scaled');
  770. goog.style.setSize(el, 300, 200);
  771. var noScaleDims = goog.style.getTransformedSize(el);
  772. assertEquals(300, noScaleDims.width);
  773. assertEquals(200, noScaleDims.height);
  774. el.style.webkitTransform = 'scale(2, 0.5)';
  775. var scaledDims = goog.style.getTransformedSize(el);
  776. assertEquals(600, scaledDims.width);
  777. assertEquals(100, scaledDims.height);
  778. }
  779. function hasWebkitTransform() {
  780. return 'webkitTransform' in document.body.style;
  781. }
  782. function testGetSizeOfOrphanElement() {
  783. var orphanElem = goog.dom.createElement(goog.dom.TagName.DIV);
  784. var size = goog.style.getSize(orphanElem);
  785. assertEquals(0, size.width);
  786. assertEquals(0, size.height);
  787. }
  788. function testGetBounds() {
  789. var el = $('testEl');
  790. var dims = goog.style.getSize(el);
  791. var pos = goog.style.getPageOffset(el);
  792. var rect = goog.style.getBounds(el);
  793. // Relies on getSize and getPageOffset being correct.
  794. assertEquals(dims.width, rect.width);
  795. assertEquals(dims.height, rect.height);
  796. assertEquals(pos.x, rect.left);
  797. assertEquals(pos.y, rect.top);
  798. }
  799. function testInstallStyles() {
  800. var el = $('installTest0');
  801. var originalBackground = goog.style.getBackgroundColor(el);
  802. // Uses background-color because it's easy to get the computed value
  803. var result = goog.style.installStyles(
  804. '#installTest0 { background-color: rgb(255, 192, 203); }');
  805. assertColorRgbEquals('rgb(255,192,203)', goog.style.getBackgroundColor(el));
  806. goog.style.uninstallStyles(result);
  807. assertEquals(originalBackground, goog.style.getBackgroundColor(el));
  808. }
  809. function testInstallSafeStyleSheet() {
  810. var el = $('installTest0');
  811. var originalBackground = goog.style.getBackgroundColor(el);
  812. // Uses background-color because it's easy to get the computed value
  813. var result = goog.style.installSafeStyleSheet(
  814. goog.html.testing.newSafeStyleSheetForTest(
  815. '#installTest0 { background-color: rgb(255, 192, 203); }'));
  816. assertColorRgbEquals('rgb(255,192,203)', goog.style.getBackgroundColor(el));
  817. goog.style.uninstallStyles(result);
  818. assertEquals(originalBackground, goog.style.getBackgroundColor(el));
  819. }
  820. function testSetStyles() {
  821. var el = $('installTest1');
  822. // Change to pink
  823. var ss = goog.style.installStyles(
  824. '#installTest1 { background-color: rgb(255, 192, 203); }');
  825. assertColorRgbEquals('rgb(255,192,203)', goog.style.getBackgroundColor(el));
  826. // Now change to orange
  827. goog.style.setStyles(
  828. ss, '#installTest1 { background-color: rgb(255, 255, 0); }');
  829. assertColorRgbEquals('rgb(255,255,0)', goog.style.getBackgroundColor(el));
  830. }
  831. function testSetSafeStyleSheet() {
  832. var el = $('installTest1');
  833. // Change to pink
  834. var ss = goog.style.installSafeStyleSheet(
  835. goog.html.testing.newSafeStyleSheetForTest(
  836. '#installTest1 { background-color: rgb(255, 192, 203); }'));
  837. assertColorRgbEquals('rgb(255,192,203)', goog.style.getBackgroundColor(el));
  838. // Now change to orange
  839. goog.style.setSafeStyleSheet(ss,
  840. goog.html.testing.newSafeStyleSheetForTest(
  841. '#installTest1 { background-color: rgb(255, 255, 0); }'));
  842. assertColorRgbEquals('rgb(255,255,0)', goog.style.getBackgroundColor(el));
  843. }
  844. function assertColorRgbEquals(expected, actual) {
  845. assertEquals(
  846. expected, goog.color.hexToRgbStyle(goog.color.parse(actual).hex));
  847. }
  848. function testIsRightToLeft() {
  849. assertFalse(goog.style.isRightToLeft($('rtl1')));
  850. assertTrue(goog.style.isRightToLeft($('rtl2')));
  851. assertFalse(goog.style.isRightToLeft($('rtl3')));
  852. assertFalse(goog.style.isRightToLeft($('rtl4')));
  853. assertTrue(goog.style.isRightToLeft($('rtl5')));
  854. assertFalse(goog.style.isRightToLeft($('rtl6')));
  855. assertTrue(goog.style.isRightToLeft($('rtl7')));
  856. assertFalse(goog.style.isRightToLeft($('rtl8')));
  857. assertTrue(goog.style.isRightToLeft($('rtl9')));
  858. assertFalse(goog.style.isRightToLeft($('rtl10')));
  859. }
  860. function testIsUnselectable() {
  861. assertEquals(
  862. goog.userAgent.GECKO, goog.style.isUnselectable($('unselectable-gecko')));
  863. assertEquals(
  864. goog.userAgent.IE || goog.userAgent.OPERA,
  865. goog.style.isUnselectable($('unselectable-ie')));
  866. // Note: Firefox can go either way here - newer versions see -webkit-*
  867. // properties and automatically add Moz* to the style object.
  868. if (!goog.userAgent.GECKO) {
  869. assertEquals(
  870. goog.userAgent.WEBKIT || goog.userAgent.EDGE,
  871. goog.style.isUnselectable($('unselectable-webkit')));
  872. }
  873. }
  874. function testSetUnselectable() {
  875. var el = $('make-unselectable');
  876. assertFalse(goog.style.isUnselectable(el));
  877. function assertDescendantsUnselectable(unselectable) {
  878. goog.array.forEach(el.getElementsByTagName('*'), function(descendant) {
  879. // Skip MathML or any other elements that do not have a style property.
  880. if (descendant.style) {
  881. assertEquals(unselectable, goog.style.isUnselectable(descendant));
  882. }
  883. });
  884. }
  885. goog.style.setUnselectable(el, true);
  886. assertTrue(goog.style.isUnselectable(el));
  887. assertDescendantsUnselectable(true);
  888. goog.style.setUnselectable(el, false);
  889. assertFalse(goog.style.isUnselectable(el));
  890. assertDescendantsUnselectable(false);
  891. goog.style.setUnselectable(el, true, true);
  892. assertTrue(goog.style.isUnselectable(el));
  893. assertDescendantsUnselectable(false);
  894. goog.style.setUnselectable(el, false, true);
  895. assertFalse(goog.style.isUnselectable(el));
  896. assertDescendantsUnselectable(false);
  897. }
  898. function testPosWithAbsoluteAndScroll() {
  899. var el = $('pos-scroll-abs');
  900. var el1 = $('pos-scroll-abs-1');
  901. var el2 = $('pos-scroll-abs-2');
  902. el1.scrollTop = 200;
  903. var pos = goog.style.getPageOffset(el2);
  904. assertEquals(200, pos.x);
  905. // Don't bother with IE in quirks mode
  906. if (!goog.userAgent.IE || document.compatMode == 'CSS1Compat') {
  907. assertRoughlyEquals(300, pos.y, .1);
  908. }
  909. }
  910. function testPosWithAbsoluteAndWindowScroll() {
  911. window.scrollBy(0, 200);
  912. var el = $('abs-upper-left');
  913. var pos = goog.style.getPageOffset(el);
  914. assertRoughlyEquals('Top should be about 0', 0, pos.y, 0.1);
  915. }
  916. function testGetBorderBoxSize() {
  917. // Strict mode
  918. var getBorderBoxSize = goog.style.getBorderBoxSize;
  919. var el = $('size-a');
  920. var rect = getBorderBoxSize(el);
  921. assertEquals('width:100px', 100, rect.width);
  922. assertEquals('height:100px', 100, rect.height);
  923. // with border: 10px
  924. el = $('size-b');
  925. rect = getBorderBoxSize(el);
  926. assertEquals('width:100px;border:10px', isBorderBox ? 100 : 120, rect.width);
  927. assertEquals(
  928. 'height:100px;border:10px', isBorderBox ? 100 : 120, rect.height);
  929. // with border: 10px; padding: 10px
  930. el = $('size-c');
  931. rect = getBorderBoxSize(el);
  932. assertEquals(
  933. 'width:100px;border:10px;padding:10px', isBorderBox ? 100 : 140,
  934. rect.width);
  935. assertEquals(
  936. 'height:100px;border:10px;padding:10px', isBorderBox ? 100 : 140,
  937. rect.height);
  938. // size, padding and borders are all in non pixel units
  939. // all we test here is that we get a number out
  940. el = $('size-d');
  941. rect = getBorderBoxSize(el);
  942. assertEquals('number', typeof rect.width);
  943. assertEquals('number', typeof rect.height);
  944. assertFalse(isNaN(rect.width));
  945. assertFalse(isNaN(rect.height));
  946. }
  947. function testGetContentBoxSize() {
  948. // Strict mode
  949. var getContentBoxSize = goog.style.getContentBoxSize;
  950. var el = $('size-a');
  951. var rect = getContentBoxSize(el);
  952. assertEquals('width:100px', 100, rect.width);
  953. assertEquals('height:100px', 100, rect.height);
  954. // with border: 10px
  955. el = $('size-b');
  956. rect = getContentBoxSize(el);
  957. assertEquals('width:100px;border:10px', isBorderBox ? 80 : 100, rect.width);
  958. assertEquals('height:100px;border:10px', isBorderBox ? 80 : 100, rect.height);
  959. // with border: 10px; padding: 10px
  960. el = $('size-c');
  961. rect = getContentBoxSize(el);
  962. assertEquals(
  963. 'width:100px;border:10px;padding:10px', isBorderBox ? 60 : 100,
  964. rect.width);
  965. assertEquals(
  966. 'height:100px;border:10px;padding:10px', isBorderBox ? 60 : 100,
  967. rect.height);
  968. // size, padding and borders are all in non pixel units
  969. // all we test here is that we get a number out
  970. el = $('size-d');
  971. rect = getContentBoxSize(el);
  972. assertEquals('number', typeof rect.width);
  973. assertEquals('number', typeof rect.height);
  974. assertFalse(isNaN(rect.width));
  975. assertFalse(isNaN(rect.height));
  976. // test whether getContentBoxSize works when width and height
  977. // aren't explicitly set, but the default of 'auto'.
  978. // 'size-f' has no margin, border, or padding, so offsetWidth/Height
  979. // should match the content box size
  980. el = $('size-f');
  981. rect = getContentBoxSize(el);
  982. assertEquals(el.offsetWidth, rect.width);
  983. assertEquals(el.offsetHeight, rect.height);
  984. }
  985. function testSetBorderBoxSize() {
  986. // Strict mode
  987. var el = $('size-e');
  988. var Size = goog.math.Size;
  989. var setBorderBoxSize = goog.style.setBorderBoxSize;
  990. // Clean up
  991. // style element has 100x100, no border and no padding
  992. el.style.padding = '';
  993. el.style.margin = '';
  994. el.style.borderWidth = '';
  995. el.style.width = '';
  996. el.style.height = '';
  997. setBorderBoxSize(el, new Size(100, 100));
  998. assertEquals(100, el.offsetWidth);
  999. assertEquals(100, el.offsetHeight);
  1000. el.style.borderWidth = '10px';
  1001. setBorderBoxSize(el, new Size(100, 100));
  1002. assertEquals('width:100px;border:10px', 100, el.offsetWidth);
  1003. assertEquals('height:100px;border:10px', 100, el.offsetHeight);
  1004. el.style.padding = '10px';
  1005. setBorderBoxSize(el, new Size(100, 100));
  1006. assertEquals(100, el.offsetWidth);
  1007. assertEquals(100, el.offsetHeight);
  1008. el.style.borderWidth = '0';
  1009. setBorderBoxSize(el, new Size(100, 100));
  1010. assertEquals(100, el.offsetWidth);
  1011. assertEquals(100, el.offsetHeight);
  1012. if (goog.userAgent.GECKO) {
  1013. assertEquals('border-box', el.style.MozBoxSizing);
  1014. } else if (goog.userAgent.WEBKIT) {
  1015. assertEquals('border-box', el.style.WebkitBoxSizing);
  1016. } else if (
  1017. goog.userAgent.OPERA ||
  1018. goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(8)) {
  1019. assertEquals('border-box', el.style.boxSizing);
  1020. }
  1021. // Try a negative width/height.
  1022. setBorderBoxSize(el, new Size(-10, -10));
  1023. // Setting the border box smaller than the borders will just give you
  1024. // a content box of size 0.
  1025. // NOTE(nicksantos): I'm not really sure why IE7 is special here.
  1026. var isIeLt8Quirks = goog.userAgent.IE &&
  1027. !goog.userAgent.isDocumentModeOrHigher(8) && !goog.dom.isCss1CompatMode();
  1028. assertEquals(20, el.offsetWidth);
  1029. assertEquals(isIeLt8Quirks ? 39 : 20, el.offsetHeight);
  1030. }
  1031. function testSetContentBoxSize() {
  1032. // Strict mode
  1033. var el = $('size-e');
  1034. var Size = goog.math.Size;
  1035. var setContentBoxSize = goog.style.setContentBoxSize;
  1036. // Clean up
  1037. // style element has 100x100, no border and no padding
  1038. el.style.padding = '';
  1039. el.style.margin = '';
  1040. el.style.borderWidth = '';
  1041. el.style.width = '';
  1042. el.style.height = '';
  1043. setContentBoxSize(el, new Size(100, 100));
  1044. assertEquals(100, el.offsetWidth);
  1045. assertEquals(100, el.offsetHeight);
  1046. el.style.borderWidth = '10px';
  1047. setContentBoxSize(el, new Size(100, 100));
  1048. assertEquals('width:100px;border-width:10px', 120, el.offsetWidth);
  1049. assertEquals('height:100px;border-width:10px', 120, el.offsetHeight);
  1050. el.style.padding = '10px';
  1051. setContentBoxSize(el, new Size(100, 100));
  1052. assertEquals(
  1053. 'width:100px;border-width:10px;padding:10px', 140, el.offsetWidth);
  1054. assertEquals(
  1055. 'height:100px;border-width:10px;padding:10px', 140, el.offsetHeight);
  1056. el.style.borderWidth = '0';
  1057. setContentBoxSize(el, new Size(100, 100));
  1058. assertEquals('width:100px;padding:10px', 120, el.offsetWidth);
  1059. assertEquals('height:100px;padding:10px', 120, el.offsetHeight);
  1060. if (goog.userAgent.GECKO) {
  1061. assertEquals('content-box', el.style.MozBoxSizing);
  1062. } else if (goog.userAgent.WEBKIT) {
  1063. assertEquals('content-box', el.style.WebkitBoxSizing);
  1064. } else if (
  1065. goog.userAgent.OPERA ||
  1066. goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(8)) {
  1067. assertEquals('content-box', el.style.boxSizing);
  1068. }
  1069. // Try a negative width/height.
  1070. setContentBoxSize(el, new Size(-10, -10));
  1071. // NOTE(nicksantos): I'm not really sure why IE7 is special here.
  1072. var isIeLt8Quirks = goog.userAgent.IE &&
  1073. !goog.userAgent.isDocumentModeOrHigher('8') &&
  1074. !goog.dom.isCss1CompatMode();
  1075. assertEquals(20, el.offsetWidth);
  1076. assertEquals(isIeLt8Quirks ? 39 : 20, el.offsetHeight);
  1077. }
  1078. function testGetPaddingBox() {
  1079. // Strict mode
  1080. var el = $('size-e');
  1081. var Size = goog.math.Size;
  1082. var getPaddingBox = goog.style.getPaddingBox;
  1083. // Clean up
  1084. // style element has 100x100, no border and no padding
  1085. el.style.padding = '';
  1086. el.style.margin = '';
  1087. el.style.borderWidth = '';
  1088. el.style.width = '';
  1089. el.style.height = '';
  1090. el.style.padding = '10px';
  1091. var rect = getPaddingBox(el);
  1092. assertEquals(10, rect.left);
  1093. assertEquals(10, rect.right);
  1094. assertEquals(10, rect.top);
  1095. assertEquals(10, rect.bottom);
  1096. el.style.padding = '0';
  1097. rect = getPaddingBox(el);
  1098. assertEquals(0, rect.left);
  1099. assertEquals(0, rect.right);
  1100. assertEquals(0, rect.top);
  1101. assertEquals(0, rect.bottom);
  1102. el.style.padding = '1px 2px 3px 4px';
  1103. rect = getPaddingBox(el);
  1104. assertEquals(1, rect.top);
  1105. assertEquals(2, rect.right);
  1106. assertEquals(3, rect.bottom);
  1107. assertEquals(4, rect.left);
  1108. el.style.padding = '1mm 2em 3ex 4%';
  1109. rect = getPaddingBox(el);
  1110. assertFalse(isNaN(rect.top));
  1111. assertFalse(isNaN(rect.right));
  1112. assertFalse(isNaN(rect.bottom));
  1113. assertFalse(isNaN(rect.left));
  1114. assertTrue(rect.top >= 0);
  1115. assertTrue(rect.right >= 0);
  1116. assertTrue(rect.bottom >= 0);
  1117. assertTrue(rect.left >= 0);
  1118. }
  1119. function testGetPaddingBoxUnattached() {
  1120. var el = goog.dom.createElement(goog.dom.TagName.DIV);
  1121. var box = goog.style.getPaddingBox(el);
  1122. if (goog.userAgent.WEBKIT) {
  1123. assertTrue(isNaN(box.top));
  1124. assertTrue(isNaN(box.right));
  1125. assertTrue(isNaN(box.bottom));
  1126. assertTrue(isNaN(box.left));
  1127. } else {
  1128. assertObjectEquals(new goog.math.Box(0, 0, 0, 0), box);
  1129. }
  1130. }
  1131. function testGetMarginBox() {
  1132. // Strict mode
  1133. var el = $('size-e');
  1134. var Size = goog.math.Size;
  1135. var getMarginBox = goog.style.getMarginBox;
  1136. // Clean up
  1137. // style element has 100x100, no border and no padding
  1138. el.style.padding = '';
  1139. el.style.margin = '';
  1140. el.style.borderWidth = '';
  1141. el.style.width = '';
  1142. el.style.height = '';
  1143. el.style.margin = '10px';
  1144. var rect = getMarginBox(el);
  1145. assertEquals(10, rect.left);
  1146. // In webkit the right margin is the calculated distance from right edge and
  1147. // not the computed right margin so it is not reliable.
  1148. // See https://bugs.webkit.org/show_bug.cgi?id=19828
  1149. if (!goog.userAgent.WEBKIT) {
  1150. assertEquals(10, rect.right);
  1151. }
  1152. assertEquals(10, rect.top);
  1153. assertEquals(10, rect.bottom);
  1154. el.style.margin = '0';
  1155. rect = getMarginBox(el);
  1156. assertEquals(0, rect.left);
  1157. // In webkit the right margin is the calculated distance from right edge and
  1158. // not the computed right margin so it is not reliable.
  1159. // See https://bugs.webkit.org/show_bug.cgi?id=19828
  1160. if (!goog.userAgent.WEBKIT) {
  1161. assertEquals(0, rect.right);
  1162. }
  1163. assertEquals(0, rect.top);
  1164. assertEquals(0, rect.bottom);
  1165. el.style.margin = '1px 2px 3px 4px';
  1166. rect = getMarginBox(el);
  1167. assertEquals(1, rect.top);
  1168. // In webkit the right margin is the calculated distance from right edge and
  1169. // not the computed right margin so it is not reliable.
  1170. // See https://bugs.webkit.org/show_bug.cgi?id=19828
  1171. if (!goog.userAgent.WEBKIT) {
  1172. assertEquals(2, rect.right);
  1173. }
  1174. assertEquals(3, rect.bottom);
  1175. assertEquals(4, rect.left);
  1176. el.style.margin = '1mm 2em 3ex 4%';
  1177. rect = getMarginBox(el);
  1178. assertFalse(isNaN(rect.top));
  1179. assertFalse(isNaN(rect.right));
  1180. assertFalse(isNaN(rect.bottom));
  1181. assertFalse(isNaN(rect.left));
  1182. assertTrue(rect.top >= 0);
  1183. // In webkit the right margin is the calculated distance from right edge and
  1184. // not the computed right margin so it is not reliable.
  1185. // See https://bugs.webkit.org/show_bug.cgi?id=19828
  1186. if (!goog.userAgent.WEBKIT) {
  1187. assertTrue(rect.right >= 0);
  1188. }
  1189. assertTrue(rect.bottom >= 0);
  1190. assertTrue(rect.left >= 0);
  1191. }
  1192. function testGetBorderBox() {
  1193. // Strict mode
  1194. var el = $('size-e');
  1195. var Size = goog.math.Size;
  1196. var getBorderBox = goog.style.getBorderBox;
  1197. // Clean up
  1198. // style element has 100x100, no border and no padding
  1199. el.style.padding = '';
  1200. el.style.margin = '';
  1201. el.style.borderWidth = '';
  1202. el.style.width = '';
  1203. el.style.height = '';
  1204. el.style.borderWidth = '10px';
  1205. var rect = getBorderBox(el);
  1206. assertEquals(10, rect.left);
  1207. assertEquals(10, rect.right);
  1208. assertEquals(10, rect.top);
  1209. assertEquals(10, rect.bottom);
  1210. el.style.borderWidth = '0';
  1211. rect = getBorderBox(el);
  1212. assertEquals(0, rect.left);
  1213. assertEquals(0, rect.right);
  1214. assertEquals(0, rect.top);
  1215. assertEquals(0, rect.bottom);
  1216. el.style.borderWidth = '1px 2px 3px 4px';
  1217. rect = getBorderBox(el);
  1218. assertEquals(1, rect.top);
  1219. assertEquals(2, rect.right);
  1220. assertEquals(3, rect.bottom);
  1221. assertEquals(4, rect.left);
  1222. // % does not work for border widths in IE
  1223. el.style.borderWidth = '1mm 2em 3ex 4pt';
  1224. rect = getBorderBox(el);
  1225. assertFalse(isNaN(rect.top));
  1226. assertFalse(isNaN(rect.right));
  1227. assertFalse(isNaN(rect.bottom));
  1228. assertFalse(isNaN(rect.left));
  1229. assertTrue(rect.top >= 0);
  1230. assertTrue(rect.right >= 0);
  1231. assertTrue(rect.bottom >= 0);
  1232. assertTrue(rect.left >= 0);
  1233. el.style.borderWidth = 'thin medium thick 1px';
  1234. rect = getBorderBox(el);
  1235. assertFalse(isNaN(rect.top));
  1236. assertFalse(isNaN(rect.right));
  1237. assertFalse(isNaN(rect.bottom));
  1238. assertFalse(isNaN(rect.left));
  1239. assertTrue(rect.top >= 0);
  1240. assertTrue(rect.right >= 0);
  1241. assertTrue(rect.bottom >= 0);
  1242. assertTrue(rect.left >= 0);
  1243. }
  1244. function testGetFontFamily() {
  1245. // I tried to use common fonts for these tests. It's possible the test fails
  1246. // because the testing platform doesn't have one of these fonts installed:
  1247. // Comic Sans MS or Century Schoolbook L
  1248. // Times
  1249. // Helvetica
  1250. var tmpFont = goog.style.getFontFamily($('font-tag'));
  1251. assertTrue(
  1252. 'FontFamily should be detectable when set via <font face>',
  1253. 'Times' == tmpFont || 'Times New Roman' == tmpFont);
  1254. tmpFont = goog.style.getFontFamily($('small-text'));
  1255. assertTrue(
  1256. 'Multiword fonts should be reported with quotes stripped.',
  1257. 'Comic Sans MS' == tmpFont || 'Century Schoolbook L' == tmpFont);
  1258. // Firefox fails this test & retuns a generic 'monospace' instead of the
  1259. // actually displayed font (e.g., "Times New").
  1260. // tmpFont = goog.style.getFontFamily($('pre-font'));
  1261. // assertEquals('<pre> tags should use a fixed-width font',
  1262. // 'Times New',
  1263. // tmpFont);
  1264. tmpFont = goog.style.getFontFamily($('inherit-font'));
  1265. assertEquals(
  1266. 'Explicitly inherited fonts should be detectable', 'Helvetica', tmpFont);
  1267. tmpFont = goog.style.getFontFamily($('times-font-family'));
  1268. assertEquals(
  1269. 'Font-family set via style attribute should be detected', 'Times',
  1270. tmpFont);
  1271. tmpFont = goog.style.getFontFamily($('bold-font'));
  1272. assertEquals(
  1273. 'Implicitly inherited font should be detected', 'Helvetica', tmpFont);
  1274. tmpFont = goog.style.getFontFamily($('css-html-tag-redefinition'));
  1275. assertEquals('HTML tag CSS rewrites should be detected', 'Times', tmpFont);
  1276. tmpFont = goog.style.getFontFamily($('no-text-font-styles'));
  1277. assertEquals(
  1278. 'Font family should exist even with no text', 'Helvetica', tmpFont);
  1279. tmpFont = goog.style.getFontFamily($('icon-font'));
  1280. assertNotEquals(
  1281. 'icon is a special font-family value', 'icon', tmpFont.toLowerCase());
  1282. tmpFont = goog.style.getFontFamily($('font-style-badfont'));
  1283. // Firefox fails this test and reports the specified "badFont", which is
  1284. // obviously not displayed.
  1285. // assertEquals('Invalid fonts should not be returned',
  1286. // 'Helvetica',
  1287. // tmpFont);
  1288. tmpFont = goog.style.getFontFamily($('img-font-test'));
  1289. assertTrue(
  1290. 'Even img tags should inherit the document body\'s font', tmpFont != '');
  1291. tmpFont = goog.style.getFontFamily($('nested-font'));
  1292. assertEquals(
  1293. 'An element with nested content should be unaffected.', 'Arial', tmpFont);
  1294. // IE raises an 'Invalid Argument' error when using the moveToElementText
  1295. // method from the TextRange object with an element that is not attached to
  1296. // a document.
  1297. var element = goog.dom.createDom(
  1298. goog.dom.TagName.SPAN, {style: 'font-family:Times,sans-serif;'},
  1299. 'some text');
  1300. tmpFont = goog.style.getFontFamily(element);
  1301. assertEquals(
  1302. 'Font should be correctly retrieved for element not attached' +
  1303. ' to a document',
  1304. 'Times', tmpFont);
  1305. }
  1306. function testGetFontSize() {
  1307. assertEquals(
  1308. 'Font size should be determined even without any text', 30,
  1309. goog.style.getFontSize($('no-text-font-styles')));
  1310. assertEquals(
  1311. 'A 5em font should be 5x larger than its parent.', 150,
  1312. goog.style.getFontSize($('css-html-tag-redefinition')));
  1313. assertTrue(
  1314. 'Setting font size=-1 should result in a positive font size.',
  1315. goog.style.getFontSize($('font-tag')) > 0);
  1316. assertEquals(
  1317. 'Inheriting a 50% font-size should have no additional effect',
  1318. goog.style.getFontSize($('font-style-badfont')),
  1319. goog.style.getFontSize($('inherit-50pct-font')));
  1320. assertTrue(
  1321. 'In pretty much any display, 3in should be > 8px',
  1322. goog.style.getFontSize($('times-font-family')) >
  1323. goog.style.getFontSize($('no-text-font-styles')));
  1324. assertTrue(
  1325. 'With no applied styles, font-size should still be defined.',
  1326. goog.style.getFontSize($('no-font-style')) > 0);
  1327. assertEquals(
  1328. '50% of 30px is 15', 15, goog.style.getFontSize($('font-style-badfont')));
  1329. assertTrue(
  1330. 'x-small text should be smaller than small text',
  1331. goog.style.getFontSize($('x-small-text')) <
  1332. goog.style.getFontSize($('small-text')));
  1333. // IE fails this test, the decimal portion of px lengths isn't reported
  1334. // by getCascadedStyle. Firefox passes, but only because it ignores the
  1335. // decimals altogether.
  1336. // assertEquals('12.5px should be the same as 0.5em nested in a 25px node.',
  1337. // goog.style.getFontSize($('font-size-12-point-5-px')),
  1338. // goog.style.getFontSize($('font-size-50-pct-of-25-px')));
  1339. assertEquals(
  1340. 'Font size should not doubly count em values', 2,
  1341. goog.style.getFontSize($('em-font-size')));
  1342. }
  1343. function testGetLengthUnits() {
  1344. assertEquals('px', goog.style.getLengthUnits('15px'));
  1345. assertEquals('%', goog.style.getLengthUnits('99%'));
  1346. assertNull(goog.style.getLengthUnits(''));
  1347. }
  1348. function testParseStyleAttribute() {
  1349. var css = 'left: 0px; text-align: center';
  1350. var expected = {'left': '0px', 'textAlign': 'center'};
  1351. assertObjectEquals(expected, goog.style.parseStyleAttribute(css));
  1352. }
  1353. function testToStyleAttribute() {
  1354. var object = {'left': '0px', 'textAlign': 'center'};
  1355. var expected = 'left:0px;text-align:center;';
  1356. assertEquals(expected, goog.style.toStyleAttribute(object));
  1357. }
  1358. function testStyleAttributePassthrough() {
  1359. var object = {'left': '0px', 'textAlign': 'center'};
  1360. assertObjectEquals(
  1361. object,
  1362. goog.style.parseStyleAttribute(goog.style.toStyleAttribute(object)));
  1363. }
  1364. function testGetFloat() {
  1365. assertEquals('', goog.style.getFloat($('no-float')));
  1366. assertEquals('none', goog.style.getFloat($('float-none')));
  1367. assertEquals('left', goog.style.getFloat($('float-left')));
  1368. }
  1369. function testSetFloat() {
  1370. var el = $('float-test');
  1371. goog.style.setFloat(el, 'left');
  1372. assertEquals('left', goog.style.getFloat(el));
  1373. goog.style.setFloat(el, 'right');
  1374. assertEquals('right', goog.style.getFloat(el));
  1375. goog.style.setFloat(el, 'none');
  1376. assertEquals('none', goog.style.getFloat(el));
  1377. goog.style.setFloat(el, '');
  1378. assertEquals('', goog.style.getFloat(el));
  1379. }
  1380. function testIsElementShown() {
  1381. var el = $('testEl');
  1382. goog.style.setElementShown(el, false);
  1383. assertFalse(goog.style.isElementShown(el));
  1384. goog.style.setElementShown(el, true);
  1385. assertTrue(goog.style.isElementShown(el));
  1386. }
  1387. function testGetOpacity() {
  1388. var el1 = {style: {opacity: '0.3'}};
  1389. var el2 = {style: {MozOpacity: '0.1'}};
  1390. var el3 = {
  1391. style: {filter: 'some:other,filter;alpha(opacity=25.5);alpha(more=100);'}
  1392. };
  1393. assertEquals(0.3, goog.style.getOpacity(el1));
  1394. assertEquals(0.1, goog.style.getOpacity(el2));
  1395. assertEquals(0.255, goog.style.getOpacity(el3));
  1396. el1.style.opacity = '0';
  1397. el2.style.MozOpacity = '0';
  1398. el3.style.filter = 'some:other,filter;alpha(opacity=0);alpha(more=100);';
  1399. assertEquals(0, goog.style.getOpacity(el1));
  1400. assertEquals(0, goog.style.getOpacity(el2));
  1401. assertEquals(0, goog.style.getOpacity(el3));
  1402. el1.style.opacity = '';
  1403. el2.style.MozOpacity = '';
  1404. el3.style.filter = '';
  1405. assertEquals('', goog.style.getOpacity(el1));
  1406. assertEquals('', goog.style.getOpacity(el2));
  1407. assertEquals('', goog.style.getOpacity(el3));
  1408. var el4 = {style: {}};
  1409. assertEquals('', goog.style.getOpacity(el4));
  1410. assertEquals('', goog.style.getOpacity($('test-opacity')));
  1411. }
  1412. function testSetOpacity() {
  1413. var el1 = {style: {opacity: '0.3'}};
  1414. goog.style.setOpacity(el1, 0.8);
  1415. var el2 = {style: {MozOpacity: '0.1'}};
  1416. goog.style.setOpacity(el2, 0.5);
  1417. var el3 = {style: {filter: 'alpha(opacity=25)'}};
  1418. goog.style.setOpacity(el3, 0.1);
  1419. assertEquals(0.8, Number(el1.style.opacity));
  1420. assertEquals(0.5, Number(el2.style.MozOpacity));
  1421. assertEquals('alpha(opacity=10)', el3.style.filter);
  1422. goog.style.setOpacity(el1, 0);
  1423. goog.style.setOpacity(el2, 0);
  1424. goog.style.setOpacity(el3, 0);
  1425. assertEquals(0, Number(el1.style.opacity));
  1426. assertEquals(0, Number(el2.style.MozOpacity));
  1427. assertEquals('alpha(opacity=0)', el3.style.filter);
  1428. goog.style.setOpacity(el1, '');
  1429. goog.style.setOpacity(el2, '');
  1430. goog.style.setOpacity(el3, '');
  1431. assertEquals('', el1.style.opacity);
  1432. assertEquals('', el2.style.MozOpacity);
  1433. assertEquals('', el3.style.filter);
  1434. }
  1435. function testFramedPageOffset() {
  1436. // Set up a complicated iframe ancestor chain.
  1437. var iframe = goog.dom.getElement('test-frame-offset');
  1438. var iframeDoc = goog.dom.getFrameContentDocument(iframe);
  1439. var iframeWindow = goog.dom.getWindow(iframeDoc);
  1440. var iframePos = 'style="display:block;position:absolute;' +
  1441. 'top:50px;left:50px;width:50px;height:50px;"';
  1442. iframeDoc.write(
  1443. '<iframe id="test-frame-offset-2" ' + iframePos + '></iframe>' +
  1444. '<div id="test-element-2" ' +
  1445. ' style="position:absolute;left:300px;top:300px">hi mom!</div>');
  1446. iframeDoc.close();
  1447. var iframe2 = iframeDoc.getElementById('test-frame-offset-2');
  1448. var testElement2 = iframeDoc.getElementById('test-element-2');
  1449. var iframeDoc2 = goog.dom.getFrameContentDocument(iframe2);
  1450. var iframeWindow2 = goog.dom.getWindow(iframeDoc2);
  1451. iframeDoc2.write(
  1452. '<div id="test-element-3" ' +
  1453. ' style="position:absolute;left:500px;top:500px">hi mom!</div>');
  1454. iframeDoc2.close();
  1455. var testElement3 = iframeDoc2.getElementById('test-element-3');
  1456. assertCoordinateApprox(300, 300, 0, goog.style.getPageOffset(testElement2));
  1457. assertCoordinateApprox(500, 500, 0, goog.style.getPageOffset(testElement3));
  1458. assertCoordinateApprox(
  1459. 350, 350, 0, goog.style.getFramedPageOffset(testElement2, window));
  1460. assertCoordinateApprox(
  1461. 300, 300, 0, goog.style.getFramedPageOffset(testElement2, iframeWindow));
  1462. assertCoordinateApprox(
  1463. 600, 600, 0, goog.style.getFramedPageOffset(testElement3, window));
  1464. assertCoordinateApprox(
  1465. 550, 550, 0, goog.style.getFramedPageOffset(testElement3, iframeWindow));
  1466. assertCoordinateApprox(
  1467. 500, 500, 0, goog.style.getFramedPageOffset(testElement3, iframeWindow2));
  1468. // Scroll the iframes a bit.
  1469. window.scrollBy(0, 5);
  1470. iframeWindow.scrollBy(0, 11);
  1471. iframeWindow2.scrollBy(0, 18);
  1472. // On Firefox 2, scrolling inner iframes causes off by one errors
  1473. // in the page position, because we're using screen coords to compute them.
  1474. assertCoordinateApprox(300, 300, 2, goog.style.getPageOffset(testElement2));
  1475. assertCoordinateApprox(500, 500, 2, goog.style.getPageOffset(testElement3));
  1476. assertCoordinateApprox(
  1477. 350, 350 - 11, 2, goog.style.getFramedPageOffset(testElement2, window));
  1478. assertCoordinateApprox(
  1479. 300, 300, 2, goog.style.getFramedPageOffset(testElement2, iframeWindow));
  1480. assertCoordinateApprox(
  1481. 600, 600 - 18 - 11, 2,
  1482. goog.style.getFramedPageOffset(testElement3, window));
  1483. assertCoordinateApprox(
  1484. 550, 550 - 18, 2,
  1485. goog.style.getFramedPageOffset(testElement3, iframeWindow));
  1486. assertCoordinateApprox(
  1487. 500, 500, 2, goog.style.getFramedPageOffset(testElement3, iframeWindow2));
  1488. // In IE, if the element is in a frame that's been removed from the DOM and
  1489. // relativeWin is not that frame's contentWindow, the contentWindow's parent
  1490. // reference points to itself. We want to guarantee that we don't fall into
  1491. // an infinite loop.
  1492. var iframeParent = iframe.parentElement;
  1493. iframeParent.removeChild(iframe);
  1494. // We don't check the value returned as it differs by browser. 0,0 for Chrome
  1495. // and FF. IE returns 30000 or 30198 for x in IE8-9 and 300 in IE10-11
  1496. goog.style.getFramedPageOffset(testElement2, window);
  1497. }
  1498. /**
  1499. * Asserts that the coordinate is approximately equal to the given
  1500. * x and y coordinates, give or take delta.
  1501. */
  1502. function assertCoordinateApprox(x, y, delta, coord) {
  1503. assertTrue(
  1504. 'Expected x: ' + x + ', actual x: ' + coord.x,
  1505. coord.x >= x - delta && coord.x <= x + delta);
  1506. assertTrue(
  1507. 'Expected y: ' + y + ', actual y: ' + coord.y,
  1508. coord.y >= y - delta && coord.y <= y + delta);
  1509. }
  1510. function testTranslateRectForAnotherFrame() {
  1511. var rect = new goog.math.Rect(1, 2, 3, 4);
  1512. var thisDom = goog.dom.getDomHelper();
  1513. goog.style.translateRectForAnotherFrame(rect, thisDom, thisDom);
  1514. assertEquals(1, rect.left);
  1515. assertEquals(2, rect.top);
  1516. assertEquals(3, rect.width);
  1517. assertEquals(4, rect.height);
  1518. var iframe = $('test-translate-frame-standard');
  1519. var iframeDoc = goog.dom.getFrameContentDocument(iframe);
  1520. var iframeDom = goog.dom.getDomHelper(iframeDoc);
  1521. // Cannot rely on iframe starting at origin.
  1522. iframeDom.getWindow().scrollTo(0, 0);
  1523. // iframe is at (100, 150) and its body is not scrolled.
  1524. rect = new goog.math.Rect(1, 2, 3, 4);
  1525. goog.style.translateRectForAnotherFrame(rect, iframeDom, thisDom);
  1526. assertEquals(1 + 100, rect.left);
  1527. assertRoughlyEquals(2 + 150, rect.top, .1);
  1528. assertEquals(3, rect.width);
  1529. assertEquals(4, rect.height);
  1530. iframeDom.getWindow().scrollTo(11, 13);
  1531. rect = new goog.math.Rect(1, 2, 3, 4);
  1532. goog.style.translateRectForAnotherFrame(rect, iframeDom, thisDom);
  1533. assertEquals(1 + 100 - 11, rect.left);
  1534. assertRoughlyEquals(2 + 150 - 13, rect.top, .1);
  1535. assertEquals(3, rect.width);
  1536. assertEquals(4, rect.height);
  1537. iframe = $('test-translate-frame-quirk');
  1538. iframeDoc = goog.dom.getFrameContentDocument(iframe);
  1539. iframeDom = goog.dom.getDomHelper(iframeDoc);
  1540. // Cannot rely on iframe starting at origin.
  1541. iframeDom.getWindow().scrollTo(0, 0);
  1542. // iframe is at (100, 350) and its body is not scrolled.
  1543. rect = new goog.math.Rect(1, 2, 3, 4);
  1544. goog.style.translateRectForAnotherFrame(rect, iframeDom, thisDom);
  1545. assertEquals(1 + 100, rect.left);
  1546. assertRoughlyEquals(2 + 350, rect.top, .1);
  1547. assertEquals(3, rect.width);
  1548. assertEquals(4, rect.height);
  1549. iframeDom.getWindow().scrollTo(11, 13);
  1550. rect = new goog.math.Rect(1, 2, 3, 4);
  1551. goog.style.translateRectForAnotherFrame(rect, iframeDom, thisDom);
  1552. assertEquals(1 + 100 - 11, rect.left);
  1553. assertRoughlyEquals(2 + 350 - 13, rect.top, .1);
  1554. assertEquals(3, rect.width);
  1555. assertEquals(4, rect.height);
  1556. }
  1557. function testGetVisibleRectForElement() {
  1558. var container = goog.dom.getElement('test-visible');
  1559. var el = goog.dom.getElement('test-visible-el');
  1560. var dom = goog.dom.getDomHelper(el);
  1561. var winScroll = dom.getDocumentScroll();
  1562. var winSize = dom.getViewportSize();
  1563. // Skip this test if the window size is small. Firefox3/Linux in Selenium
  1564. // sometimes fails without this check.
  1565. if (winSize.width < 20 || winSize.height < 20) {
  1566. return;
  1567. }
  1568. // Move the container element to the window's viewport.
  1569. var h = winSize.height < 100 ? winSize.height / 2 : 100;
  1570. goog.style.setSize(container, winSize.width / 2, h);
  1571. goog.style.setPosition(container, 8, winScroll.y + winSize.height - h);
  1572. var visible = goog.style.getVisibleRectForElement(el);
  1573. var bounds = goog.style.getBounds(container);
  1574. // VisibleRect == Bounds rect of the offsetParent
  1575. assertNotNull(visible);
  1576. assertEquals(bounds.left, visible.left);
  1577. assertEquals(bounds.top, visible.top);
  1578. assertEquals(bounds.left + bounds.width, visible.right);
  1579. assertEquals(bounds.top + bounds.height, visible.bottom);
  1580. // Move a part of the container element to outside of the viewpoert.
  1581. goog.style.setPosition(container, 8, winScroll.y + winSize.height - h / 2);
  1582. visible = goog.style.getVisibleRectForElement(el);
  1583. bounds = goog.style.getBounds(container);
  1584. // Confirm VisibleRect == Intersection of the bounds rect of the
  1585. // offsetParent and the viewport.
  1586. assertNotNull(visible);
  1587. assertEquals(bounds.left, visible.left);
  1588. assertEquals(bounds.top, visible.top);
  1589. assertEquals(bounds.left + bounds.width, visible.right);
  1590. assertEquals(winScroll.y + winSize.height, visible.bottom);
  1591. // Move the container element to outside of the viewpoert.
  1592. goog.style.setPosition(container, 8, winScroll.y + winSize.height * 2);
  1593. visible = goog.style.getVisibleRectForElement(el);
  1594. assertNull(visible);
  1595. // Test the case with body element of height 0
  1596. var iframe = goog.dom.getElement('test-visible-frame');
  1597. var iframeDoc = goog.dom.getFrameContentDocument(iframe);
  1598. el = iframeDoc.getElementById('test-visible');
  1599. visible = goog.style.getVisibleRectForElement(el);
  1600. var iframeViewportSize = goog.dom.getDomHelper(el).getViewportSize();
  1601. // NOTE(chrishenry): For iframe, the clipping viewport is always the iframe
  1602. // viewport, and not the actual browser viewport.
  1603. assertNotNull(visible);
  1604. assertEquals(0, visible.top);
  1605. assertEquals(iframeViewportSize.height, visible.bottom);
  1606. assertEquals(0, visible.left);
  1607. assertEquals(iframeViewportSize.width, visible.right);
  1608. }
  1609. function testGetVisibleRectForElementWithBodyScrolled() {
  1610. var container = goog.dom.getElement('test-visible2');
  1611. var dom = goog.dom.getDomHelper(container);
  1612. var el = dom.createDom(goog.dom.TagName.DIV, undefined, 'Test');
  1613. el.style.position = 'absolute';
  1614. dom.append(container, el);
  1615. container.style.position = 'absolute';
  1616. goog.style.setPosition(container, 20, 500);
  1617. goog.style.setSize(container, 100, 150);
  1618. // Scroll body container such that container is exactly at top.
  1619. window.scrollTo(0, 500);
  1620. var visibleRect = goog.style.getVisibleRectForElement(el);
  1621. assertNotNull(visibleRect);
  1622. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1623. assertRoughlyEquals(20, visibleRect.left, EPSILON);
  1624. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1625. assertRoughlyEquals(120, visibleRect.right, EPSILON);
  1626. // Top 100px is clipped by window viewport.
  1627. window.scrollTo(0, 600);
  1628. var visibleRect = goog.style.getVisibleRectForElement(el);
  1629. assertNotNull(visibleRect);
  1630. assertRoughlyEquals(600, visibleRect.top, EPSILON);
  1631. assertRoughlyEquals(20, visibleRect.left, EPSILON);
  1632. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1633. assertRoughlyEquals(120, visibleRect.right, EPSILON);
  1634. var winSize = dom.getViewportSize();
  1635. // Left 50px is clipped by window viewport.
  1636. // Right part is clipped by window viewport.
  1637. goog.style.setSize(container, 10000, 150);
  1638. window.scrollTo(70, 500);
  1639. var visibleRect = goog.style.getVisibleRectForElement(el);
  1640. assertNotNull(visibleRect);
  1641. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1642. assertRoughlyEquals(70, visibleRect.left, EPSILON);
  1643. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1644. assertRoughlyEquals(70 + winSize.width, visibleRect.right, EPSILON);
  1645. // Bottom part is clipped by window viewport.
  1646. goog.style.setSize(container, 100, 2000);
  1647. window.scrollTo(0, 500);
  1648. var visibleRect = goog.style.getVisibleRectForElement(el);
  1649. assertNotNull(visibleRect);
  1650. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1651. assertRoughlyEquals(20, visibleRect.left, EPSILON);
  1652. assertRoughlyEquals(120, visibleRect.right, EPSILON);
  1653. assertRoughlyEquals(500 + winSize.height, visibleRect.bottom, EPSILON);
  1654. goog.style.setPosition(container, 10000, 10000);
  1655. assertNull(goog.style.getVisibleRectForElement(el));
  1656. }
  1657. function testGetVisibleRectForElementWithNestedAreaAndNonOffsetAncestor() {
  1658. // IE7 quirks mode somehow consider container2 below as offset parent
  1659. // of the element, which is incorrect.
  1660. if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(8) &&
  1661. !goog.dom.isCss1CompatMode()) {
  1662. return;
  1663. }
  1664. var container = goog.dom.getElement('test-visible2');
  1665. var dom = goog.dom.getDomHelper(container);
  1666. var container2 = dom.createDom(goog.dom.TagName.DIV);
  1667. var el = dom.createDom(goog.dom.TagName.DIV, undefined, 'Test');
  1668. el.style.position = 'absolute';
  1669. dom.append(container, container2);
  1670. dom.append(container2, el);
  1671. container.style.position = 'absolute';
  1672. goog.style.setPosition(container, 20, 500);
  1673. goog.style.setSize(container, 100, 150);
  1674. // container2 is a scrollable container but is not an offsetParent of
  1675. // the element. It is ignored in the computation.
  1676. container2.style.overflow = 'hidden';
  1677. container2.style.marginTop = '50px';
  1678. container2.style.marginLeft = '100px';
  1679. goog.style.setSize(container2, 150, 100);
  1680. // Scroll body container such that container is exactly at top.
  1681. window.scrollTo(0, 500);
  1682. var visibleRect = goog.style.getVisibleRectForElement(el);
  1683. assertNotNull(visibleRect);
  1684. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1685. assertRoughlyEquals(20, visibleRect.left, EPSILON);
  1686. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1687. assertRoughlyEquals(120, visibleRect.right, EPSILON);
  1688. // Top 100px is clipped by window viewport.
  1689. window.scrollTo(0, 600);
  1690. var visibleRect = goog.style.getVisibleRectForElement(el);
  1691. assertNotNull(visibleRect);
  1692. assertRoughlyEquals(600, visibleRect.top, EPSILON);
  1693. assertRoughlyEquals(20, visibleRect.left, EPSILON);
  1694. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1695. assertRoughlyEquals(120, visibleRect.right, EPSILON);
  1696. var winSize = dom.getViewportSize();
  1697. // Left 50px is clipped by window viewport.
  1698. // Right part is clipped by window viewport.
  1699. goog.style.setSize(container, 10000, 150);
  1700. window.scrollTo(70, 500);
  1701. var visibleRect = goog.style.getVisibleRectForElement(el);
  1702. assertNotNull(visibleRect);
  1703. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1704. assertRoughlyEquals(70, visibleRect.left, EPSILON);
  1705. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1706. assertRoughlyEquals(70 + winSize.width, visibleRect.right, EPSILON);
  1707. // Bottom part is clipped by window viewport.
  1708. goog.style.setSize(container, 100, 2000);
  1709. window.scrollTo(0, 500);
  1710. var visibleRect = goog.style.getVisibleRectForElement(el);
  1711. assertNotNull(visibleRect);
  1712. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1713. assertRoughlyEquals(20, visibleRect.left, EPSILON);
  1714. assertRoughlyEquals(120, visibleRect.right, EPSILON);
  1715. assertRoughlyEquals(500 + winSize.height, visibleRect.bottom, EPSILON);
  1716. goog.style.setPosition(container, 10000, 10000);
  1717. assertNull(goog.style.getVisibleRectForElement(el));
  1718. }
  1719. function testGetVisibleRectForElementInsideNestedScrollableArea() {
  1720. var container = goog.dom.getElement('test-visible2');
  1721. var dom = goog.dom.getDomHelper(container);
  1722. var container2 = dom.createDom(goog.dom.TagName.DIV);
  1723. var el = dom.createDom(goog.dom.TagName.DIV, undefined, 'Test');
  1724. el.style.position = 'absolute';
  1725. dom.append(container, container2);
  1726. dom.append(container2, el);
  1727. container.style.position = 'absolute';
  1728. goog.style.setPosition(container, 100 /* left */, 500 /* top */);
  1729. goog.style.setSize(container, 300 /* width */, 300 /* height */);
  1730. container2.style.overflow = 'hidden';
  1731. container2.style.position = 'relative';
  1732. goog.style.setPosition(container2, 100, 50);
  1733. goog.style.setSize(container2, 150, 100);
  1734. // Scroll body container such that container is exactly at top.
  1735. window.scrollTo(0, 500);
  1736. var visibleRect = goog.style.getVisibleRectForElement(el);
  1737. assertNotNull(visibleRect);
  1738. assertRoughlyEquals(550, visibleRect.top, EPSILON);
  1739. assertRoughlyEquals(200, visibleRect.left, EPSILON);
  1740. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1741. assertRoughlyEquals(350, visibleRect.right, EPSILON);
  1742. // Left 50px is clipped by container.
  1743. goog.style.setPosition(container2, -50, 50);
  1744. var visibleRect = goog.style.getVisibleRectForElement(el);
  1745. assertNotNull(visibleRect);
  1746. assertRoughlyEquals(550, visibleRect.top, EPSILON);
  1747. assertRoughlyEquals(100, visibleRect.left, EPSILON);
  1748. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1749. assertRoughlyEquals(200, visibleRect.right, EPSILON);
  1750. // Right part is clipped by container.
  1751. goog.style.setPosition(container2, 100, 50);
  1752. goog.style.setWidth(container2, 1000, 100);
  1753. var visibleRect = goog.style.getVisibleRectForElement(el);
  1754. assertNotNull(visibleRect);
  1755. assertRoughlyEquals(550, visibleRect.top, EPSILON);
  1756. assertRoughlyEquals(200, visibleRect.left, EPSILON);
  1757. assertRoughlyEquals(650, visibleRect.bottom, EPSILON);
  1758. assertRoughlyEquals(400, visibleRect.right, EPSILON);
  1759. // Top 50px is clipped by container.
  1760. goog.style.setStyle(container2, 'width', '150px');
  1761. goog.style.setStyle(container2, 'top', '-50px');
  1762. var visibleRect = goog.style.getVisibleRectForElement(el);
  1763. assertNotNull(visibleRect);
  1764. assertRoughlyEquals(500, visibleRect.top, EPSILON);
  1765. assertRoughlyEquals(200, visibleRect.left, EPSILON);
  1766. assertRoughlyEquals(550, visibleRect.bottom, EPSILON);
  1767. assertRoughlyEquals(350, visibleRect.right, EPSILON);
  1768. // Bottom part is clipped by container.
  1769. goog.style.setStyle(container2, 'top', '50px');
  1770. goog.style.setStyle(container2, 'height', '1000px');
  1771. var visibleRect = goog.style.getVisibleRectForElement(el);
  1772. assertNotNull(visibleRect);
  1773. assertRoughlyEquals(550, visibleRect.top, EPSILON);
  1774. assertRoughlyEquals(200, visibleRect.left, EPSILON);
  1775. assertRoughlyEquals(800, visibleRect.bottom, EPSILON);
  1776. assertRoughlyEquals(350, visibleRect.right, EPSILON);
  1777. // Outside viewport.
  1778. goog.style.setStyle(container2, 'top', '10000px');
  1779. goog.style.setStyle(container2, 'left', '10000px');
  1780. assertNull(goog.style.getVisibleRectForElement(el));
  1781. }
  1782. function testScrollIntoContainerViewQuirks() {
  1783. if (goog.dom.isCss1CompatMode()) return;
  1784. var container = goog.dom.getElement('scrollable-container');
  1785. // Scroll the minimum amount to make the elements visible.
  1786. goog.style.scrollIntoContainerView(goog.dom.getElement('item7'), container);
  1787. assertEquals('scroll to item7', 79, container.scrollTop);
  1788. goog.style.scrollIntoContainerView(goog.dom.getElement('item8'), container);
  1789. assertEquals('scroll to item8', 100, container.scrollTop);
  1790. goog.style.scrollIntoContainerView(goog.dom.getElement('item7'), container);
  1791. assertEquals('item7 still visible', 100, container.scrollTop);
  1792. goog.style.scrollIntoContainerView(goog.dom.getElement('item1'), container);
  1793. assertEquals('scroll to item1', 17, container.scrollTop);
  1794. // Center the element in the first argument.
  1795. goog.style.scrollIntoContainerView(
  1796. goog.dom.getElement('item1'), container, true);
  1797. assertEquals('center item1', 0, container.scrollTop);
  1798. goog.style.scrollIntoContainerView(
  1799. goog.dom.getElement('item4'), container, true);
  1800. assertEquals('center item4', 48, container.scrollTop);
  1801. // The element is higher than the container.
  1802. goog.dom.getElement('item3').style.height = '140px';
  1803. goog.style.scrollIntoContainerView(goog.dom.getElement('item3'), container);
  1804. assertEquals('show item3 with increased height', 59, container.scrollTop);
  1805. goog.style.scrollIntoContainerView(
  1806. goog.dom.getElement('item3'), container, true);
  1807. assertEquals('center item3 with increased height', 87, container.scrollTop);
  1808. goog.dom.getElement('item3').style.height = '';
  1809. // Scroll to non-integer position.
  1810. goog.dom.getElement('item4').style.height = '21px';
  1811. goog.style.scrollIntoContainerView(
  1812. goog.dom.getElement('item4'), container, true);
  1813. assertEquals('scroll position is rounded down', 48, container.scrollTop);
  1814. goog.dom.getElement('item4').style.height = '';
  1815. }
  1816. function testScrollIntoContainerViewStandard() {
  1817. if (!goog.dom.isCss1CompatMode()) return;
  1818. var container = goog.dom.getElement('scrollable-container');
  1819. // Scroll the minimum amount to make the elements visible.
  1820. goog.style.scrollIntoContainerView(goog.dom.getElement('item7'), container);
  1821. assertEquals('scroll to item7', 115, container.scrollTop);
  1822. goog.style.scrollIntoContainerView(goog.dom.getElement('item8'), container);
  1823. assertEquals('scroll to item8', 148, container.scrollTop);
  1824. goog.style.scrollIntoContainerView(goog.dom.getElement('item7'), container);
  1825. assertEquals('item7 still visible', 148, container.scrollTop);
  1826. goog.style.scrollIntoContainerView(goog.dom.getElement('item1'), container);
  1827. assertEquals('scroll to item1', 17, container.scrollTop);
  1828. // Center the element in the first argument.
  1829. goog.style.scrollIntoContainerView(
  1830. goog.dom.getElement('item1'), container, true);
  1831. assertEquals('center item1', 0, container.scrollTop);
  1832. goog.style.scrollIntoContainerView(
  1833. goog.dom.getElement('item4'), container, true);
  1834. assertEquals('center item4', 66, container.scrollTop);
  1835. // The element is higher than the container.
  1836. goog.dom.getElement('item3').style.height = '140px';
  1837. goog.style.scrollIntoContainerView(goog.dom.getElement('item3'), container);
  1838. assertEquals('show item3 with increased height', 83, container.scrollTop);
  1839. goog.style.scrollIntoContainerView(
  1840. goog.dom.getElement('item3'), container, true);
  1841. assertEquals('center item3 with increased height', 93, container.scrollTop);
  1842. goog.dom.getElement('item3').style.height = '';
  1843. // Scroll to non-integer position.
  1844. goog.dom.getElement('item4').style.height = '21px';
  1845. goog.style.scrollIntoContainerView(
  1846. goog.dom.getElement('item4'), container, true);
  1847. assertEquals('scroll position is rounded down', 66, container.scrollTop);
  1848. goog.dom.getElement('item4').style.height = '';
  1849. }
  1850. function testScrollIntoContainerViewSvg() {
  1851. if (!goog.dom.isCss1CompatMode()) {
  1852. return;
  1853. }
  1854. var svgEl = document.createElementNS &&
  1855. document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  1856. if (!svgEl || svgEl.getAttribute('transform') == '' ||
  1857. (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher(534.8))) {
  1858. // SVG not supported, or getBoundingClientRect not supported on SVG
  1859. // elements.
  1860. return;
  1861. }
  1862. var assertEqualsForSvgPos = function(expected, actual) {
  1863. if (goog.userAgent.EDGE_OR_IE) {
  1864. // The bounding size is 1 larger than the SVG element in IE. The scrollTop
  1865. // value maybe 1 less or 1 more than the expected value depending on the
  1866. // scroll direction.
  1867. assertRoughlyEquals(expected, actual, 1);
  1868. } else {
  1869. assertEquals(expected, actual);
  1870. }
  1871. };
  1872. var svgItem1 = goog.dom.getElement('svg-item1');
  1873. var svgItem2 = goog.dom.getElement('svg-item2');
  1874. var svgItem3 = goog.dom.getElement('svg-item3');
  1875. // Scroll the minimum amount to make the elements visible.
  1876. var container = goog.dom.getElement('svg-container');
  1877. goog.style.scrollIntoContainerView(svgItem1, container);
  1878. assertEquals(0, container.scrollTop);
  1879. goog.style.scrollIntoContainerView(svgItem2, container);
  1880. assertEqualsForSvgPos(50, container.scrollTop);
  1881. goog.style.scrollIntoContainerView(svgItem3, container);
  1882. assertEqualsForSvgPos(150, container.scrollTop);
  1883. goog.style.scrollIntoContainerView(svgItem2, container);
  1884. assertEqualsForSvgPos(100, container.scrollTop);
  1885. // Center the element in the first argument.
  1886. goog.style.scrollIntoContainerView(svgItem2, container, true);
  1887. assertEqualsForSvgPos(75, container.scrollTop);
  1888. goog.style.scrollIntoContainerView(svgItem3, container, true);
  1889. assertEqualsForSvgPos(175, container.scrollTop);
  1890. // The element is higher than the container.
  1891. svgItem3.setAttribute('height', 200);
  1892. goog.style.scrollIntoContainerView(svgItem3, container);
  1893. assertEqualsForSvgPos(200, container.scrollTop);
  1894. goog.style.scrollIntoContainerView(svgItem3, container, true);
  1895. assertEqualsForSvgPos(225, container.scrollTop);
  1896. // Scroll to non-integer position.
  1897. svgItem3.setAttribute('height', 75);
  1898. goog.style.scrollIntoContainerView(svgItem3, container, true);
  1899. // Scroll position is rounded down from 162.5
  1900. assertEqualsForSvgPos(162, container.scrollTop);
  1901. svgItem3.setAttribute('height', 100);
  1902. }
  1903. function testOffsetParent() {
  1904. var parent = goog.dom.getElement('offset-parent');
  1905. var child = goog.dom.getElement('offset-child');
  1906. assertEquals(parent, goog.style.getOffsetParent(child));
  1907. }
  1908. function testOverflowOffsetParent() {
  1909. var parent = goog.dom.getElement('offset-parent-overflow');
  1910. var child = goog.dom.getElement('offset-child-overflow');
  1911. assertEquals(parent, goog.style.getOffsetParent(child));
  1912. }
  1913. function testShadowDomOffsetParent() {
  1914. // Ignore browsers that don't support shadowDOM.
  1915. if (!document.createShadowRoot) {
  1916. return;
  1917. }
  1918. var parent = goog.dom.createDom(goog.dom.TagName.DIV);
  1919. parent.style.position = 'relative';
  1920. var host = goog.dom.createDom(goog.dom.TagName.DIV);
  1921. goog.dom.appendChild(parent, host);
  1922. var root = host.createShadowRoot();
  1923. var child = goog.dom.createDom(goog.dom.TagName.DIV);
  1924. goog.dom.appendChild(root, child);
  1925. assertEquals(parent, goog.style.getOffsetParent(child));
  1926. }
  1927. function testGetViewportPageOffset() {
  1928. expectedFailures.expectFailureFor(
  1929. goog.userAgent.IE && !goog.userAgent.isVersionOrHigher(10),
  1930. 'Test has been flaky for ie9-win7 and ie8-winxp image. Disabling. ' +
  1931. 'See b/22873770.');
  1932. try {
  1933. var testViewport = goog.dom.getElement('test-viewport');
  1934. testViewport.style.height = '5000px';
  1935. testViewport.style.width = '5000px';
  1936. var offset = goog.style.getViewportPageOffset(document);
  1937. assertEquals(0, offset.x);
  1938. assertEquals(0, offset.y);
  1939. window.scrollTo(0, 100);
  1940. offset = goog.style.getViewportPageOffset(document);
  1941. assertEquals(0, offset.x);
  1942. assertEquals(100, offset.y);
  1943. window.scrollTo(100, 0);
  1944. offset = goog.style.getViewportPageOffset(document);
  1945. assertEquals(100, offset.x);
  1946. assertEquals(0, offset.y);
  1947. } catch (e) {
  1948. expectedFailures.handleException(e);
  1949. }
  1950. }
  1951. function testGetsTranslation() {
  1952. var element = document.getElementById('translation');
  1953. if (goog.userAgent.IE) {
  1954. if (!goog.userAgent.isDocumentModeOrHigher(9) ||
  1955. (!goog.dom.isCss1CompatMode() &&
  1956. !goog.userAgent.isDocumentModeOrHigher(10))) {
  1957. // 'CSS transforms were introduced in IE9, but only in standards mode
  1958. // later browsers support the translations in quirks mode.
  1959. return;
  1960. }
  1961. }
  1962. // First check the element is actually translated, and we haven't missed
  1963. // one of the vendor-specific transform properties
  1964. var position = goog.style.getClientPosition(element);
  1965. var translation = goog.style.getCssTranslation(element);
  1966. var expectedTranslation = new goog.math.Coordinate(20, 30);
  1967. assertEquals(30, position.x);
  1968. assertRoughlyEquals(40, position.y, .1);
  1969. assertObjectEquals(expectedTranslation, translation);
  1970. }
  1971. /**
  1972. * Test browser detection for a user agent configuration.
  1973. * @param {Array<number>} expectedAgents Array of expected userAgents.
  1974. * @param {string} uaString User agent string.
  1975. * @param {string=} opt_product Navigator product string.
  1976. * @param {string=} opt_vendor Navigator vendor string.
  1977. */
  1978. function assertUserAgent(expectedAgents, uaString, opt_product, opt_vendor) {
  1979. var mockNavigator =
  1980. {'userAgent': uaString, 'product': opt_product, 'vendor': opt_vendor};
  1981. mockUserAgent.setNavigator(mockNavigator);
  1982. mockUserAgent.setUserAgentString(uaString);
  1983. // Force User-Agent lib to reread the global userAgent.
  1984. goog.labs.userAgent.util.setUserAgent(null);
  1985. goog.userAgentTestUtil.reinitializeUserAgent();
  1986. for (var ua in goog.userAgentTestUtil.UserAgents) {
  1987. var isExpected = goog.array.contains(
  1988. expectedAgents, goog.userAgentTestUtil.UserAgents[ua]);
  1989. assertEquals(
  1990. isExpected, goog.userAgentTestUtil.getUserAgentDetected(
  1991. goog.userAgentTestUtil.UserAgents[ua]));
  1992. }
  1993. }
  1994. /**
  1995. * Test for the proper vendor style name for a CSS property
  1996. * with a vendor prefix for Webkit.
  1997. */
  1998. function testGetVendorStyleNameWebkit() {
  1999. var mockElement = {'style': {'WebkitTransformOrigin': ''}};
  2000. assertUserAgent([goog.userAgentTestUtil.UserAgents.WEBKIT], 'WebKit');
  2001. assertEquals(
  2002. '-webkit-transform-origin',
  2003. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2004. }
  2005. /**
  2006. * Test for the proper vendor style name for a CSS property
  2007. * when it exists without a vendor prefix for Webkit.
  2008. */
  2009. function testGetVendorStyleNameWebkitNoPrefix() {
  2010. var mockElement = {
  2011. 'style': {'WebkitTransformOrigin': '', 'transformOrigin': ''}
  2012. };
  2013. assertUserAgent([goog.userAgentTestUtil.UserAgents.WEBKIT], 'WebKit');
  2014. assertEquals(
  2015. 'transform-origin',
  2016. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2017. }
  2018. /**
  2019. * Test for the proper vendor style name for a CSS property
  2020. * with a vendor prefix for Gecko.
  2021. */
  2022. function testGetVendorStyleNameGecko() {
  2023. var mockElement = {'style': {'MozTransformOrigin': ''}};
  2024. assertUserAgent([goog.userAgentTestUtil.UserAgents.GECKO], 'Gecko', 'Gecko');
  2025. assertEquals(
  2026. '-moz-transform-origin',
  2027. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2028. }
  2029. /**
  2030. * Test for the proper vendor style name for a CSS property
  2031. * when it exists without a vendor prefix for Gecko.
  2032. */
  2033. function testGetVendorStyleNameGeckoNoPrefix() {
  2034. var mockElement = {
  2035. 'style': {'MozTransformOrigin': '', 'transformOrigin': ''}
  2036. };
  2037. assertUserAgent([goog.userAgentTestUtil.UserAgents.GECKO], 'Gecko', 'Gecko');
  2038. assertEquals(
  2039. 'transform-origin',
  2040. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2041. }
  2042. /**
  2043. * Test for the proper vendor style name for a CSS property
  2044. * with a vendor prefix for IE.
  2045. */
  2046. function testGetVendorStyleNameIE() {
  2047. var mockElement = {'style': {'msTransformOrigin': ''}};
  2048. assertUserAgent([goog.userAgentTestUtil.UserAgents.IE], 'MSIE');
  2049. assertEquals(
  2050. '-ms-transform-origin',
  2051. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2052. }
  2053. /**
  2054. * Test for the proper vendor style name for a CSS property
  2055. * when it exists without a vendor prefix for IE.
  2056. */
  2057. function testGetVendorStyleNameIENoPrefix() {
  2058. var mockElement = {'style': {'msTransformOrigin': '', 'transformOrigin': ''}};
  2059. assertUserAgent([goog.userAgentTestUtil.UserAgents.IE], 'MSIE');
  2060. assertEquals(
  2061. 'transform-origin',
  2062. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2063. }
  2064. /**
  2065. * Test for the proper vendor style name for a CSS property
  2066. * with a vendor prefix for Opera.
  2067. */
  2068. function testGetVendorStyleNameOpera() {
  2069. var mockElement = {'style': {'OTransformOrigin': ''}};
  2070. assertUserAgent([goog.userAgentTestUtil.UserAgents.OPERA], 'Opera');
  2071. assertEquals(
  2072. '-o-transform-origin',
  2073. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2074. }
  2075. /**
  2076. * Test for the proper vendor style name for a CSS property
  2077. * when it exists without a vendor prefix for Opera.
  2078. */
  2079. function testGetVendorStyleNameOperaNoPrefix() {
  2080. var mockElement = {'style': {'OTransformOrigin': '', 'transformOrigin': ''}};
  2081. assertUserAgent([goog.userAgentTestUtil.UserAgents.OPERA], 'Opera');
  2082. assertEquals(
  2083. 'transform-origin',
  2084. goog.style.getVendorStyleName_(mockElement, 'transform-origin'));
  2085. }
  2086. /**
  2087. * Test for the proper vendor style name for a CSS property
  2088. * with a vendor prefix for Webkit.
  2089. */
  2090. function testGetVendorJsStyleNameWebkit() {
  2091. var mockElement = {'style': {'WebkitTransformOrigin': ''}};
  2092. assertUserAgent([goog.userAgentTestUtil.UserAgents.WEBKIT], 'WebKit');
  2093. assertEquals(
  2094. 'WebkitTransformOrigin',
  2095. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2096. }
  2097. /**
  2098. * Test for the proper vendor style name for a CSS property
  2099. * when it exists without a vendor prefix for Webkit.
  2100. */
  2101. function testGetVendorJsStyleNameWebkitNoPrefix() {
  2102. var mockElement = {
  2103. 'style': {'WebkitTransformOrigin': '', 'transformOrigin': ''}
  2104. };
  2105. assertUserAgent([goog.userAgentTestUtil.UserAgents.WEBKIT], 'WebKit');
  2106. assertEquals(
  2107. 'transformOrigin',
  2108. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2109. }
  2110. /**
  2111. * Test for the proper vendor style name for a CSS property
  2112. * with a vendor prefix for Gecko.
  2113. */
  2114. function testGetVendorJsStyleNameGecko() {
  2115. var mockElement = {'style': {'MozTransformOrigin': ''}};
  2116. assertUserAgent([goog.userAgentTestUtil.UserAgents.GECKO], 'Gecko', 'Gecko');
  2117. assertEquals(
  2118. 'MozTransformOrigin',
  2119. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2120. }
  2121. /**
  2122. * Test for the proper vendor style name for a CSS property
  2123. * when it exists without a vendor prefix for Gecko.
  2124. */
  2125. function testGetVendorJsStyleNameGeckoNoPrefix() {
  2126. var mockElement = {
  2127. 'style': {'MozTransformOrigin': '', 'transformOrigin': ''}
  2128. };
  2129. assertUserAgent([goog.userAgentTestUtil.UserAgents.GECKO], 'Gecko', 'Gecko');
  2130. assertEquals(
  2131. 'transformOrigin',
  2132. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2133. }
  2134. /**
  2135. * Test for the proper vendor style name for a CSS property
  2136. * with a vendor prefix for IE.
  2137. */
  2138. function testGetVendorJsStyleNameIE() {
  2139. var mockElement = {'style': {'msTransformOrigin': ''}};
  2140. assertUserAgent([goog.userAgentTestUtil.UserAgents.IE], 'MSIE');
  2141. assertEquals(
  2142. 'msTransformOrigin',
  2143. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2144. }
  2145. /**
  2146. * Test for the proper vendor style name for a CSS property
  2147. * when it exists without a vendor prefix for IE.
  2148. */
  2149. function testGetVendorJsStyleNameIENoPrefix() {
  2150. var mockElement = {'style': {'msTransformOrigin': '', 'transformOrigin': ''}};
  2151. assertUserAgent([goog.userAgentTestUtil.UserAgents.IE], 'MSIE');
  2152. assertEquals(
  2153. 'transformOrigin',
  2154. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2155. }
  2156. /**
  2157. * Test for the proper vendor style name for a CSS property
  2158. * with a vendor prefix for Opera.
  2159. */
  2160. function testGetVendorJsStyleNameOpera() {
  2161. var mockElement = {'style': {'OTransformOrigin': ''}};
  2162. assertUserAgent([goog.userAgentTestUtil.UserAgents.OPERA], 'Opera');
  2163. assertEquals(
  2164. 'OTransformOrigin',
  2165. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2166. }
  2167. /**
  2168. * Test for the proper vendor style name for a CSS property
  2169. * when it exists without a vendor prefix for Opera.
  2170. */
  2171. function testGetVendorJsStyleNameOperaNoPrefix() {
  2172. var mockElement = {'style': {'OTransformOrigin': '', 'transformOrigin': ''}};
  2173. assertUserAgent([goog.userAgentTestUtil.UserAgents.OPERA], 'Opera');
  2174. assertEquals(
  2175. 'transformOrigin',
  2176. goog.style.getVendorJsStyleName_(mockElement, 'transform-origin'));
  2177. }
  2178. /**
  2179. * Test for the setting a style name for a CSS property
  2180. * with a vendor prefix for Webkit.
  2181. */
  2182. function testSetVendorStyleWebkit() {
  2183. var mockElement = {'style': {'WebkitTransform': ''}};
  2184. var styleValue = 'translate3d(0,0,0)';
  2185. assertUserAgent([goog.userAgentTestUtil.UserAgents.WEBKIT], 'WebKit');
  2186. goog.style.setStyle(mockElement, 'transform', styleValue);
  2187. assertEquals(styleValue, mockElement.style.WebkitTransform);
  2188. }
  2189. /**
  2190. * Test for the setting a style name for a CSS property
  2191. * with a vendor prefix for Mozilla.
  2192. */
  2193. function testSetVendorStyleGecko() {
  2194. var mockElement = {'style': {'MozTransform': ''}};
  2195. var styleValue = 'translate3d(0,0,0)';
  2196. assertUserAgent([goog.userAgentTestUtil.UserAgents.GECKO], 'Gecko', 'Gecko');
  2197. goog.style.setStyle(mockElement, 'transform', styleValue);
  2198. assertEquals(styleValue, mockElement.style.MozTransform);
  2199. }
  2200. /**
  2201. * Test for the setting a style name for a CSS property
  2202. * with a vendor prefix for IE.
  2203. */
  2204. function testSetVendorStyleIE() {
  2205. var mockElement = {'style': {'msTransform': ''}};
  2206. var styleValue = 'translate3d(0,0,0)';
  2207. assertUserAgent([goog.userAgentTestUtil.UserAgents.IE], 'MSIE');
  2208. goog.style.setStyle(mockElement, 'transform', styleValue);
  2209. assertEquals(styleValue, mockElement.style.msTransform);
  2210. }
  2211. /**
  2212. * Test for the setting a style name for a CSS property
  2213. * with a vendor prefix for Opera.
  2214. */
  2215. function testSetVendorStyleOpera() {
  2216. var mockElement = {'style': {'OTransform': ''}};
  2217. var styleValue = 'translate3d(0,0,0)';
  2218. assertUserAgent([goog.userAgentTestUtil.UserAgents.OPERA], 'Opera');
  2219. goog.style.setStyle(mockElement, 'transform', styleValue);
  2220. assertEquals(styleValue, mockElement.style.OTransform);
  2221. }
  2222. /**
  2223. * Test for the getting a style name for a CSS property
  2224. * with a vendor prefix for Webkit.
  2225. */
  2226. function testGetVendorStyleWebkit() {
  2227. var mockElement = {'style': {'WebkitTransform': ''}};
  2228. var styleValue = 'translate3d(0,0,0)';
  2229. assertUserAgent([goog.userAgentTestUtil.UserAgents.WEBKIT], 'WebKit');
  2230. goog.style.setStyle(mockElement, 'transform', styleValue);
  2231. assertEquals(styleValue, goog.style.getStyle(mockElement, 'transform'));
  2232. }
  2233. /**
  2234. * Test for the getting a style name for a CSS property
  2235. * with a vendor prefix for Mozilla.
  2236. */
  2237. function testGetVendorStyleGecko() {
  2238. var mockElement = {'style': {'MozTransform': ''}};
  2239. var styleValue = 'translate3d(0,0,0)';
  2240. assertUserAgent([goog.userAgentTestUtil.UserAgents.GECKO], 'Gecko', 'Gecko');
  2241. goog.style.setStyle(mockElement, 'transform', styleValue);
  2242. assertEquals(styleValue, goog.style.getStyle(mockElement, 'transform'));
  2243. }
  2244. /**
  2245. * Test for the getting a style name for a CSS property
  2246. * with a vendor prefix for IE.
  2247. */
  2248. function testGetVendorStyleIE() {
  2249. var mockElement = {'style': {'msTransform': ''}};
  2250. var styleValue = 'translate3d(0,0,0)';
  2251. assertUserAgent([goog.userAgentTestUtil.UserAgents.IE], 'MSIE');
  2252. goog.style.setStyle(mockElement, 'transform', styleValue);
  2253. assertEquals(styleValue, goog.style.getStyle(mockElement, 'transform'));
  2254. }
  2255. /**
  2256. * Test for the getting a style name for a CSS property
  2257. * with a vendor prefix for Opera.
  2258. */
  2259. function testGetVendorStyleOpera() {
  2260. var mockElement = {'style': {'OTransform': ''}};
  2261. var styleValue = 'translate3d(0,0,0)';
  2262. assertUserAgent([goog.userAgentTestUtil.UserAgents.OPERA], 'Opera');
  2263. goog.style.setStyle(mockElement, 'transform', styleValue);
  2264. assertEquals(styleValue, goog.style.getStyle(mockElement, 'transform'));
  2265. }
  2266. function testParseStyleAttributeWithColon() {
  2267. // Regression test for https://github.com/google/closure-library/issues/127.
  2268. var cssObj = goog.style.parseStyleAttribute(
  2269. 'left: 0px; text-align: center; background-image: ' +
  2270. 'url(http://www.google.ca/Test.gif); -ms-filter: ' +
  2271. 'progid:DXImageTransform.Microsoft.MotionBlur(strength=50), ' +
  2272. 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1);');
  2273. assertEquals('url(http://www.google.ca/Test.gif)', cssObj.backgroundImage);
  2274. assertEquals(
  2275. 'progid:DXImageTransform.Microsoft.MotionBlur(strength=50), ' +
  2276. 'progid:DXImageTransform.Microsoft.BasicImage(mirror=1)',
  2277. cssObj.MsFilter);
  2278. }