Advertisement
lores

bordasArredondadas DD_roundies_0.0.2a.js

Aug 9th, 2011
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var DD_roundies = {
  2.  
  3.     ns: 'DD_roundies',
  4.    
  5.     IE6: false,
  6.     IE7: false,
  7.     IE8: false,
  8.     IEversion: function() {
  9.         if (document.documentMode != 8 && document.namespaces && !document.namespaces[this.ns]) {
  10.             this.IE6 = true;
  11.             this.IE7 = true;
  12.         }
  13.         else if (document.documentMode == 8) {
  14.             this.IE8 = true;
  15.         }
  16.     },
  17.     querySelector: document.querySelectorAll,
  18.     selectorsToProcess: [],
  19.     imgSize: {},
  20.    
  21.     createVmlNameSpace: function() { /* enable VML */
  22.         if (this.IE6 || this.IE7) {
  23.             document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml');
  24.         }
  25.         if (this.IE8) {
  26.             document.writeln('<?import namespace="' + this.ns + '" implementation="#default#VML" ?>');
  27.         }
  28.     },
  29.    
  30.     createVmlStyleSheet: function() { /* style VML, enable behaviors */
  31.         /*
  32.             Just in case lots of other developers have added
  33.             lots of other stylesheets using document.createStyleSheet
  34.             and hit the 31-limit mark, let's not use that method!
  35.             further reading: http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx
  36.         */
  37.         var style = document.createElement('style');
  38.         document.documentElement.firstChild.insertBefore(style, document.documentElement.firstChild.firstChild);
  39.         if (style.styleSheet) { /* IE */
  40.             try {
  41.                 var styleSheet = style.styleSheet;
  42.                 styleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}');
  43.                 this.styleSheet = styleSheet;
  44.             } catch(err) {}
  45.         }
  46.         else {
  47.             this.styleSheet = style;
  48.         }
  49.     },
  50.    
  51.     /**
  52.     * Method to use from afar - refer to it whenever.
  53.     * Example for IE only: DD_roundies.addRule('div.boxy_box', '10px 5px');
  54.     * Example for IE, Firefox, and WebKit: DD_roundies.addRule('div.boxy_box', '10px 5px', true);
  55.     * @param {String} selector - REQUIRED - a CSS selector, such as '#doc .container'
  56.     * @param {Integer} radius - REQUIRED - the desired radius for the box corners
  57.     * @param {Boolean} standards - OPTIONAL - true if you also wish to output -moz-border-radius/-webkit-border-radius/border-radius declarations
  58.     **/
  59.     addRule: function(selector, rad, standards) {
  60.         if (typeof rad == 'undefined' || rad === null) {
  61.             rad = 0;
  62.         }
  63.         if (rad.constructor.toString().search('Array') == -1) {
  64.             rad = rad.toString().replace(/[^0-9 ]/g, '').split(' ');
  65.         }
  66.         for (var i=0; i<4; i++) {
  67.             rad[i] = (!rad[i] && rad[i] !== 0) ? rad[Math.max((i-2), 0)] : rad[i];
  68.         }
  69.         if (this.styleSheet) {
  70.             if (this.styleSheet.addRule) { /* IE */
  71.                 var selectors = selector.split(','); /* multiple selectors supported, no need for multiple calls to this anymore */
  72.                 for (var i=0; i<selectors.length; i++) {
  73.                     this.styleSheet.addRule(selectors[i], 'behavior:expression(DD_roundies.roundify.call(this, [' + rad.join(',') + ']))'); /* seems to execute the function without adding it to the stylesheet - interesting... */
  74.                 }
  75.             }
  76.             else if (standards) {
  77.                 var moz_implementation = rad.join('px ') + 'px';
  78.                 this.styleSheet.appendChild(document.createTextNode(selector + ' {border-radius:' + moz_implementation + '; -moz-border-radius:' + moz_implementation + ';}'));
  79.                 this.styleSheet.appendChild(document.createTextNode(selector + ' {-webkit-border-top-left-radius:' + rad[0] + 'px ' + rad[0] + 'px; -webkit-border-top-right-radius:' + rad[1] + 'px ' + rad[1] + 'px; -webkit-border-bottom-right-radius:' + rad[2] + 'px ' + rad[2] + 'px; -webkit-border-bottom-left-radius:' + rad[3] + 'px ' + rad[3] + 'px;}'));
  80.             }
  81.         }
  82.         else if (this.IE8) {
  83.             this.selectorsToProcess.push({'selector':selector, 'radii':rad});
  84.         }
  85.     },
  86.    
  87.     readPropertyChanges: function(el) {
  88.         switch (event.propertyName) {
  89.             case 'style.border':
  90.             case 'style.borderWidth':
  91.             case 'style.padding':
  92.                 this.applyVML(el);
  93.                 break;
  94.             case 'style.borderColor':
  95.                 this.vmlStrokeColor(el);
  96.                 break;
  97.             case 'style.backgroundColor':
  98.             case 'style.backgroundPosition':
  99.             case 'style.backgroundRepeat':
  100.                 this.applyVML(el);
  101.                 break;
  102.             case 'style.display':
  103.                 el.vmlBox.style.display = (el.style.display == 'none') ? 'none' : 'block';
  104.                 break;
  105.             case 'style.filter':
  106.                 this.vmlOpacity(el);
  107.                 break;
  108.             case 'style.zIndex':
  109.                 el.vmlBox.style.zIndex = el.style.zIndex;
  110.                 break;
  111.         }
  112.     },
  113.    
  114.     applyVML: function(el) {
  115.         el.runtimeStyle.cssText = '';
  116.         this.vmlFill(el);
  117.         this.vmlStrokeColor(el);
  118.         this.vmlStrokeWeight(el);
  119.         this.vmlOffsets(el);
  120.         this.vmlPath(el);
  121.         this.nixBorder(el);
  122.         this.vmlOpacity(el);
  123.     },
  124.    
  125.     vmlOpacity: function(el) {
  126.         if (el.currentStyle.filter.search('lpha') != -1) {
  127.             var trans = el.currentStyle.filter;
  128.             trans = parseInt(trans.substring(trans.lastIndexOf('=')+1, trans.lastIndexOf(')')), 10)/100;
  129.             for (var v in el.vml) {
  130.                 el.vml[v].filler.opacity = trans;
  131.             }
  132.         }
  133.     },
  134.    
  135.     vmlFill: function(el) {
  136.         if (!el.currentStyle) {
  137.             return;
  138.         } else {
  139.             var elStyle = el.currentStyle;
  140.         }
  141.         el.runtimeStyle.backgroundColor = '';
  142.         el.runtimeStyle.backgroundImage = '';
  143.         var noColor = (elStyle.backgroundColor == 'transparent');
  144.         var noImg = true;
  145.         if (elStyle.backgroundImage != 'none' || el.isImg) {
  146.             if (!el.isImg) {
  147.                 el.vmlBg = elStyle.backgroundImage;
  148.                 el.vmlBg = el.vmlBg.substr(5, el.vmlBg.lastIndexOf('")')-5);
  149.             }
  150.             else {
  151.                 el.vmlBg = el.src;
  152.             }
  153.             var lib = this;
  154.             if (!lib.imgSize[el.vmlBg]) { /* determine size of loaded image */
  155.                 var img = document.createElement('img');
  156.                 img.attachEvent('onload', function() {
  157.                     this.width = this.offsetWidth; /* weird cache-busting requirement! */
  158.                     this.height = this.offsetHeight;
  159.                     lib.vmlOffsets(el);
  160.                 });
  161.                 img.className = lib.ns + '_sizeFinder';
  162.                 img.runtimeStyle.cssText = 'behavior:none; position:absolute; top:-10000px; left:-10000px; border:none;'; /* make sure to set behavior to none to prevent accidental matching of the helper elements! */
  163.                 img.src = el.vmlBg;
  164.                 img.removeAttribute('width');
  165.                 img.removeAttribute('height');
  166.                 document.body.insertBefore(img, document.body.firstChild);
  167.                 lib.imgSize[el.vmlBg] = img;
  168.             }
  169.             el.vml.image.filler.src = el.vmlBg;
  170.             noImg = false;
  171.         }
  172.         el.vml.image.filled = !noImg;
  173.         el.vml.image.fillcolor = 'none';
  174.         el.vml.color.filled = !noColor;
  175.         el.vml.color.fillcolor = elStyle.backgroundColor;
  176.         el.runtimeStyle.backgroundImage = 'none';
  177.         el.runtimeStyle.backgroundColor = 'transparent';
  178.     },
  179.    
  180.     vmlStrokeColor: function(el) {
  181.         el.vml.stroke.fillcolor = el.currentStyle.borderColor;
  182.     },
  183.    
  184.     vmlStrokeWeight: function(el) {
  185.         var borders = ['Top', 'Right', 'Bottom', 'Left'];
  186.         el.bW = {};
  187.         for (var b=0; b<4; b++) {
  188.             el.bW[borders[b]] = parseInt(el.currentStyle['border' + borders[b] + 'Width'], 10) || 0;
  189.         }
  190.     },
  191.    
  192.     vmlOffsets: function(el) {
  193.         var dims = ['Left', 'Top', 'Width', 'Height'];
  194.         for (var d=0; d<4; d++) {
  195.             el.dim[dims[d]] = el['offset'+dims[d]];
  196.         }
  197.         var assign = function(obj, topLeft) {
  198.             obj.style.left = (topLeft ? 0 : el.dim.Left) + 'px';
  199.             obj.style.top = (topLeft ? 0 : el.dim.Top) + 'px';
  200.             obj.style.width = el.dim.Width + 'px';
  201.             obj.style.height = el.dim.Height + 'px';
  202.         };
  203.         for (var v in el.vml) {
  204.             var mult = (v == 'image') ? 1 : 2;
  205.             el.vml[v].coordsize = (el.dim.Width*mult) + ', ' + (el.dim.Height*mult);
  206.             assign(el.vml[v], true);
  207.         }
  208.         assign(el.vmlBox, false);
  209.        
  210.         if (DD_roundies.IE8) {
  211.             el.vml.stroke.style.margin = '-1px';
  212.             if (typeof el.bW == 'undefined') {
  213.                 this.vmlStrokeWeight(el);
  214.             }
  215.             el.vml.color.style.margin = (el.bW.Top-1) + 'px ' + (el.bW.Left-1) + 'px';
  216.         }
  217.     },
  218.    
  219.     vmlPath: function(el) {
  220.         var coords = function(direction, w, h, r, aL, aT, mult) {
  221.             var cmd = direction ? ['m', 'qy', 'l', 'qx', 'l', 'qy', 'l', 'qx', 'l'] : ['qx', 'l', 'qy', 'l', 'qx', 'l', 'qy', 'l', 'm']; /* whoa */
  222.             aL *= mult;
  223.             aT *= mult;
  224.             w *= mult;
  225.             h *= mult;
  226.             var R = r.slice(); /* do not affect original array */
  227.             for (var i=0; i<4; i++) {
  228.                 R[i] *= mult;
  229.                 R[i] = Math.min(w/2, h/2, R[i]); /* make sure you do not get funky shapes - pick the smallest: half of the width, half of the height, or current value */
  230.             }
  231.             var coords = [
  232.                 cmd[0] + Math.floor(0+aL) +','+ Math.floor(R[0]+aT),
  233.                 cmd[1] + Math.floor(R[0]+aL) +','+ Math.floor(0+aT),
  234.                 cmd[2] + Math.ceil(w-R[1]+aL) +','+ Math.floor(0+aT),
  235.                 cmd[3] + Math.ceil(w+aL) +','+ Math.floor(R[1]+aT),
  236.                 cmd[4] + Math.ceil(w+aL) +','+ Math.ceil(h-R[2]+aT),
  237.                 cmd[5] + Math.ceil(w-R[2]+aL) +','+ Math.ceil(h+aT),
  238.                 cmd[6] + Math.floor(R[3]+aL) +','+ Math.ceil(h+aT),
  239.                 cmd[7] + Math.floor(0+aL) +','+ Math.ceil(h-R[3]+aT),
  240.                 cmd[8] + Math.floor(0+aL) +','+ Math.floor(R[0]+aT)
  241.             ];
  242.             if (!direction) {
  243.                 coords.reverse();
  244.             }
  245.             var path = coords.join('');
  246.             return path;
  247.         };
  248.    
  249.         if (typeof el.bW == 'undefined') {
  250.             this.vmlStrokeWeight(el);
  251.         }
  252.         var bW = el.bW;
  253.         var rad = el.DD_radii.slice();
  254.        
  255.         /* determine outer curves */
  256.         var outer = coords(true, el.dim.Width, el.dim.Height, rad, 0, 0, 2);
  257.        
  258.         /* determine inner curves */
  259.         rad[0] -= Math.max(bW.Left, bW.Top);
  260.         rad[1] -= Math.max(bW.Top, bW.Right);
  261.         rad[2] -= Math.max(bW.Right, bW.Bottom);
  262.         rad[3] -= Math.max(bW.Bottom, bW.Left);
  263.         for (var i=0; i<4; i++) {
  264.             rad[i] = Math.max(rad[i], 0);
  265.         }
  266.         var inner = coords(false, el.dim.Width-bW.Left-bW.Right, el.dim.Height-bW.Top-bW.Bottom, rad, bW.Left, bW.Top, 2);
  267.         var image = coords(true, el.dim.Width-bW.Left-bW.Right+1, el.dim.Height-bW.Top-bW.Bottom+1, rad, bW.Left, bW.Top, 1);
  268.        
  269.         /* apply huge path string */
  270.         el.vml.color.path = inner;
  271.         el.vml.image.path = image;
  272.         el.vml.stroke.path = outer + inner;
  273.        
  274.         this.clipImage(el);
  275.     },
  276.    
  277.     nixBorder: function(el) {
  278.         var s = el.currentStyle;
  279.         var sides = ['Top', 'Left', 'Right', 'Bottom'];
  280.         for (var i=0; i<4; i++) {
  281.             el.runtimeStyle['padding' + sides[i]] = (parseInt(s['padding' + sides[i]], 10) || 0) + (parseInt(s['border' + sides[i] + 'Width'], 10) || 0) + 'px';
  282.         }
  283.         el.runtimeStyle.border = 'none';
  284.     },
  285.    
  286.     clipImage: function(el) {
  287.         var lib = DD_roundies;
  288.         if (!el.vmlBg || !lib.imgSize[el.vmlBg]) {
  289.             return;
  290.         }
  291.         var thisStyle = el.currentStyle;
  292.         var bg = {'X':0, 'Y':0};
  293.         var figurePercentage = function(axis, position) {
  294.             var fraction = true;
  295.             switch(position) {
  296.                 case 'left':
  297.                 case 'top':
  298.                     bg[axis] = 0;
  299.                     break;
  300.                 case 'center':
  301.                     bg[axis] = 0.5;
  302.                     break;
  303.                 case 'right':
  304.                 case 'bottom':
  305.                     bg[axis] = 1;
  306.                     break;
  307.                 default:
  308.                     if (position.search('%') != -1) {
  309.                         bg[axis] = parseInt(position, 10) * 0.01;
  310.                     }
  311.                     else {
  312.                         fraction = false;
  313.                     }
  314.             }
  315.             var horz = (axis == 'X');
  316.             bg[axis] = Math.ceil(fraction ? (( el.dim[horz ? 'Width' : 'Height'] - (el.bW[horz ? 'Left' : 'Top'] + el.bW[horz ? 'Right' : 'Bottom']) ) * bg[axis]) - (lib.imgSize[el.vmlBg][horz ? 'width' : 'height'] * bg[axis]) : parseInt(position, 10));
  317.             bg[axis] += 1;
  318.         };
  319.         for (var b in bg) {
  320.             figurePercentage(b, thisStyle['backgroundPosition'+b]);
  321.         }
  322.         el.vml.image.filler.position = (bg.X/(el.dim.Width-el.bW.Left-el.bW.Right+1)) + ',' + (bg.Y/(el.dim.Height-el.bW.Top-el.bW.Bottom+1));
  323.         var bgR = thisStyle.backgroundRepeat;
  324.         var c = {'T':1, 'R':el.dim.Width+1, 'B':el.dim.Height+1, 'L':1}; /* these are defaults for repeat of any kind */
  325.         var altC = { 'X': {'b1': 'L', 'b2': 'R', 'd': 'Width'}, 'Y': {'b1': 'T', 'b2': 'B', 'd': 'Height'} };
  326.         if (bgR != 'repeat') {
  327.             c = {'T':(bg.Y), 'R':(bg.X+lib.imgSize[el.vmlBg].width), 'B':(bg.Y+lib.imgSize[el.vmlBg].height), 'L':(bg.X)}; /* these are defaults for no-repeat - clips down to the image location */
  328.             if (bgR.search('repeat-') != -1) { /* now let's revert to dC for repeat-x or repeat-y */
  329.                 var v = bgR.split('repeat-')[1].toUpperCase();
  330.                 c[altC[v].b1] = 1;
  331.                 c[altC[v].b2] = el.dim[altC[v].d]+1;
  332.             }
  333.             if (c.B > el.dim.Height) {
  334.                 c.B = el.dim.Height+1;
  335.             }
  336.         }
  337.         el.vml.image.style.clip = 'rect('+c.T+'px '+c.R+'px '+c.B+'px '+c.L+'px)';
  338.     },
  339.    
  340.     pseudoClass: function(el) {
  341.         var self = this;
  342.         setTimeout(function() { /* would not work as intended without setTimeout */
  343.             self.applyVML(el);
  344.         }, 1);
  345.     },
  346.    
  347.     reposition: function(el) {
  348.         this.vmlOffsets(el);
  349.         this.vmlPath(el);
  350.     },
  351.    
  352.     roundify: function(rad) {
  353.         this.style.behavior = 'none';
  354.         if (!this.currentStyle) {
  355.             return;
  356.         }
  357.         else {
  358.             var thisStyle = this.currentStyle;
  359.         }
  360.         var allowed = {BODY: false, TABLE: false, TR: false, TD: false, SELECT: false, OPTION: false, TEXTAREA: false};
  361.         if (allowed[this.nodeName] === false) { /* elements not supported yet */
  362.             return;
  363.         }
  364.         var self = this; /* who knows when you might need a setTimeout */
  365.         var lib = DD_roundies;
  366.         this.DD_radii = rad;
  367.         this.dim = {};
  368.  
  369.         /* attach handlers */
  370.         var handlers = {resize: 'reposition', move: 'reposition'};
  371.         if (this.nodeName == 'A') {
  372.             var moreForAs = {mouseleave: 'pseudoClass', mouseenter: 'pseudoClass', focus: 'pseudoClass', blur: 'pseudoClass'};
  373.             for (var a in moreForAs) {
  374.                 handlers[a] = moreForAs[a];
  375.             }
  376.         }
  377.         for (var h in handlers) {
  378.             this.attachEvent('on' + h, function() {
  379.                 lib[handlers[h]](self);
  380.             });
  381.         }
  382.         this.attachEvent('onpropertychange', function() {
  383.             lib.readPropertyChanges(self);
  384.         });
  385.        
  386.         /* ensure that this elent and its parent is given hasLayout (needed for accurate positioning) */
  387.         var giveLayout = function(el) {
  388.             el.style.zoom = 1;
  389.             if (el.currentStyle.position == 'static') {
  390.                 el.style.position = 'relative';
  391.             }
  392.         };
  393.         giveLayout(this.offsetParent);
  394.         giveLayout(this);
  395.        
  396.         /* create vml elements */
  397.         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 */
  398.         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! */
  399.         this.vmlBox.style.zIndex = thisStyle.zIndex;
  400.         this.vml = {'color':true, 'image':true, 'stroke':true};
  401.         for (var v in this.vml) {
  402.             this.vml[v] = document.createElement(lib.ns + ':shape');
  403.             this.vml[v].filler = document.createElement(lib.ns + ':fill');
  404.             this.vml[v].appendChild(this.vml[v].filler);
  405.             this.vml[v].stroked = false;
  406.             this.vml[v].style.position = 'absolute';
  407.             this.vml[v].style.zIndex = thisStyle.zIndex;
  408.             this.vml[v].coordorigin = '1,1';
  409.             this.vmlBox.appendChild(this.vml[v]);
  410.         }
  411.         this.vml.image.fillcolor = 'none';
  412.         this.vml.image.filler.type = 'tile';
  413.         this.parentNode.insertBefore(this.vmlBox, this);
  414.        
  415.         this.isImg = false;
  416.         if (this.nodeName == 'IMG') {
  417.             this.isImg = true;
  418.             this.style.visibility = 'hidden';
  419.         }
  420.        
  421.         setTimeout(function() {
  422.             lib.applyVML(self);
  423.         }, 1);
  424.     }
  425.    
  426. };
  427.  
  428. try {
  429.     document.execCommand("BackgroundImageCache", false, true);
  430. } catch(err) {}
  431. DD_roundies.IEversion();
  432. DD_roundies.createVmlNameSpace();
  433. DD_roundies.createVmlStyleSheet();
  434.  
  435. if (DD_roundies.IE8 && document.attachEvent && DD_roundies.querySelector) {
  436.     document.attachEvent('onreadystatechange', function() {
  437.         if (document.readyState == 'complete') {
  438.             var selectors = DD_roundies.selectorsToProcess;
  439.             var length = selectors.length;
  440.             var delayedCall = function(node, radii, index) {
  441.                 setTimeout(function() {
  442.                     DD_roundies.roundify.call(node, radii);
  443.                 }, index*100);
  444.             };
  445.             for (var i=0; i<length; i++) {
  446.                 var results = document.querySelectorAll(selectors[i].selector);
  447.                 var rLength = results.length;
  448.                 for (var r=0; r<rLength; r++) {
  449.                     if (results[r].nodeName != 'INPUT') { /* IE8 doesn't like to do this to inputs yet */
  450.                         delayedCall(results[r], selectors[i].radii, r);
  451.                     }
  452.                 }
  453.             }
  454.         }
  455.     });
  456. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement