Permalink
Browse files

first commit

first commit of the scoped polyfill
  • Loading branch information...
0 parents commit 06ed133b771b7a3fc3c1301f47b8abe6cad6ede3 @PM5544 committed Oct 8, 2011
Showing with 336 additions and 0 deletions.
  1. +77 −0 index.htm
  2. +69 −0 indexjquery.htm
  3. +165 −0 scoped.js
  4. +25 −0 ugly.css
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html dir="ltr" lang="en">
+<head>
+<meta charset="utf-8" />
+<title>JavaScript scoped polyfill test page</title>
+<link rel="stylesheet" type="text/css" href="ugly.css" />
+</head>
+<body>
+
+<style>
+/* putItHereToTestIfItWouldBreakWhenMultipleStyleNodesWhereInTheDOM */
+</style>
+<div id="testID1">
+
+ <div class="widgetContent">
+ <h1>my ugly widget</h1>
+ <ol>
+ <li>my first ugly list item
+ <li>my second ugly list item
+ </ol>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a turpis ut enim venenatis consectetur eu ac risus. Quisque sollicitudin enim luctus turpis viverra eget elementum sapien ultricies. Donec ultrices mollis risus, vitae sagittis lectus molestie sed. Curabitur rhoncus, velit nec adipiscing adipiscing, mi est pharetra libero, et tincidunt sapien magna sit amet nulla. Nulla vitae ultricies erat. Pellentesque laoreet feugiat tellus, at luctus nibh sodales et. Nulla vehicula faucibus neque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec ullamcorper ipsum eu quam dapibus ut varius lorem suscipit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
+ </div>
+
+ <div id="testID2">
+
+ <div>
+ <style scoped>
+ .widgetContent{
+ border:none;
+ font-family: Verdana,sans-serif;
+ border-radius: 5px;
+ box-shadow: 2px 2px 5px rgba( 30,30,30,.5 );
+ padding:10px 20px;
+ }
+ .widgetContent,
+ .widgetContent h1,
+ .widgetContent li,
+ .widgetContent ul,
+ .widgetContent ol,
+ .widgetContent p{
+ background:#fff;
+ border:none;
+ color:#000
+ }
+ h1{
+ font-size:16px;
+ line-height:2em;
+ padding: 0;
+ }
+ li{
+ list-style: disc inside;
+ padding: 3px 3px 3px 10px;
+ border-bottom: 1px solid #e0e0e0;
+ }
+ ul, ol{
+ padding:5px;
+ }
+ p{
+ margin: 1em 0;
+ }
+ </style>
+ <div class="widgetContent">
+ <h1>my super pretty widget</h1>
+ <ol>
+ <li>my first Uber list item
+ <li>my second cool list item
+ <li>my thrid shiny list item
+ </ol>
+ <p>Lorem ipsizzle dolizzle sit amet, consectetizzle adipiscing break yo neck, yall. Nullizzle brizzle velizzle, daahng dawg volutpizzle, suscipizzle black, dawg vizzle, crunk. Pellentesque yo tortor. Owned izzle. Ma nizzle izzle dolor dapibus turpis crazy . Mauris pellentesque nibh et turpizzle. Gizzle in tortizzle. I'm in the shizzle break it down rhoncizzle nisi. In break yo neck, yall sure platea dictumst. Dawg dapibizzle. Curabitur stuff urna, fo shizzle pot, yippiyo i'm in the shizzle, fo shizzle vitae, my shizz. Black suscipizzle. Integizzle sempizzle velit sizzle break it down.</p>
+ </div>
+ </div>
+
+ </div>
+</div>
+<script src="scoped.js"></script>
+</body>
+</html>
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html dir="ltr" lang="en">
+<head>
+<meta charset="utf-8" />
+<title>JavaScript scoped polyfill test page</title>
+<link rel="stylesheet" type="text/css" href="ugly.css" />
+</head>
+<body>
+
+<style>
+/* putItHereToTestIfItWouldBreakWhenMultipleStyleNodesWhereInTheDOM */
+</style>
+<div id="testID1">
+
+ <div class="widgetContent">
+ <h1>my ugly widget</h1>
+ <ol>
+ <li>my first ugly list item
+ <li>my second ugly list item
+ </ol>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc a turpis ut enim venenatis consectetur eu ac risus. Quisque sollicitudin enim luctus turpis viverra eget elementum sapien ultricies. Donec ultrices mollis risus, vitae sagittis lectus molestie sed. Curabitur rhoncus, velit nec adipiscing adipiscing, mi est pharetra libero, et tincidunt sapien magna sit amet nulla. Nulla vitae ultricies erat. Pellentesque laoreet feugiat tellus, at luctus nibh sodales et. Nulla vehicula faucibus neque. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec ullamcorper ipsum eu quam dapibus ut varius lorem suscipit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p>
+ </div>
+
+ <div id="testID2">
+
+ <div class="scopeThis">
+ <div class="widgetContent">
+ <h1>my first super pretty widget</h1>
+ <ol>
+ <li>my first Uber list item
+ <li>my second cool list item
+ <li>my thrid shiny list item
+ </ol>
+ <p>Lorem ipsizzle dolizzle sit amet, consectetizzle adipiscing break yo neck, yall. Nullizzle brizzle velizzle, daahng dawg volutpizzle, suscipizzle black, dawg vizzle, crunk. Pellentesque yo tortor. Owned izzle. Ma nizzle izzle dolor dapibus turpis crazy . Mauris pellentesque nibh et turpizzle. Gizzle in tortizzle. I'm in the shizzle break it down rhoncizzle nisi. In break yo neck, yall sure platea dictumst. Dawg dapibizzle. Curabitur stuff urna, fo shizzle pot, yippiyo i'm in the shizzle, fo shizzle vitae, my shizz. Black suscipizzle. Integizzle sempizzle velit sizzle break it down.</p>
+ </div>
+ </div>
+
+ <div class="scopeThis">
+ <div class="widgetContent">
+ <h1>my second super pretty widget</h1>
+ <ol>
+ <li>my first Uber list item
+ <li>my second cool list item
+ <li>my thrid shiny list item
+ </ol>
+ <p>Lorem ipsizzle dolizzle sit amet, consectetizzle adipiscing break yo neck, yall. Nullizzle brizzle velizzle, daahng dawg volutpizzle, suscipizzle black, dawg vizzle, crunk. Pellentesque yo tortor. Owned izzle. Ma nizzle izzle dolor dapibus turpis crazy . Mauris pellentesque nibh et turpizzle. Gizzle in tortizzle. I'm in the shizzle break it down rhoncizzle nisi. In break yo neck, yall sure platea dictumst. Dawg dapibizzle. Curabitur stuff urna, fo shizzle pot, yippiyo i'm in the shizzle, fo shizzle vitae, my shizz. Black suscipizzle. Integizzle sempizzle velit sizzle break it down.</p>
+ </div>
+ </div>
+
+ </div>
+</div>
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
+<script src="scoped.js"></script>
+<script>
+// append the style node like it was loaded through AJAX or something and appended to the DOM after loading
+// and run it through the polyfill function right away
+var $appendedStyles = $( "<style scoped>.widgetContent{ border:none;font-family: Verdana,sans-serif;border-radius: 5px;box-shadow: 2px 2px 5px rgba( 30,30,30,.5 );padding:10px 20px;}"
+ + ".widgetContent,.widgetContent h1,.widgetContent li,.widgetContent ul,.widgetContent ol,.widgetContent p{background:#fff;border:none;color:#000;}"
+ + "h1{font-size:16px;line-height:2em;padding: 0;} li{list-style: disc inside;padding: 3px 3px 3px 10px;border-bottom: 1px solid #e0e0e0;}"
+ + "ul,ol{padding:5px;}p{margin: 1em 0;}</style>"
+)
+.prependTo(
+ $( ".scopeThis" )
+)
+// call it on the <style> not on the containing node!
+scopePolyFill( $appendedStyles )
+</script>
+</body>
+</html>
@@ -0,0 +1,165 @@
+var scopePolyFill = ( function ( doc )
+{
+ // check for support of scope and certain option
+ var compat = (function ()
+ {
+ var check = doc.createElement( 'style' )
+ , DOMStyle = 'undefined' !== typeof check.sheet ? 'sheet' : 'undefined' !== typeof check.getSheet ? 'getSheet' : 'styleSheet'
+ , scopeSupported = '' === check.scope
+ , testSheet
+ , DOMRules
+ , testStyle
+ ;
+
+ // we need to append it to the DOM because the DOM element at least FF keeps NULL as a sheet utill appended
+ // and we can't check for the rules / cssRules and changeSelectorText untill we have that
+ doc.body.appendChild( check )
+ testSheet = check[ DOMStyle ]
+
+ // add a test styleRule to be able to test selectorText changing support
+ // IE doent allow inserting of '' as a styleRule
+ testSheet.addRule ? testSheet.addRule( 'c', 'blink' ) : testSheet.insertRule( 'c{}', 0 )
+
+ // store the way to get to the list of rules
+ DOMRules = testSheet.rules ? 'rules' : 'cssRules'
+
+ // cache the test rule (its allways the first since we didn't have any other thing inside this <style>
+ testStyle = testSheet[ DOMRules ][ 0 ]
+
+ // try catch it to prevent IE from throwing errors
+ // can't check the read only flag since IE just throws errors when setting it and Firefox won't allow setting it (and gas no read only flag
+ try{
+ testStyle.selectorText = 'd'
+ }catch( e ){}
+
+ // check if the selectorText has changed to the value we tried to set it to
+ var changeSelectorTextAllowed = 'd' === testStyle.selectorText || 'D' === testStyle.selectorText;
+
+ // remove the <style> to clean up
+ check.parentNode.removeChild( check );
+
+ // return the object with the appropriate flags
+ return {
+ scopeSupported: scopeSupported
+ , rules: DOMRules
+ , sheet: DOMStyle
+ , changeSelectorTextAllowed: changeSelectorTextAllowed
+ }
+ } ) ()
+
+ // scope is supported? just return
+ if ( compat.scopeSupported )
+ return
+
+ // this was called so we "scope" all the <style> nodes which need to be scoped now
+ var scopedSheets
+ , i
+ , idCounter = 0
+ ;
+ if ( doc.querySelectorAll )
+ {
+ scopedSheets = doc.querySelectorAll( 'style[scoped]' )
+ }
+ else
+ {
+ var tempSheets = []
+ scopedSheets = doc.getElementsByTagName( 'style' )
+ i = scopedSheets.length
+
+ while ( i-- )
+ {
+ if ( '' === scopedSheets[ i ].getAttribute( 'scoped' ) )
+ tempSheets.push( scopedSheets[ i ] )
+ }
+ scopedSheets = tempSheets
+ }
+
+ i = scopedSheets.length
+ while ( i-- )
+ {
+ scopeIt( scopedSheets[ i ] )
+ }
+
+ // make a function so we can return it to enable the "scoping" of other <styles> which are inserted later on for instance
+ function scopeIt( styleNode, jQueryItem )
+ {
+ // catch the item if were calling this via the $.each
+ if ( jQueryItem )
+ styleNode = jQueryItem
+
+ // check if we received a <style> node
+ // if not chcek if it's a jQuery object and go from there
+ // if no <style> and no jQuery? return to avoid errors
+ if ( !styleNode.nodeName )
+ {
+ if ( !styleNode.jquery )
+ return
+ else
+ return styleNode.each( scopeIt )
+ }
+ if ( 'style' !== styleNode.nodeName.toLowerCase() )
+ return
+
+ // init some vars
+ var sheet = styleNode[ compat.sheet ]
+ , allRules = sheet[ compat.rules ]
+ , par = styleNode.parentNode
+ , id = par.id || ( par.id = 'scopedByScopePolyfill_' + ++idCounter )
+ , glue = ''
+ , rule
+ , index = allRules.length || 0
+ , selector
+ , styleRule
+ ;
+
+
+ // get al the ids from the parents so we are as specific as possible
+ // if no ids are found we always have the id which is placed on the <style>'s parentNode
+ while ( par )
+ {
+ if ( par.id )
+ glue = '#' + par.id + ' ' + glue
+ par = par.parentNode
+ }
+
+ // iterate over the collection from the end back to account for IE's inability to insert a styleRule at a certain point
+ // it can only add them to the end...
+ while( index-- )
+ {
+ rule = allRules[ index ]
+ selector = glue + ' ' + rule.selectorText.split( ',' ).join( ', ' + glue )
+
+ // we can just change the selectorText for this
+ if ( compat.changeSelectorTextAllowed )
+ {
+ rule.selectorText = selector;
+ }
+ else // or we need to remove the rule and add it back in if we cant edit the selectorText
+ {
+ /*
+ * IE only adds the normal rules to the array (no @imports, @page etc)
+ * and also does not have a type attribute so we check if that exists and execute the old IE part if it doesn't
+ * all other browsers have the type attribute to show the type
+ * 1 : normal style rules
+ * 2 : @charset
+ * 3 : @import
+ * 4 : @media
+ * 5 : @font-face
+ * 6 : @page rules
+ *
+ */
+ if ( "undefined" === typeof rule.type || 1 === rule.type )
+ {
+ styleRule = rule.style.cssText
+ sheet.removeRule ? sheet.removeRule( index ) : sheet.deleteRule( index )
+ sheet.addRule ? sheet.addRule( selector, styleRule ) : sheet.insertRule( selector + '{' + styleRule + '}', index )
+
+ }
+ }
+
+ }
+ }
+
+ return scopeIt
+
+} ) ( document );
@@ -0,0 +1,25 @@
+*{
+ background:#bada55;
+ color:#f00;
+ padding:10px;
+}
+.widgetContent,
+.widgetContent *{
+ border: 2px solid #000;
+}
+li{
+ list-style:none;
+}
+ul, ol, p{
+ padding:0;
+ margin:0;
+}
+.widgetContent{
+ width:300px;
+ height:auto;
+ margin:30px;
+ float:left;
+}
+.widgetContent{
+ font-family: comic-sans,Geneva, serif;
+}

0 comments on commit 06ed133

Please sign in to comment.