/** * DD_roundies, this adds rounded-corner CSS in standard browsers and VML sublayers in IE that accomplish a similar appearance when comparing said browsers. * Author: Drew Diller * Email: drew.diller@gmail.com * URL: http://www.dillerdesign.com/experiment/DD_roundies/ * Version: 0.0.2a * Licensed under the MIT License: http://dillerdesign.com/experiment/DD_roundies/#license * * Usage: * DD_roundies.addRule('#doc .container', '10px 5px'); // selector and multiple radii * DD_roundies.addRule('.box', 5, true); // selector, radius, and optional addition of border-radius code for standard browsers. * * Just want the PNG fixing effect for IE6, and don't want to also use the DD_belatedPNG library? Don't give any additional arguments after the CSS selector. * DD_roundies.addRule('.your .example img'); **/ var DD_roundies = { ns: 'DD_roundies', IE6: false, IE7: false, IE8: false, IEversion: function() { if (document.documentMode != 8 && document.namespaces && !document.namespaces[this.ns]) { this.IE6 = true; this.IE7 = true; } else if (document.documentMode == 8) { this.IE8 = true; } }, querySelector: document.querySelectorAll, selectorsToProcess: [], imgSize: {}, createVmlNameSpace: function() { /* enable VML */ if (this.IE6 || this.IE7) { document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml'); } if (this.IE8) { document.writeln(''); } }, createVmlStyleSheet: function() { /* style VML, enable behaviors */ /* Just in case lots of other developers have added lots of other stylesheets using document.createStyleSheet and hit the 31-limit mark, let's not use that method! further reading: http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx */ var style = document.createElement('style'); document.documentElement.firstChild.insertBefore(style, document.documentElement.firstChild.firstChild); if (style.styleSheet) { /* IE */ try { var styleSheet = style.styleSheet; styleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}'); this.styleSheet = styleSheet; } catch(err) {} } else { this.styleSheet = style; } }, /** * Method to use from afar - refer to it whenever. * Example for IE only: DD_roundies.addRule('div.boxy_box', '10px 5px'); * Example for IE, Firefox, and WebKit: DD_roundies.addRule('div.boxy_box', '10px 5px', true); * @param {String} selector - REQUIRED - a CSS selector, such as '#doc .container' * @param {Integer} radius - REQUIRED - the desired radius for the box corners * @param {Boolean} standards - OPTIONAL - true if you also wish to output -moz-border-radius/-webkit-border-radius/border-radius declarations **/ addRule: function(selector, rad, standards) { if (typeof rad == 'undefined' || rad === null) { rad = 0; } if (rad.constructor.toString().search('Array') == -1) { rad = rad.toString().replace(/[^0-9 ]/g, '').split(' '); } for (var i=0; i<4; i++) { rad[i] = (!rad[i] && rad[i] !== 0) ? rad[Math.max((i-2), 0)] : rad[i]; } if (this.styleSheet) { if (this.styleSheet.addRule) { /* IE */ var selectors = selector.split(','); /* multiple selectors supported, no need for multiple calls to this anymore */ for (var i=0; i el.dim.Height) { c.B = el.dim.Height+1; } } el.vml.image.style.clip = 'rect('+c.T+'px '+c.R+'px '+c.B+'px '+c.L+'px)'; }, pseudoClass: function(el) { var self = this; setTimeout(function() { /* would not work as intended without setTimeout */ self.applyVML(el); }, 1); }, reposition: function(el) { this.vmlOffsets(el); this.vmlPath(el); }, roundify: function(rad) { this.style.behavior = 'none'; if (!this.currentStyle) { return; } else { var thisStyle = this.currentStyle; } var allowed = {BODY: false, TABLE: false, TR: false, TD: false, SELECT: false, OPTION: false, TEXTAREA: false}; if (allowed[this.nodeName] === false) { /* elements not supported yet */ return; } var self = this; /* who knows when you might need a setTimeout */ var lib = DD_roundies; this.DD_radii = rad; this.dim = {}; /* attach handlers */ var handlers = {resize: 'reposition', move: 'reposition'}; if (this.nodeName == 'A') { var moreForAs = {mouseleave: 'pseudoClass', mouseenter: 'pseudoClass', focus: 'pseudoClass', blur: 'pseudoClass'}; for (var a in moreForAs) { handlers[a] = moreForAs[a]; } } for (var h in handlers) { this.attachEvent('on' + h, function() { lib[handlers[h]](self); }); } this.attachEvent('onpropertychange', function() { lib.readPropertyChanges(self); }); /* ensure that this elent and its parent is given hasLayout (needed for accurate positioning) */ var giveLayout = function(el) { el.style.zoom = 1; if (el.currentStyle.position == 'static') { el.style.position = 'relative'; } }; giveLayout(this.offsetParent); giveLayout(this); /* create vml elements */ this.vmlBox = document.createElement('ignore'); /* IE8 really wants to be encased in a wrapper element for the VML to work, and I don't want to disturb getElementsByTagName('div') - open to suggestion on how to do this differently */ this.vmlBox.runtimeStyle.cssText = 'behavior:none; position:absolute; margin:0; padding:0; border:0; background:none;'; /* super important - if something accidentally matches this (you yourseld did this once, Drew), you'll get infinitely-created elements and a frozen browser! */ this.vmlBox.style.zIndex = thisStyle.zIndex; this.vml = {'color':true, 'image':true, 'stroke':true}; for (var v in this.vml) { this.vml[v] = document.createElement(lib.ns + ':shape'); this.vml[v].filler = document.createElement(lib.ns + ':fill'); this.vml[v].appendChild(this.vml[v].filler); this.vml[v].stroked = false; this.vml[v].style.position = 'absolute'; this.vml[v].style.zIndex = thisStyle.zIndex; this.vml[v].coordorigin = '1,1'; this.vmlBox.appendChild(this.vml[v]); } this.vml.image.fillcolor = 'none'; this.vml.image.filler.type = 'tile'; this.parentNode.insertBefore(this.vmlBox, this); this.isImg = false; if (this.nodeName == 'IMG') { this.isImg = true; this.style.visibility = 'hidden'; } setTimeout(function() { lib.applyVML(self); }, 1); } }; try { document.execCommand("BackgroundImageCache", false, true); } catch(err) {} DD_roundies.IEversion(); DD_roundies.createVmlNameSpace(); DD_roundies.createVmlStyleSheet(); if (DD_roundies.IE8 && document.attachEvent && DD_roundies.querySelector) { document.attachEvent('onreadystatechange', function() { if (document.readyState == 'complete') { var selectors = DD_roundies.selectorsToProcess; var length = selectors.length; var delayedCall = function(node, radii, index) { setTimeout(function() { DD_roundies.roundify.call(node, radii); }, index*100); }; for (var i=0; i