GLOBAL-ALIGN::center SET-TIMER::5min selector.js改 ---- 下田洋志 aka Piro ---- what is [[#{font-size: 2em;}:selector.js改]]? ---- generates [[EM:XPath expressions]] from [[EM:CSS3 selector]] ---- why I made it? ---- [[Text Shadow|https://piro.sakura.ne.jp/xul/textshadow/]] ---- Firefox add-on to render CSS2 text-shadow ---- ALIGN::left 1. find CSS declaration includes "text-shadow" 2. find element nodes selected by the selector of the declaration 3. render text shadow for them ---- methods to [[EM:find]] DOM nodes ---- 1 [[#{font-size: 2em;}:DOM Core]] ---- [[EM:easy]] ---- but ---- less functions ---- [[PRE: var node = document.getElementById('menupopup'); var nodes = node.childNodes; Array.prototype.slice.apply(nodes).forEach(function (aNode) { aNode.removeAttribute('hidden'); }) var count = 0; var lastShownSep; Array.prototype.slice.apply(nodes).forEach(function (aNode) { switch (aNode.localName) { case 'menuseparator': if (!count) { aNode.setAttribute('hidden', true); } else { aNode.removeAttribute('hidden'); lastShownSep = aNode; } count = 0; break; case 'menu': case 'menuitem': if (!aNode.hasAttribute('hidden')) count++; break; }) if (lastShownSep && !count) lastShownSep.setAttribute('hidden', true); ]] ---- logics of [[#{font-size: 2em;}:"finding nodes"]] and [[#{font-size: 2em;}:"processing nodes"]] are [[EM:mixed]] ---- too [[EM:dirty]] ---- 2 [[#{font-size: 2em;}:XPath]] (with DOM3 XPath) ---- [[EM:powerful]] ---- but ---- difficult ---- [[PRE: descendant::xul:menuseparator[ not(following-sibling::*[not(@hidden)]) or not(preceding-sibling::*[not(@hidden)]) or local-name(following-sibling::*[not(@hidden)]) = "menuseparator"] ]] (from [[Multiple Tab Handler|https://piro.sakura.ne.jp/xul/multipletab/]]) ---- 3 [[#{font-size: 2em;}:CSS selector]] ---- [[EM:powerful]] and [[EM:easy]] ---- [[PRE: tabbrowser[position="left"][inverted="true"] arrowscrollbox > scrollbox ]] [[PRE: tabbrowser:not([mode="vertical"]) tab:not([nest="0"]) + tab[nest="0"] ]] (from [[Tree Style Tab|https://piro.sakura.ne.jp/xul/treestyletab/]]) ---- fatal problem ---- there is [[EM:no way]] to [[EM:find DOM nodes]] by [[EM:CSS selector]] ---- >< ---- some libraries ---- can generate XPath expression from CSS selector ---- problem ---- [[EM:unperfect]] ---- some selectors are not supported ---- NO!! ---- Hey, you should use jQuery! ---- NO!! ---- Why? ---- I'm a [[EM:W3C fool]] ---- specifications are [[EM:justice!!!]] ---- I want [[EM:perfect library]] of "CSS => XPath"!! ---- Why don't you [[EM:create]] it? ---- I've done it. ---- selector.js[[EM:改]] ---- based on [[#{font-size: 2em;}:selector.js]] made by "Nyarla," ---- google [["selector.js改"|http://www.google.co.jp/search?hl=ja&client=firefox&rls=org.mozilla%3Aja%3Aofficial&hs=PN9&q=selector.js%E6%94%B9&btnG=%E6%A4%9C%E7%B4%A2&lr=lang_ja]] ---- supports most CSS2 and CSS3 selectors ---- ALIGN::left CSS2 |*|E |E F|E > F |E + F|E[foo] |E[foo="warning"]|E[foo~="warning"] |E[lang|="en"]|E.myClass |E#myID|E:first-child |E:first-line|E:first-letter |E:link| ---- ALIGN::left CSS3 (draft) |E[foo^="bar"]|E[foo$="bar"]|E[foo*="bar"] |E:root|E:nth-child(n)|E:nth-last-child(n) |E:nth-of-type(n)|E:nth-last-of-type(n)|E:last-child |E:first-of-type|E:last-of-type|E:only-child |E:only-of-type|E:empty|E:target |E:enabled|E:disabled|E:contains("foo") |E::first-line|E::first-letter|E:not(s) |E ~ F|namespaceprefix|E ---- ALIGN::left supports only in chrome window |E:visited|E:active |E:hover|E:focus ---- ALIGN::left dropped... |E:before|E:after |E::before|E::after |E:lang(ja) ---- usage "convertSelectorToXPath" ---- [[PRE: var exp = document.convertSelectorToXPath( 'p > em:first-of-type'); ]] ---- [[PRE: /descendant::*[local-name() = "p" or local-name() = "P"] /*[local-name() = "em" or local-name() = "EM"] [not(preceding-sibling::*[local-name() = "em" or local-name() = "EM"])] [not(following-sibling::*[local-name() = "em" or local-name() = "EM"])] ]] ---- [[PRE: var resolver = { lookupNamespaceURI : function(aPrefix) { switch (aPrefix) { case 'html': return 'http://www.w3.org/1999/xhtml'; } return null; } }; var exp = document.convertSelectorToXPath( 'html|p:nth-child(even), html|li:nth-child(2n+1)', resolver); ]] ---- [[PRE: /descendant::html:p[count(preceding-sibling::*) mod 2 = 1] | /descendant::html:li[(count(preceding-sibling::*) + 1) mod 2 = 1] ]] ---- usage "getElementsBySelector" ---- [[PRE: var nodes = document.getElementsBySelector( 'p > em:first-of-type'); nodes.forEach(function(aNode) { aNode.style.border = 'red solid 1px'; }); ]] ---- [[PRE: var resolver = { lookupNamespaceURI : function(aPrefix) { switch (aPrefix) { case 'html': return 'http://www.w3.org/1999/xhtml'; } return null; } }; var nodes = document.getElementsBySelector( 'html|p:nth-child(even), html|li:nth-child(2n+1)', resolver); nodes.forEach(function(aNode) { aNode.style.background = 'blue'; }); ]] ---- problem 1 ---- not optimized yet (possibly heavy) ---- my policy ---- assurance >>> speed ---- problem 2 ---- works only on Firefox ---- >< ---- conclusion ---- Let's learn [[EM:XPath]] and write [[EM:XPath expressions]] directly!! ---- end