UNPKG

sku-pg

Version:

Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!

392 lines (359 loc) 13.7 kB
<html> <!-- Copyright 2010 The Closure Library Authors. All Rights Reserved. Use of this source code is governed by the Apache License, Version 2.0. See the COPYING file for details. --> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <script src="../../base.js"></script> <script> goog.require('goog.cssom'); goog.require('goog.cssom.iframe.style'); goog.require('goog.testing.jsunit'); </script> <script> // unit tests var propertiesToTest = [ 'color', 'font-family', 'font-style', 'font-size', 'font-variant', 'border-top-style', 'border-top-width', 'border-top-color', 'background-color', 'margin-bottom' ]; function crawlDom(startNode, func) { if (startNode.nodeType != 1) { return; } func(startNode); for (var i = 0; i < startNode.childNodes.length; i++) { crawlDom(startNode.childNodes[i], func); } } function getCurrentCssProperties(node, propList) { var props = {}; if (node.nodeType != 1) { return; } for (var i = 0; i < propList.length; i++) { var prop = propList[i]; if (node.currentStyle) { // IE var propCamelCase = ''; var propParts = prop.split('-'); for (var j = 0; j < propParts.length; j++) { propCamelCase += propParts[j].charAt(0).toUpperCase() + propParts[j].substring(1, propParts[j].length); } props[prop] = node.currentStyle[propCamelCase]; } else { // standards-compliant browsers props[prop] = node.ownerDocument.defaultView.getComputedStyle( node, '').getPropertyValue(prop); } } return props; } function CssPropertyCollector(){ var propsList = []; this.propsList = propsList this.collectProps = function(node) { var nodeProps = getCurrentCssProperties(node, propertiesToTest); if (nodeProps) { propsList.push([nodeProps, node]); } } } function recursivelyListCssProperties(el) { var collector = new CssPropertyCollector(); crawlDom(el, collector.collectProps); return collector.propsList; } function testMatchCssSelector() { var container = document.createElement('div'); container.className = 'container'; var el = document.createElement('div'); x = el; el.id = 'mydiv'; el.className = 'colorful foo'; // set some arbirtrary content el.innerHTML = '<div><ul><li>One</li><li>Two</li></ul></div>'; container.appendChild(el); document.body.appendChild(container); var elementAncestry = new goog.cssom.iframe.style.NodeAncestry_(el); assertEquals(5, elementAncestry.nodes.length); // list of input/output results. Output is the index of the selector // that we expect to match - for example, in 'body div div.colorful', // 'div.colorful' has an index of 2. var expectedResults = [ ['body div', [4, 1]], ['h1', null], ['body div h1', [4, 1]], ['body div.colorful h1', [4, 1]], ['body div div', [4, 2]], ['body div div div', [4, 2]], ['body div div.somethingelse div', [4, 1]], ['body div.somethingelse div', [2, 0]], ['div.container', [3, 0]], ['div.container div', [4, 1]], ['#mydiv', [4, 0]], ['div#mydiv', [4, 0]], ['div.colorful', [4, 0]], ['div#mydiv .colorful', [4, 0]], ['.colorful', [4, 0]], ['body * div', [4,2]], ['body * *', [4,2]] ]; for (var i = 0; i < expectedResults.length; i++) { var input = expectedResults[i][0]; var expectedResult = expectedResults[i][1]; var selector = new goog.cssom.iframe.style.CssSelector_(input); var result = selector.matchElementAncestry(elementAncestry); if (expectedResult == null) { assertEquals('Expected null result', expectedResult, result); } else { assertEquals('Expected element index for ' + input, expectedResult[0], result.elementIndex); assertEquals('Expected selector part index for ' + input, expectedResult[1], result.selectorPartIndex); } } document.body.removeChild(container); } function makeIframeDocument(iframe) { var doc = goog.dom.getFrameContentDocument(iframe); doc.open(); doc.write('<html><head>'); doc.write('<style>html,body { background-color: transparent; }</style>'); doc.write('</head><body></body></html>'); doc.close(); return doc; } function testCopyCss() { for (var i = 1; i <= 4; i++) { var sourceElement = document.getElementById('source'+i); var newFrame = document.createElement('iframe'); newFrame.allowTransparency = true; sourceElement.parentNode.insertBefore(newFrame, sourceElement.nextSibling); var doc = makeIframeDocument(newFrame); goog.cssom.addCssText( goog.cssom.iframe.style.getElementContext(sourceElement), new goog.dom.DomHelper(doc)); doc.body.innerHTML = sourceElement.innerHTML; var oldProps = recursivelyListCssProperties(sourceElement); var newProps = recursivelyListCssProperties(doc.body); assertEquals(oldProps.length, newProps.length); for (var j = 0; j < oldProps.length; j++) { for (var k = 0; k < propertiesToTest.length; k++) { assertEquals('testing property ' + propertiesToTest[k], oldProps[j][0][propertiesToTest[k]], newProps[j][0][propertiesToTest[k]]); } } } } function normalizeCssText(cssText) { // Normalize cssText for testing purposes. return cssText.replace(/\s/g, '').toLowerCase(); } function testAImportantInFF2() { var testDiv = document.getElementById('source1'); var cssText = normalizeCssText( goog.cssom.iframe.style.getElementContext(testDiv)); var color = standardizeCSSValue('color', 'red'); var NORMAL_RULE = 'a{color:' + color; var FF_2_RULE = 'a{color:' + color + '!important'; if (goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9a')) { assertContains(FF_2_RULE, cssText); } else { assertContains(NORMAL_RULE, cssText); assertNotContains(FF_2_RULE, cssText); } } function testCopyBackgroundContext() { var testDiv = document.getElementById('backgroundTest'); var cssText = goog.cssom.iframe.style.getElementContext(testDiv, null, true); var iframe = document.createElement('iframe'); var ancestor = document.getElementById('backgroundTest-ancestor-1'); ancestor.parentNode.insertBefore(iframe, ancestor.nextSibling); iframe.style.width = '100%'; iframe.style.height = '100px'; iframe.style.borderWidth = '0px'; var doc = makeIframeDocument(iframe); goog.cssom.addCssText(cssText, new goog.dom.DomHelper(doc)); doc.body.innerHTML = testDiv.innerHTML; var normalizedCssText = normalizeCssText(cssText); assertTrue( 'Background color should be copied from parent element', /body{[^{]*background-color:(?:rgb\(128,0,128\)|#800080)/.test( normalizedCssText)); assertTrue( 'Background image should be copied from ancestor element', /body{[^{]*background-image:url\(/.test(normalizedCssText)); // Background-position can't be calculated in FF2, due to this bug: // http://bugzilla.mozilla.org/show_bug.cgi?id=316981 if (!(goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9'))) { // Expected x position is: // originalBackgroundPositionX - elementOffsetLeft // 40px - (1px + 8px) == 31px // Expected y position is: // originalBackgroundPositionY - elementOffsetLeft // 70px - (1px + 10px + 5px) == 54px; assertTrue('Background image position should be adjusted correctly', /body{[^{]*background-position:31px54px/.test(normalizedCssText)); } } function testCopyBackgroundContextFromIframe() { var testDiv = document.getElementById('backgroundTest'); var iframe = document.createElement('iframe'); iframe.allowTransparency = true; iframe.style.position = 'absolute'; iframe.style.top = '5px'; iframe.style.left = '5px'; iframe.style.borderWidth = '2px'; iframe.style.borderStyle = 'solid'; testDiv.appendChild(iframe); var doc = makeIframeDocument(iframe); doc.body.backgroundColor = 'transparent'; doc.body.style.margin = '0'; doc.body.style.padding = '0'; doc.body.innerHTML = '<p style="margin: 0">I am transparent!</p>'; var normalizedCssText = normalizeCssText( goog.cssom.iframe.style.getElementContext( doc.body.firstChild, null, true)); // Background properties should get copied through from the parent // document since the iframe is transparent assertTrue( 'Background color should be copied from parent element', /body{[^{]*background-color:(?:rgb\(128,0,128\)|#800080)/.test( normalizedCssText)); assertTrue( 'Background image should be copied from ancestor element', /body{[^{]*background-image:url\(/.test(normalizedCssText)); // Background-position can't be calculated in FF2, due to this bug: // http://bugzilla.mozilla.org/show_bug.cgi?id=316981 if (!(goog.userAgent.GECKO && !goog.userAgent.isVersionOrHigher('1.9'))) { // Image offset should have been calculated to be the same as the // above example, but adding iframe offset and borderWidth. // Expected x position is: // originalBackgroundPositionX - elementOffsetLeft // 40px - (1px + 8px + 5px + 2px) == 24px // Expected y position is: // originalBackgroundPositionY - elementOffsetLeft // 70px - (1px + 10px + 5px + 5px + 2px) == 47px; assertTrue('Background image position should be adjusted correctly', !!/body{[^{]*background-position:24px47px/.exec( normalizedCssText)) } iframe.parentNode.removeChild(iframe); } function testCopyFontFaceRules() { var isFontFaceCssomSupported = goog.userAgent.WEBKIT || goog.userAgent.OPERA || (goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.1')); // We cannot use goog.testing.ExpectedFailures since it dynamically // brings in CSS which causes the background context tests to fail // in IE6. if (isFontFaceCssomSupported) { var cssText = goog.cssom.iframe.style.getElementContext( document.getElementById('cavalier')); assertTrue('The font face rule should have been copied correctly', /@font-face/.test(cssText)); } } </script> <style type="text/css"> @import url("style_test_import.css"); body { font-family: Verdana; } div { background-color: #ffc; margin: 10px 0; } p { margin: 10px 0; } .boxy { padding: 5px; background-color: #fa0; } .special .boxy { padding: 10px; background-color: #abef00; } div div strong { color: red; } div { line-height: 1.3; } .wrapper .inner-wrapper { border: 2px solid pink;} a { color: red; } #source4 { background-color: #900; } #backgroundTest-ancestor-1 { background-color: rgb(128,0,128); } #backgroundTest-ancestor-0 { background-image: url("../../images/blank.gif"); background-position: 40px 70px; background-repeat: repeat; background-color: transparent; padding: 5px 8px; } div#backgroundTest-parent { border: 1px solid black; background-color: transparent; } div#backgroundTest { position: relative; background-color: transparent; height: 100px; margin-top: 0; } </style> <style type="text/css"> .goog-presently-theme-monochrome { background-color: black; color: #CCC; } .goog-presently-theme-monochrome a { color: #FFF; } .goog-presently-theme-monochrome p#source4 { font-variant: small-caps; } .italic { font-style: italic; } </style> <style type="text/css"> @font-face { font-family: Cavalier; } #cavalier { font-family: Cavalier; } </style> </head> <body> <div class="wrapper"> <div class="inner-wrapper"> <div id="source1" class="italic"> hello world </div> <div id="source2"> <div>Some <strong>strong</strong> text</div> <div class="boxy exciting">A box</div> <div class="inner-wrapper">A wrapper</div> </div> <div id="source3" class="special"> Some <strong>strong</strong> text <div class="boxy">A box</div> </div> <div id="ancestor" class="goog-presently-theme-monochrome"> <p id="source4" style="background-color: #900"> Here's a link: <a href="#">my link</a> </p> </div> <div id="backgroundTest-ancestor-1"> <div id="backgroundTest-ancestor-0"> <div id="backgroundTest-parent"> <div id="backgroundTest"> hello </div> </div> </div> </div> <div id="cavalier"></div> </div> </div> <br /> </body> </html>