diff options
Diffstat (limited to 'skins/vector/csshover.htc')
-rw-r--r-- | skins/vector/csshover.htc | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/skins/vector/csshover.htc b/skins/vector/csshover.htc deleted file mode 100644 index a13ea68..0000000 --- a/skins/vector/csshover.htc +++ /dev/null @@ -1,284 +0,0 @@ -<public:attach event="ondocumentready" onevent="CSSHover()" /> -<script> -/** - * Whatever:hover - V3.11 - * ------------------------------------------------------------ - * Author - Peter Nederlof, http://www.xs4all.nl/~peterned - * License - http://creativecommons.org/licenses/LGPL/2.1 - * - * Special thanks to Sergiu Dumitriu, http://purl.org/net/sergiu, - * for fixing the expression loop. - * - * Whatever:hover is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * Whatever:hover is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * howto: body { behavior:url("csshover3.htc"); } - * ------------------------------------------------------------ - */ - -window.CSSHover = (function(){ - - // regular expressions, used and explained later on. - var REG_INTERACTIVE = /(^|\s)((([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active|focus))/i; - var REG_AFFECTED = /(.*?)\:(hover|active|focus)/i; - var REG_PSEUDO = /[^:]+:([a-z\-]+).*/i; - var REG_SELECT = /(\.([a-z0-9_\-]+):[a-z]+)|(:[a-z]+)/gi; - var REG_CLASS = /\.([a-z0-9_\-]*on(hover|active|focus))/i; - var REG_MSIE = /msie (5|6|7)/i; - var REG_COMPAT = /backcompat/i; - - // property mapping, real css properties must be used in order to clear expressions later on... - // Uses obscure css properties that no-one is likely to use. The properties are borrowed to - // set an expression, and are then restored to the most likely correct value. - var Properties = { - index: 0, - list: ['text-kashida', 'text-kashida-space', 'text-justify'], - get: function() { - return this.list[(this.index++)%this.list.length]; - } - }; - - // camelize is used to convert css properties from (eg) text-kashida to textKashida - var camelize = function(str) { - return str.replace(/-(.)/mg, function(result, match){ - return match.toUpperCase(); - }); - }; - - /** - * Local CSSHover object - * -------------------------- - */ - - var CSSHover = { - - // array of CSSHoverElements, used to unload created events - elements: [], - - // buffer used for checking on duplicate expressions - callbacks: {}, - - // init, called once ondomcontentready via the exposed window.CSSHover function - init:function() { - // don't run in IE8 standards; expressions don't work in standards mode anyway, - // and the stuff we're trying to fix should already work properly - if(!REG_MSIE.test(navigator.userAgent) && !REG_COMPAT.test(window.document.compatMode)) { - return; - } - - // start parsing the existing stylesheets - var sheets = window.document.styleSheets, l = sheets.length; - for(var i=0; i<l; i++) { - this.parseStylesheet(sheets[i]); - } - }, - - // called from init, parses individual stylesheets - parseStylesheet:function(sheet) { - // check sheet imports and parse those recursively - if(sheet.imports) { - try { - var imports = sheet.imports; - var l = imports.length; - for(var i=0; i<l; i++) { - this.parseStylesheet(sheet.imports[i]); - } - } catch(securityException){ - // trycatch for various possible errors - } - } - - // interate the sheet's rules and send them to the parser - try { - var rules = sheet.rules; - var r = rules.length; - for(var j=0; j<r; j++) { - this.parseCSSRule(rules[j], sheet); - } - } catch(someException){ - // trycatch for various errors, most likely accessing the sheet's rules. - } - }, - - // magic starts here ... - parseCSSRule:function(rule, sheet) { - - // The sheet is used to insert new rules into, this must be the same sheet the rule - // came from, to ensure that relative paths keep pointing to the right location. - - // only parse a rule if it contains an interactive pseudo. - var select = rule.selectorText; - if(REG_INTERACTIVE.test(select)) { - var style = rule.style.cssText; - - // affected elements are found by truncating the selector after the interactive pseudo, - // eg: "div li:hover" >> "div li" - var affected = REG_AFFECTED.exec(select)[1]; - - // that pseudo is needed for a classname, and defines the type of interaction (focus, hover, active) - // eg: "li:hover" >> "onhover" - var pseudo = select.replace(REG_PSEUDO, 'on$1'); - - // the new selector is going to use that classname in a new css rule, - // since IE6 doesn't support multiple classnames, this is merged into one classname - // eg: "li:hover" >> "li.onhover", "li.folder:hover" >> "li.folderonhover" - var newSelect = select.replace(REG_SELECT, '.$2' + pseudo); - - // the classname is needed for the events that are going to be set on affected nodes - // eg: "li.folder:hover" >> "folderonhover" - var className = REG_CLASS.exec(newSelect)[1]; - - // no need to set the same callback more than once when the same selector uses the same classname - var hash = affected + className; - if(!this.callbacks[hash]) { - - // affected elements are given an expression under a borrowed css property, because fake properties - // can't have their expressions cleared. Different properties are used per pseudo, to avoid - // expressions from overwriting eachother. The expression does a callback to CSSHover.patch, - // rerouted via the exposed window.CSSHover function. - var property = Properties.get(); - var atRuntime = camelize(property); - - // because the expression is added to the stylesheet, and styles are always applied to html that is - // dynamically added to the dom, the expression will also trigger for those new elements (provided - // they are selected by the affected selector). - sheet.addRule(affected, property + ':expression(CSSHover(this, "'+pseudo+'", "'+className+'", "'+atRuntime+'"))'); - - // hash it, so an identical selector/class combo does not duplicate the expression - this.callbacks[hash] = true; - } - - // duplicate expressions need not be set, but the style could differ - sheet.addRule(newSelect, style); - } - }, - - // called via the expression, patches individual nodes - patch:function(node, type, className, property) { - - // restores the borrowed css property to the value of its immediate parent, clearing - // the expression so that it's not repeatedly called. - try { - var value = node.parentNode.currentStyle[property]; - node.style[property] = value; - } catch(e) { - // the above reset should never fail, but just in case, clear the runtimeStyle if it does. - // this will also stop the expression. - node.runtimeStyle[property] = ''; - } - - // just to make sure, also keep track of patched classnames locally on the node - if(!node.csshover) { - node.csshover = []; - } - - // and check for it to prevent duplicate events with the same classname from being set - if(!node.csshover[className]) { - node.csshover[className] = true; - - // create an instance for the given type and class - var element = new CSSHoverElement(node, type, className); - - // and store that instance for unloading later on - this.elements.push(element); - } - - // returns a dummy value to the expression - return type; - }, - - // unload stuff onbeforeunload - unload:function() { - try { - - // remove events - var l = this.elements.length; - for(var i=0; i<l; i++) { - this.elements[i].unload(); - } - - // and set properties to null - this.elements = []; - this.callbacks = {}; - - } catch (e) { - } - } - }; - - /** - * CSSHoverElement - * -------------------------- - */ - - // the event types associated with the interactive pseudos - var CSSEvents = { - onhover: { activator: 'onmouseenter', deactivator: 'onmouseleave' }, - onactive: { activator: 'onmousedown', deactivator: 'onmouseup' }, - onfocus: { activator: 'onfocus', deactivator: 'onblur' } - }; - - // CSSHoverElement constructor, called via CSSHover.patch - function CSSHoverElement(node, type, className) { - - // the CSSHoverElement patches individual nodes by manually applying the events that should - // have fired by the css pseudoclasses, eg mouseenter and mouseleave for :hover. - - this.node = node; - this.type = type; - var replacer = new RegExp('(^|\\s)'+className+'(\\s|$)', 'g'); - - // store event handlers for removal onunload - this.activator = function(){ node.className += ' ' + className; }; - this.deactivator = function(){ node.className = node.className.replace(replacer, ' '); }; - - // add the events - node.attachEvent(CSSEvents[type].activator, this.activator); - node.attachEvent(CSSEvents[type].deactivator, this.deactivator); - } - - CSSHoverElement.prototype = { - // onbeforeunload, called via CSSHover.unload - unload:function() { - - // remove events - this.node.detachEvent(CSSEvents[this.type].activator, this.activator); - this.node.detachEvent(CSSEvents[this.type].deactivator, this.deactivator); - - // and set properties to null - this.activator = null; - this.deactivator = null; - this.node = null; - this.type = null; - } - }; - - // add the unload to the onbeforeunload event - window.attachEvent('onbeforeunload', function(){ - CSSHover.unload(); - }); - - /** - * Public hook - * -------------------------- - */ - - return function(node, type, className, property) { - if(node) { - // called via the css expression; patches individual nodes - return CSSHover.patch(node, type, className, property); - } else { - // called ondomcontentready via the public:attach node - CSSHover.init(); - } - }; - -})(); -</script>
\ No newline at end of file |