From e12e9cb6100ae69ace3647ef87a479c8c60be2bc Mon Sep 17 00:00:00 2001 From: Manolo Carrasco Date: Mon, 19 Jul 2010 10:53:34 +0000 Subject: [PATCH] Re-factor of the Benchmark Example Module, now it is possible to select which bench to run, and much more --- samples/pom.xml | 2 +- .../samples/client/GwtQueryBenchModule.java | 2477 +++++++++++-- .../gwtquery/samples/client/MySelectors.java | 83 +- .../public/DOMAssistantComplete-2.7.js | 1545 -------- .../samples/public/GwtQueryBench.html | 3252 +---------------- .../gwtquery/samples/public/dojobench.html | 3172 ---------------- .../samples/public/html/dojobench.html | 13 + .../public/html/domassistantbench.html | 13 + .../samples/public/html/gwtbench.html | 7 + .../samples/public/html/iframebench.html | 38 + .../samples/public/html/jquerybench.html | 13 + .../samples/public/html/prototypebench.html | 13 + .../samples/public/html/sizzlebench.html | 13 + .../{ => images/bench}/animated-flag.gif | Bin .../bench}/grass-texture-small.jpg | Bin .../{ => images/bench}/grass-texture.jpg | Bin .../public/{ => images/bench}/horse.gif | Bin .../public/{ => images/bench}/horse.png | Bin .../bench/logo-dojo.gif} | Bin .../public/images/bench/logo-domassistant.gif | Bin 0 -> 805 bytes .../bench/logo-gwt.gif} | Bin .../bench/logo-jquery.gif} | Bin .../public/images/bench/logo-prototype.gif | Bin 0 -> 1932 bytes .../public/images/bench/logo-sizzle.gif | Bin 0 -> 1597 bytes .../gwtquery/samples/public/jquerybench.html | 3172 ---------------- .../public/js/DOMAssistantComplete-2.7.js | 1529 ++++++++ .../gwtquery/samples/public/{ => js}/dojo.js | 0 .../samples/public/{ => js}/ext-all.js | 0 .../samples/public/{ => js}/ext-base.js | 0 .../samples/public/{ => js}/ext-core.js | 0 .../samples/public/{ => js}/jquery-1.2.3.js | 0 .../samples/public/{ => js}/jquery-1.3.1.js | 0 .../public/{ => js}/prototype-1.6.0.3.js | 0 .../gwtquery/samples/public/js/selector.js | 414 +++ .../java/gwtquery/samples/public/js/sizzle.js | 1068 ++++++ .../samples/public/prototype_logo.gif | Bin 2659 -> 0 bytes .../samples/public/prototypebench.html | 3172 ---------------- .../gwtquery/samples/public/racetrack.html | 73 - 38 files changed, 5483 insertions(+), 14586 deletions(-) delete mode 100644 samples/src/main/java/gwtquery/samples/public/DOMAssistantComplete-2.7.js delete mode 100644 samples/src/main/java/gwtquery/samples/public/dojobench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/dojobench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/domassistantbench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/gwtbench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/iframebench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/jquerybench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/prototypebench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/html/sizzlebench.html rename samples/src/main/java/gwtquery/samples/public/{ => images/bench}/animated-flag.gif (100%) rename samples/src/main/java/gwtquery/samples/public/{ => images/bench}/grass-texture-small.jpg (100%) rename samples/src/main/java/gwtquery/samples/public/{ => images/bench}/grass-texture.jpg (100%) rename samples/src/main/java/gwtquery/samples/public/{ => images/bench}/horse.gif (100%) rename samples/src/main/java/gwtquery/samples/public/{ => images/bench}/horse.png (100%) rename samples/src/main/java/gwtquery/samples/public/{dojo-logo-text.gif => images/bench/logo-dojo.gif} (100%) create mode 100644 samples/src/main/java/gwtquery/samples/public/images/bench/logo-domassistant.gif rename samples/src/main/java/gwtquery/samples/public/{gwt-logo-cs.gif => images/bench/logo-gwt.gif} (100%) rename samples/src/main/java/gwtquery/samples/public/{logo_jquery.gif => images/bench/logo-jquery.gif} (100%) create mode 100644 samples/src/main/java/gwtquery/samples/public/images/bench/logo-prototype.gif create mode 100644 samples/src/main/java/gwtquery/samples/public/images/bench/logo-sizzle.gif delete mode 100644 samples/src/main/java/gwtquery/samples/public/jquerybench.html create mode 100644 samples/src/main/java/gwtquery/samples/public/js/DOMAssistantComplete-2.7.js rename samples/src/main/java/gwtquery/samples/public/{ => js}/dojo.js (100%) rename samples/src/main/java/gwtquery/samples/public/{ => js}/ext-all.js (100%) rename samples/src/main/java/gwtquery/samples/public/{ => js}/ext-base.js (100%) rename samples/src/main/java/gwtquery/samples/public/{ => js}/ext-core.js (100%) rename samples/src/main/java/gwtquery/samples/public/{ => js}/jquery-1.2.3.js (100%) rename samples/src/main/java/gwtquery/samples/public/{ => js}/jquery-1.3.1.js (100%) rename samples/src/main/java/gwtquery/samples/public/{ => js}/prototype-1.6.0.3.js (100%) create mode 100644 samples/src/main/java/gwtquery/samples/public/js/selector.js create mode 100644 samples/src/main/java/gwtquery/samples/public/js/sizzle.js delete mode 100644 samples/src/main/java/gwtquery/samples/public/prototype_logo.gif delete mode 100644 samples/src/main/java/gwtquery/samples/public/prototypebench.html delete mode 100644 samples/src/main/java/gwtquery/samples/public/racetrack.html diff --git a/samples/pom.xml b/samples/pom.xml index b4f3be73..10590804 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -37,7 +37,7 @@ ${gwt.loglevel} ${gwtversion} - true + false gwtquery.samples.GwtQueryEffects gwtquery.samples.GwtQuerySample diff --git a/samples/src/main/java/gwtquery/samples/client/GwtQueryBenchModule.java b/samples/src/main/java/gwtquery/samples/client/GwtQueryBenchModule.java index c1b76429..64a5910a 100644 --- a/samples/src/main/java/gwtquery/samples/client/GwtQueryBenchModule.java +++ b/samples/src/main/java/gwtquery/samples/client/GwtQueryBenchModule.java @@ -1,285 +1,2336 @@ package gwtquery.samples.client; +import static com.google.gwt.query.client.GQuery.$; +import static com.google.gwt.query.client.GQuery.document; + +import java.util.ArrayList; + import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; -import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.query.client.DeferredGQuery; +import com.google.gwt.query.client.Function; +import com.google.gwt.query.client.GQuery; import com.google.gwt.query.client.SelectorEngine; +import com.google.gwt.query.client.impl.SelectorEngineCssToXPath; +import com.google.gwt.query.client.impl.SelectorEngineImpl; +import com.google.gwt.query.client.impl.SelectorEngineJS; +import com.google.gwt.query.client.impl.SelectorEngineSizzle; +import com.google.gwt.query.client.impl.SelectorEngineSizzleGwt; +import com.google.gwt.query.client.impl.SelectorEngineXPath; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.IncrementalCommand; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.PopupPanel; +import com.google.gwt.user.client.ui.RootPanel; +/** + * Module to test and compare the performance of each Js-Library and + * each Gwt selector implementation. + * + * It is possible to select which benchmarks to run. Be aware that + * not all of them work in all browsers. + * By default selected options are gwt_compiled, gwt_dynamic, jquery and prototype. + * + * It uses iframes to avoid interferences when updating the document. + * By default the iframe is shared for all libraries, but you can use + * a different one for each benchmark appending the parameter share=false. + * + * Parameters available in the url + * share=false Use different iframes for each bench + * min=200 Minimum time running each selector + * track=false Don't draw the horse race + * ask=false Run default benchmarks, don't ask the user. + * + */ public class GwtQueryBenchModule implements EntryPoint { - private StringBuffer log = new StringBuffer(); - - private static final int MIN_TIME = 200; + public interface Benchmark { + String getId(); + int runSelector(DeferredGQuery dq, String selector); + } + + /** + * Benchmark for the default dynamic selector implementation + */ + private class DynamicBenchmark extends GQueryDynamicBenchmark { + private SelectorEngineImpl engine; - private static final String GCOMPILED = "gwt"; + DynamicBenchmark(SelectorEngineImpl engine, String name) { + super(name); + this.engine = engine; + } - private static final String JQUERY = "jquery"; + public int runSelector(DeferredGQuery dq, String selector) { + return engine.select(selector, gwtiframe).getLength(); + } + } - private static final String GDYNAMIC = "dgwt"; + /** + * Benchmark for the compiled selectors + */ + private class GQueryCompiledBenchmark implements Benchmark { + + String id; + + GQueryCompiledBenchmark(String id) { + this.id = id; + } + + public String getId() { + return id; + } - private static final String DOJO = "dojo"; + public int runSelector(DeferredGQuery dq, String selector) { + return dq.array(gwtiframe).getLength(); + } + } - private static final String PROTOTYPE = "prototype"; + /** + * Benchmark for others dynamic selectors + */ + private class GQueryDynamicBenchmark implements Benchmark { - public void onModuleLoad() { - final MySelectors m = GWT.create(MySelectors.class); + private SelectorEngine engine; + private String id; - final DeferredGQuery dg[] = m.getAllSelectors(); - HTML h = HTML.wrap(Document.get().getElementById("startrace")); - initResultsTable(dg, "GQuery", GCOMPILED, "DGQuery", GDYNAMIC, "jQuery" - /*"DOMAssistant 2.7" */, JQUERY, "Dojo", DOJO, "Prototype", PROTOTYPE); + GQueryDynamicBenchmark(String name) { + this.id = name; + this.engine = new SelectorEngine(); + } - h.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent clickEvent) { + public String getId() { + return id; + } - runBenchmarks(dg,new GQueryDynamicBenchmark(), new GQueryCompiledBenchmark(), new JQueryBenchmark(), - new DojoBenchmark(), new PrototypeBenchmark()); - } - }); + public int runSelector(DeferredGQuery dq, String selector) { + return engine.select(selector, gwtiframe).getLength(); + } } - public interface Benchmark { + /** + * Benchmark for external libraries + */ + private class IframeBenchmark implements Benchmark { + private String id; - public int runSelector(DeferredGQuery dq, String selector); + IframeBenchmark(String name) { + this.id = name; + } - String getId(); - } + public String getId() { + return id; + } - public void runBenchmarks(final DeferredGQuery[] dg, - final Benchmark... benchmark) { - DeferredCommand.addCommand(new IncrementalCommand() { - int selectorNumber = 0; + public int runSelector(DeferredGQuery dq, String selector) { + return runSelector(dq, id, selector); + } - int numCalls = 0; + public native int runSelector(DeferredGQuery dq, String id, String selector) /*-{ + return eval("$wnd." + id + "benchmark('" + selector + "')"); + }-*/; + } - int benchMarkNumber = 0; + private int min_time = 200; + + private boolean shareIframes = true; + + private boolean useTrack = true; + private boolean ask = true; - double totalTimes[] = new double[benchmark.length]; + /** + * List of available benchmarks. + */ + private final Benchmark[] benchmarks = new Benchmark[] { + new GQueryCompiledBenchmark("gwt_compiled"), + new GQueryDynamicBenchmark("gwt_dynamic"), + new DynamicBenchmark(new SelectorEngineSizzle(), "gwt_sizzle_jsni"), + new DynamicBenchmark(new SelectorEngineSizzleGwt(), "gwt_sizzle_java"), + new DynamicBenchmark(new SelectorEngineJS(), "gwt_domassist_java"), + new DynamicBenchmark(new SelectorEngineXPath(), "gwt_xpath"), + new DynamicBenchmark(new SelectorEngineCssToXPath(), "gwt_css2xpath"), + new IframeBenchmark("jquery"), + new IframeBenchmark("dojo"), + new IframeBenchmark("prototype"), + new IframeBenchmark("sizzle"), + new IframeBenchmark("domassistant") + }; + + /** + * Pre-selected benchmarks + */ + private String[] defaultBenchmarks = {"gwt_compiled", "gwt_dynamic", "jquery", "prototype", "dojo"}; - double runTimes[] = new double[benchmark.length]; + private DeferredGQuery dg[]; + private FlexTable grid = new FlexTable(); + private Element gwtiframe; + private Benchmark[] selectedBenchmarks; + private double trackWidth; + private PopupPanel selectPanel = new PopupPanel(); + + private Function askBenchMarks = new Function(){ + public void f(Element e) { + selectPanel.center(); + } + }; - long cumTime = 0; + /** + * Main function to run all the selected benchmarks + */ + private Function runBenchMarks = new Function() { + public void f(Element elem) { + + selectedBenchmarks = readBenchmarkSelection(); + selectPanel.hide(); + $("#startrace").hide(); - int numRuns = 0; + initResultsTable(dg, selectedBenchmarks); + initTrack(selectedBenchmarks); + + DeferredCommand.addCommand(new IncrementalCommand() { + int benchMarkNumber = 0; + int numCalls = 0; + int row = 0; + double runTimes[] = new double[selectedBenchmarks.length]; + int selectorNumber = 0; + double totalTimes[] = new double[selectedBenchmarks.length]; + int winner = -1; + double winTime = Double.MAX_VALUE; - int winner = -1; + public boolean execute() { + if (benchMarkNumber >= selectedBenchmarks.length) { + benchMarkNumber = 0; + numCalls = 0; + row ++; - double winTime = Double.MAX_VALUE; + moveHorses(selectedBenchmarks, row, totalTimes); + setResultClass(selectorNumber, winner); - public boolean execute() { - if (benchMarkNumber >= benchmark.length) { - benchMarkNumber = 0; - numCalls = 0; - cumTime = 0; - numRuns = 0; - setResultClass(benchmark[winner].getId(), selectorNumber, "win"); - double totalMovement = (790.0 - 124.0) / dg.length; - moveHorse(benchmark[winner].getId(), totalMovement); - - for (int i = 0; i < benchmark.length; i++) { - if (i != winner) { - moveHorse(benchmark[i].getId(), - (int) (totalMovement * (double) (winTime - / (double) runTimes[i]))); - setResultClass(benchmark[i].getId(), selectorNumber, "lose"); - } - } - selectorNumber++; - winner = -1; - winTime = Double.MAX_VALUE; - if (selectorNumber >= dg.length) { - double min = Double.MAX_VALUE; - for (int i = 0; i < totalTimes.length; i++) { - if (totalTimes[i] < min) { - min = totalTimes[i]; + selectorNumber++; + winner = -1; + winTime = Double.MAX_VALUE; + if (selectorNumber >= dg.length) { + double min = Double.MAX_VALUE; + for (int i = 0; i < totalTimes.length; i++) { + if (totalTimes[i] < min) { + min = totalTimes[i]; + } } - } - for (int i = 0; i < totalTimes.length; i++) { - d(benchmark[i].getId(), dg.length, - (((int) (totalTimes[i] * 100)) / 100.0) + " ms"); - setResultClass(benchmark[i].getId(), dg.length, - totalTimes[i] <= min ? "win" : "lose"); - if (totalTimes[i] <= min) { - flagWinner(benchmark[i].getId()); + + d(selectorNumber, -1, "Total"); + for (int i = 0; i < totalTimes.length; i++) { + d(selectorNumber, i, (((int) (totalTimes[i] * 100)) / 100.0) + " ms"); + if (totalTimes[i] <= min) { + flagWinner(selectedBenchmarks[i].getId()); + $("#startrace").show(); + setResultClass(selectorNumber, i); + } } + return false; } - - return false; } + DeferredGQuery d = dg[selectorNumber]; + long start = System.currentTimeMillis(); + int num = 0; + long end = start; + Benchmark m = selectedBenchmarks[benchMarkNumber]; + String selector = d.getSelector(); + double runtime = min_time; + int found = 0; + try { + do { + num += m.runSelector(d, selector); + end = System.currentTimeMillis(); + numCalls++; + } while (end - start < min_time); + runtime = (double) (end - start) / numCalls; + if (runtime < winTime) { + winTime = runtime; + winner = benchMarkNumber; + } + found = num / numCalls; + } catch (Exception e) { + found = -1; + } + runTimes[benchMarkNumber] = runtime; + d(selectorNumber, benchMarkNumber, runtime, found); + totalTimes[benchMarkNumber] += runtime; + numCalls = 0; + benchMarkNumber++; + return true; } - DeferredGQuery d = dg[selectorNumber]; - long start = System.currentTimeMillis(); - int num = 0; - long end = start; - Benchmark m = benchmark[benchMarkNumber]; - String selector = d.getSelector(); - - do { - num += m.runSelector(d, selector); - end = System.currentTimeMillis(); - numCalls++; - } while (end - start < MIN_TIME); - double runtime = (double) (end - start) / numCalls; - if (runtime < winTime) { - winTime = runtime; - winner = benchMarkNumber; - } - runTimes[benchMarkNumber] = runtime; - d(m.getId(), selectorNumber, runtime, (num / numCalls)); - totalTimes[benchMarkNumber] += runtime; - numCalls = 0; - benchMarkNumber++; - return true; - } - }); - } - - private native void flagWinner(String id) /*-{ - $wnd.flagWinner(id); - }-*/; + }); + } + }; - private native void moveHorse(String id, double totalMovement) /*-{ - $wnd.moveHorse(id, totalMovement); - }-*/; + /** + * EntryPoint + */ + public void onModuleLoad() { + final MySelectors m = GWT.create(MySelectors.class); + dg = m.getAllSelectors(); + + String par = Window.Location.getParameter("min"); + if (par != null) { + min_time = Integer.parseInt(par); + } + par = Window.Location.getParameter("share"); + if (par != null && "false".equals(par)) { + shareIframes = false; + } + par = Window.Location.getParameter("track"); + if (par != null && "false".equals(par)) { + useTrack = false; + } + par = Window.Location.getParameter("ask"); + if (par != null && "false".equals(par)) { + ask = false; + } + + initSelects(benchmarks); + initIFrames(); - private void setResultClass(String id, int i, String clz) { - Element td = Document.get().getElementById(id + i); - td.setClassName(clz); + $("#startrace").click(ask ? askBenchMarks: runBenchMarks); } - private void d(String type, int i, String text) { - Element td = Document.get().getElementById(type + i); - td.setInnerHTML(text); + private void d(int selnumber, int benchnumber, String text) { + grid.setText(selnumber + 1, benchnumber + 1, text); + Element td = grid.getCellFormatter().getElement(selnumber + 1, benchnumber + 1); DOM.scrollIntoView((com.google.gwt.user.client.Element) td); } - private void d(String type, int i, double v, int i1) { + private void d(int selnumber, int benchnumber, double time, int found) { + String text = found < 0 ? "Error" : "" + (((int) (time * 10)) / 10.0) + " ms | " + found + " found"; + d(selnumber, benchnumber, text); + } - Element td = Document.get().getElementById(type + i); - td.setInnerHTML( - "" + (((int) (v * 100)) / 100.0) + " ms, found " + i1 + " nodes"); - DOM.scrollIntoView((com.google.gwt.user.client.Element) td); + private void flagWinner(String idWinner) { + GQuery g = $("#" + idWinner + "horse" + " nobr"); + $(".flag").appendTo(g).show(); } + + /** + * Insert the iframes for benchmarking. + * Depending on the parameter share, we will generate one iframe + * for each benchmark or we will share the same one. + */ + private void initIFrames() { + String i = ""; + if (! shareIframes ) { + $(i.replaceAll("%ID%", "gwt")).appendTo(document).hide(); + for (Benchmark b : benchmarks) { + if (b instanceof IframeBenchmark) { + $(i.replaceAll("%ID%", b.getId())).appendTo(document).hide(); + } + } + } else { + $(i.replaceAll("%ID%", "iframe")).appendTo(document).hide(); + } + // Wait a while until the iframe/s have been loaded + new Timer() { + public void run() { + writeTestContent($(".ibench").contents().find("body").get(0)); + gwtiframe = $(".ibench").eq(0).contents().get(0); + } + }.schedule(1000); + } + - private void initResultsTable(DeferredGQuery[] dg, String... options) { + /** + * Reset the result table + */ + private void initResultsTable(DeferredGQuery[] dg, Benchmark... benchs) { int numRows = dg.length; - Document doc = Document.get(); - Element table = doc.getElementById("resultstable"); - Element thead = doc.createTHeadElement(); -// thead.getStyle().setProperty("position", "relative"); - table.appendChild(thead); - Element selectorHeader = doc.createTHElement(); - Element theadtr = doc.createTRElement(); - selectorHeader.setInnerHTML("Selector"); - theadtr.appendChild(selectorHeader); - thead.appendChild(theadtr); - - Element tbody = doc.createTBodyElement(); -// tbody.getStyle().setProperty("overflow", "scroll"); -// tbody.getStyle().setProperty("height", "200px"); - table.appendChild(tbody); - - for (int i = 0; i < options.length; i += 2) { - Element th = doc.createTHElement(); - th.setInnerHTML(options[i]); - theadtr.appendChild(th); + grid = new FlexTable(); + grid.addStyleName("resultstable"); + RootPanel.get("results").clear(); + RootPanel.get("results").add(grid); + + grid.setText(0, 0, "Selector"); + for (int i=0; i < benchs.length; i++) { + grid.setText(0, i+1, benchs[i].getId()); } + for (int i = 0; i < numRows; i++) { - Element tr = doc.createTRElement(); - Element lab = doc.createTHElement(); - lab.setInnerHTML(dg[i].getSelector()); - tr.appendChild(lab); - for (int j = 0; j < options.length; j += 2) { - Element placeholder = doc.createTDElement(); - placeholder.setInnerHTML("Not Tested"); - placeholder.setId(options[j + 1] + i); - tr.appendChild(placeholder); + grid.setText(i+1, 0, dg[i].getSelector()); + for (int j = 0; j < benchs.length; j++) { + grid.setText(i+1, j+1, "-"); } - tbody.appendChild(tr); } - Element totalRow = doc.createTRElement(); - Element totalLab = doc.createTHElement(); - totalLab.setInnerHTML("Total"); - totalRow.appendChild(totalLab); - for (int j = 0; j < options.length; j += 2) { - Element placeholder = doc.createTDElement(); - placeholder.setInnerHTML("0"); - placeholder.setId(options[j + 1] + numRows); - totalRow.appendChild(placeholder); - } - tbody.appendChild(totalRow); } - private void d(String s) { - log.append(s + "
"); + /** + * Initialize the selects to choose the benchmarks to run + */ + private void initSelects(Benchmark... benchs) { + String opt = "%ID%
"; + selectPanel.add(new HTML("
Make your selection
")); + selectPanel.show(); + GQuery g = $("#selectcontainer"); + for (Benchmark b : benchs) { + String select = opt; + for (String s : defaultBenchmarks) { + if (s.equals(b.getId())) { + select = select.replaceAll("%SEL%", "checked='checked'"); + } + } + g.append(select.replaceAll("%ID%", b.getId()).replaceAll("%SEL", "")); + } + g.append("
"); + $("#run").click(runBenchMarks); + selectPanel.hide(); } - private static class GQueryCompiledBenchmark implements Benchmark { - - public int runSelector(DeferredGQuery dq, String selector) { - return dq.array(null).getLength(); + /** + * Initialize the track with the horses + */ + private void initTrack(Benchmark... benchs) { + if (!useTrack) return; + String tpl = "
%ID%
"; + GQuery g = $("#racefield").html(""); + for (Benchmark b : benchs) { + String id = b.getId(); + String lg = id.contains("gwt") ? "gwt" : id; + String s = tpl.replaceAll("%ID%", id).replaceAll("%LG%", lg); + g.append($(s)); } - public String getId() { - return GCOMPILED; - } + int height = g.find(".horse").height() * (benchs.length + 1); + $("#racetrack").css("height", height + "px"); + + GQuery flag = $("").appendTo(document); + trackWidth = g.width() - g.find(".horse").width() - flag.width(); + flag.hide(); } - - private static class JQueryBenchmark implements Benchmark { - - public native int runSelector(DeferredGQuery dq, String selector) /*-{ - return $wnd.jquerybenchmark(selector); - }-*/; - - public String getId() { - return JQUERY; + + /** + * Update horse possition. + * Note that the calculated position is relative with the faster horse, + * so a horse could move back. + */ + private void moveHorses(Benchmark[] b, int row, double[] totalTimes) { + if (!useTrack) return; + double winnerTime = Double.MAX_VALUE; + for (double d : totalTimes) { + winnerTime = Math.min(winnerTime, d); } - } - - private static class DojoBenchmark implements Benchmark { - - public native int runSelector(DeferredGQuery dq, String selector) /*-{ - return $wnd.dojobenchmark(selector); - }-*/; - - public String getId() { - return DOJO; + double winnerPos = row * (double) trackWidth / (double) dg.length; + for (int i = 0; i < b.length; i++) { + GQuery g = $("#" + b[i].getId() + "horse"); + double pos = winnerPos * winnerTime / totalTimes[i]; + g.css("left", (int)pos + "px"); } } - - private static class PrototypeBenchmark implements Benchmark { - - public native int runSelector(DeferredGQuery dq, String selector) /*-{ - return $wnd.prototypebenchmark(selector); - }-*/; - - public String getId() { - return PROTOTYPE; - } + + private void setResultClass(int selNumber, int winNumber) { + Element e = grid.getCellFormatter().getElement(selNumber + 1, winNumber + 1); + $(e).addClass("win").siblings().attr("class", "").addClass("tie").eq(0).removeClass("tie"); } - - private static class GQueryDynamicBenchmark implements Benchmark { - - private SelectorEngine engine; - - private GQueryDynamicBenchmark() { - engine = new SelectorEngine(); - } - - public int runSelector(DeferredGQuery dq, String selector) { - return engine.select(selector, Document.get()).getLength(); + + private Benchmark[] readBenchmarkSelection() { + ArrayList bs = new ArrayList(); + for (Element e : $("input", selectPanel.getElement()).elements()) { + String val = $(e).val(); + if (!"".equals(val)) { + for (Benchmark b : benchmarks) { + if (b.getId().equals(val)) { + bs.add(b); + } + } + } } + return bs.toArray(new Benchmark[bs.size()]); + } - public String getId() { - return GDYNAMIC; - } + /** + * This ugly method is used to initialize a huge html String + * plenty of html tags which will be used for the tests, + * because java 1.5 has a limitation in the size of static strings. + */ + private void writeTestContent(Element e) { + String ret = ""; + ret += "
"; + ret += "
"; + ret += "

W3C

"; + ret += "

Selectors

"; + ret += " ."; + ret += "

W3C Working Draft 15 December 2005

"; + ret += "
"; + ret += "
This version:
"; + ret += "
"; + ret += " http://www.w3.org/TR/2005/WD-css3-selectors-20051215
"; + ret += "
Latest version:"; + ret += "
"; + ret += " http://www.w3.org/TR/css3-selectors"; + ret += "
Previous version:"; + ret += "
"; + ret += " http://www.w3.org/TR/2001/CR-css3-selectors-20011113"; + ret += "
Editors:"; + ret += "
Daniel Glazman (Invited"; + ret += "
"; + ret += "
Tantek Çelik"; + ret += "
Ian"; + ret += " Hickson (Google)"; + ret += "
Peter Linss (former"; + ret += " editor, Netscape/AOL)"; + ret += "
John Williams (former editor, Quark, Inc.)"; + ret += "
"; + ret += "
"; + ret += "
"; + ret += "

Abstract

"; + ret += "

Selectors are patterns that match against elements in a"; + ret += " tree. Selectors have been optimized for use with HTML and XML, and"; + ret += " are designed to be usable in performance-critical code.

"; + ret += "

CSS (Cascading"; + ret += " Style Sheets) is a language for describing the rendering of HTML and XML documents on"; + ret += " screen, on paper, in speech, etc. CSS uses Selectors for binding"; + ret += " describes extensions to the selectors defined in CSS level 2. These"; + ret += " extended selectors will be used by CSS level 3."; + ret += "

Selectors define the following function:

"; + ret += "
expression ∗ element → boolean
"; + ret += "

That is, given an element and a selector, this specification"; + ret += " defines whether that element matches the selector.

"; + ret += "

These expressions can also be used, for instance, to select a set"; + ret += " subtree. STTS (Simple Tree Transformation Sheets), a"; + ret += " language for transforming XML trees, uses this mechanism. [STTS]

"; + ret += "

Status of this document

"; + ret += "

This section describes the status of this document at the"; + ret += " of this technical report can be found in the W3C technical reports index at"; + ret += " http://www.w3.org/TR/.

"; + ret += "

This document describes the selectors that already exist in CSS1 and CSS2, and"; + ret += " also proposes new selectors for CSS3 and other languages that may need them.

"; + ret += "

The CSS Working Group doesn't expect that all implementations of"; + ret += " CSS3 will have to implement all selectors. Instead, there will"; + ret += " will include all of the selectors.

"; + ret += "

This specification is a last call working draft for the the CSS Working Group"; + ret += " (Style Activity). This"; + ret += " document is a revision of the Candidate"; + ret += " Recommendation dated 2001 November 13, and has incorporated"; + ret += " be demonstrable.

"; + ret += "

All persons are encouraged to review and implement this"; + ret += " specification and return comments to the (archived)"; + ret += " public mailing list www-style"; + ret += " (see instructions). W3C"; + ret += " The deadline for comments is 14 January 2006.

"; + ret += "

This is still a draft document and may be updated, replaced, or"; + ret += "

This document may be available in translation."; + ret += "

"; + ret += "

Table of contents

"; + ret += " "; + ret += "
"; + ret += "

1. Introduction

"; + ret += "

1.1. Dependencies

"; + ret += "

Some features of this specification are specific to CSS, or have"; + ret += " specification, these have been described in terms of CSS2.1. [CSS21]

"; + ret += "

1.2. Terminology

"; + ret += "

All of the text of this specification is normative except"; + ret += " non-normative.

"; + ret += "

1.3. Changes from CSS2

"; + ret += "

This section is non-normative.

"; + ret += "

The main differences between the selectors in CSS2 and those in"; + ret += " Selectors are:"; + ret += "

    "; + ret += "
  • the list of basic definitions (selector, group of selectors,"; + ret += " of simple selectors, and the term 'simple selector' is now used for"; + ret += "
  • "; + ret += "
  • an optional namespace component is now allowed in type element"; + ret += " selectors, the universal selector and attribute selectors"; + ret += "
  • "; + ret += "
  • a new combinator has been"; + ret += "
  • "; + ret += "
  • new simple selectors including substring matching attribute"; + ret += " selectors, and new pseudo-classes"; + ret += "
  • "; + ret += "
  • new pseudo-elements, and introduction of the '::' convention"; + ret += "
  • "; + ret += "
  • the grammar has been rewritten
  • "; + ret += "
  • profiles to be added to specifications integrating Selectors"; + ret += " and defining the set of selectors which is actually supported by"; + ret += "
  • "; + ret += "
  • Selectors are now a CSS3 Module and an independent"; + ret += "
  • "; + ret += "
  • the specification now has its own test suite
  • "; + ret += "
"; + ret += "

2. Selectors

"; + ret += "

This section is non-normative, as it merely summarizes the"; + ret += " following sections.

"; + ret += "

A Selector represents a structure. This structure can be used as a"; + ret += " HTML or XML fragment corresponding to that structure.

"; + ret += "

Selectors may range from simple element names to rich contextual"; + ret += " representations.

"; + ret += "

The following table summarizes the Selector syntax:

"; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += "
PatternMeaningDescribed in sectionFirst defined in CSS level
*any elementUniversal"; + ret += " selector2
Ean element of type EType selector1
E[foo]an E element with a 'foo' attributeAttribute"; + ret += " selectors2
E[foo='bar']an E element whose 'foo' attribute value is exactly"; + ret += " Attribute"; + ret += " selectors2
E[foo~='bar']an E element whose 'foo' attribute value is a list of"; + ret += " Attribute"; + ret += " selectors2
E[foo^='bar']an E element whose 'foo' attribute value begins exactly"; + ret += " Attribute"; + ret += " selectors3
E[foo$='bar']an E element whose 'foo' attribute value ends exactly"; + ret += " Attribute"; + ret += " selectors3
E[foo*='bar']an E element whose 'foo' attribute value contains the"; + ret += " Attribute"; + ret += " selectors3
E[hreflang|='en']an E element whose 'hreflang' attribute has a"; + ret += " Attribute"; + ret += " selectors2
E:rootan E element, root of the documentStructural"; + ret += " pseudo-classes3
E:nth-child(n)an E element, the n-th child of its parentStructural"; + ret += " pseudo-classes3
E:nth-last-child(n)an E element, the n-th child of its parent, counting"; + ret += " Structural"; + ret += " pseudo-classes3
E:nth-of-type(n)an E element, the n-th sibling of its typeStructural"; + ret += " pseudo-classes3
E:nth-last-of-type(n)an E element, the n-th sibling of its type, counting"; + ret += " Structural"; + ret += " pseudo-classes3
E:first-childan E element, first child of its parentStructural"; + ret += " pseudo-classes2
E:last-childan E element, last child of its parentStructural"; + ret += " pseudo-classes3
E:first-of-typean E element, first sibling of its typeStructural"; + ret += " pseudo-classes3
E:last-of-typean E element, last sibling of its typeStructural"; + ret += " pseudo-classes3
E:only-childan E element, only child of its parentStructural"; + ret += " pseudo-classes3
E:only-of-typean E element, only sibling of its typeStructural"; + ret += " pseudo-classes3
E:emptyan E element that has no children (including text"; + ret += " Structural"; + ret += " pseudo-classes3
E:link
E:visited
an E element being the source anchor of a hyperlink of"; + ret += " The link"; + ret += " pseudo-classes1
E:active
E:hover
E:focus
an E element during certain user actionsThe user"; + ret += " action pseudo-classes1 and 2
E:targetan E element being the target of the referring URIThe target"; + ret += " pseudo-class3
E:lang(fr)an element of type E in language 'fr' (the document"; + ret += " The :lang()"; + ret += " pseudo-class2
E:enabled
E:disabled
a user interface element E which is enabled or"; + ret += " The UI element states"; + ret += " pseudo-classes3
E:checkeda user interface element E which is checked (for instance a radio-button or checkbox)"; + ret += " The UI element states"; + ret += " pseudo-classes3
E::first-linethe first formatted line of an E elementThe ::first-line"; + ret += " pseudo-element1
E::first-letterthe first formatted letter of an E elementThe ::first-letter"; + ret += " pseudo-element1
E::selectionthe portion of an E element that is currently"; + ret += " The UI element"; + ret += " fragments pseudo-elements3
E::beforegenerated content before an E elementThe ::before"; + ret += " pseudo-element2
E::aftergenerated content after an E elementThe ::after"; + ret += " pseudo-element2
E.warningan E element whose class is"; + ret += " Class"; + ret += " selectors1
E#myidan E element with ID equal to 'myid'.ID"; + ret += " selectors1
E:not(s)an E element that does not match simple selector sNegation"; + ret += " pseudo-class3
E Fan F element descendant of an E elementDescendant"; + ret += " combinator1
E > Fan F element child of an E elementChild"; + ret += " combinator2
E + Fan F element immediately preceded by an E elementAdjacent sibling combinator"; + ret += " 2
E ~ Fan F element preceded by an E elementGeneral sibling combinator"; + ret += " 3
"; + ret += "

The meaning of each selector is derived from the table above by"; + ret += " column.

"; + ret += "

3. Case sensitivity

"; + ret += "

The case sensitivity of document language element names, attribute"; + ret += " names, and attribute values in selectors depends on the document"; + ret += " but in XML, they are case-sensitive.

"; + ret += "

4. Selector syntax

"; + ret += "

A selector is a chain of one"; + ret += " or more sequences of simple selectors"; + ret += " separated by combinators.

"; + ret += "

A sequence of simple selectors"; + ret += " is a chain of simple selectors"; + ret += " that are not separated by a combinator. It"; + ret += " always begins with a type selector or a"; + ret += " universal selector. No other type"; + ret += " selector or universal selector is allowed in the sequence.

"; + ret += "

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, content selector, or pseudo-class. One pseudo-element may be appended to the last"; + ret += " sequence of simple selectors.

"; + ret += "

Combinators are: white space, 'greater-than"; + ret += " sign' (U+003E, >), 'plus sign' (U+002B,"; + ret += " +) and 'tilde' (U+007E, ~). White"; + ret += " space may appear between a combinator and the simple selectors around"; + ret += " it. Only the characters 'space' (U+0020), 'tab'"; + ret += " never part of white space.

"; + ret += "

The elements of a document tree that are represented by a selector"; + ret += " are the subjects of the selector. A"; + ret += " selector consisting of a single sequence of simple selectors"; + ret += " sequence of simple selectors and a combinator to a sequence imposes"; + ret += " simple selectors.

"; + ret += "

An empty selector, containing no sequence of simple selectors and"; + ret += " no pseudo-element, is an invalid"; + ret += " selector.

"; + ret += "

5. Groups of selectors

"; + ret += "

When several selectors share the same declarations, they may be"; + ret += " grouped into a comma-separated list. (A comma is U+002C.)

"; + ret += "
"; + ret += "

CSS examples:

"; + ret += "

In this example, we condense three rules with identical"; + ret += " declarations into one. Thus,

"; + ret += "
h1 { font-family: sans-serif }";
+    ret += "      h3 { font-family: sans-serif }
"; + ret += "

is equivalent to:

"; + ret += "
h1, h2, h3 { font-family: sans-serif }
"; + ret += "
"; + ret += "

Warning: the equivalence is true in this example"; + ret += " because all the selectors are valid selectors. If just one of these"; + ret += " selectors were invalid, the entire group of selectors would be"; + ret += " heading rules would be invalidated.

"; + ret += "

6. Simple selectors

"; + ret += "

6.1. Type selector

"; + ret += "

A type selector is the name of a document language"; + ret += " type in the document tree.

"; + ret += "
"; + ret += "

Example:

"; + ret += "

The following selector represents an h1 element in the"; + ret += " document tree:

"; + ret += "
h1
"; + ret += "
"; + ret += "

6.1.1. Type selectors and namespaces

"; + ret += "

Type selectors allow an optional namespace ([XMLNAMES]) component. A namespace prefix"; + ret += " (U+007C, |).

"; + ret += "

The namespace component may be left empty to indicate that the"; + ret += " selector is only to represent elements with no declared namespace.

"; + ret += "

An asterisk may be used for the namespace prefix, indicating that"; + ret += " with no namespace).

"; + ret += "

Element type selectors that have no namespace component (no"; + ret += " element's namespace (equivalent to '*|') unless a default"; + ret += " namespace.

"; + ret += "

A type selector containing a namespace prefix that has not been"; + ret += " previously declared is an invalid selector."; + ret += " language implementing Selectors. In CSS, such a mechanism is defined"; + ret += " in the General Syntax module.

"; + ret += "

In a namespace-aware client, element type selectors will only match"; + ret += " against the local"; + ret += " part"; + ret += " of the element's qualified"; + ret += " name. See below for notes about matching"; + ret += " behaviors in down-level clients.

"; + ret += "

In summary:

"; + ret += "
"; + ret += "
ns|E
"; + ret += "
elements with name E in namespace ns
"; + ret += "
*|E
"; + ret += "
elements with name E in any namespace, including those without any"; + ret += "
"; + ret += "
|E
"; + ret += "
elements with name E without any declared namespace
"; + ret += "
E
"; + ret += "
if no default namespace has been specified, this is equivalent to *|E."; + ret += "
"; + ret += "
"; + ret += "
"; + ret += "

CSS examples:

"; + ret += "
@namespace foo url(http://www.example.com);";
+    ret += "       h1 { color: green }
"; + ret += "

The first rule will match only h1 elements in the"; + ret += " 'http://www.example.com' namespace.

"; + ret += "

The second rule will match all elements in the"; + ret += " 'http://www.example.com' namespace.

"; + ret += "

The third rule will match only h1 elements without"; + ret += " any declared namespace.

"; + ret += "

The fourth rule will match h1 elements in any"; + ret += " namespace (including those without any declared namespace).

"; + ret += "

The last rule is equivalent to the fourth rule because no default"; + ret += " namespace has been defined.

"; + ret += "
"; + ret += "

6.2. Universal selector

"; + ret += "

The universal selector, written 'asterisk'"; + ret += " (*), represents the qualified name of any element"; + ret += " specified, see Universal selector and"; + ret += " Namespaces below.

"; + ret += "

If the universal selector is not the only component of a sequence"; + ret += " of simple selectors, the * may be omitted.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "
    "; + ret += "
  • *[hreflang|=en] and [hreflang|=en] are"; + ret += "
  • "; + ret += "
  • *.warning and .warning are equivalent,"; + ret += "
  • "; + ret += "
  • *#myid and #myid are equivalent.
  • "; + ret += "
"; + ret += "
"; + ret += "

Note: it is recommended that the"; + ret += " *, representing the universal selector, not be"; + ret += " omitted.

"; + ret += "

6.2.1. Universal selector and namespaces

"; + ret += "

The universal selector allows an optional namespace component. It"; + ret += " is used as follows:

"; + ret += "
"; + ret += "
ns|*
"; + ret += "
all elements in namespace ns
"; + ret += "
*|*
"; + ret += "
all elements
"; + ret += "
|*
"; + ret += "
all elements without any declared namespace
"; + ret += "
*
"; + ret += "
if no default namespace has been specified, this is equivalent to *|*."; + ret += "
"; + ret += "
"; + ret += "

A universal selector containing a namespace prefix that has not"; + ret += " been previously declared is an invalid"; + ret += " to the language implementing Selectors. In CSS, such a mechanism is"; + ret += " defined in the General Syntax module.

"; + ret += "

6.3. Attribute selectors

"; + ret += "

Selectors allow the representation of an element's attributes. When"; + ret += " attribute selectors must be considered to match an element if that"; + ret += " attribute selector.

"; + ret += "

6.3.1. Attribute presence and values"; + ret += " selectors

"; + ret += "

CSS2 introduced four attribute selectors:

"; + ret += "
"; + ret += "
[att]"; + ret += "
Represents an element with the att attribute, whatever the"; + ret += "
"; + ret += "
[att=val]
"; + ret += "
Represents an element with the att attribute whose value is"; + ret += "
"; + ret += "
[att~=val]
"; + ret += "
Represents an element with the att attribute whose value is"; + ret += " a whitespace-separated list of words, one"; + ret += " represent anything (since the words are separated by"; + ret += "
"; + ret += "
[att|=val]"; + ret += "
Represents an element with the att attribute, its value"; + ret += " matches (e.g., the hreflang attribute on the"; + ret += " link element in HTML) as described in RFC 3066 ([RFC3066]). For lang (or"; + ret += " xml:lang) language subcode matching, please see the :lang pseudo-class."; + ret += "
"; + ret += "
"; + ret += "

Attribute values must be identifiers or strings. The"; + ret += " case-sensitivity of attribute names and values in selectors depends on"; + ret += " the document language.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "

The following attribute selector represents an h1"; + ret += " element that carries the title attribute, whatever its"; + ret += " value:

"; + ret += "
h1[title]
"; + ret += "

In the following example, the selector represents a"; + ret += " span element whose class attribute has"; + ret += " exactly the value 'example':

"; + ret += "
span[class='example']
"; + ret += "

Multiple attribute selectors can be used to represent several"; + ret += " attribute. Here, the selector represents a span element"; + ret += " whose hello attribute has exactly the value 'Cleveland'"; + ret += " and whose goodbye attribute has exactly the value"; + ret += " 'Columbus':

"; + ret += "
span[hello='Cleveland'][goodbye='Columbus']
"; + ret += "

The following selectors illustrate the differences between '='"; + ret += " 'copyright copyleft copyeditor' on a rel attribute. The"; + ret += " second selector will only represent an a element with"; + ret += " an href attribute having the exact value"; + ret += " 'http://www.w3.org/'.

"; + ret += "
a[rel~='copyright']";
+    ret += "      a[href='http://www.w3.org/']
"; + ret += "

The following selector represents a link element"; + ret += " whose hreflang attribute is exactly 'fr'.

"; + ret += "
link[hreflang=fr]
"; + ret += "

The following selector represents a link element for"; + ret += " which the values of the hreflang attribute begins with"; + ret += " 'en', including 'en', 'en-US', and 'en-cockney':

"; + ret += "
link[hreflang|='en']
"; + ret += "

Similarly, the following selectors represents a"; + ret += " DIALOGUE element whenever it has one of two different"; + ret += " values for an attribute character:

"; + ret += "
DIALOGUE[character=romeo]";
+    ret += "      DIALOGUE[character=juliet]
"; + ret += "
"; + ret += "

6.3.2. Substring matching attribute"; + ret += " selectors

"; + ret += "

Three additional attribute selectors are provided for matching"; + ret += " substrings in the value of an attribute:

"; + ret += "
"; + ret += "
[att^=val]
"; + ret += "
Represents an element with the att attribute whose value"; + ret += "
"; + ret += "
[att$=val]"; + ret += "
Represents an element with the att attribute whose value"; + ret += "
"; + ret += "
[att*=val]"; + ret += "
Represents an element with the att attribute whose value"; + ret += "
"; + ret += "
"; + ret += "

Attribute values must be identifiers or strings. The"; + ret += " case-sensitivity of attribute names in selectors depends on the"; + ret += " document language.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "

The following selector represents an HTML object,"; + ret += " image:

"; + ret += "
object[type^='image/']
"; + ret += "

The following selector represents an HTML anchor a with an"; + ret += " href attribute whose value ends with '.html'.

"; + ret += "
a[href$='.html']
"; + ret += "

The following selector represents an HTML paragraph with a"; + ret += " title"; + ret += " attribute whose value contains the substring 'hello'

"; + ret += "
p[title*='hello']
"; + ret += "
"; + ret += "

6.3.3. Attribute selectors and namespaces

"; + ret += "

Attribute selectors allow an optional namespace component to the"; + ret += " separator 'vertical bar' (|). In keeping with"; + ret += " apply to attributes, therefore attribute selectors without a namespace"; + ret += " (equivalent to '|attr'). An asterisk may be used for the"; + ret += "

An attribute selector with an attribute name containing a namespace"; + ret += " prefix that has not been previously declared is an invalid selector. The mechanism for"; + ret += " a namespace prefix is left up to the language implementing Selectors."; + ret += "

"; + ret += "

CSS examples:

"; + ret += "
@namespace foo 'http://www.example.com';";
+    ret += "      [att] { color: green }
"; + ret += "

The first rule will match only elements with the attribute"; + ret += " att in the 'http://www.example.com' namespace with the"; + ret += " value 'val'.

"; + ret += "

The second rule will match only elements with the attribute"; + ret += " att regardless of the namespace of the attribute"; + ret += " (including no declared namespace).

"; + ret += "

The last two rules are equivalent and will match only elements"; + ret += " with the attribute att where the attribute is not"; + ret += " declared to be in a namespace.

"; + ret += "
"; + ret += "

6.3.4. Default attribute values in DTDs

"; + ret += "

Attribute selectors represent explicitly set attribute values in"; + ret += " selectors. Selectors should be designed so that they work even if the"; + ret += " default values are not included in the document tree.

"; + ret += "

More precisely, a UA is not required to read an 'external"; + ret += " subset' of the DTD but is required to look for default"; + ret += " attribute values in the document's 'internal subset.' (See [XML10] for definitions of these subsets.)

"; + ret += "

A UA that recognizes an XML namespace [XMLNAMES] is not required to use its"; + ret += " required to use its built-in knowledge of the XHTML DTD.)

"; + ret += "

Note: Typically, implementations"; + ret += " choose to ignore external subsets.

"; + ret += "
"; + ret += "

Example:

"; + ret += "

Consider an element EXAMPLE with an attribute 'notation' that has a"; + ret += " default value of 'decimal'. The DTD fragment might be

"; + ret += "
<!ATTLIST EXAMPLE notation (decimal,octal) 'decimal'>
"; + ret += "

If the style sheet contains the rules

"; + ret += "
EXAMPLE[notation=decimal] { /*... default property settings ...*/ }";
+    ret += "      EXAMPLE[notation=octal]   { /*... other settings...*/ }
"; + ret += "

the first rule will not match elements whose 'notation' attribute"; + ret += " attribute selector for the default value must be dropped:

"; + ret += "
EXAMPLE                   { /*... default property settings ...*/ }";
+    ret += "      EXAMPLE[notation=octal]   { /*... other settings...*/ }
"; + ret += "

Here, because the selector EXAMPLE[notation=octal] is"; + ret += " cases' style rules.

"; + ret += "
"; + ret += "

6.4. Class selectors

"; + ret += "

Working with HTML, authors may use the period (U+002E,"; + ret += " .) notation as an alternative to the ~="; + ret += " notation when representing the class attribute. Thus, for"; + ret += " HTML, div.value and div[class~=value] have"; + ret += " 'period' (.).

"; + ret += "

UAs may apply selectors using the period (.) notation in XML"; + ret += " 1.0 [SVG] describes the SVG"; + ret += " 'class' attribute and how a UA should interpret it, and"; + ret += " similarly MathML 1.01 [MATH] describes the MathML"; + ret += " 'class' attribute.)

"; + ret += "
"; + ret += "

CSS examples:

"; + ret += "

We can assign style information to all elements with"; + ret += " class~='pastoral' as follows:

"; + ret += "
*.pastoral { color: green }  /* all elements with class~=pastoral */
"; + ret += "

or just

"; + ret += "
.pastoral { color: green }  /* all elements with class~=pastoral */
"; + ret += "

The following assigns style only to H1 elements with"; + ret += " class~='pastoral':

"; + ret += "
H1.pastoral { color: green }  /* H1 elements with class~=pastoral */
"; + ret += "

Given these rules, the first H1 instance below would not have"; + ret += " green text, while the second would:

"; + ret += "
<H1>Not green</H1>";
+    ret += "      <H1 class='pastoral'>Very green</H1>
"; + ret += "
"; + ret += "

To represent a subset of 'class' values, each value must be preceded"; + ret += " by a '.', in any order.

"; + ret += "
"; + ret += "

CSS example:

"; + ret += "

The following rule matches any P element whose 'class' attribute"; + ret += " has been assigned a list of whitespace-separated values that includes"; + ret += " 'pastoral' and 'marine':

"; + ret += "
p.pastoral.marine { color: green }
"; + ret += "

This rule matches when class='pastoral blue aqua"; + ret += " marine' but does not match for class='pastoral"; + ret += " blue'.

"; + ret += "
"; + ret += "

Note: Because CSS gives considerable"; + ret += " not.

"; + ret += "

Note: If an element has multiple"; + ret += " this specification.

"; + ret += "

6.5. ID selectors

"; + ret += "

Document languages may contain attributes that are declared to be"; + ret += " applies.

"; + ret += "

An ID-typed attribute of a document language allows authors to"; + ret += " ID selectors represent an element instance based on its identifier. An"; + ret += " #) immediately followed by the ID value, which must be an"; + ret += " identifier.

"; + ret += "

Selectors does not specify how a UA knows the ID-typed attribute of"; + ret += "

"; + ret += "

Examples:

"; + ret += "

The following ID selector represents an h1 element"; + ret += " whose ID-typed attribute has the value 'chapter1':

"; + ret += "
h1#chapter1
"; + ret += "

The following ID selector represents any element whose ID-typed"; + ret += " attribute has the value 'chapter1':

"; + ret += "
#chapter1
"; + ret += "

The following selector represents any element whose ID-typed"; + ret += " attribute has the value 'z98y'.

"; + ret += "
*#z98y
"; + ret += "
"; + ret += "

Note. In XML 1.0 [XML10], the information about which attribute"; + ret += " should use normal attribute selectors instead:"; + ret += " [name=p371] instead of #p371. Elements in"; + ret += " XML 1.0 documents without a DTD do not have IDs at all.

"; + ret += "

If an element has multiple ID attributes, all of them must be"; + ret += " DOM3 Core, XML DTDs, and namespace-specific knowledge.

"; + ret += "

6.6. Pseudo-classes

"; + ret += "

The pseudo-class concept is introduced to permit selection based on"; + ret += " expressed using the other simple selectors.

"; + ret += "

A pseudo-class always consists of a 'colon'"; + ret += " (:) followed by the name of the pseudo-class and"; + ret += " optionally by a value between parentheses.

"; + ret += "

Pseudo-classes are allowed in all sequences of simple selectors"; + ret += " sequences of simple selectors, after the leading type selector or"; + ret += " document.

"; + ret += "

6.6.1. Dynamic pseudo-classes

"; + ret += "

Dynamic pseudo-classes classify elements on characteristics other"; + ret += " that cannot be deduced from the document tree.

"; + ret += "

Dynamic pseudo-classes do not appear in the document source or"; + ret += " document tree.

"; + ret += "
The link pseudo-classes: :link and :visited
"; + ret += "

User agents commonly display unvisited links differently from"; + ret += " previously visited ones. Selectors"; + ret += " provides the pseudo-classes :link and"; + ret += " :visited to distinguish them:

"; + ret += "
    "; + ret += "
  • The :link pseudo-class applies to links that have"; + ret += "
  • "; + ret += "
  • The :visited pseudo-class applies once the link has"; + ret += "
  • "; + ret += "
"; + ret += "

After some amount of time, user agents may choose to return a"; + ret += " visited link to the (unvisited) ':link' state.

"; + ret += "

The two states are mutually exclusive.

"; + ret += "
"; + ret += "

Example:

"; + ret += "

The following selector represents links carrying class"; + ret += " external and already visited:

"; + ret += "
a.external:visited
"; + ret += "
"; + ret += "

Note: It is possible for style sheet"; + ret += "

UAs may therefore treat all links as unvisited links, or implement"; + ret += " and unvisited links differently.

"; + ret += "
The user action pseudo-classes"; + ret += " :hover, :active, and :focus
"; + ret += "

Interactive user agents sometimes change the rendering in response"; + ret += " to user actions. Selectors provides"; + ret += " acting on.

"; + ret += "
    "; + ret += "
  • The :hover pseudo-class applies while the user"; + ret += " element. User agents not that do not support interactive"; + ret += " media do not have to support this pseudo-class. Some conforming"; + ret += " user agents that support interactive"; + ret += " media may not be able to support this pseudo-class (e.g., a pen"; + ret += "
  • "; + ret += "
  • The :active pseudo-class applies while an element"; + ret += "
  • "; + ret += "
  • The :focus pseudo-class applies while an element"; + ret += "
  • "; + ret += "
"; + ret += "

There may be document language or implementation specific limits on"; + ret += " which elements can become :active or acquire"; + ret += " :focus.

"; + ret += "

These pseudo-classes are not mutually exclusive. An element may"; + ret += " match several pseudo-classes at the same time.

"; + ret += "

Selectors doesn't define if the parent of an element that is"; + ret += " ':active' or ':hover' is also in that state.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "
a:link    /* unvisited links */";
+    ret += "      a:active  /* active links */
"; + ret += "

An example of combining dynamic pseudo-classes:

"; + ret += "
a:focus";
+    ret += "      a:focus:hover
"; + ret += "

The last selector matches a elements that are in"; + ret += " the pseudo-class :focus and in the pseudo-class :hover.

"; + ret += "
"; + ret += "

Note: An element can be both ':visited'"; + ret += " and ':active' (or ':link' and ':active').

"; + ret += "

6.6.2. The target pseudo-class :target

"; + ret += "

Some URIs refer to a location within a resource. This kind of URI"; + ret += " identifier (called the fragment identifier).

"; + ret += "

URIs with fragment identifiers link to a certain element within the"; + ret += " pointing to an anchor named section_2 in an HTML"; + ret += " document:

"; + ret += "
http://example.com/html/top.html#section_2
"; + ret += "

A target element can be represented by the :target"; + ret += " the document has no target element.

"; + ret += "
"; + ret += "

Example:

"; + ret += "
p.note:target
"; + ret += "

This selector represents a p element of class"; + ret += " note that is the target element of the referring"; + ret += " URI.

"; + ret += "
"; + ret += "
"; + ret += "

CSS example:

"; + ret += "

Here, the :target pseudo-class is used to make the"; + ret += " target element red and place an image before it, if there is one:

"; + ret += "
*:target { color : red }";
+    ret += "      *:target::before { content : url(target.png) }
"; + ret += "
"; + ret += "

6.6.3. The language pseudo-class :lang

"; + ret += "

If the document language specifies how the human language of an"; + ret += " element is determined, it is possible to write selectors that"; + ret += " represent an element based on its language. For example, in HTML [HTML4], the language is determined by a"; + ret += " combination of the lang attribute, the meta"; + ret += " headers). XML uses an attribute called xml:lang, and"; + ret += " the language.

"; + ret += "

The pseudo-class :lang(C) represents an element that"; + ret += " :lang() selector is based solely on the identifier C"; + ret += " element's language value, in the same way as if performed by the '|=' operator in attribute"; + ret += " selectors. The identifier C does not have to be a valid language"; + ret += " name.

"; + ret += "

C must not be empty. (If it is, the selector is invalid.)

"; + ret += "

Note: It is recommended that"; + ret += " documents and protocols indicate language using codes from RFC 3066 [RFC3066] or its successor, and by means of"; + ret += " 'xml:lang' attributes in the case of XML-based documents [XML10]. See "; + ret += " 'FAQ: Two-letter or three-letter language codes.'

"; + ret += "
"; + ret += "

Examples:

"; + ret += "

The two following selectors represent an HTML document that is in"; + ret += " Belgian, French, or German. The two next selectors represent"; + ret += " q quotations in an arbitrary element in Belgian, French,"; + ret += " or German.

"; + ret += "
html:lang(fr-be)";
+    ret += "      :lang(de) > q
"; + ret += "
"; + ret += "

6.6.4. The UI element states pseudo-classes

"; + ret += "
The :enabled and :disabled pseudo-classes
"; + ret += "

The :enabled pseudo-class allows authors to customize"; + ret += " an enabled input element without also specifying what it"; + ret += " would look like when it was disabled.

"; + ret += "

Similar to :enabled, :disabled allows the"; + ret += " element should look.

"; + ret += "

Most elements will be neither enabled nor disabled. An element is"; + ret += " presently activate it or transfer focus to it.

"; + ret += "
The :checked pseudo-class
"; + ret += "

Radio and checkbox elements can be toggled by the user. Some menu"; + ret += " toggled 'on' the :checked pseudo-class applies. The"; + ret += " :checked pseudo-class initially applies to such elements"; + ret += " that have the HTML4 selected and checked"; + ret += " attributes as described in Section"; + ret += " 17.2.1 of HTML4, but of course the user can toggle 'off' such"; + ret += " elements in which case the :checked pseudo-class would no"; + ret += " longer apply. While the :checked pseudo-class is dynamic"; + ret += " on the presence of the semantic HTML4 selected and"; + ret += " checked attributes, it applies to all media."; + ret += "

The :indeterminate pseudo-class
"; + ret += "
"; + ret += "

Radio and checkbox elements can be toggled by the user, but are"; + ret += " This can be due to an element attribute, or DOM manipulation.

"; + ret += "

A future version of this specification may introduce an"; + ret += " :indeterminate pseudo-class that applies to such elements."; + ret += "

"; + ret += "
"; + ret += "

6.6.5. Structural pseudo-classes

"; + ret += "

Selectors introduces the concept of structural"; + ret += " pseudo-classes to permit selection based on extra information that"; + ret += " the document tree but cannot be represented by other simple selectors or"; + ret += "

Note that standalone pieces of PCDATA (text nodes in the DOM) are"; + ret += "

:root pseudo-class
"; + ret += "

The :root pseudo-class represents an element that is"; + ret += " HTML element."; + ret += "

:nth-child() pseudo-class
"; + ret += "

The"; + ret += " :nth-child(an+b)"; + ret += " an+b-1 siblings"; + ret += " before it in the document tree, for a given positive"; + ret += " integer or zero value of n, and has a parent element. In"; + ret += " other words, this matches the bth child of an element after"; + ret += " all the children have been split into groups of a elements"; + ret += " each. For example, this allows the selectors to address every other"; + ret += " of paragraph text in a cycle of four. The a and"; + ret += " b values must be zero, negative integers or positive"; + ret += "

In addition to this, :nth-child() can take"; + ret += " 'odd' and 'even' as arguments instead."; + ret += " 'odd' has the same signification as 2n+1,"; + ret += " and 'even' has the same signification as 2n."; + ret += "

"; + ret += "

Examples:

"; + ret += "
tr:nth-child(2n+1) /* represents every odd row of an HTML table */";
+    ret += "      p:nth-child(4n+4) { color: purple; }
"; + ret += "
"; + ret += "

When a=0, no repeating is used, so for example"; + ret += " :nth-child(0n+5) matches only the fifth child. When"; + ret += " a=0, the an part need not be"; + ret += " :nth-child(b) and the last example simplifies"; + ret += " to :nth-child(5)."; + ret += "

"; + ret += "

Examples:

"; + ret += "
foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */";
+    ret += "      foo:nth-child(1)      /* same */
"; + ret += "
"; + ret += "

When a=1, the number may be omitted from the rule."; + ret += "

"; + ret += "

Examples:

"; + ret += "

The following selectors are therefore equivalent:

"; + ret += "
bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */";
+    ret += "      bar                   /* same but lower specificity (0,0,1) */
"; + ret += "
"; + ret += "

If b=0, then every ath element is picked. In"; + ret += " such a case, the b part may be omitted."; + ret += "

"; + ret += "

Examples:

"; + ret += "
tr:nth-child(2n+0) /* represents every even row of an HTML table */";
+    ret += "      tr:nth-child(2n) /* same */
"; + ret += "
"; + ret += "

If both a and b are equal to zero, the"; + ret += " pseudo-class represents no element in the document tree.

"; + ret += "

The value a can be negative, but only the positive"; + ret += " values of an+b, for"; + ret += " n≥0, may represent an element in the document"; + ret += " tree.

"; + ret += "
"; + ret += "

Example:

"; + ret += "
html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
"; + ret += "
"; + ret += "

When the value b is negative, the '+' character in the"; + ret += " character indicating the negative value of b).

"; + ret += "
"; + ret += "

Examples:

"; + ret += "
:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */";
+    ret += "      :nth-child(10n+-1) /* Syntactically invalid, and would be ignored */
"; + ret += "
"; + ret += "
:nth-last-child() pseudo-class
"; + ret += "

The :nth-last-child(an+b)"; + ret += " an+b-1 siblings"; + ret += " after it in the document tree, for a given positive"; + ret += " integer or zero value of n, and has a parent element. See"; + ret += " :nth-child() pseudo-class for the syntax of its argument."; + ret += " It also accepts the 'even' and 'odd' values"; + ret += "

"; + ret += "

Examples:

"; + ret += "
tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */";
+    ret += "                                    counting from the last one */
"; + ret += "
"; + ret += "
:nth-of-type() pseudo-class
"; + ret += "

The :nth-of-type(an+b)"; + ret += " an+b-1 siblings with the same"; + ret += " element name before it in the document tree, for a"; + ret += " given zero or positive integer value of n, and has a"; + ret += " parent element. In other words, this matches the bth child"; + ret += " groups of a elements each. See :nth-child() pseudo-class"; + ret += " 'even' and 'odd' values."; + ret += "

"; + ret += "

CSS example:

"; + ret += "

This allows an author to alternate the position of floated images:

"; + ret += "
img:nth-of-type(2n+1) { float: right; }";
+    ret += "      img:nth-of-type(2n) { float: left; }
"; + ret += "
"; + ret += "
:nth-last-of-type() pseudo-class
"; + ret += "

The :nth-last-of-type(an+b)"; + ret += " an+b-1 siblings with the same"; + ret += " element name after it in the document tree, for a"; + ret += " given zero or positive integer value of n, and has a"; + ret += " parent element. See :nth-child() pseudo-class for the"; + ret += " syntax of its argument. It also accepts the 'even' and 'odd'"; + ret += "

"; + ret += "

Example:

"; + ret += "

To represent all h2 children of an XHTML"; + ret += " body except the first and last, one could use the"; + ret += " following selector:

"; + ret += "
body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
"; + ret += "

In this case, one could also use :not(), although the"; + ret += " selector ends up being just as long:

"; + ret += "
body > h2:not(:first-of-type):not(:last-of-type)
"; + ret += "
"; + ret += "
:first-child pseudo-class
"; + ret += "

Same as :nth-child(1). The :first-child"; + ret += "

"; + ret += "

Examples:

"; + ret += "

The following selector represents a p element that is"; + ret += " the first child of a div element:

"; + ret += "
div > p:first-child
"; + ret += "

This selector can represent the p inside the"; + ret += " div of the following fragment:

"; + ret += "
<p> The last P before the note.</p>";
+    ret += "      </div>
"; + ret += " but cannot represent the second p in the following"; + ret += "
<p> The last P before the note.</p>";
+    ret += "      </div>
"; + ret += "

The following two selectors are usually equivalent:

"; + ret += "
* > a:first-child /* a is first child of any element */";
+    ret += "      a:first-child /* Same (assuming a is not the root element) */
"; + ret += "
"; + ret += "
:last-child pseudo-class
"; + ret += "

Same as :nth-last-child(1). The :last-child"; + ret += "

"; + ret += "

Example:

"; + ret += "

The following selector represents a list item li that"; + ret += " is the last child of an ordered list ol."; + ret += "

ol > li:last-child
"; + ret += "
"; + ret += "
:first-of-type pseudo-class
"; + ret += "

Same as :nth-of-type(1). The :first-of-type"; + ret += "

"; + ret += "

Example:

"; + ret += "

The following selector represents a definition title"; + ret += " dt inside a definition list dl, this"; + ret += " dt being the first of its type in the list of children of"; + ret += " its parent element.

"; + ret += "
dl dt:first-of-type
"; + ret += "

It is a valid description for the first two dt"; + ret += " elements in the following example but not for the third one:

"; + ret += "
<dl>";
+    ret += "      </dl>
"; + ret += "
"; + ret += "
:last-of-type pseudo-class
"; + ret += "

Same as :nth-last-of-type(1). The"; + ret += " :last-of-type pseudo-class represents an element that is"; + ret += " element.

"; + ret += "
"; + ret += "

Example:

"; + ret += "

The following selector represents the last data cell"; + ret += " td of a table row.

"; + ret += "
tr > td:last-of-type
"; + ret += "
"; + ret += "
:only-child pseudo-class
"; + ret += "

Represents an element that has a parent element and whose parent"; + ret += " :first-child:last-child or"; + ret += " :nth-child(1):nth-last-child(1), but with a lower"; + ret += " specificity.

"; + ret += "
:only-of-type pseudo-class
"; + ret += "

Represents an element that has a parent element and whose parent"; + ret += " as :first-of-type:last-of-type or"; + ret += " :nth-of-type(1):nth-last-of-type(1), but with a lower"; + ret += " specificity.

"; + ret += "
:empty pseudo-class
"; + ret += "

The :empty pseudo-class represents an element that has"; + ret += " empty or not.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "

p:empty is a valid representation of the following fragment:"; + ret += "

"; + ret += "
<p></p>
"; + ret += "

foo:empty is not a valid representation for the"; + ret += " following fragments:

"; + ret += "
<foo>bar</foo>
"; + ret += "
<foo><bar>bla</bar></foo>
"; + ret += "
<foo>this is not <bar>:empty</bar></foo>
"; + ret += "
"; + ret += "

6.6.6. Blank

"; + ret += " "; + ret += "

This section intentionally left blank.

"; + ret += " "; + ret += "

6.6.7. The negation pseudo-class

"; + ret += "

The negation pseudo-class, :not(X), is a"; + ret += " functional notation taking a simple"; + ret += " selector (excluding the negation pseudo-class itself and"; + ret += " "; + ret += "

"; + ret += "

Examples:

"; + ret += "

The following CSS selector matches all button"; + ret += " elements in an HTML document that are not disabled.

"; + ret += "
button:not([DISABLED])
"; + ret += "

The following selector represents all but FOO"; + ret += " elements.

"; + ret += "
*:not(FOO)
"; + ret += "

The following group of selectors represents all HTML elements"; + ret += " except links.

"; + ret += "
html|*:not(:link):not(:visited)
"; + ret += "
"; + ret += "

Default namespace declarations do not affect the argument of the"; + ret += " type selector.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "

Assuming that the default namespace is bound to"; + ret += " elements that are not in that namespace:

"; + ret += "
*|*:not(*)
"; + ret += "

The following CSS selector matches any element being hovered,"; + ret += " rule when they are being hovered.

"; + ret += "
*|*:not(:hover)
"; + ret += "
"; + ret += "

Note: the :not() pseudo allows"; + ret += " useless selectors to be written. For instance :not(*|*),"; + ret += " which represents no element at all, or foo:not(bar),"; + ret += " which is equivalent to foo but with a higher"; + ret += " specificity.

"; + ret += "

7. Pseudo-elements

"; + ret += "

Pseudo-elements create abstractions about the document tree beyond"; + ret += " source document (e.g., the ::before and"; + ret += " ::after pseudo-elements give access to generated"; + ret += " content).

"; + ret += "

A pseudo-element is made of two colons (::) followed"; + ret += " by the name of the pseudo-element.

"; + ret += "

This :: notation is introduced by the current document"; + ret += " :first-line, :first-letter,"; + ret += " :before and :after). This compatibility is"; + ret += " not allowed for the new pseudo-elements introduced in CSS level 3.

"; + ret += "

Only one pseudo-element may appear per selector, and if present it"; + ret += " must appear after the sequence of simple selectors that represents the"; + ret += " subjects of the selector. A"; + ret += " pesudo-elements per selector.

"; + ret += "

7.1. The ::first-line pseudo-element

"; + ret += "

The ::first-line pseudo-element describes the contents"; + ret += "

"; + ret += "

CSS example:

"; + ret += "
p::first-line { text-transform: uppercase }
"; + ret += "

The above rule means 'change the letters of the first line of every"; + ret += " paragraph to uppercase'.

"; + ret += "
"; + ret += "

The selector p::first-line does not match any real"; + ret += " agents will insert at the beginning of every paragraph.

"; + ret += "

Note that the length of the first line depends on a number of"; + ret += " an ordinary HTML paragraph such as:

"; + ret += "
      <P>This is a somewhat long HTML ";
+    ret += "      
"; + ret += "

the lines of which happen to be broken as follows:"; + ret += "

      THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT";
+    ret += "      
"; + ret += "

This paragraph might be 'rewritten' by user agents to include the"; + ret += " fictional tag sequence for ::first-line. This"; + ret += " fictional tag sequence helps to show how properties are inherited.

"; + ret += "
      <P><P::first-line> This is a somewhat long HTML ";
+    ret += "      paragraph that </P::first-line> will be broken into several";
+    ret += "      
"; + ret += "

If a pseudo-element breaks up a real element, the desired effect"; + ret += " with a span element:

"; + ret += "
      <P><SPAN class='test'> This is a somewhat long HTML";
+    ret += "      lines.</SPAN> The first line will be identified";
+    ret += "      
"; + ret += "

the user agent could simulate start and end tags for"; + ret += " span when inserting the fictional tag sequence for"; + ret += " ::first-line."; + ret += "

      <P><P::first-line><SPAN class='test'> This is a";
+    ret += "      paragraph that will </SPAN></P::first-line><SPAN";
+    ret += "          class='test'> be";
+    ret += "      lines.</SPAN> The first line will be identified";
+    ret += "      
"; + ret += "

In CSS, the ::first-line pseudo-element can only be"; + ret += " or a table-cell.

"; + ret += "

The 'first formatted line' of an"; + ret += " line of the div in <DIV><P>This"; + ret += " line...</P></DIV> is the first line of the p"; + ret += " that both p and div are block-level)."; + ret += "

The first line of a table-cell or inline-block cannot be the first"; + ret += " formatted line of an ancestor element. Thus, in <DIV><P"; + ret += " etcetera</DIV> the first formatted line of the"; + ret += " div is not the line 'Hello'."; + ret += "

Note that the first line of the p in this"; + ret += " fragment: <p><br>First... doesn't contain any"; + ret += " letters (assuming the default style for br in HTML"; + ret += "

A UA should act as if the fictional start tags of the"; + ret += " ::first-line pseudo-elements were nested just inside the"; + ret += " is an example. The fictional tag sequence for

"; + ret += "
      <DIV>";
+    ret += "      
"; + ret += "

is

"; + ret += "
      <DIV>";
+    ret += "      
"; + ret += "

The ::first-line pseudo-element is similar to an"; + ret += " following properties apply to a ::first-line"; + ret += " properties as well.

"; + ret += "

7.2. The ::first-letter pseudo-element

"; + ret += "

The ::first-letter pseudo-element represents the first"; + ret += " is 'none'; otherwise, it is similar to a floated element.

"; + ret += "

In CSS, these are the properties that apply to ::first-letter"; + ret += " of the letter, unlike for normal elements.

"; + ret += "
"; + ret += "

Example:

"; + ret += "

This example shows a possible rendering of an initial cap. Note"; + ret += " ::first-letter"; + ret += " fictional start tag of the first letter is inside the span,"; + ret += " the font weight of the first letter is normal, not bold as the span:"; + ret += "

      p { line-height: 1.1 }";
+    ret += "      
"; + ret += "
"; + ret += "

Image illustrating the ::first-letter pseudo-element"; + ret += "

"; + ret += "
"; + ret += "
"; + ret += "

The following CSS will make a drop cap initial letter span about two"; + ret += " lines:

"; + ret += "
      <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'>";
+    ret += "      
"; + ret += "

This example might be formatted as follows:

"; + ret += "
"; + ret += "

Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements"; + ret += "

"; + ret += "
"; + ret += "

The fictional tag sequence is:

"; + ret += "
      <P>";
+    ret += "      
"; + ret += "

Note that the ::first-letter pseudo-element tags abut"; + ret += " block element.

"; + ret += "

In order to achieve traditional drop caps formatting, user agents"; + ret += " glyph outline may be taken into account when formatting.

"; + ret += "

Punctuation (i.e, characters defined in Unicode in the 'open' (Ps),"; + ret += " be included. [UNICODE]

"; + ret += "
"; + ret += "

Quotes that precede the";
+    ret += "      first letter should be included.

"; + ret += "
"; + ret += "

The ::first-letter also applies if the first letter is"; + ret += " money.'

"; + ret += "

In CSS, the ::first-letter pseudo-element applies to"; + ret += " elements. A future version of this specification"; + ret += " types.

"; + ret += "

The ::first-letter pseudo-element can be used with all"; + ret += " the element, even if that first text is in a descendant.

"; + ret += "
"; + ret += "

Example:

"; + ret += "

The fictional tag sequence for this HTMLfragment:"; + ret += "

<div>";
+    ret += "      <p>The first text.
"; + ret += "

is:"; + ret += "

<div>";
+    ret += "      <p><div::first-letter><p::first-letter>T</...></...>he first text.
"; + ret += "
"; + ret += "

The first letter of a table-cell or inline-block cannot be the"; + ret += " first letter of an ancestor element. Thus, in <DIV><P"; + ret += " etcetera</DIV> the first letter of the div is"; + ret += " letter 'H'. In fact, the div doesn't have a first letter."; + ret += "

The first letter must occur on the first formatted line. For example, in"; + ret += " this fragment: <p><br>First... the first line"; + ret += " doesn't contain any letters and ::first-letter doesn't"; + ret += " match anything (assuming the default style for br in HTML"; + ret += "

In CSS, if an element is a list item ('display: list-item'), the"; + ret += " ::first-letter applies to the first letter in the"; + ret += " ::first-letter on list items with 'list-style-position:"; + ret += " inside'. If an element has ::before or"; + ret += " ::after content, the ::first-letter applies"; + ret += " to the first letter of the element including that content."; + ret += "

"; + ret += "

Example:

"; + ret += "

After the rule 'p::before {content: 'Note: '}', the selector"; + ret += " 'p::first-letter' matches the 'N' of 'Note'.

"; + ret += "
"; + ret += "

Some languages may have specific rules about how to treat certain"; + ret += " considered within the ::first-letter pseudo-element."; + ret += "

If the letters that would form the ::first-letter are not in the"; + ret += " same element, such as ''T' in <p>'<em>T..., the UA"; + ret += " both elements, or simply not create a pseudo-element.

"; + ret += "

Similarly, if the first letter(s) of the block are not at the start"; + ret += "

"; + ret += "

Example:

"; + ret += "

The following example illustrates"; + ret += " paragraph will be 'red'.

"; + ret += "
p { color: red; font-size: 12pt }";
+    ret += "      <P>Some text that ends up on two lines</P>
"; + ret += "

Assuming that a line break will occur before the word 'ends', the"; + ret += " fictional tag"; + ret += " sequence for this fragment might be:

"; + ret += "
<P>";
+    ret += "      </P>
"; + ret += "

Note that the ::first-letter element is inside the ::first-line"; + ret += " element. Properties set on ::first-line are inherited by"; + ret += " ::first-letter, but are overridden if the same property is"; + ret += " ::first-letter.

"; + ret += "
"; + ret += "

7.3. The ::selection"; + ret += " pseudo-element

"; + ret += "

The ::selection pseudo-element applies to the portion"; + ret += " field. This pseudo-element should not be confused with the :checked pseudo-class (which used to be"; + ret += " named :selected)"; + ret += "

Although the ::selection pseudo-element is dynamic in"; + ret += " [CSS21]) which was originally rendered to a"; + ret += " ::selection state to that other medium, and have all the"; + ret += " required — UAs may omit the ::selection"; + ret += "

These are the CSS properties that apply to ::selection"; + ret += " ::selection may be ignored."; + ret += "

7.4. The ::before and ::after pseudo-elements

"; + ret += "

The ::before and ::after pseudo-elements"; + ret += " content. They are explained in CSS 2.1 [CSS21].

"; + ret += "

When the ::first-letter and ::first-line"; + ret += " pseudo-elements are combined with ::before and"; + ret += " ::after, they apply to the first letter or line of the"; + ret += " element including the inserted text.

"; + ret += "

8. Combinators

"; + ret += "

8.1. Descendant combinator

"; + ret += "

At times, authors may want selectors to describe an element that is"; + ret += " EM element that is contained within an H1"; + ret += " descendant combinator is white space that"; + ret += " separates two sequences of simple selectors. A selector of the form"; + ret += " 'A B' represents an element B that is an"; + ret += " arbitrary descendant of some ancestor element A."; + ret += "

"; + ret += "

Examples:

"; + ret += "

For example, consider the following selector:

"; + ret += "
h1 em
"; + ret += "

It represents an em element being the descendant of"; + ret += " an h1 element. It is a correct and valid, but partial,"; + ret += " description of the following fragment:

"; + ret += "
<h1>This <span class='myclass'>headline";
+    ret += "      is <em>very</em> important</span></h1>
"; + ret += "

The following selector:

"; + ret += "
div * p
"; + ret += "

represents a p element that is a grandchild or later"; + ret += " descendant of a div element. Note the whitespace on"; + ret += " of the P.

"; + ret += "

The following selector, which combines descendant combinators and"; + ret += " attribute selectors, represents an"; + ret += " element that (1) has the href attribute set and (2) is"; + ret += " inside a p that is itself inside a div:

"; + ret += "
div p *[href]
"; + ret += "
"; + ret += "

8.2. Child combinators

"; + ret += "

A child combinator describes a childhood relationship"; + ret += " 'greater-than sign' (>) character and"; + ret += " separates two sequences of simple selectors."; + ret += "

"; + ret += "

Examples:

"; + ret += "

The following selector represents a p element that is"; + ret += " child of body:

"; + ret += "
body > p
"; + ret += "

The following example combines descendant combinators and child"; + ret += " combinators.

"; + ret += "
div ol>li p
"; + ret += " "; + ret += "

It represents a p element that is a descendant of an"; + ret += " li element; the li element must be the"; + ret += " child of an ol element; the ol element must"; + ret += " be a descendant of a div. Notice that the optional white"; + ret += " space around the '>' combinator has been left out.

"; + ret += "
"; + ret += "

For information on selecting the first child of an element, please"; + ret += " see the section on the :first-child pseudo-class"; + ret += " above.

"; + ret += "

8.3. Sibling combinators

"; + ret += "

There are two different sibling combinators: the adjacent sibling"; + ret += " considering adjacency of elements.

"; + ret += "

8.3.1. Adjacent sibling combinator"; + ret += "

"; + ret += "

The adjacent sibling combinator is made of the 'plus"; + ret += " sign' (U+002B, +) character that separates two"; + ret += " sequences of simple selectors. The elements represented by the two"; + ret += " represented by the second one.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "

The following selector represents a p element"; + ret += " immediately following a math element:

"; + ret += "
math + p
"; + ret += "

The following selector is conceptually similar to the one in the"; + ret += " adds a constraint to the h1 element, that it must have"; + ret += " class='opener':

"; + ret += "
h1.opener + h2
"; + ret += "
"; + ret += "

8.3.2. General sibling combinator"; + ret += "

"; + ret += "

The general sibling combinator is made of the 'tilde'"; + ret += " (U+007E, ~) character that separates two sequences of"; + ret += " simple selectors. The elements represented by the two sequences share"; + ret += " represented by the second one.

"; + ret += "
"; + ret += "

Example:

"; + ret += "
h1 ~ pre
"; + ret += "

represents a pre element following an h1. It"; + ret += " is a correct and valid, but partial, description of:

"; + ret += "
<h1>Definition of the function a</h1>";
+    ret += "      <pre>function a(x) = 12x/13.5</pre>
"; + ret += "
"; + ret += "

9. Calculating a selector's specificity

"; + ret += "

A selector's specificity is calculated as follows:

"; + ret += "
    "; + ret += "
  • count the number of ID selectors in the selector (= a)
  • "; + ret += "
  • count the number of class selectors, attributes selectors, and"; + ret += "
  • "; + ret += "
  • count the number of element names in the selector (= c)
  • "; + ret += "
  • ignore pseudo-elements
  • "; + ret += "
"; + ret += "

Selectors inside the negation pseudo-class"; + ret += " a pseudo-class.

"; + ret += "

Concatenating the three numbers a-b-c (in a number system with a"; + ret += " large base) gives the specificity.

"; + ret += "
"; + ret += "

Examples:

"; + ret += "
*               /* a=0 b=0 c=0 -> specificity =   0 */";
+    ret += "      
"; + ret += "
"; + ret += "

Note: the specificity of the styles"; + ret += " specified in an HTML style attribute is described in CSS"; + ret += " 2.1. [CSS21].

"; + ret += "

10. The grammar of Selectors

"; + ret += "

10.1. Grammar

"; + ret += "

The grammar below defines the syntax of Selectors. It is globally"; + ret += " shorthand notations beyond Yacc (see [YACC])"; + ret += " are used:

"; + ret += "
    "; + ret += "
  • *: 0 or more"; + ret += "
  • +: 1 or more"; + ret += "
  • ?: 0 or 1"; + ret += "
  • |: separates alternatives"; + ret += "
  • [ ]: grouping
  • "; + ret += "
"; + ret += "

The productions are:

"; + ret += "
selectors_group";
+    ret += "        ;
"; + ret += "

10.2. Lexical scanner

"; + ret += "

The following is the tokenizer, written in Flex (see"; + ret += " [FLEX]) notation. The tokenizer is"; + ret += " case-insensitive.

"; + ret += "

The two occurrences of '\377' represent the highest character"; + ret += " possible code point in Unicode/ISO-10646. [UNICODE]

"; + ret += "
%option case-insensitive";
+    ret += "      .                return *yytext;
"; + ret += "

11. Namespaces and down-level clients

"; + ret += "

An important issue is the interaction of CSS selectors with XML"; + ret += " to construct a CSS style sheet which will properly match selectors in"; + ret += " is possible to construct a style sheet in which selectors would match"; + ret += " elements and attributes correctly.

"; + ret += "

It should be noted that a down-level CSS client will (if it"; + ret += " @namespace at-rules, as well as all style rules that make"; + ret += " use of namespace qualified element type or attribute selectors. The"; + ret += " than possibly match them incorrectly.

"; + ret += "

The use of default namespaces in CSS makes it possible to write"; + ret += " element type selectors that will function in both namespace aware CSS"; + ret += " down-level clients may incorrectly match selectors against XML"; + ret += " elements in other namespaces.

"; + ret += "

The following are scenarios and examples in which it is possible to"; + ret += " that do not implement this proposal.

"; + ret += "
    "; + ret += "
  1. "; + ret += "

    The XML document does not use namespaces.

    "; + ret += "
      "; + ret += "
    • In this case, it is obviously not necessary to declare or use"; + ret += " attribute selectors will function adequately in a down-level"; + ret += "
    • "; + ret += "
    • In a CSS namespace aware client, the default behavior of"; + ret += " element selectors matching without regard to namespace will"; + ret += " present. However, the use of specific element type selectors"; + ret += " match only elements that have no namespace ('|name')"; + ret += " will guarantee that selectors will match only XML elements that"; + ret += "
    • "; + ret += "
    "; + ret += "
  2. "; + ret += "
  3. "; + ret += "

    The XML document defines a single, default namespace used"; + ret += " names.

    "; + ret += "
      "; + ret += "
    • In this case, a down-level client will function as if"; + ret += " element type and attribute selectors will match against all"; + ret += "
    • "; + ret += "
    "; + ret += "
  4. "; + ret += "
  5. "; + ret += "

    The XML document does not use a default namespace, all"; + ret += " to the same URI).

    "; + ret += "
      "; + ret += "
    • In this case, the down-level client will view and match"; + ret += " element type and attribute selectors based on their fully"; + ret += " qualified name, not the local part as outlined in the Type selectors and Namespaces"; + ret += " selectors may be declared using an escaped colon"; + ret += " '\\:'"; + ret += " 'html\\:h1' will match"; + ret += " <html:h1>. Selectors using the qualified name"; + ret += "
    • "; + ret += "
    • Note that selectors declared in this fashion will"; + ret += " only match in down-level clients. A CSS namespace aware"; + ret += " client will match element type and attribute selectors based on"; + ret += " the name's local part. Selectors declared with the fully"; + ret += "
    • "; + ret += "
    "; + ret += "
  6. "; + ret += "
"; + ret += "

In other scenarios: when the namespace prefixes used in the XML are"; + ret += " different namespace URIs within the same document, or in"; + ret += " a CSS and XML namespace aware client.

"; + ret += "

12. Profiles

"; + ret += "

Each specification using Selectors must define the subset of W3C"; + ret += " Selectors it allows and excludes, and describe the local meaning of"; + ret += " all the components of that subset.

"; + ret += "

Non normative examples:"; + ret += "

"; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += "
Selectors profile
SpecificationCSS level 1
Acceptstype selectors
class selectors
ID selectors
:link,"; + ret += " :visited and :active pseudo-classes
descendant combinator"; + ret += "
::first-line and ::first-letter pseudo-elements"; + ret += "
Excludes"; + ret += "

universal selector
attribute selectors
:hover and"; + ret += " pseudo-classes
:target pseudo-class
:lang()"; + ret += " pseudo-class
all UI"; + ret += " element states pseudo-classes
all structural"; + ret += " pseudo-classes
negation pseudo-class
all"; + ret += " UI element fragments pseudo-elements
::before and ::after"; + ret += " pseudo-elements
child combinators
sibling combinators"; + ret += "

namespaces

Extra constraintsonly one class selector allowed per sequence of simple"; + ret += " selectors"; + ret += "
"; + ret += "

"; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += "
Selectors profile
SpecificationCSS level 2
Acceptstype selectors
universal selector
attribute presence and"; + ret += " values selectors
class selectors
ID selectors
:link,"; + ret += "
descendant combinator
child combinator
adjacent"; + ret += " combinator
::first-line and ::first-letter"; + ret += " pseudo-elements
::before"; + ret += "
Excludes"; + ret += "

content selectors
substring matching attribute"; + ret += " selectors
:target pseudo-classes
all UI element"; + ret += " states pseudo-classes
all structural pseudo-classes other"; + ret += " than :first-child
negation pseudo-class
all UI element"; + ret += " fragments pseudo-elements
general sibling combinators"; + ret += "

namespaces

Extra constraintsmore than one class selector per sequence of simple selectors"; + ret += "
"; + ret += "

In CSS, selectors express pattern matching rules that determine which"; + ret += "

The following selector (CSS level 2) will match all anchors a"; + ret += " with attribute name set inside a section 1 header"; + ret += " h1:"; + ret += "

h1 a[name]
"; + ret += "

All CSS declarations attached to such a selector are applied to elements"; + ret += " matching it.

"; + ret += "
"; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += " "; + ret += "
Selectors profile
SpecificationSTTS 3
Accepts"; + ret += "

type selectors
universal selectors
attribute"; + ret += " selectors
class"; + ret += " selectors
ID selectors
all structural"; + ret += " pseudo-classes
"; + ret += "

namespaces

Excludesnon-accepted pseudo-classes
pseudo-elements
Extra constraintssome selectors and combinators are not allowed in fragment"; + ret += "
"; + ret += "

Selectors can be used in STTS 3 in two different"; + ret += "

    "; + ret += "
  1. a selection mechanism equivalent to CSS selection mechanism:"; + ret += "
  2. fragment descriptions that appear on the right side of declarations."; + ret += "
  3. "; + ret += "
"; + ret += "
"; + ret += "

13. Conformance and requirements

"; + ret += "

This section defines conformance with the present specification only."; + ret += "

The inability of a user agent to implement part of this specification due to"; + ret += "

All specifications reusing Selectors must contain a Profile listing the"; + ret += " subset of Selectors it accepts or excludes, and describing the constraints"; + ret += "

Invalidity is caused by a parsing error, e.g. an unrecognized token or a"; + ret += "

User agents must observe the rules for handling parsing errors:"; + ret += "

    "; + ret += "
  • a simple selector containing an undeclared namespace prefix is invalid"; + ret += "
  • "; + ret += "
  • a selector containing an invalid simple selector, an invalid combinator"; + ret += "
  • "; + ret += "
  • a group of selectors containing an invalid selector is invalid.
  • "; + ret += "
"; + ret += "

Specifications reusing Selectors must define how to handle parsing"; + ret += " used is dropped.)

"; + ret += " "; + ret += "

14. Tests

"; + ret += "

This specification has a test"; + ret += " suite allowing user agents to verify their basic conformance to"; + ret += " and does not cover all possible combined cases of Selectors.

"; + ret += "

15. Acknowledgements

"; + ret += "

The CSS working group would like to thank everyone who has sent"; + ret += " comments on this specification over the years.

"; + ret += "

The working group would like to extend special thanks to Donna"; + ret += " the final editorial review.

"; + ret += "

16. References

"; + ret += "
"; + ret += "
[CSS1]"; + ret += "
Bert Bos, HÃ¥kon Wium Lie; 'Cascading"; + ret += " Style Sheets, level 1', W3C Recommendation, 17 Dec 1996, revised"; + ret += "
(http://www.w3.org/TR/REC-CSS1)"; + ret += "
[CSS21]"; + ret += "
Bert Bos, Tantek Çelik, Ian Hickson, Håkon"; + ret += " Wium Lie, editors; 'Cascading Style Sheets, level 2 revision"; + ret += " 1', W3C Working Draft, 13 June 2005"; + ret += "
(http://www.w3.org/TR/CSS21)"; + ret += "
[CWWW]"; + ret += "
Martin J. Dürst, François Yergeau,"; + ret += " Misha Wolf, Asmus Freytag, Tex Texin, editors; 'Character Model"; + ret += " for the World Wide Web', W3C Recommendation, 15 February 2005"; + ret += "
(http://www.w3.org/TR/charmod/)"; + ret += "
[FLEX]"; + ret += "
'Flex: The Lexical Scanner"; + ret += " Generator', Version 2.3.7, ISBN 1882114213"; + ret += "
[HTML4]"; + ret += "
Dave Ragget, Arnaud Le Hors, Ian Jacobs,"; + ret += " editors; 'HTML 4.01 Specification', W3C Recommendation, 24"; + ret += "
"; + ret += " (http://www.w3.org/TR/html4/)"; + ret += "
[MATH]"; + ret += "
Patrick Ion, Robert Miner, editors; 'Mathematical"; + ret += " Markup Language (MathML) 1.01', W3C Recommendation, revision of 7"; + ret += "
(http://www.w3.org/TR/REC-MathML/)"; + ret += "
[RFC3066]"; + ret += "
H. Alvestrand; 'Tags for the"; + ret += " Identification of Languages', Request for Comments 3066, January"; + ret += "
(http://www.ietf.org/rfc/rfc3066.txt)"; + ret += "
[STTS]"; + ret += "
Daniel Glazman; 'Simple Tree Transformation"; + ret += " Sheets 3', Electricité de France, submission to the W3C,"; + ret += "
(http://www.w3.org/TR/NOTE-STTS3)"; + ret += "
[SVG]"; + ret += "
Jon Ferraiolo, 藤沢 淳, Dean"; + ret += " Jackson, editors; 'Scalable Vector Graphics (SVG) 1.1"; + ret += " Specification', W3C Recommendation, 14 January 2003"; + ret += "
(http://www.w3.org/TR/SVG/)"; + ret += "
[UNICODE]
"; + ret += "
The Unicode"; + ret += " Standard, Version 4.1, The Unicode Consortium. Boston, MA,"; + ret += " Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by Unicode"; + ret += " 4.0.1 and Unicode"; + ret += " 4.1.0."; + ret += "
(http://www.unicode.org/versions/)"; + ret += "
"; + ret += "
[XML10]"; + ret += "
Tim Bray, Jean Paoli, C. M. Sperberg-McQueen,"; + ret += " Eve Maler, François Yergeau, editors; 'Extensible Markup"; + ret += " Language (XML) 1.0 (Third Edition)', W3C Recommendation, 4"; + ret += "
(http://www.w3.org/TR/REC-xml/)"; + ret += "
[XMLNAMES]"; + ret += "
Tim Bray, Dave Hollander, Andrew Layman,"; + ret += " editors; 'Namespaces in XML', W3C Recommendation, 14"; + ret += "
(http://www.w3.org/TR/REC-xml-names/)"; + ret += "
[YACC]"; + ret += "
S. C. Johnson; 'YACC — Yet another"; + ret += " compiler compiler', Technical Report, Murray Hill, 1975"; + ret += "
';
"; + ret += " 1"; + ret += " 2"; + $(e).html(ret); } + } diff --git a/samples/src/main/java/gwtquery/samples/client/MySelectors.java b/samples/src/main/java/gwtquery/samples/client/MySelectors.java index 2bbffad1..63317122 100644 --- a/samples/src/main/java/gwtquery/samples/client/MySelectors.java +++ b/samples/src/main/java/gwtquery/samples/client/MySelectors.java @@ -1,6 +1,7 @@ package gwtquery.samples.client; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.NodeList; import com.google.gwt.query.client.Selector; import com.google.gwt.query.client.Selectors; @@ -11,122 +12,122 @@ import com.google.gwt.query.client.Selectors; public interface MySelectors extends Selectors { @Selector("h1[id]:contains(Selectors)") - NodeList h1IdContainsSelectors(); + NodeList h1IdContainsSelectors(Node n); @Selector("a[href][lang][class]") - NodeList aHrefLangClass(); + NodeList aHrefLangClass(Node n); - @Selector("*:checked") - NodeList allChecked(); +// @Selector("*:checked") +// NodeList allChecked(Node n); @Selector("body") - NodeList body(); + NodeList body(Node n); @Selector("body div") - NodeList bodyDiv(); + NodeList bodyDiv(Node n); @Selector("div .example") - NodeList divExample(); + NodeList divExample(Node n); @Selector("div > div") - NodeList divGtP(); + NodeList divGtP(Node n); // @Selector("*:first") -// NodeList allFirst(); +// NodeList allFirst(Node n); @Selector("div:not(.example)") - NodeList divNotExample(); + NodeList divNotExample(Node n); @Selector("div p") - NodeList divP(); + NodeList divP(Node n); @Selector("div p a") - NodeList divPA(); + NodeList divPA(Node n); @Selector("div + p") - NodeList divPlusP(); + NodeList divPlusP(Node n); @Selector("div[class^=exa][class$=mple]") - NodeList divPrefixExaSuffixMple(); + NodeList divPrefixExaSuffixMple(Node n); @Selector("div #title") - NodeList divSpaceTitle(); + NodeList divSpaceTitle(Node n); @Selector("div ~ p") - NodeList divTildeP(); + NodeList divTildeP(Node n); @Selector("div[class]") - NodeList divWithClass(); + NodeList divWithClass(Node n); @Selector("div[class~=dialog]") - NodeList divWithClassContainsDialog(); + NodeList divWithClassContainsDialog(Node n); @Selector("div[class*=e]") - NodeList divWithClassContainsE(); + NodeList divWithClassContainsE(Node n); @Selector("div[class=example]") - NodeList divWithClassExample(); + NodeList divWithClassExample(Node n); @Selector("div[class!=madeup]") - NodeList divWithClassNotContainsMadeup(); + NodeList divWithClassNotContainsMadeup(Node n); @Selector("div[class~=dialog]") - NodeList divWithClassListContainsDialog(); + NodeList divWithClassListContainsDialog(Node n); @Selector("div[class^=exa]") - NodeList divWithClassPrefixExa(); + NodeList divWithClassPrefixExa(Node n); @Selector("div[class$=mple]") - NodeList divWithClassSuffixMple(); + NodeList divWithClassSuffixMple(Node n); @Selector("p:first-child") - NodeList firstChild(); + NodeList firstChild(Node n); @Selector("h1#title") - NodeList h1Title(); + NodeList h1Title(Node n); @Selector("h1#title + div > p") - NodeList h1TitlePlusDivGtP(); + NodeList h1TitlePlusDivGtP(Node n); @Selector("p:last-child") - NodeList lastChild(); + NodeList lastChild(Node n); @Selector("div, p a") - NodeList divCommaPA(); + NodeList divCommaPA(Node n); @Selector(".note") - NodeList note(); + NodeList note(Node n); @Selector("p:nth-child(n)") - NodeList nthChild(); + NodeList nthChild(Node n); @Selector("p:nth-child(2n)") - NodeList nThChild2n(); + NodeList nThChild2n(Node n); @Selector("p:nth-child(2n+1)") - NodeList nThChild2nPlus1(); + NodeList nThChild2nPlus1(Node n); @Selector("p:contains(selectors)") - NodeList pContainsSelectors(); + NodeList pContainsSelectors(Node n); @Selector("p:nth-child(even)") - NodeList nThChildEven(); + NodeList nThChildEven(Node n); @Selector("p:nth-child(odd)") - NodeList nThChildOdd(); + NodeList nThChildOdd(Node n); @Selector("p:only-child") - NodeList onlyChild(); + NodeList onlyChild(Node n); @Selector("#title") - NodeList title(); + NodeList title(Node n); @Selector("#title,h1#title") - NodeList titleAndh1Title(); + NodeList titleAndh1Title(Node n); @Selector("ul .tocline2") - NodeList ulTocline2(); + NodeList ulTocline2(Node n); @Selector("ui.toc li.tocline2") - NodeList ulTocLiTocLine2(); + NodeList ulTocLiTocLine2(Node n); } diff --git a/samples/src/main/java/gwtquery/samples/public/DOMAssistantComplete-2.7.js b/samples/src/main/java/gwtquery/samples/public/DOMAssistantComplete-2.7.js deleted file mode 100644 index ae887c9d..00000000 --- a/samples/src/main/java/gwtquery/samples/public/DOMAssistantComplete-2.7.js +++ /dev/null @@ -1,1545 +0,0 @@ -// Developed by Robert Nyman/DOMAssistant team, code/licensing: http://code.google.com/p/domassistant/, documentation: http://www.domassistant.com/documentation, version 2.7 -var DOMAssistant = function () { - var HTMLArray = function () { - // Constructor - }; - var isIE = /*@cc_on!@*/false; - var cachedElms = []; - var pushAll = function (set1, set2) { - for (var j = 0, jL = set2.length; j < jL; j++) { - set1.push(set2[j]); - } - return set1; - }; - if (isIE) { - pushAll = function (set1, set2) { - if (set2.slice) { - return set1.concat(set2); - } - for (var i = 0, iL = set2.length; i < iL; i++) { - set1[set1.length] = set2[i]; - } - return set1; - }; - } - return { - allMethods : [], - publicMethods : [ - "cssSelect", - "elmsByClass", - "elmsByAttribute", - "elmsByTag" - ], - - initCore : function () { - this.applyMethod.call(window, "$", this.$); - this.applyMethod.call(window, "$$", this.$$); - window.DOMAssistant = this; - if (isIE) { - HTMLArray = Array; - } - HTMLArray.prototype = []; - HTMLArray.prototype.each = function (functionCall) { - for (var i = 0, il = this.length; i < il; i++) { - functionCall.call(this[i]); - } - return this; - }; - HTMLArray.prototype.first = function () { - return (typeof this[0] !== "undefined") - ? DOMAssistant.addMethodsToElm(this[0]) : null; - }; - HTMLArray.prototype.end = function () { - return this.previousSet; - }; - this.attach(this); - }, - - addMethods : function (name, method) { - if (typeof this.allMethods[name] === "undefined") { - this.allMethods[name] = method; - this.addHTMLArrayPrototype(name, method); - } - }, - - addMethodsToElm : function (elm) { - for (var method in this.allMethods) { - if (typeof this.allMethods[method] !== "undefined") { - this.applyMethod.call(elm, method, this.allMethods[method]); - } - } - return elm; - }, - - applyMethod : function (method, func) { - if (typeof this[method] !== "function") { - this[method] = func; - } - }, - - attach : function (plugin) { - var publicMethods = plugin.publicMethods; - if (typeof publicMethods === "undefined") { - for (var method in plugin) { - if (method !== "init" && typeof plugin[method] - !== "undefined") { - this.addMethods(method, plugin[method]); - } - } - } else if (publicMethods.constructor === Array) { - for (var i = 0, current; (current = publicMethods[i]); i++) { - this.addMethods(current, plugin[current]); - } - } - if (typeof plugin.init === "function") { - plugin.init(); - } - }, - - addHTMLArrayPrototype : function (name, method) { - HTMLArray.prototype[name] = function () { - var elmsToReturn = new HTMLArray(); - elmsToReturn.previousSet = this; - var elms; - for (var i = 0, il = this.length; i < il; i++) { - elms = method.apply(this[i], arguments); - if (typeof elms !== "undefined" && elms !== null - && elms.constructor === Array) { - elmsToReturn = pushAll(elmsToReturn, elms); - } else { - elmsToReturn.push(elms); - } - } - return elmsToReturn; - }; - }, - - getSequence : function (expression) { - var start, add = 2, max = -1, modVal = -1; - var expressionRegExp = /^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n((\+|\-)(\d+))?)|(\-(([1-9]\d*)?)n\+(\d+)))$/; - var pseudoValue = expressionRegExp.exec(expression); - if (!pseudoValue) { - return null; - } else { - if (pseudoValue[2]) { // odd or even - start = (pseudoValue[2] === "odd") ? 1 : 2; - modVal = (start === 1) ? 1 : 0; - } else if (pseudoValue[3]) { // single digit - start = parseInt(pseudoValue[3], 10); - add = 0; - max = start; - } else if (pseudoValue[4]) { // an+b - add = pseudoValue[6] ? parseInt(pseudoValue[6], 10) : 1; - start = pseudoValue[7] ? parseInt(pseudoValue[8] - + pseudoValue[9], 10) : 0; - while (start < 1) { - start += add; - } - modVal = (start > add) ? (start - add) % add : ((start - === add) ? 0 : start); - } else if (pseudoValue[10]) { // -an+b - add = pseudoValue[12] ? parseInt(pseudoValue[12], 10) : 1; - start = max = parseInt(pseudoValue[13], 10); - while (start > add) { - start -= add; - } - modVal = (max > add) ? (max - add) % add : ((max === add) - ? 0 : max); - } - } - return { start: start, add: add, max: max, modVal: modVal }; - }, - - $ : function () { - var elm = new HTMLArray(); - if (document.getElementById) { - var arg = arguments[0]; - if (typeof arg === "string") { - arg = arg.replace(/^[^#]*(#)/, "$1"); - if (/^#[\w\u00C0-\uFFFF\-\_]+$/.test(arg)) { - var idMatch = DOMAssistant.$$(arg.substr(1), false); - if (idMatch) { - elm.push(idMatch); - } - } else { - elm = DOMAssistant.cssSelection.call(document, arg); - } - } else if (typeof arg === "object") { - elm = (arguments.length === 1) ? DOMAssistant.$$(arg) - : pushAll(elm, arguments); - } - } - return elm; - }, - - $$ : function (id, addMethods) { - var elm = (typeof id === "object") ? id - : document.getElementById(id); - var applyMethods = addMethods || true; - if (typeof id === "string" && elm && elm.id !== id) { - elm = null; - for (var i = 0, item; (item = document.all[i]); i++) { - if (item.id === id) { - elm = item; - break; - } - } - } - if (elm && applyMethods) { - DOMAssistant.addMethodsToElm(elm); - } - return elm; - }, - - cssSelection : function (cssRule) { - if (document.evaluate) { - DOMAssistant.cssSelection = function (cssRule) { - var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(","); - var elm = new HTMLArray(); - var currentRule, identical, cssSelectors, xPathExpression, cssSelector, splitRule, sequence; - var cssSelectorRegExp = /^(\w+)?(#[\w\u00C0-\uFFFF\-\_]+|(\*))?((\.[\w\u00C0-\uFFFF\-_]+)*)?((\[\w+(\^|\$|\*|\||~)?(=[\w\u00C0-\uFFFF\s\-\_\.]+)?\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\-?\d*n?((\+|\-)\d+)?|[\w\u00C0-\uFFFF\-_]+|((\w*\.[\w\u00C0-\uFFFF\-_]+)*)?|(\[#?\w+(\^|\$|\*|\||~)?=?[\w\u00C0-\uFFFF\s\-\_\.]+\]+)|(:\w+[\w\-]*))\))?)*)?(>|\+|~)?/; - var selectorSplitRegExp = new RegExp("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]", "g"); - - function attrToXPath(match, p1, p2, p3) { - switch (p2) { - case "^": return "starts-with(@" + p1 + ", '" + p3 - + "')"; - case "$": return "substring(@" + p1 - + ", (string-length(@" + p1 + ") - " - + (p3.length - 1) + "), " + p3.length - + ") = '" + p3 + "'"; - case "*": return "contains(concat(' ', @" + p1 - + ", ' '), '" + p3 + "')"; - case "|": return "(@" + p1 + "='" + p3 - + "' or starts-with(@" + p1 + ", '" + p3 - + "-'))"; - case "~": return "contains(concat(' ', @" + p1 - + ", ' '), ' " + p3 + " ')"; - default: return "@" + p1 + (p3 ? "='" + p3 + "'" - : ""); - } - } - - function pseudoToXPath(tag, pseudoClass, pseudoValue) { - var xpath = ""; - switch (pseudoClass) { - case "first-child": - xpath = "not(preceding-sibling::*)"; - break; - case "first-of-type": - xpath = "not(preceding-sibling::" + tag + ")"; - break; - case "last-child": - xpath = "not(following-sibling::*)"; - break; - case "last-of-type": - xpath = "not(following-sibling::" + tag + ")"; - break; - case "only-child": - xpath = "not(preceding-sibling::* or following-sibling::*)"; - break; - case "only-of-type": - xpath = "not(preceding-sibling::" + tag - + " or following-sibling::" + tag + ")"; - break; - case "nth-child": - if (!/^n$/.test(pseudoValue)) { - sequence - = DOMAssistant.getSequence(pseudoValue); - if (sequence) { - if (sequence.start === sequence.max) { - xpath = "count(preceding-sibling::*) = " - + (sequence.start - 1); - } else { - xpath = "(count(preceding-sibling::*) + 1) mod " - + sequence.add + " = " - + sequence.modVal - + ((sequence.start > 1) - ? " and count(preceding-sibling::*) >= " - + (sequence.start - 1) : "") - + ((sequence.max > 0) - ? " and count(preceding-sibling::*) <= " - + (sequence.max - 1) : ""); - } - } - } - break; - case "nth-of-type": - if (!/^n$/.test(pseudoValue)) { - sequence - = DOMAssistant.getSequence(pseudoValue); - if (sequence) { - if (sequence.start === sequence.max) { - xpath = pseudoValue; - } else { - xpath = "position() mod " - + sequence.add + " = " - + sequence.modVal - + ((sequence.start > 1) - ? " and position() >= " - + sequence.start : "") - + ((sequence.max > 0) - ? " and position() <= " - + sequence.max : ""); - } - } - } - break; - case "empty": - xpath = "count(child::*) = 0 and string-length(text()) = 0"; - break; - case "contains": - xpath = "contains(., '" + pseudoValue + "')"; - break; - case "enabled": - xpath = "not(@disabled)"; - break; - case "disabled": - xpath = "@disabled"; - break; - case "checked": - xpath = "@checked='checked'"; // Doesn't work in Opera 9.24 - break; - case "not": - if (/^(:\w+[\w\-]*)$/.test(pseudoValue)) { - xpath = "not(" - + pseudoToXPath(tag, pseudoValue.slice(1)) - + ")"; - } else { - pseudoValue - = pseudoValue.replace(/^\[#([\w\u00C0-\uFFFF\-\_]+)\]$/, "[id=$1]"); - var notSelector = pseudoValue.replace(/^(\w+)/, "self::$1"); - notSelector - = notSelector.replace(/^\.([\w\u00C0-\uFFFF\-_]+)/g, "contains(concat(' ', @class, ' '), ' $1 ')"); - notSelector - = notSelector.replace(/\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/g, attrToXPath); - xpath = "not(" + notSelector + ")"; - } - break; - default: - xpath = "@" + pseudoClass + "='" + pseudoValue - + "'"; - break; - } - return xpath; - } - - for (var i = 0; (currentRule = cssRules[i]); i++) { - if (i > 0) { - identical = false; - for (var x = 0, xl = i; x < xl; x++) { - if (cssRules[i] === cssRules[x]) { - identical = true; - break; - } - } - if (identical) { - continue; - } - } - cssSelectors = currentRule.match(selectorSplitRegExp); - xPathExpression = "."; - for (var j = 0, jl = cssSelectors.length; j < jl; j++) { - cssSelector - = cssSelectorRegExp.exec(cssSelectors[j]); - splitRule = { - tag : (!cssSelector[1] || cssSelector[3] - === "*") ? "*" : cssSelector[1], - id : (cssSelector[3] !== "*") ? cssSelector[2] - : null, - allClasses : cssSelector[4], - allAttr : cssSelector[6], - allPseudos : cssSelector[10], - tagRelation : cssSelector[22] - }; - if (splitRule.tagRelation) { - switch (splitRule.tagRelation) { - case ">": - xPathExpression += "/child::"; - break; - case "+": - xPathExpression - += "/following-sibling::*[1]/self::"; - break; - case "~": - xPathExpression - += "/following-sibling::"; - break; - } - } else { - xPathExpression += (j > 0 - && /(>|\+|~)/.test(cssSelectors[j - 1])) - ? splitRule.tag : ("/descendant::" - + splitRule.tag); - } - if (splitRule.id) { - xPathExpression += "[@id = '" - + splitRule.id.replace(/^#/, "") + "']"; - } - if (splitRule.allClasses) { - xPathExpression - += splitRule.allClasses.replace(/\.([\w\u00C0-\uFFFF\-_]+)/g, "[contains(concat(' ', @class, ' '), ' $1 ')]"); - } - if (splitRule.allAttr) { - xPathExpression - += splitRule.allAttr.replace(/(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?/g, attrToXPath); - } - if (splitRule.allPseudos) { - var pseudoSplitRegExp = /:(\w[\w\-]*)(\(([^\)]+)\))?/; - splitRule.allPseudos - = splitRule.allPseudos.match(/(:\w+[\w\-]*)(\([^\)]+\))?/g); - for (var k = 0, kl = splitRule.allPseudos.length; - k < kl; k++) { - var pseudo = splitRule.allPseudos[k].match(pseudoSplitRegExp); - var pseudoClass = pseudo[1] - ? pseudo[1].toLowerCase() : null; - var pseudoValue = pseudo[3] ? pseudo[3] - : null; - var xpath = pseudoToXPath(splitRule.tag, pseudoClass, pseudoValue); - if (xpath.length) { - xPathExpression += "[" + xpath + "]"; - } - } - } - } - var xPathNodes = document.evaluate(xPathExpression, this, null, 0, null), node; - while ((node = xPathNodes.iterateNext())) { - elm.push(node); - } - } - return elm; - }; - } else { - DOMAssistant.cssSelection = function (cssRule) { - var cssRules = cssRule.replace(/\s*(,)\s*/g, "$1").split(","); - var elm = new HTMLArray(); - var prevElm = [], matchingElms = []; - var prevParents, currentRule, identical, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, regExpClassNames, matchingClassElms, regExpAttributes, matchingAttributeElms, attributeMatchRegExp, current, previous, prevParent, addElm, iteratorNext, childCount, childElm, sequence; - var childOrSiblingRefRegExp = /^(>|\+|~)$/; - var cssSelectorRegExp = /^(\w+)?(#[\w\u00C0-\uFFFF\-\_]+|(\*))?((\.[\w\u00C0-\uFFFF\-_]+)*)?((\[\w+(\^|\$|\*|\||~)?(=[\w\u00C0-\uFFFF\s\-\_\.]+)?\]+)*)?(((:\w+[\w\-]*)(\((odd|even|\-?\d*n?((\+|\-)\d+)?|[\w\u00C0-\uFFFF\-_]+|((\w*\.[\w\u00C0-\uFFFF\-_]+)*)?|(\[#?\w+(\^|\$|\*|\||~)?=?[\w\u00C0-\uFFFF\s\-\_\.]+\]+)|(:\w+[\w\-]*))\))?)*)?/; - var selectorSplitRegExp; - try { - selectorSplitRegExp - = new RegExp("(?:\\[[^\\[]*\\]|\\(.*\\)|[^\\s\\+>~\\[\\(])+|[\\+>~]", "g"); - } catch (e) { - selectorSplitRegExp = /[^\s]+/g; - } - function clearAdded(elm) { - elm = elm || prevElm; - for (var n = 0, nl = elm.length; n < nl; n++) { - elm[n].added = null; - } - } - - function clearChildElms() { - for (var n = 0, nl = prevParents.length; n < nl; n++) { - prevParents[n].childElms = null; - } - } - - function subtractArray(arr1, arr2) { - for (var i = 0, src1; (src1 = arr1[i]); i++) { - var found = false; - for (var j = 0, src2; (src2 = arr2[j]); j++) { - if (src2 === src1) { - found = true; - break; - } - } - if (found) { - arr1.splice(i--, 1); - } - } - return arr1; - } - - function getAttr(elm, attr) { - if (isIE) { - switch (attr) { - case "id": - return elm.id; - case "for": - return elm.htmlFor; - case "class": - return elm.className; - } - } - return elm.getAttribute(attr, 2); - } - - function attrToRegExp(attrVal, substrOperator) { - switch (substrOperator) { - case "^": return "^" + attrVal; - case "$": return attrVal + "$"; - case "*": return attrVal; - case "|": return "(^" + attrVal + "(\\-\\w+)*$)"; - case "~": return "\\b" + attrVal + "\\b"; - default: return attrVal ? "^" + attrVal + "$" - : null; - } - } - - function getElementsByTagName(tag, parent) { - tag = tag || "*"; - parent = parent || document; - if (parent === document || parent.lastModified) { - if (!cachedElms[tag]) { - cachedElms[tag] = isIE ? ((tag === "*") - ? document.all : document.all.tags(tag)) - : document.getElementsByTagName(tag); - } - return cachedElms[tag]; - } - return isIE ? ((tag === "*") ? parent.all - : parent.all.tags(tag)) - : parent.getElementsByTagName(tag); - } - - function getElementsByPseudo(previousMatch, pseudoClass, - pseudoValue) { - prevParents = []; - var direction = (/^first/.test(pseudoClass)) - ? "previousSibling" : "nextSibling"; - var matchingElms = [], prev, next; - switch (pseudoClass) { - case "first-child": - case "last-child": - for (var j = 0; - (next = previous = previousMatch[j]); - j++) { - while ((next = next[direction]) - && next.nodeType !== 1) { - } - if (!next) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - case "only-child": - for (var k = 0, kParent; (prev = next = previous - = previousMatch[k]); k++) { - prevParent = previous.parentNode; - if (prevParent !== kParent) { - while ((prev = prev.previousSibling) - && prev.nodeType !== 1) { - } - while ((next = next.nextSibling) - && next.nodeType !== 1) { - } - if (!prev && !next) { - matchingElms[matchingElms.length] - = previous; - } - kParent = prevParent; - } - } - break; - case "nth-child": - if (/^n$/.test(pseudoValue)) { - matchingElms = previousMatch; - } else { - sequence - = DOMAssistant.getSequence(pseudoValue); - if (sequence) { - for (var l = 0; - (previous = previousMatch[l]); - l++) { - prevParent = previous.parentNode; - if (!prevParent.childElms) { - iteratorNext = sequence.start; - childCount = 0; - childElm - = prevParent.firstChild; - while (childElm && (sequence.max - < 0 || iteratorNext - <= sequence.max)) { - if (childElm.nodeType - === 1) { - if (++childCount - === iteratorNext) { - if (childElm.nodeName - === previous.nodeName) { - matchingElms[matchingElms.length] - = childElm; - } - iteratorNext - += sequence.add; - } - } - childElm - = childElm.nextSibling; - } - prevParent.childElms = true; - prevParents[prevParents.length] - = prevParent; - } - } - clearChildElms(); - } - } - break; - case "first-of-type": - case "last-of-type": - for (var n = 0; - (next = previous = previousMatch[n]); - n++) { - while ((next = next[direction]) - && next.nodeName - !== previous.nodeName) { - } - if (!next) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - case "only-of-type": - for (var o = 0, oParent; (prev = next = previous - = previousMatch[o]); o++) { - prevParent = previous.parentNode; - if (prevParent !== oParent) { - while ((prev = prev.previousSibling) - && prev.nodeName - !== previous.nodeName) { - } - while ((next = next.nextSibling) - && next.nodeName - !== previous.nodeName) { - } - if (!prev && !next) { - matchingElms[matchingElms.length] - = previous; - } - oParent = prevParent; - } - } - break; - case "nth-of-type": - if (/^n$/.test(pseudoValue)) { - matchingElms = previousMatch; - } else { - sequence - = DOMAssistant.getSequence(pseudoValue); - if (sequence) { - for (var p = 0; - (previous = previousMatch[p]); - p++) { - prevParent = previous.parentNode; - if (!prevParent.childElms) { - iteratorNext = sequence.start; - childCount = 0; - childElm - = prevParent.firstChild; - while (childElm && (sequence.max - < 0 || iteratorNext - <= sequence.max)) { - if (childElm.nodeName - === previous.nodeName) { - if (++childCount - === iteratorNext) { - matchingElms[matchingElms.length] - = childElm; - iteratorNext - += sequence.add; - } - } - childElm - = childElm.nextSibling; - } - prevParent.childElms = true; - prevParents[prevParents.length] - = prevParent; - } - } - clearChildElms(); - } - } - break; - case "empty": - for (var q = 0; (previous = previousMatch[q]); - q++) { - if (!previous.childNodes.length) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - case "enabled": - for (var r = 0; (previous = previousMatch[r]); - r++) { - if (!previous.disabled) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - case "disabled": - for (var s = 0; (previous = previousMatch[s]); - s++) { - if (previous.disabled) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - case "checked": - for (var t = 0; (previous = previousMatch[t]); - t++) { - if (previous.checked) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - case "contains": - for (var u = 0; (previous = previousMatch[u]); - u++) { - if (!previous.added) { - if (previous.innerText.indexOf(pseudoValue) - !== -1) { - previous.added = true; - matchingElms[matchingElms.length] - = previous; - } - } - } - break; - case "not": - if (/^(:\w+[\w\-]*)$/.test(pseudoValue)) { - matchingElms - = subtractArray(previousMatch, getElementsByPseudo(previousMatch, pseudoValue.slice(1))); - } else { - pseudoValue - = pseudoValue.replace(/^\[#([\w\u00C0-\uFFFF\-\_]+)\]$/, "[id=$1]"); - var notTag = /^(\w+)/.exec(pseudoValue); - var notClass = /^\.([\w\u00C0-\uFFFF\-_]+)/.exec(pseudoValue); - var notAttr = /\[(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?\]/.exec(pseudoValue); - var notRegExp = new RegExp("(^|\\s)" - + (notTag ? notTag[1] : notClass - ? notClass[1] : "") - + "(\\s|$)", "i"); - if (notAttr) { - var notAttribute = notAttr[3] - ? notAttr[3].replace(/\./g, "\\.") - : null; - var notMatchingAttrVal = attrToRegExp(notAttribute, notAttr[2]); - notRegExp - = new RegExp(notMatchingAttrVal, "i"); - } - for (var v = 0, notElm; - (notElm = previousMatch[v]); v++) { - addElm = null; - if (notTag - && !notRegExp.test(notElm.nodeName)) { - addElm = notElm; - } else if (notClass - && !notRegExp.test(notElm.className)) { - addElm = notElm; - } else if (notAttr) { - var att = getAttr(notElm, notAttr[1]); - if (!att || !notRegExp.test(att)) { - addElm = notElm; - } - } - if (addElm && !addElm.added) { - addElm.added = true; - matchingElms[matchingElms.length] - = addElm; - } - } - } - break; - default: - for (var w = 0; (previous = previousMatch[w]); - w++) { - if (previous.getAttribute(pseudoClass, 2) - === pseudoValue) { - matchingElms[matchingElms.length] - = previous; - } - } - break; - } - return matchingElms; - } - - for (var a = 0; (currentRule = cssRules[a]); a++) { - if (a > 0) { - identical = false; - for (var b = 0, bl = a; b < bl; b++) { - if (cssRules[a] === cssRules[b]) { - identical = true; - break; - } - } - if (identical) { - continue; - } - } - cssSelectors = currentRule.match(selectorSplitRegExp); - prevElm = [this]; - for (var i = 0, rule; (rule = cssSelectors[i]); i++) { - matchingElms = []; - if (i > 0 && childOrSiblingRefRegExp.test(rule)) { - childOrSiblingRef - = childOrSiblingRefRegExp.exec(rule); - if (childOrSiblingRef) { - nextTag = /^\w+/.exec(cssSelectors[i + 1]); - if (nextTag) { - nextTag = nextTag[0]; - nextRegExp = new RegExp("(^|\\s)" - + nextTag + "(\\s|$)", "i"); - } - for (var j = 0, prevRef; - (prevRef = prevElm[j]); j++) { - switch (childOrSiblingRef[0]) { - case ">": - var children = getElementsByTagName(nextTag, prevRef); - for (var k = 0, child; - (child = children[k]); - k++) { - if (child.parentNode - === prevRef) { - matchingElms[matchingElms.length] - = child; - } - } - break; - case "+": - while ((prevRef - = prevRef.nextSibling) - && prevRef.nodeType - !== 1) { - } - if (prevRef) { - if (!nextTag - || nextRegExp.test(prevRef.nodeName)) { - matchingElms[matchingElms.length] - = prevRef; - } - } - break; - case "~": - while ((prevRef - = prevRef.nextSibling) - && !prevRef.added) { - if (!nextTag - || nextRegExp.test(prevRef.nodeName)) { - prevRef.added = true; - matchingElms[matchingElms.length] - = prevRef; - } - } - break; - } - } - prevElm = matchingElms; - clearAdded(); - rule = cssSelectors[++i]; - if (/^\w+$/.test(rule)) { - continue; - } - prevElm.skipTag = true; - } - } - var cssSelector = cssSelectorRegExp.exec(rule); - var splitRule = { - tag : (!cssSelector[1] || cssSelector[3] - === "*") ? "*" : cssSelector[1], - id : (cssSelector[3] !== "*") ? cssSelector[2] - : null, - allClasses : cssSelector[4], - allAttr : cssSelector[6], - allPseudos : cssSelector[10] - }; - if (splitRule.id) { - var DOMElm = document.getElementById(splitRule.id.replace(/#/, "")); - if (DOMElm) { - matchingElms = [DOMElm]; - } - prevElm = matchingElms; - } else if (splitRule.tag && !prevElm.skipTag) { - if (i === 0 && !matchingElms.length - && prevElm.length === 1) { - prevElm = matchingElms - = pushAll([], getElementsByTagName(splitRule.tag, prevElm[0])); - } else { - for (var l = 0, ll = prevElm.length, tagCollectionMatches, tagMatch; - l < ll; l++) { - tagCollectionMatches - = getElementsByTagName(splitRule.tag, prevElm[l]); - for (var m = 0; (tagMatch - = tagCollectionMatches[m]); - m++) { - if (!tagMatch.added) { - tagMatch.added = true; - matchingElms[matchingElms.length] - = tagMatch; - } - } - } - prevElm = matchingElms; - clearAdded(); - } - } - if (!matchingElms.length) { - break; - } - prevElm.skipTag = false; - if (splitRule.allClasses) { - splitRule.allClasses - = splitRule.allClasses.replace(/^\./, "").split("."); - regExpClassNames = []; - for (var n = 0, nl = splitRule.allClasses.length; - n < nl; n++) { - regExpClassNames[regExpClassNames.length] - = new RegExp("(^|\\s)" - + splitRule.allClasses[n] - + "(\\s|$)"); - } - matchingClassElms = []; - for (var o = 0, elmClass; - (current = prevElm[o]); o++) { - elmClass = current.className; - if (elmClass && !current.added) { - addElm = false; - for (var p = 0, pl = regExpClassNames.length; - p < pl; p++) { - addElm = regExpClassNames[p].test(elmClass); - if (!addElm) { - break; - } - } - if (addElm) { - current.added = true; - matchingClassElms[matchingClassElms.length] - = current; - } - } - } - clearAdded(); - prevElm = matchingElms = matchingClassElms; - } - if (splitRule.allAttr) { - splitRule.allAttr - = splitRule.allAttr.match(/\[[^\]]+\]/g); - regExpAttributes = []; - attributeMatchRegExp - = /(\w+)(\^|\$|\*|\||~)?=?([\w\u00C0-\uFFFF\s\-_\.]+)?/; - for (var q = 0, ql = splitRule.allAttr.length, attributeMatch, attributeValue, attrVal; - q < ql; q++) { - attributeMatch - = attributeMatchRegExp.exec(splitRule.allAttr[q]); - attributeValue = attributeMatch[3] - ? attributeMatch[3].replace(/\./g, "\\.") - : null; - attrVal = attrToRegExp(attributeValue, (attributeMatch[2] - || null)); - regExpAttributes[regExpAttributes.length] - = [(attrVal ? new RegExp(attrVal) - : null), attributeMatch[1]]; - } - matchingAttributeElms = []; - for (var r = 0, currentAttr; - (current = matchingElms[r]); r++) { - for (var s = 0, sl = regExpAttributes.length, attributeRegExp; - s < sl; s++) { - addElm = false; - attributeRegExp - = regExpAttributes[s][0]; - currentAttr - = getAttr(current, regExpAttributes[s][1]); - if (typeof currentAttr === "string" - && currentAttr.length) { - if (!attributeRegExp - || typeof attributeRegExp - === "undefined" - || (attributeRegExp - && attributeRegExp.test(currentAttr))) { - addElm = true; - } - } - if (!addElm) { - break; - } - } - if (addElm) { - matchingAttributeElms[matchingAttributeElms.length] - = current; - } - } - prevElm = matchingElms = matchingAttributeElms; - } - if (splitRule.allPseudos) { - var pseudoSplitRegExp = /:(\w[\w\-]*)(\(([^\)]+)\))?/; - splitRule.allPseudos - = splitRule.allPseudos.match(/(:\w+[\w\-]*)(\([^\)]+\))?/g); - for (var t = 0, tl = splitRule.allPseudos.length; - t < tl; t++) { - var pseudo = splitRule.allPseudos[t].match(pseudoSplitRegExp); - var pseudoClass = pseudo[1] - ? pseudo[1].toLowerCase() : null; - var pseudoValue = pseudo[3] ? pseudo[3] - : null; - matchingElms - = getElementsByPseudo(matchingElms, pseudoClass, pseudoValue); - clearAdded(matchingElms); - } - prevElm = matchingElms; - } - } - elm = pushAll(elm, prevElm); - } - return elm; - }; - } - if (document.querySelectorAll) { - var cssSelectionBackup = DOMAssistant.cssSelection; - DOMAssistant.cssSelection = function (cssRule) { - try { - var elm = new HTMLArray(); - return pushAll(elm, this.querySelectorAll(cssRule)); - } catch (e) { - return cssSelectionBackup.call(this, cssRule); - } - }; - } - return DOMAssistant.cssSelection.call(this, cssRule); - }, - - cssSelect : function (cssRule) { - return DOMAssistant.cssSelection.call(this, cssRule); - }, - - elmsByClass : function (className, tag) { - var cssRule = (tag || "") + "." + className; - return DOMAssistant.cssSelection.call(this, cssRule); - }, - - elmsByAttribute : function (attr, attrVal, tag, substrMatchSelector) { - var cssRule = (tag || "") + "[" + attr + ((attrVal && attrVal - !== "*") ? ((substrMatchSelector || "") + "=" + attrVal - + "]") : "]"); - return DOMAssistant.cssSelection.call(this, cssRule); - }, - - elmsByTag : function (tag) { - return DOMAssistant.cssSelection.call(this, tag); - } - }; -}(); -DOMAssistant.initCore(); -DOMAssistant.AJAX = function () { - var globalXMLHttp = null; - var readyState = 0; - var status = -1; - var statusText = ""; - var createAjaxObj = function (url, method, callback, addToContent) { - var params = null; - if (/POST/i.test(method)) { - url = url.split("?"); - params = url[1]; - url = url[0]; - } - return { - url: url, - method : method, - callback : callback, - params : params, - headers : {}, - responseType : "text", - addToContent : addToContent || false - }; - }; - return { - publicMethods : [ - "ajax", - "get", - "post", - "load", - "replaceWithAJAXContent" - ], - - initRequest : function () { - var XMLHttp = null; - if (typeof XMLHttpRequest !== "undefined") { - XMLHttp = new XMLHttpRequest(); - DOMAssistant.AJAX.initRequest = function () { - return new XMLHttpRequest(); - }; - } else if (typeof window.ActiveXObject !== "undefined") { - var XMLHttpMS = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"]; - for (var i = 0; i < XMLHttpMS.length; i++) { - try { - XMLHttp = new window.ActiveXObject(XMLHttpMS[i]); - DOMAssistant.AJAX.initRequest = function () { - return new window.ActiveXObject(XMLHttpMS[i]); - }; - break; - } catch (e) { - XMLHttp = null; - } - } - } - return XMLHttp; - }, - - ajax : function (ajaxObj) { - if (ajaxObj.url && /\?/.test(ajaxObj.url) && ajaxObj.method - && /POST/i.test(ajaxObj.method)) { - var url = ajaxObj.url.split("?"); - ajaxObj.url = url[0]; - ajaxObj.params = url[1] + ((url[1].length > 0 && ajaxObj.params) - ? ("&" + ajaxObj.params) : ""); - } - return DOMAssistant.AJAX.makeCall.call(this, ajaxObj); - }, - - get : function (url, callback, addToContent) { - var ajaxObj = createAjaxObj(url, "GET", callback, addToContent); - return DOMAssistant.AJAX.makeCall.call(this, ajaxObj); - }, - - post : function (url, callback) { - var ajaxObj = createAjaxObj(url, "POST", callback); - return DOMAssistant.AJAX.makeCall.call(this, ajaxObj); - }, - - load : function (url, addToContent) { - DOMAssistant.AJAX.get.call(this, url, DOMAssistant.AJAX.replaceWithAJAXContent, addToContent); - }, - - makeCall : function (ajaxObj) { - var XMLHttp = DOMAssistant.AJAX.initRequest(); - if (XMLHttp) { - globalXMLHttp = XMLHttp; - var ajaxCall = function (elm) { - var url = ajaxObj.url; - var method = ajaxObj.method || "GET"; - var callback = ajaxObj.callback; - var params = ajaxObj.params; - var headers = ajaxObj.headers; - var responseType = ajaxObj.responseType || "text"; - var addToContent = ajaxObj.addToContent; - XMLHttp.open(method, url, true); - XMLHttp.setRequestHeader("AJAX", "true"); - XMLHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - if (method === "POST") { - var contentLength = params ? params.length : 0; - XMLHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - XMLHttp.setRequestHeader("Content-length", contentLength); - if (XMLHttp.overrideMimeType) { - XMLHttp.setRequestHeader("Connection", "close"); - } - } - for (var i in headers) { - if (typeof i === "string") { - XMLHttp.setRequestHeader(i, headers[i]); - } - } - if (typeof callback === "function") { - XMLHttp.onreadystatechange = function () { - if (XMLHttp.readyState === 4) { - var response = (/xml/i.test(responseType)) - ? XMLHttp.responseXML - : XMLHttp.responseText; - callback.call(elm, response, addToContent); - readyState = 4; - status = XMLHttp.status; - statusText = XMLHttp.statusText; - globalXMLHttp = null; - XMLHttp = null; - } - }; - } - XMLHttp.send(params); - }(this); - } - return this; - }, - - replaceWithAJAXContent : function (content, add) { - if (add) { - this.innerHTML += content; - } else { - var elms = this.elmsByTag("*"); - for (var i = 0, elm, attr; (elm = elms[i]); i++) { - attr = elm.attributes; - if (attr) { - for (var j = 0, jl = attr.length; j < jl; j++) { - if (typeof elm[attr[j].name] === "function") { - elm[attr[j].name] = null; - } - } - } - } - this.innerHTML = content; - } - }, - - getReadyState : function () { - return (globalXMLHttp && typeof globalXMLHttp.readyState - !== "undefined") ? globalXMLHttp.readyState : readyState; - }, - - getStatus : function () { - return status; - }, - - getStatusText : function () { - return statusText; - } - }; -}(); -DOMAssistant.attach(DOMAssistant.AJAX); -DOMAssistant.CSS = function () { - return { - addClass : function (className) { - var currentClass = this.className; - if (!new RegExp(("(^|\\s)" + className - + "(\\s|$)"), "i").test(currentClass)) { - this.className = currentClass + (currentClass.length ? " " : "") - + className; - } - return this; - }, - - removeClass : function (className) { - var classToRemove = new RegExp(("(^|\\s)" + className - + "(\\s|$)"), "i"); - this.className = this.className.replace(classToRemove, function ( - match) { - var retVal = ""; - if (new RegExp("^\\s+.*\\s+$").test(match)) { - retVal = match.replace(/(\s+).+/, "$1"); - } - return retVal; - }).replace(/^\s+|\s+$/g, ""); - return this; - }, - - replaceClass : function (className, newClass) { - var classToRemove = new RegExp(("(^|\\s)" + className - + "(\\s|$)"), "i"); - this.className = this.className.replace(classToRemove, function ( - match, p1, p2) { - var retVal = p1 + newClass + p2; - if (new RegExp("^\\s+.*\\s+$").test(match)) { - retVal = match.replace(/(\s+).+/, "$1"); - } - return retVal; - }).replace(/^\s+|\s+$/g, ""); - return this; - }, - - hasClass : function (className) { - return new RegExp(("(^|\\s)" + className - + "(\\s|$)"), "i").test(this.className); - }, - - setStyle : function (style, value) { - if (typeof this.style.cssText !== "undefined") { - var styleToSet = this.style.cssText; - if (typeof style === "object") { - for (var i in style) { - if (typeof i === "string") { - styleToSet += ";" + i + ":" + style[i]; - } - } - } else { - styleToSet += ";" + style + ":" + value; - } - this.style.cssText = styleToSet; - } - return this; - }, - - getStyle : function (cssRule) { - var cssVal = ""; - if (document.defaultView && document.defaultView.getComputedStyle) { - cssVal = document.defaultView.getComputedStyle(this, "").getPropertyValue(cssRule); - } else if (this.currentStyle) { - cssVal = cssRule.replace(/\-(\w)/g, function (match, p1) { - return p1.toUpperCase(); - }); - cssVal = this.currentStyle[cssVal]; - } - return cssVal; - } - }; -}(); -DOMAssistant.attach(DOMAssistant.CSS); -DOMAssistant.Content = function () { - return { - prev : function () { - var prevSib = this; - while ((prevSib = prevSib.previousSibling) && prevSib.nodeType - !== 1) { - } - return DOMAssistant.$(prevSib); - }, - - next : function () { - var nextSib = this; - while ((nextSib = nextSib.nextSibling) && nextSib.nodeType !== 1) { - } - return DOMAssistant.$(nextSib); - }, - - create : function (name, attr, append, content) { - var elm = DOMAssistant.$(document.createElement(name)); - if (attr) { - elm.setAttributes(attr); - } - if (typeof content !== "undefined") { - elm.addContent(content); - } - if (append) { - DOMAssistant.Content.addContent.call(this, elm); - } - return elm; - }, - - setAttributes : function (attr) { - for (var i in attr) { - if (/class/i.test(i)) { - this.className = attr[i]; - } else { - this.setAttribute(i, attr[i]); - } - } - return this; - }, - - addContent : function (content) { - if (typeof content === "string") { - this.innerHTML += content; - } else if (typeof content === "object" && content) { - this.appendChild(content); - } - return this; - }, - - replaceContent : function (newContent) { - for (var i = (this.childNodes.length - 1), child, attr; i >= 0; - i--) { - child = this.childNodes[i]; - attr = child.attributes; - if (attr) { - for (var j = 0, jl = attr.length; j < jl; j++) { - if (typeof child[attr[j].name] === "function") { - child[attr[j].name] = null; - } - } - } - child.parentNode.removeChild(child); - } - DOMAssistant.$(this).addContent(newContent); - return this; - }, - - remove : function () { - this.parentNode.removeChild(this); - return null; - } - }; -}(); -DOMAssistant.attach(DOMAssistant.Content); -DOMAssistant.Events = function () { - var uniqueHandlerId = 1; - return { - publicMethods : [ - "addEvent", - "removeEvent", - "preventDefault", - "cancelBubble" - ], - - init : function () { - window.addEvent = this.addEvent; - window.removeEvent = this.removeEvent; - DOMAssistant.preventDefault = this.preventDefault; - DOMAssistant.cancelBubble = this.cancelBubble; - }, - - addEvent : function (evt, func) { - var XULEvent = (/^DOM/.test(evt)); - if (XULEvent) { - if (this.addEventListener) { - this.addEventListener(evt, func, false); - } - } else { - if (!this.uniqueHandlerId) { - this.uniqueHandlerId = uniqueHandlerId++; - } - var alreadyExists = false; - if (func.attachedElements && func.attachedElements[evt - + this.uniqueHandlerId]) { - alreadyExists = true; - } - if (!alreadyExists) { - if (!this.events) { - this.events = {}; - } - if (!this.events[evt]) { - this.events[evt] = []; - var existingEvent = this["on" + evt]; - if (existingEvent) { - this.events[evt].push(existingEvent); - } - } - this.events[evt].push(func); - this["on" + evt] = DOMAssistant.Events.handleEvent; - if (typeof this.window === "object") { - this.window["on" + evt] - = DOMAssistant.Events.handleEvent; - } - if (!func.attachedElements) { - func.attachedElements = {}; - } - func.attachedElements[evt + this.uniqueHandlerId] = true; - } - } - return this; - }, - - handleEvent : function (evt) { - var currentEvt = evt || event; - var currentTarget = currentEvt.target || currentEvt.srcElement - || document; - while (currentTarget.nodeType !== 1 && currentTarget.parentNode) { - currentTarget = currentTarget.parentNode; - } - currentEvt.eventTarget = currentTarget; - var eventType = currentEvt.type; - var eventColl = this.events[eventType]; - var eventCollLength = eventColl.length; - var eventReturn; - for (var i = 0; i < eventCollLength; i++) { - eventReturn = eventColl[i].call(this, currentEvt); - if (i === (eventCollLength - 1)) { - return eventReturn; - } - } - }, - - removeEvent : function (evt, func) { - if (this.events) { - var eventColl = this.events[evt]; - for (var i = 0; i < eventColl.length; i++) { - if (eventColl[i] === func) { - delete eventColl[i]; - eventColl.splice(i, 1); - } - } - func.attachedElements[evt + this.uniqueHandlerId] = null; - } - return this; - }, - - preventDefault : function (evt) { - if (evt && evt.preventDefault) { - DOMAssistant.Events.preventDefault = function (evt) { - evt.preventDefault(); - }; - } else { - DOMAssistant.Events.preventDefault = function (evt) { - event.returnValue = false; - }; - } - return DOMAssistant.Events.preventDefault(evt); - }, - - cancelBubble : function (evt) { - if (evt && evt.stopPropagation) { - DOMAssistant.Events.cancelBubble = function (evt) { - evt.stopPropagation(); - }; - } else { - DOMAssistant.Events.cancelBubble = function (evt) { - event.cancelBubble = true; - }; - } - return DOMAssistant.Events.cancelBubble(evt); - } - }; -}(); -DOMAssistant.attach(DOMAssistant.Events); -DOMAssistant.DOMLoad = function () { - var DOMLoaded = false; - var DOMLoadTimer = null; - var functionsToCall = []; - var addedStrings = {}; - var errorHandling = null; - var execFunctions = function () { - for (var i = 0, il = functionsToCall.length; i < il; i++) { - try { - functionsToCall[i](); - } catch (e) { - if (errorHandling && typeof errorHandling === "function") { - errorHandling(e); - } - } - } - functionsToCall = []; - }; - var DOMHasLoaded = function () { - if (DOMLoaded) { - return; - } - DOMLoaded = true; - execFunctions(); - }; - /* Internet Explorer */ - /*@cc_on - @if (@_win32 || @_win64) - if (document.getElementById) { - document.write(" - - - - - - - + GwtQuery BenchMarks -

GWTSpeed - - GWT Query - benchmarks -
Start Race
-

- - - - - - -
- - -
-
-
- - -

Abstract

- -

Selectors are patterns that match against elements in a - tree. Selectors have been optimized for use with HTML and XML, and - are designed to be usable in performance-critical code.

- -

CSS (Cascading - Style Sheets) is a language for describing the rendering of HTML and XML documents on - screen, on paper, in speech, etc. CSS uses Selectors for binding - style properties to elements in the document. This document - describes extensions to the selectors defined in CSS level 2. These - extended selectors will be used by CSS level 3. - -

Selectors define the following function:

- -
expression ∗ element → boolean
- -

That is, given an element and a selector, this specification - defines whether that element matches the selector.

- -

These expressions can also be used, for instance, to select a set - of elements, or a single element from a set of elements, by - evaluating the expression across all the elements in a - subtree. STTS (Simple Tree Transformation Sheets), a - language for transforming XML trees, uses this mechanism. [STTS]

- -

Status of this document

- -

This section describes the status of this document at the - time of its publication. Other documents may supersede this - document. A list of current W3C publications and the latest revision - of this technical report can be found in the W3C technical reports index at - http://www.w3.org/TR/.

- -

This document describes the selectors that already exist in CSS1 and CSS2, and - also proposes new selectors for CSS3 and other languages that may need them.

- -

The CSS Working Group doesn't expect that all implementations of - CSS3 will have to implement all selectors. Instead, there will - probably be a small number of variants of CSS3, called profiles. For - example, it may be that only a profile for interactive user agents - will include all of the selectors.

- -

This specification is a last call working draft for the the CSS Working Group - (Style Activity). This - document is a revision of the Candidate - Recommendation dated 2001 November 13, and has incorporated - implementation feedback received in the past few years. It is - expected that this last call will proceed straight to Proposed - Recommendation stage since it is believed that interoperability will - be demonstrable.

- -

All persons are encouraged to review and implement this - specification and return comments to the (archived) - public mailing list www-style - (see instructions). W3C - Members can also send comments directly to the CSS Working - Group. - The deadline for comments is 14 January 2006.

- -

This is still a draft document and may be updated, replaced, or - obsoleted by other documents at any time. It is inappropriate to - cite a W3C Working Draft as other than "work in progress". - -

This document may be available in translation. - The English version of this specification is the only normative - version. - -

- -

Table of contents

- - - -
- -

1. Introduction

- -

1.1. Dependencies

- -

Some features of this specification are specific to CSS, or have - particular limitations or rules specific to CSS. In this - specification, these have been described in terms of CSS2.1. [CSS21]

- -

1.2. Terminology

- -

All of the text of this specification is normative except - examples, notes, and sections explicitly marked as - non-normative.

- -

1.3. Changes from CSS2

- -

This section is non-normative.

- -

The main differences between the selectors in CSS2 and those in - Selectors are: - -

    - -
  • the list of basic definitions (selector, group of selectors, - simple selector, etc.) has been changed; in particular, what was - referred to in CSS2 as a simple selector is now called a sequence - of simple selectors, and the term "simple selector" is now used for - the components of this sequence -
  • - -
  • an optional namespace component is now allowed in type element - selectors, the universal selector and attribute selectors -
  • - -
  • a new combinator has been - introduced -
  • - -
  • new simple selectors including substring matching attribute - selectors, and new pseudo-classes -
  • - -
  • new pseudo-elements, and introduction of the "::" convention - for pseudo-elements -
  • - -
  • the grammar has been rewritten
  • - -
  • profiles to be added to specifications integrating Selectors - and defining the set of selectors which is actually supported by - each specification -
  • - -
  • Selectors are now a CSS3 Module and an independent - specification; other specifications can now refer to this document - independently of CSS -
  • - -
  • the specification now has its own test suite
  • - -
- -

2. Selectors

- -

This section is non-normative, as it merely summarizes the - following sections.

- -

A Selector represents a structure. This structure can be used as a - condition (e.g. in a CSS rule) that determines which elements a - selector matches in the document tree, or as a flat description of the - HTML or XML fragment corresponding to that structure.

- -

Selectors may range from simple element names to rich contextual - representations.

- -

The following table summarizes the Selector syntax:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PatternMeaningDescribed in sectionFirst defined in CSS level
*any elementUniversal - selector2
Ean element of type EType selector1
E[foo]an E element with a "foo" attributeAttribute - selectors2
E[foo="bar"]an E element whose "foo" attribute value is exactly - equal to "bar" - Attribute - selectors2
E[foo~="bar"]an E element whose "foo" attribute value is a list of - space-separated values, one of which is exactly equal to "bar" - Attribute - selectors2
E[foo^="bar"]an E element whose "foo" attribute value begins exactly - with the string "bar" - Attribute - selectors3
E[foo$="bar"]an E element whose "foo" attribute value ends exactly - with the string "bar" - Attribute - selectors3
E[foo*="bar"]an E element whose "foo" attribute value contains the - substring "bar" - Attribute - selectors3
E[hreflang|="en"]an E element whose "hreflang" attribute has a - hyphen-separated - list of values beginning (from the left) with "en" - Attribute - selectors2
E:rootan E element, root of the documentStructural - pseudo-classes3
E:nth-child(n)an E element, the n-th child of its parentStructural - pseudo-classes3
E:nth-last-child(n)an E element, the n-th child of its parent, counting - from the last one - Structural - pseudo-classes3
E:nth-of-type(n)an E element, the n-th sibling of its typeStructural - pseudo-classes3
E:nth-last-of-type(n)an E element, the n-th sibling of its type, counting - from the last one - Structural - pseudo-classes3
E:first-childan E element, first child of its parentStructural - pseudo-classes2
E:last-childan E element, last child of its parentStructural - pseudo-classes3
E:first-of-typean E element, first sibling of its typeStructural - pseudo-classes3
E:last-of-typean E element, last sibling of its typeStructural - pseudo-classes3
E:only-childan E element, only child of its parentStructural - pseudo-classes3
E:only-of-typean E element, only sibling of its typeStructural - pseudo-classes3
E:emptyan E element that has no children (including text - nodes) - Structural - pseudo-classes3
E:link
E:visited
an E element being the source anchor of a hyperlink of - which the target is not yet visited (:link) or already visited - (:visited) - The link - pseudo-classes1
E:active
E:hover
E:focus
an E element during certain user actionsThe user - action pseudo-classes1 and 2
E:targetan E element being the target of the referring URIThe target - pseudo-class3
E:lang(fr)an element of type E in language "fr" (the document - language specifies how language is determined) - The :lang() - pseudo-class2
E:enabled
E:disabled
a user interface element E which is enabled or - disabled - The UI element states - pseudo-classes3
E:checkeda user interface element E which is checked (for instance a radio-button or checkbox) - The UI element states - pseudo-classes3
E::first-linethe first formatted line of an E elementThe ::first-line - pseudo-element1
E::first-letterthe first formatted letter of an E elementThe ::first-letter - pseudo-element1
E::selectionthe portion of an E element that is currently - selected/highlighted by the user - The UI element - fragments pseudo-elements3
E::beforegenerated content before an E elementThe ::before - pseudo-element2
E::aftergenerated content after an E elementThe ::after - pseudo-element2
E.warningan E element whose class is - "warning" (the document language specifies how class is determined). - Class - selectors1
E#myidan E element with ID equal to "myid".ID - selectors1
E:not(s)an E element that does not match simple selector sNegation - pseudo-class3
E Fan F element descendant of an E elementDescendant - combinator1
E > Fan F element child of an E elementChild - combinator2
E + Fan F element immediately preceded by an E elementAdjacent sibling combinator - 2
E ~ Fan F element preceded by an E elementGeneral sibling combinator - 3
- -

The meaning of each selector is derived from the table above by - prepending "matches" to the contents of each cell in the "Meaning" - column.

- -

3. Case sensitivity

- -

The case sensitivity of document language element names, attribute - names, and attribute values in selectors depends on the document - language. For example, in HTML, element names are case-insensitive, - but in XML, they are case-sensitive.

- -

4. Selector syntax

- -

A selector is a chain of one - or more sequences of simple selectors - separated by combinators.

- -

A sequence of simple selectors - is a chain of simple selectors - that are not separated by a combinator. It - always begins with a type selector or a - universal selector. No other type - selector or universal selector is allowed in the sequence.

- -

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, content selector, or pseudo-class. One pseudo-element may be appended to the last - sequence of simple selectors.

- -

Combinators are: white space, "greater-than - sign" (U+003E, >), "plus sign" (U+002B, - +) and "tilde" (U+007E, ~). White - space may appear between a combinator and the simple selectors around - it. Only the characters "space" (U+0020), "tab" - (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form - feed" (U+000C) can occur in white space. Other space-like characters, - such as "em-space" (U+2003) and "ideographic space" (U+3000), are - never part of white space.

- -

The elements of a document tree that are represented by a selector - are the subjects of the selector. A - selector consisting of a single sequence of simple selectors - represents any element satisfying its requirements. Prepending another - sequence of simple selectors and a combinator to a sequence imposes - additional matching constraints, so the subjects of a selector are - always a subset of the elements represented by the last sequence of - simple selectors.

- -

An empty selector, containing no sequence of simple selectors and - no pseudo-element, is an invalid - selector.

- -

5. Groups of selectors

- -

When several selectors share the same declarations, they may be - grouped into a comma-separated list. (A comma is U+002C.)

- -
-

CSS examples:

- -

In this example, we condense three rules with identical - declarations into one. Thus,

-
h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }
-

is equivalent to:

-
h1, h2, h3 { font-family: sans-serif }
-
- -

Warning: the equivalence is true in this example - because all the selectors are valid selectors. If just one of these - selectors were invalid, the entire group of selectors would be - invalid. This would invalidate the rule for all three heading - elements, whereas in the former case only one of the three individual - heading rules would be invalidated.

- - -

6. Simple selectors

- -

6.1. Type selector

- -

A type selector is the name of a document language - element type. A type selector represents an instance of the element - type in the document tree.

- -
-

Example:

- -

The following selector represents an h1 element in the - document tree:

-
h1
-
- - -

6.1.1. Type selectors and namespaces

- -

Type selectors allow an optional namespace ([XMLNAMES]) component. A namespace prefix - that has been previously declared may be prepended to the element name - separated by the namespace separator "vertical bar" - (U+007C, |).

- -

The namespace component may be left empty to indicate that the - selector is only to represent elements with no declared namespace.

- -

An asterisk may be used for the namespace prefix, indicating that - the selector represents elements in any namespace (including elements - with no namespace).

- -

Element type selectors that have no namespace component (no - namespace separator), represent elements without regard to the - element's namespace (equivalent to "*|") unless a default - namespace has been declared. If a default namespace has been declared, - the selector will represent only elements in the default - namespace.

- -

A type selector containing a namespace prefix that has not been - previously declared is an invalid selector. - The mechanism for declaring a namespace prefix is left up to the - language implementing Selectors. In CSS, such a mechanism is defined - in the General Syntax module.

- -

In a namespace-aware client, element type selectors will only match - against the local - part - of the element's qualified - name. See below for notes about matching - behaviors in down-level clients.

- -

In summary:

- -
-
ns|E
-
elements with name E in namespace ns
-
*|E
-
elements with name E in any namespace, including those without any - declared namespace -
-
|E
-
elements with name E without any declared namespace
-
E
-
if no default namespace has been specified, this is equivalent to *|E. - Otherwise it is equivalent to ns|E where ns is the default namespace. -
-
- -
-

CSS examples:

- -
@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }
- -

The first rule will match only h1 elements in the - "http://www.example.com" namespace.

- -

The second rule will match all elements in the - "http://www.example.com" namespace.

- -

The third rule will match only h1 elements without - any declared namespace.

- -

The fourth rule will match h1 elements in any - namespace (including those without any declared namespace).

- -

The last rule is equivalent to the fourth rule because no default - namespace has been defined.

- -
- -

6.2. Universal selector

- -

The universal selector, written "asterisk" - (*), represents the qualified name of any element - type. It represents any single element in the document tree in any - namespace (including those without any declared namespace) if no - default namespace has been specified. If a default namespace has been - specified, see Universal selector and - Namespaces below.

- -

If the universal selector is not the only component of a sequence - of simple selectors, the * may be omitted.

- -
-

Examples:

-
    -
  • *[hreflang|=en] and [hreflang|=en] are - equivalent, -
  • -
  • *.warning and .warning are equivalent, -
  • -
  • *#myid and #myid are equivalent.
  • -
-
- -

Note: it is recommended that the - *, representing the universal selector, not be - omitted.

- -

6.2.1. Universal selector and namespaces

- -

The universal selector allows an optional namespace component. It - is used as follows:

- -
-
ns|*
-
all elements in namespace ns
-
*|*
-
all elements
-
|*
-
all elements without any declared namespace
-
*
-
if no default namespace has been specified, this is equivalent to *|*. - Otherwise it is equivalent to ns|* where ns is the default namespace. -
-
- -

A universal selector containing a namespace prefix that has not - been previously declared is an invalid - selector. The mechanism for declaring a namespace prefix is left up - to the language implementing Selectors. In CSS, such a mechanism is - defined in the General Syntax module.

- - -

6.3. Attribute selectors

- -

Selectors allow the representation of an element's attributes. When - a selector is used as an expression to match against an element, - attribute selectors must be considered to match an element if that - element has an attribute that matches the attribute represented by the - attribute selector.

- -

6.3.1. Attribute presence and values - selectors

- -

CSS2 introduced four attribute selectors:

- -
-
[att] -
Represents an element with the att attribute, whatever the - value of - the attribute. -
-
[att=val]
-
Represents an element with the att attribute whose value is - exactly - "val". -
-
[att~=val]
-
Represents an element with the att attribute whose value is - a whitespace-separated list of words, one - of - which is exactly "val". If "val" contains whitespace, it will never - represent anything (since the words are separated by - spaces). -
-
[att|=val] -
Represents an element with the att attribute, its value - either - being exactly "val" or beginning with "val" immediately followed by - "-" (U+002D). This is primarily intended to allow language subcode - matches (e.g., the hreflang attribute on the - link element in HTML) as described in RFC 3066 ([RFC3066]). For lang (or - xml:lang) language subcode matching, please see the :lang pseudo-class. -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names and values in selectors depends on - the document language.

- -
- -

Examples:

- -

The following attribute selector represents an h1 - element that carries the title attribute, whatever its - value:

- -
h1[title]
- -

In the following example, the selector represents a - span element whose class attribute has - exactly the value "example":

- -
span[class="example"]
- -

Multiple attribute selectors can be used to represent several - attributes of an element, or several conditions on the same - attribute. Here, the selector represents a span element - whose hello attribute has exactly the value "Cleveland" - and whose goodbye attribute has exactly the value - "Columbus":

- -
span[hello="Cleveland"][goodbye="Columbus"]
- -

The following selectors illustrate the differences between "=" - and "~=". The first selector will represent, for example, the value - "copyright copyleft copyeditor" on a rel attribute. The - second selector will only represent an a element with - an href attribute having the exact value - "http://www.w3.org/".

- -
a[rel~="copyright"]
-a[href="http://www.w3.org/"]
- -

The following selector represents a link element - whose hreflang attribute is exactly "fr".

- -
link[hreflang=fr]
- -

The following selector represents a link element for - which the values of the hreflang attribute begins with - "en", including "en", "en-US", and "en-cockney":

- -
link[hreflang|="en"]
- -

Similarly, the following selectors represents a - DIALOGUE element whenever it has one of two different - values for an attribute character:

- -
DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]
- -
- -

6.3.2. Substring matching attribute - selectors

- -

Three additional attribute selectors are provided for matching - substrings in the value of an attribute:

- -
-
[att^=val]
-
Represents an element with the att attribute whose value - begins - with the prefix "val". -
-
[att$=val] -
Represents an element with the att attribute whose value - ends with - the suffix "val". -
-
[att*=val] -
Represents an element with the att attribute whose value - contains - at least one instance of the substring "val". -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names in selectors depends on the - document language.

- -
-

Examples:

- -

The following selector represents an HTML object, - referencing an - image:

-
object[type^="image/"]
-

The following selector represents an HTML anchor a with an - href attribute whose value ends with ".html".

-
a[href$=".html"]
-

The following selector represents an HTML paragraph with a - title - attribute whose value contains the substring "hello"

-
p[title*="hello"]
-
- -

6.3.3. Attribute selectors and namespaces

- -

Attribute selectors allow an optional namespace component to the - attribute name. A namespace prefix that has been previously declared - may be prepended to the attribute name separated by the namespace - separator "vertical bar" (|). In keeping with - the Namespaces in the XML recommendation, default namespaces do not - apply to attributes, therefore attribute selectors without a namespace - component apply only to attributes that have no declared namespace - (equivalent to "|attr"). An asterisk may be used for the - namespace prefix indicating that the selector is to match all - attribute names without regard to the attribute's namespace. - -

An attribute selector with an attribute name containing a namespace - prefix that has not been previously declared is an invalid selector. The mechanism for - declaring - a namespace prefix is left up to the language implementing Selectors. - In CSS, such a mechanism is defined in the General Syntax module. - -

-

CSS examples:

-
@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }
- -

The first rule will match only elements with the attribute - att in the "http://www.example.com" namespace with the - value "val".

- -

The second rule will match only elements with the attribute - att regardless of the namespace of the attribute - (including no declared namespace).

- -

The last two rules are equivalent and will match only elements - with the attribute att where the attribute is not - declared to be in a namespace.

- -
- -

6.3.4. Default attribute values in DTDs

- -

Attribute selectors represent explicitly set attribute values in - the document tree. Default attribute values may be defined in a DTD or - elsewhere, but cannot always be selected by attribute - selectors. Selectors should be designed so that they work even if the - default values are not included in the document tree.

- -

More precisely, a UA is not required to read an "external - subset" of the DTD but is required to look for default - attribute values in the document's "internal subset." (See [XML10] for definitions of these subsets.)

- -

A UA that recognizes an XML namespace [XMLNAMES] is not required to use its - knowledge of that namespace to treat default attribute values as if - they were present in the document. (For example, an XHTML UA is not - required to use its built-in knowledge of the XHTML DTD.)

- -

Note: Typically, implementations - choose to ignore external subsets.

- -
-

Example:

- -

Consider an element EXAMPLE with an attribute "notation" that has a - default value of "decimal". The DTD fragment might be

- -
<!ATTLIST EXAMPLE notation (decimal,octal) "decimal">
- -

If the style sheet contains the rules

- -
EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

the first rule will not match elements whose "notation" attribute - is set by default, i.e. not set explicitly. To catch all cases, the - attribute selector for the default value must be dropped:

- -
EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

Here, because the selector EXAMPLE[notation=octal] is - more specific than the tag - selector alone, the style declarations in the second rule will override - those in the first for elements that have a "notation" attribute value - of "octal". Care has to be taken that all property declarations that - are to apply only to the default case are overridden in the non-default - cases' style rules.

- -
- -

6.4. Class selectors

- -

Working with HTML, authors may use the period (U+002E, - .) notation as an alternative to the ~= - notation when representing the class attribute. Thus, for - HTML, div.value and div[class~=value] have - the same meaning. The attribute value must immediately follow the - "period" (.).

- -

UAs may apply selectors using the period (.) notation in XML - documents if the UA has namespace-specific knowledge that allows it to - determine which attribute is the "class" attribute for the - respective namespace. One such example of namespace-specific knowledge - is the prose in the specification for a particular namespace (e.g. SVG - 1.0 [SVG] describes the SVG - "class" attribute and how a UA should interpret it, and - similarly MathML 1.01 [MATH] describes the MathML - "class" attribute.)

- -
-

CSS examples:

- -

We can assign style information to all elements with - class~="pastoral" as follows:

- -
*.pastoral { color: green }  /* all elements with class~=pastoral */
- -

or just

- -
.pastoral { color: green }  /* all elements with class~=pastoral */
- -

The following assigns style only to H1 elements with - class~="pastoral":

- -
H1.pastoral { color: green }  /* H1 elements with class~=pastoral */
- -

Given these rules, the first H1 instance below would not have - green text, while the second would:

- -
<H1>Not green</H1>
-<H1 class="pastoral">Very green</H1>
- -
- -

To represent a subset of "class" values, each value must be preceded - by a ".", in any order.

- -
- -

CSS example:

- -

The following rule matches any P element whose "class" attribute - has been assigned a list of whitespace-separated values that includes - "pastoral" and "marine":

- -
p.pastoral.marine { color: green }
- -

This rule matches when class="pastoral blue aqua - marine" but does not match for class="pastoral - blue".

- -
- -

Note: Because CSS gives considerable - power to the "class" attribute, authors could conceivably design their - own "document language" based on elements with almost no associated - presentation (such as DIV and SPAN in HTML) and assigning style - information through the "class" attribute. Authors should avoid this - practice since the structural elements of a document language often - have recognized and accepted meanings and author-defined classes may - not.

- -

Note: If an element has multiple - class attributes, their values must be concatenated with spaces - between the values before searching for the class. As of this time the - working group is not aware of any manner in which this situation can - be reached, however, so this behavior is explicitly non-normative in - this specification.

- -

6.5. ID selectors

- -

Document languages may contain attributes that are declared to be - of type ID. What makes attributes of type ID special is that no two - such attributes can have the same value in a document, regardless of - the type of the elements that carry them; whatever the document - language, an ID typed attribute can be used to uniquely identify its - element. In HTML all ID attributes are named "id"; XML applications - may name ID attributes differently, but the same restriction - applies.

- -

An ID-typed attribute of a document language allows authors to - assign an identifier to one element instance in the document tree. W3C - ID selectors represent an element instance based on its identifier. An - ID selector contains a "number sign" (U+0023, - #) immediately followed by the ID value, which must be an - identifier.

- -

Selectors does not specify how a UA knows the ID-typed attribute of - an element. The UA may, e.g., read a document's DTD, have the - information hard-coded or ask the user. - -

-

Examples:

- -

The following ID selector represents an h1 element - whose ID-typed attribute has the value "chapter1":

-
h1#chapter1
-

The following ID selector represents any element whose ID-typed - attribute has the value "chapter1":

-
#chapter1
-

The following selector represents any element whose ID-typed - attribute has the value "z98y".

-
*#z98y
-
- -

Note. In XML 1.0 [XML10], the information about which attribute - contains an element's IDs is contained in a DTD or a schema. When - parsing XML, UAs do not always read the DTD, and thus may not know - what the ID of an element is (though a UA may have namespace-specific - knowledge that allows it to determine which attribute is the ID - attribute for that namespace). If a style sheet designer knows or - suspects that a UA may not know what the ID of an element is, he - should use normal attribute selectors instead: - [name=p371] instead of #p371. Elements in - XML 1.0 documents without a DTD do not have IDs at all.

- -

If an element has multiple ID attributes, all of them must be - treated as IDs for that element for the purposes of the ID - selector. Such a situation could be reached using mixtures of xml:id, - DOM3 Core, XML DTDs, and namespace-specific knowledge.

- -

6.6. Pseudo-classes

- -

The pseudo-class concept is introduced to permit selection based on - information that lies outside of the document tree or that cannot be - expressed using the other simple selectors.

- -

A pseudo-class always consists of a "colon" - (:) followed by the name of the pseudo-class and - optionally by a value between parentheses.

- -

Pseudo-classes are allowed in all sequences of simple selectors - contained in a selector. Pseudo-classes are allowed anywhere in - sequences of simple selectors, after the leading type selector or - universal selector (possibly omitted). Pseudo-class names are - case-insensitive. Some pseudo-classes are mutually exclusive, while - others can be applied simultaneously to the same - element. Pseudo-classes may be dynamic, in the sense that an element - may acquire or lose a pseudo-class while a user interacts with the - document.

- - -

6.6.1. Dynamic pseudo-classes

- -

Dynamic pseudo-classes classify elements on characteristics other - than their name, attributes, or content, in principle characteristics - that cannot be deduced from the document tree.

- -

Dynamic pseudo-classes do not appear in the document source or - document tree.

- - -
The link pseudo-classes: :link and :visited
- -

User agents commonly display unvisited links differently from - previously visited ones. Selectors - provides the pseudo-classes :link and - :visited to distinguish them:

- -
    -
  • The :link pseudo-class applies to links that have - not yet been visited. -
  • -
  • The :visited pseudo-class applies once the link has - been visited by the user. -
  • -
- -

After some amount of time, user agents may choose to return a - visited link to the (unvisited) ':link' state.

- -

The two states are mutually exclusive.

- -
- -

Example:

- -

The following selector represents links carrying class - external and already visited:

- -
a.external:visited
- -
- -

Note: It is possible for style sheet - authors to abuse the :link and :visited pseudo-classes to determine - which sites a user has visited without the user's consent. - -

UAs may therefore treat all links as unvisited links, or implement - other measures to preserve the user's privacy while rendering visited - and unvisited links differently.

- -
The user action pseudo-classes - :hover, :active, and :focus
- -

Interactive user agents sometimes change the rendering in response - to user actions. Selectors provides - three pseudo-classes for the selection of an element the user is - acting on.

- -
    - -
  • The :hover pseudo-class applies while the user - designates an element with a pointing device, but does not activate - it. For example, a visual user agent could apply this pseudo-class - when the cursor (mouse pointer) hovers over a box generated by the - element. User agents not that do not support interactive - media do not have to support this pseudo-class. Some conforming - user agents that support interactive - media may not be able to support this pseudo-class (e.g., a pen - device that does not detect hovering). -
  • - -
  • The :active pseudo-class applies while an element - is being activated by the user. For example, between the times the - user presses the mouse button and releases it. -
  • - -
  • The :focus pseudo-class applies while an element - has the focus (accepts keyboard or mouse events, or other forms of - input). -
  • - -
- -

There may be document language or implementation specific limits on - which elements can become :active or acquire - :focus.

- -

These pseudo-classes are not mutually exclusive. An element may - match several pseudo-classes at the same time.

- -

Selectors doesn't define if the parent of an element that is - ':active' or ':hover' is also in that state.

- -
-

Examples:

-
a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */
-

An example of combining dynamic pseudo-classes:

-
a:focus
-a:focus:hover
-

The last selector matches a elements that are in - the pseudo-class :focus and in the pseudo-class :hover.

-
- -

Note: An element can be both ':visited' - and ':active' (or ':link' and ':active').

- -

6.6.2. The target pseudo-class :target

- -

Some URIs refer to a location within a resource. This kind of URI - ends with a "number sign" (#) followed by an anchor - identifier (called the fragment identifier).

- -

URIs with fragment identifiers link to a certain element within the - document, known as the target element. For instance, here is a URI - pointing to an anchor named section_2 in an HTML - document:

- -
http://example.com/html/top.html#section_2
- -

A target element can be represented by the :target - pseudo-class. If the document's URI has no fragment identifier, then - the document has no target element.

- -
-

Example:

-
p.note:target
-

This selector represents a p element of class - note that is the target element of the referring - URI.

-
- -
-

CSS example:

- -

Here, the :target pseudo-class is used to make the - target element red and place an image before it, if there is one:

-
*:target { color : red }
-*:target::before { content : url(target.png) }
-
- -

6.6.3. The language pseudo-class :lang

- -

If the document language specifies how the human language of an - element is determined, it is possible to write selectors that - represent an element based on its language. For example, in HTML [HTML4], the language is determined by a - combination of the lang attribute, the meta - element, and possibly by information from the protocol (such as HTTP - headers). XML uses an attribute called xml:lang, and - there may be other document language-specific methods for determining - the language.

- -

The pseudo-class :lang(C) represents an element that - is in language C. Whether an element is represented by a - :lang() selector is based solely on the identifier C - being either equal to, or a hyphen-separated substring of, the - element's language value, in the same way as if performed by the '|=' operator in attribute - selectors. The identifier C does not have to be a valid language - name.

- -

C must not be empty. (If it is, the selector is invalid.)

- -

Note: It is recommended that - documents and protocols indicate language using codes from RFC 3066 [RFC3066] or its successor, and by means of - "xml:lang" attributes in the case of XML-based documents [XML10]. See - "FAQ: Two-letter or three-letter language codes."

- -
-

Examples:

- -

The two following selectors represent an HTML document that is in - Belgian, French, or German. The two next selectors represent - q quotations in an arbitrary element in Belgian, French, - or German.

-
html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) > q
-:lang(de) > q
-
- -

6.6.4. The UI element states pseudo-classes

- -
The :enabled and :disabled pseudo-classes
- -

The :enabled pseudo-class allows authors to customize - the look of user interface elements that are enabled — which the - user can select or activate in some fashion (e.g. clicking on a button - with a mouse). There is a need for such a pseudo-class because there - is no way to programmatically specify the default appearance of say, - an enabled input element without also specifying what it - would look like when it was disabled.

- -

Similar to :enabled, :disabled allows the - author to specify precisely how a disabled or inactive user interface - element should look.

- -

Most elements will be neither enabled nor disabled. An element is - enabled if the user can either activate it or transfer the focus to - it. An element is disabled if it could be enabled, but the user cannot - presently activate it or transfer focus to it.

- - -
The :checked pseudo-class
- -

Radio and checkbox elements can be toggled by the user. Some menu - items are "checked" when the user selects them. When such elements are - toggled "on" the :checked pseudo-class applies. The - :checked pseudo-class initially applies to such elements - that have the HTML4 selected and checked - attributes as described in Section - 17.2.1 of HTML4, but of course the user can toggle "off" such - elements in which case the :checked pseudo-class would no - longer apply. While the :checked pseudo-class is dynamic - in nature, and is altered by user action, since it can also be based - on the presence of the semantic HTML4 selected and - checked attributes, it applies to all media. - - -

The :indeterminate pseudo-class
- -
- -

Radio and checkbox elements can be toggled by the user, but are - sometimes in an indeterminate state, neither checked nor unchecked. - This can be due to an element attribute, or DOM manipulation.

- -

A future version of this specification may introduce an - :indeterminate pseudo-class that applies to such elements. -

- -
- - -

6.6.5. Structural pseudo-classes

- -

Selectors introduces the concept of structural - pseudo-classes to permit selection based on extra information that - lies in - the document tree but cannot be represented by other simple selectors or - combinators. - -

Note that standalone pieces of PCDATA (text nodes in the DOM) are - not counted when calculating the position of an element in the list of - children of its parent. When calculating the position of an element in - the list of children of its parent, the index numbering starts at 1. - - -

:root pseudo-class
- -

The :root pseudo-class represents an element that is - the root of the document. In HTML 4, this is always the - HTML element. - - -

:nth-child() pseudo-class
- -

The - :nth-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - before it in the document tree, for a given positive - integer or zero value of n, and has a parent element. In - other words, this matches the bth child of an element after - all the children have been split into groups of a elements - each. For example, this allows the selectors to address every other - row in a table, and could be used to alternate the color - of paragraph text in a cycle of four. The a and - b values must be zero, negative integers or positive - integers. The index of the first child of an element is 1. - -

In addition to this, :nth-child() can take - 'odd' and 'even' as arguments instead. - 'odd' has the same signification as 2n+1, - and 'even' has the same signification as 2n. - - -

-

Examples:

-
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }
-
- -

When a=0, no repeating is used, so for example - :nth-child(0n+5) matches only the fifth child. When - a=0, the an part need not be - included, so the syntax simplifies to - :nth-child(b) and the last example simplifies - to :nth-child(5). - -

-

Examples:

-
foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */
-
- -

When a=1, the number may be omitted from the rule. - -

-

Examples:

- -

The following selectors are therefore equivalent:

-
bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */
-
- -

If b=0, then every ath element is picked. In - such a case, the b part may be omitted. - -

-

Examples:

-
tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */
-
- -

If both a and b are equal to zero, the - pseudo-class represents no element in the document tree.

- -

The value a can be negative, but only the positive - values of an+b, for - n≥0, may represent an element in the document - tree.

- -
-

Example:

-
html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
-
- -

When the value b is negative, the "+" character in the - expression must be removed (it is effectively replaced by the "-" - character indicating the negative value of b).

- -
-

Examples:

-
:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */
-
- - -
:nth-last-child() pseudo-class
- -

The :nth-last-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - after it in the document tree, for a given positive - integer or zero value of n, and has a parent element. See - :nth-child() pseudo-class for the syntax of its argument. - It also accepts the 'even' and 'odd' values - as arguments. - - -

-

Examples:

-
tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */
-
- - -
:nth-of-type() pseudo-class
- -

The :nth-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name before it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. In other words, this matches the bth child - of that type after all the children of that type have been split into - groups of a elements each. See :nth-child() pseudo-class - for the syntax of its argument. It also accepts the - 'even' and 'odd' values. - - -

-

CSS example:

- -

This allows an author to alternate the position of floated images:

-
img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }
-
- - -
:nth-last-of-type() pseudo-class
- -

The :nth-last-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name after it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. See :nth-child() pseudo-class for the - syntax of its argument. It also accepts the 'even' and 'odd' - values. - - -

-

Example:

- -

To represent all h2 children of an XHTML - body except the first and last, one could use the - following selector:

-
body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
-

In this case, one could also use :not(), although the - selector ends up being just as long:

-
body > h2:not(:first-of-type):not(:last-of-type)
-
- - -
:first-child pseudo-class
- -

Same as :nth-child(1). The :first-child - pseudo-class - represents an element that is the first child of some other element. - - -

-

Examples:

- -

The following selector represents a p element that is - the first child of a div element:

-
div > p:first-child
-

This selector can represent the p inside the - div of the following fragment:

-
<p> The last P before the note.</p>
-<div class="note">
-   <p> The first P inside the note.</p>
-</div>
- but cannot represent the second p in the following - fragment: -
<p> The last P before the note.</p>
-<div class="note">
-   <h2> Note </h2>
-   <p> The first P inside the note.</p>
-</div>
-

The following two selectors are usually equivalent:

-
* > a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */
-
- -
:last-child pseudo-class
- -

Same as :nth-last-child(1). The :last-child - pseudo-class - represents an element that is the last child of some other element. - -

-

Example:

- -

The following selector represents a list item li that - is the last child of an ordered list ol. -

ol > li:last-child
-
- -
:first-of-type pseudo-class
- -

Same as :nth-of-type(1). The :first-of-type - pseudo-class - represents an element that is the first sibling of its type in the list of - children of its parent element. - -

-

Example:

- -

The following selector represents a definition title - dt inside a definition list dl, this - dt being the first of its type in the list of children of - its parent element.

-
dl dt:first-of-type
-

It is a valid description for the first two dt - elements in the following example but not for the third one:

-
<dl>
- <dt>gigogne</dt>
- <dd>
-  <dl>
-   <dt>fusée</dt>
-   <dd>multistage rocket</dd>
-   <dt>table</dt>
-   <dd>nest of tables</dd>
-  </dl>
- </dd>
-</dl>
-
- -
:last-of-type pseudo-class
- -

Same as :nth-last-of-type(1). The - :last-of-type pseudo-class represents an element that is - the last sibling of its type in the list of children of its parent - element.

- -
-

Example:

- -

The following selector represents the last data cell - td of a table row.

-
tr > td:last-of-type
-
- -
:only-child pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children. Same as - :first-child:last-child or - :nth-child(1):nth-last-child(1), but with a lower - specificity.

- -
:only-of-type pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children with the same element name. Same - as :first-of-type:last-of-type or - :nth-of-type(1):nth-last-of-type(1), but with a lower - specificity.

- - -
:empty pseudo-class
- -

The :empty pseudo-class represents an element that has - no children at all. In terms of the DOM, only element nodes and text - nodes (including CDATA nodes and entity references) whose data has a - non-zero length must be considered as affecting emptiness; comments, - PIs, and other nodes must not affect whether an element is considered - empty or not.

- -
-

Examples:

- -

p:empty is a valid representation of the following fragment: -

-
<p></p>
-

foo:empty is not a valid representation for the - following fragments:

-
<foo>bar</foo>
-
<foo><bar>bla</bar></foo>
-
<foo>this is not <bar>:empty</bar></foo>
-
- -

6.6.6. Blank

- - -

This section intentionally left blank.

- - -

6.6.7. The negation pseudo-class

- -

The negation pseudo-class, :not(X), is a - functional notation taking a simple - selector (excluding the negation pseudo-class itself and - pseudo-elements) as an argument. It represents an element that is not - represented by the argument. - - - -

-

Examples:

- -

The following CSS selector matches all button - elements in an HTML document that are not disabled.

-
button:not([DISABLED])
-

The following selector represents all but FOO - elements.

-
*:not(FOO)
-

The following group of selectors represents all HTML elements - except links.

-
html|*:not(:link):not(:visited)
-
- -

Default namespace declarations do not affect the argument of the - negation pseudo-class unless the argument is a universal selector or a - type selector.

- -
-

Examples:

- -

Assuming that the default namespace is bound to - "http://example.com/", the following selector represents all - elements that are not in that namespace:

-
*|*:not(*)
-

The following CSS selector matches any element being hovered, - regardless of its namespace. In particular, it is not limited to - only matching elements in the default namespace that are not being - hovered, and elements not in the default namespace don't match the - rule when they are being hovered.

-
*|*:not(:hover)
-
- -

Note: the :not() pseudo allows - useless selectors to be written. For instance :not(*|*), - which represents no element at all, or foo:not(bar), - which is equivalent to foo but with a higher - specificity.

- -

7. Pseudo-elements

- -

Pseudo-elements create abstractions about the document tree beyond - those specified by the document language. For instance, document - languages do not offer mechanisms to access the first letter or first - line of an element's content. Pseudo-elements allow designers to refer - to this otherwise inaccessible information. Pseudo-elements may also - provide designers a way to refer to content that does not exist in the - source document (e.g., the ::before and - ::after pseudo-elements give access to generated - content).

- -

A pseudo-element is made of two colons (::) followed - by the name of the pseudo-element.

- -

This :: notation is introduced by the current document - in order to establish a discrimination between pseudo-classes and - pseudo-elements. For compatibility with existing style sheets, user - agents must also accept the previous one-colon notation for - pseudo-elements introduced in CSS levels 1 and 2 (namely, - :first-line, :first-letter, - :before and :after). This compatibility is - not allowed for the new pseudo-elements introduced in CSS level 3.

- -

Only one pseudo-element may appear per selector, and if present it - must appear after the sequence of simple selectors that represents the - subjects of the selector. A -future version of this specification may allow multiple -pesudo-elements per selector.

- -

7.1. The ::first-line pseudo-element

- -

The ::first-line pseudo-element describes the contents - of the first formatted line of an element. - -

-

CSS example:

-
p::first-line { text-transform: uppercase }
-

The above rule means "change the letters of the first line of every - paragraph to uppercase".

-
- -

The selector p::first-line does not match any real - HTML element. It does match a pseudo-element that conforming user - agents will insert at the beginning of every paragraph.

- -

Note that the length of the first line depends on a number of - factors, including the width of the page, the font size, etc. Thus, - an ordinary HTML paragraph such as:

- -
-<P>This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the lines of which happen to be broken as follows: - -

-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-
- -

This paragraph might be "rewritten" by user agents to include the - fictional tag sequence for ::first-line. This - fictional tag sequence helps to show how properties are inherited.

- -
-<P><P::first-line> This is a somewhat long HTML 
-paragraph that </P::first-line> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

If a pseudo-element breaks up a real element, the desired effect - can often be described by a fictional tag sequence that closes and - then re-opens the element. Thus, if we mark up the previous paragraph - with a span element:

- -
-<P><SPAN class="test"> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the user agent could simulate start and end tags for - span when inserting the fictional tag sequence for - ::first-line. - -

-<P><P::first-line><SPAN class="test"> This is a
-somewhat long HTML
-paragraph that will </SPAN></P::first-line><SPAN
-    class="test"> be
-broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

In CSS, the ::first-line pseudo-element can only be - attached to a block-level element, an inline-block, a table-caption, - or a table-cell.

- -

The "first formatted line" of an - element may occur inside a - block-level descendant in the same flow (i.e., a block-level - descendant that is not positioned and not a float). E.g., the first - line of the div in <DIV><P>This - line...</P></DIV> is the first line of the p - (assuming - that both p and div are block-level). - -

The first line of a table-cell or inline-block cannot be the first - formatted line of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first formatted line of the - div is not the line "Hello". - -

Note that the first line of the p in this - fragment: <p><br>First... doesn't contain any - letters (assuming the default style for br in HTML - 4). The word "First" is not on the first formatted line. - -

A UA should act as if the fictional start tags of the - ::first-line pseudo-elements were nested just inside the - innermost enclosing block-level element. (Since CSS1 and CSS2 were - silent on this case, authors should not rely on this behavior.) Here - is an example. The fictional tag sequence for

- -
-<DIV>
-  <P>First paragraph</P>
-  <P>Second paragraph</P>
-</DIV>
-
- -

is

- -
-<DIV>
-  <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
-  <P><P::first-line>Second paragraph</P::first-line></P>
-</DIV>
-
- -

The ::first-line pseudo-element is similar to an - inline-level element, but with certain restrictions. In CSS, the - following properties apply to a ::first-line - pseudo-element: font properties, color property, background - properties, 'word-spacing', 'letter-spacing', 'text-decoration', - 'vertical-align', 'text-transform', 'line-height'. UAs may apply other - properties as well.

- - -

7.2. The ::first-letter pseudo-element

- -

The ::first-letter pseudo-element represents the first - letter of the first line of a block, if it is not preceded by any - other content (such as images or inline tables) on its line. The - ::first-letter pseudo-element may be used for "initial caps" and "drop - caps", which are common typographical effects. This type of initial - letter is similar to an inline-level element if its 'float' property - is 'none'; otherwise, it is similar to a floated element.

- -

In CSS, these are the properties that apply to ::first-letter - pseudo-elements: font properties, 'text-decoration', 'text-transform', - 'letter-spacing', 'word-spacing' (when appropriate), 'line-height', - 'float', 'vertical-align' (only if 'float' is 'none'), margin - properties, padding properties, border properties, color property, - background properties. UAs may apply other properties as well. To - allow UAs to render a typographically correct drop cap or initial cap, - the UA may choose a line-height, width and height based on the shape - of the letter, unlike for normal elements.

- -
-

Example:

- -

This example shows a possible rendering of an initial cap. Note - that the 'line-height' that is inherited by the - ::first-letter - pseudo-element is 1.1, but the UA in this example has computed the - height of the first letter differently, so that it doesn't cause any - unnecessary space between the first two lines. Also note that the - fictional start tag of the first letter is inside the span, - and thus - the font weight of the first letter is normal, not bold as the span: -

-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>
-Erbarremt over my en mijn benaeuwde vesten<br>
-En arme burgery, en op mijn volcx gebed<br>
-En dagelix geschrey de bange stad ontzet.
-
-
-

Image illustrating the ::first-letter pseudo-element -

-
- -
-

The following CSS will make a drop cap initial letter span about two - lines:

- -
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<HTML>
- <HEAD>
-  <TITLE>Drop cap initial letter</TITLE>
-  <STYLE type="text/css">
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  </STYLE>
- </HEAD>
- <BODY>
-  <P><SPAN>The first</SPAN> few words of an article
-    in The Economist.</P>
- </BODY>
-</HTML>
-
- -

This example might be formatted as follows:

- -
-

Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements -

-
- -

The fictional tag sequence is:

- -
-<P>
-<SPAN>
-<P::first-letter>
-T
-</P::first-letter>he first
-</SPAN> 
-few words of an article in the Economist.
-</P>
-
- -

Note that the ::first-letter pseudo-element tags abut - the content (i.e., the initial character), while the ::first-line - pseudo-element start tag is inserted right after the start tag of the - block element.

- -

In order to achieve traditional drop caps formatting, user agents - may approximate font sizes, for example to align baselines. Also, the - glyph outline may be taken into account when formatting.

- -

Punctuation (i.e, characters defined in Unicode in the "open" (Ps), - "close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) - punctuation classes), that precedes or follows the first letter should - be included. [UNICODE]

- -
-

Quotes that precede the
-first letter should be included.

-
- -

The ::first-letter also applies if the first letter is - in fact a digit, e.g., the "6" in "67 million dollars is a lot of - money."

- -

In CSS, the ::first-letter pseudo-element applies to - block, list-item, table-cell, table-caption, and inline-block - elements. A future version of this specification -may allow this pesudo-element to apply to more element -types.

- -

The ::first-letter pseudo-element can be used with all - such elements that contain text, or that have a descendant in the same - flow that contains text. A UA should act as if the fictional start tag - of the ::first-letter pseudo-element is just before the first text of - the element, even if that first text is in a descendant.

- -
-

Example:

- -

The fictional tag sequence for this HTMLfragment: -

<div>
-<p>The first text.
-

is: -

<div>
-<p><div::first-letter><p::first-letter>T</...></...>he first text.
-
- -

The first letter of a table-cell or inline-block cannot be the - first letter of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first letter of the div is - not the - letter "H". In fact, the div doesn't have a first letter. - -

The first letter must occur on the first formatted line. For example, in - this fragment: <p><br>First... the first line - doesn't contain any letters and ::first-letter doesn't - match anything (assuming the default style for br in HTML - 4). In particular, it does not match the "F" of "First." - -

In CSS, if an element is a list item ('display: list-item'), the - ::first-letter applies to the first letter in the - principal box after the marker. UAs may ignore - ::first-letter on list items with 'list-style-position: - inside'. If an element has ::before or - ::after content, the ::first-letter applies - to the first letter of the element including that content. - -

-

Example:

- -

After the rule 'p::before {content: "Note: "}', the selector - 'p::first-letter' matches the "N" of "Note".

-
- -

Some languages may have specific rules about how to treat certain - letter combinations. In Dutch, for example, if the letter combination - "ij" appears at the beginning of a word, both letters should be - considered within the ::first-letter pseudo-element. - -

If the letters that would form the ::first-letter are not in the - same element, such as "'T" in <p>'<em>T..., the UA - may create a ::first-letter pseudo-element from one of the elements, - both elements, or simply not create a pseudo-element.

- -

Similarly, if the first letter(s) of the block are not at the start - of the line (for example due to bidirectional reordering), then the UA - need not create the pseudo-element(s). - -

-

Example:

- -

The following example illustrates - how overlapping pseudo-elements may interact. The first letter of - each P element will be green with a font size of '24pt'. The rest of - the first formatted line will be 'blue' while the rest of the - paragraph will be 'red'.

- -
p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-<P>Some text that ends up on two lines</P>
- -

Assuming that a line break will occur before the word "ends", the -fictional tag -sequence for this fragment might be:

- -
<P>
-<P::first-line>
-<P::first-letter> 
-S 
-</P::first-letter>ome text that 
-</P::first-line> 
-ends up on two lines 
-</P>
- -

Note that the ::first-letter element is inside the ::first-line - element. Properties set on ::first-line are inherited by - ::first-letter, but are overridden if the same property is - set on - ::first-letter.

-
- - -

7.3. The ::selection - pseudo-element

- -

The ::selection pseudo-element applies to the portion - of a document that has been highlighted by the user. This also - applies, for example, to selected text within an editable text - field. This pseudo-element should not be confused with the :checked pseudo-class (which used to be - named :selected) - -

Although the ::selection pseudo-element is dynamic in - nature, and is altered by user action, it is reasonable to expect that - when a UA re-renders to a static medium (such as a printed page, see - [CSS21]) which was originally rendered to a - dynamic medium (like screen), the UA may wish to transfer the current - ::selection state to that other medium, and have all the - appropriate formatting and rendering take effect as well. This is not - required — UAs may omit the ::selection - pseudo-element for static media. - -

These are the CSS properties that apply to ::selection - pseudo-elements: color, background, cursor (optional), outline - (optional). The computed value of the 'background-image' property on - ::selection may be ignored. - - -

7.4. The ::before and ::after pseudo-elements

- -

The ::before and ::after pseudo-elements - can be used to describe generated content before or after an element's - content. They are explained in CSS 2.1 [CSS21].

- -

When the ::first-letter and ::first-line - pseudo-elements are combined with ::before and - ::after, they apply to the first letter or line of the - element including the inserted text.

- -

8. Combinators

- -

8.1. Descendant combinator

- -

At times, authors may want selectors to describe an element that is - the descendant of another element in the document tree (e.g., "an - EM element that is contained within an H1 - element"). Descendant combinators express such a relationship. A - descendant combinator is white space that - separates two sequences of simple selectors. A selector of the form - "A B" represents an element B that is an - arbitrary descendant of some ancestor element A. - -

-

Examples:

- -

For example, consider the following selector:

-
h1 em
-

It represents an em element being the descendant of - an h1 element. It is a correct and valid, but partial, - description of the following fragment:

-
<h1>This <span class="myclass">headline
-is <em>very</em> important</span></h1>
-

The following selector:

-
div * p
-

represents a p element that is a grandchild or later - descendant of a div element. Note the whitespace on - either side of the "*" is not part of the universal selector; the - whitespace is a combinator indicating that the DIV must be the - ancestor of some element, and that that element must be an ancestor - of the P.

- -

The following selector, which combines descendant combinators and - attribute selectors, represents an - element that (1) has the href attribute set and (2) is - inside a p that is itself inside a div:

-
div p *[href]
-
- -

8.2. Child combinators

- -

A child combinator describes a childhood relationship - between two elements. A child combinator is made of the - "greater-than sign" (>) character and - separates two sequences of simple selectors. - - -

-

Examples:

- -

The following selector represents a p element that is - child of body:

-
body > p
-

The following example combines descendant combinators and child - combinators.

-
div ol>li p
- -

It represents a p element that is a descendant of an - li element; the li element must be the - child of an ol element; the ol element must - be a descendant of a div. Notice that the optional white - space around the ">" combinator has been left out.

-
- -

For information on selecting the first child of an element, please - see the section on the :first-child pseudo-class - above.

- -

8.3. Sibling combinators

- -

There are two different sibling combinators: the adjacent sibling - combinator and the general sibling combinator. In both cases, - non-element nodes (e.g. text between elements) are ignored when - considering adjacency of elements.

- -

8.3.1. Adjacent sibling combinator -

- -

The adjacent sibling combinator is made of the "plus - sign" (U+002B, +) character that separates two - sequences of simple selectors. The elements represented by the two - sequences share the same parent in the document tree and the element - represented by the first sequence immediately precedes the element - represented by the second one.

- -
-

Examples:

- -

The following selector represents a p element - immediately following a math element:

-
math + p
-

The following selector is conceptually similar to the one in the - previous example, except that it adds an attribute selector — it - adds a constraint to the h1 element, that it must have - class="opener":

-
h1.opener + h2
-
- - -

8.3.2. General sibling combinator -

- -

The general sibling combinator is made of the "tilde" - (U+007E, ~) character that separates two sequences of - simple selectors. The elements represented by the two sequences share - the same parent in the document tree and the element represented by - the first sequence precedes (not necessarily immediately) the element - represented by the second one.

- -
-

Example:

-
h1 ~ pre
-

represents a pre element following an h1. It - is a correct and valid, but partial, description of:

-
<h1>Definition of the function a</h1>
-<p>Function a(x) has to be applied to all figures in the table.</p>
-<pre>function a(x) = 12x/13.5</pre>
-
- -

9. Calculating a selector's specificity

- -

A selector's specificity is calculated as follows:

- -
    -
  • count the number of ID selectors in the selector (= a)
  • -
  • count the number of class selectors, attributes selectors, and - pseudo-classes in the selector (= b) -
  • -
  • count the number of element names in the selector (= c)
  • -
  • ignore pseudo-elements
  • -
- -

Selectors inside the negation pseudo-class - are counted like any other, but the negation itself does not count as - a pseudo-class.

- -

Concatenating the three numbers a-b-c (in a number system with a - large base) gives the specificity.

- -
-

Examples:

-
*               /* a=0 b=0 c=0 -> specificity =   0 */
-LI              /* a=0 b=0 c=1 -> specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -> specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */
-
-
- -

Note: the specificity of the styles - specified in an HTML style attribute is described in CSS - 2.1. [CSS21].

- -

10. The grammar of Selectors

- -

10.1. Grammar

- -

The grammar below defines the syntax of Selectors. It is globally - LL(1) and can be locally LL(2) (but note that most UA's should not use - it directly, since it doesn't express the parsing conventions). The - format of the productions is optimized for human consumption and some - shorthand notations beyond Yacc (see [YACC]) - are used:

- -
    -
  • *: 0 or more -
  • +: 1 or more -
  • ?: 0 or 1 -
  • |: separates alternatives -
  • [ ]: grouping
  • -
- -

The productions are:

- -
selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;
- - -

10.2. Lexical scanner

- -

The following is the tokenizer, written in Flex (see - [FLEX]) notation. The tokenizer is - case-insensitive.

- -

The two occurrences of "\377" represent the highest character - number that current versions of Flex can deal with (decimal 255). They - should be read as "\4177777" (decimal 1114111), which is the highest - possible code point in Unicode/ISO-10646. [UNICODE]

- -
%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}">"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"<!--"           return CDO;
-"-->"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;
- - -

11. Namespaces and down-level clients

- -

An important issue is the interaction of CSS selectors with XML - documents in web clients that were produced prior to this - document. Unfortunately, due to the fact that namespaces must be - matched based on the URI which identifies the namespace, not the - namespace prefix, some mechanism is required to identify namespaces in - CSS by their URI as well. Without such a mechanism, it is impossible - to construct a CSS style sheet which will properly match selectors in - all cases against a random set of XML documents. However, given - complete knowledge of the XML document to which a style sheet is to be - applied, and a limited use of namespaces within the XML document, it - is possible to construct a style sheet in which selectors would match - elements and attributes correctly.

- -

It should be noted that a down-level CSS client will (if it - properly conforms to CSS forward compatible parsing rules) ignore all - @namespace at-rules, as well as all style rules that make - use of namespace qualified element type or attribute selectors. The - syntax of delimiting namespace prefixes in CSS was deliberately chosen - so that down-level CSS clients would ignore the style rules rather - than possibly match them incorrectly.

- -

The use of default namespaces in CSS makes it possible to write - element type selectors that will function in both namespace aware CSS - clients as well as down-level clients. It should be noted that - down-level clients may incorrectly match selectors against XML - elements in other namespaces.

- -

The following are scenarios and examples in which it is possible to - construct style sheets which would function properly in web clients - that do not implement this proposal.

- -
    -
  1. - -

    The XML document does not use namespaces.

    - -
      - -
    • In this case, it is obviously not necessary to declare or use - namespaces in the style sheet. Standard CSS element type and - attribute selectors will function adequately in a down-level - client. -
    • - -
    • In a CSS namespace aware client, the default behavior of - element selectors matching without regard to namespace will - function properly against all elements, since no namespaces are - present. However, the use of specific element type selectors - that - match only elements that have no namespace ("|name") - will guarantee that selectors will match only XML elements that - do - not have a declared namespace. -
    • - -
    - -
  2. - -
  3. - -

    The XML document defines a single, default namespace used - throughout the document. No namespace prefixes are used in element - names.

    - -
      - -
    • In this case, a down-level client will function as if - namespaces were not used in the XML document at all. Standard - CSS - element type and attribute selectors will match against all - elements. -
    • - -
    - -
  4. - -
  5. - -

    The XML document does not use a default namespace, all - namespace prefixes used are known to the style sheet author, and - there is a direct mapping between namespace prefixes and namespace - URIs. (A given prefix may only be mapped to one namespace URI - throughout the XML document; there may be multiple prefixes mapped - to the same URI).

    - -
      - -
    • In this case, the down-level client will view and match - element type and attribute selectors based on their fully - qualified name, not the local part as outlined in the Type selectors and Namespaces - section. CSS - selectors may be declared using an escaped colon - "\:" - to describe the fully qualified names, e.g. - "html\:h1" will match - <html:h1>. Selectors using the qualified name - will only match XML elements that use the same prefix. Other - namespace prefixes used in the XML that are mapped to the same - URI - will not match as expected unless additional CSS style rules are - declared for them. -
    • - -
    • Note that selectors declared in this fashion will - only match in down-level clients. A CSS namespace aware - client will match element type and attribute selectors based on - the name's local part. Selectors declared with the fully - qualified name will not match (unless there is no namespace - prefix - in the fully qualified name). -
    • - -
    - -
  6. - -
- -

In other scenarios: when the namespace prefixes used in the XML are - not known in advance by the style sheet author; or a combination of - elements with no namespace are used in conjunction with elements using - a default namespace; or the same namespace prefix is mapped to - different namespace URIs within the same document, or in - different documents; it is impossible to construct a CSS style sheet - that will function properly against all elements in those documents, - unless, the style sheet is written using a namespace URI syntax (as - outlined in this document or similar) and the document is processed by - a CSS and XML namespace aware client.

- -

12. Profiles

- -

Each specification using Selectors must define the subset of W3C - Selectors it allows and excludes, and describe the local meaning of - all the components of that subset.

- -

Non normative examples: - -

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 1
Acceptstype selectors
class selectors
ID selectors
:link, - :visited and :active pseudo-classes
descendant combinator -
::first-line and ::first-letter pseudo-elements -
Excludes - -

universal selector
attribute selectors
:hover and - :focus - pseudo-classes
:target pseudo-class
:lang() - pseudo-class
all UI - element states pseudo-classes
all structural - pseudo-classes
negation pseudo-class
all - UI element fragments pseudo-elements
::before and ::after - pseudo-elements
child combinators
sibling combinators - -

namespaces

Extra constraintsonly one class selector allowed per sequence of simple - selectors -
-

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 2
Acceptstype selectors
universal selector
attribute presence and - values selectors
class selectors
ID selectors
:link, - :visited, - :active, :hover, :focus, :lang() and :first-child pseudo-classes -
descendant combinator
child combinator
adjacent - sibling - combinator
::first-line and ::first-letter - pseudo-elements
::before - and ::after pseudo-elements -
Excludes - -

content selectors
substring matching attribute - selectors
:target pseudo-classes
all UI element - states pseudo-classes
all structural pseudo-classes other - than :first-child
negation pseudo-class
all UI element - fragments pseudo-elements
general sibling combinators - -

namespaces

Extra constraintsmore than one class selector per sequence of simple selectors - (CSS1 - constraint) allowed -
- -

In CSS, selectors express pattern matching rules that determine which - style - rules apply to elements in the document tree. - -

The following selector (CSS level 2) will match all anchors a - with attribute name set inside a section 1 header - h1: -

h1 a[name]
- -

All CSS declarations attached to such a selector are applied to elements - matching it.

- -
- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationSTTS 3
Accepts - -

type selectors
universal selectors
attribute - selectors
class - selectors
ID selectors
all structural - pseudo-classes
- all combinators - -

namespaces

Excludesnon-accepted pseudo-classes
pseudo-elements
Extra constraintssome selectors and combinators are not allowed in fragment - descriptions on the right side of STTS declarations. -
- -

Selectors can be used in STTS 3 in two different - manners: -

    -
  1. a selection mechanism equivalent to CSS selection mechanism: - declarations - attached to a given selector are applied to elements matching that - selector, -
  2. fragment descriptions that appear on the right side of declarations. -
  3. -
-
- -

13. Conformance and requirements

- -

This section defines conformance with the present specification only. - -

The inability of a user agent to implement part of this specification due to - the limitations of a particular device (e.g., non interactive user agents - will - probably not implement dynamic pseudo-classes because they make no sense - without - interactivity) does not imply non-conformance. - -

All specifications reusing Selectors must contain a Profile listing the - subset of Selectors it accepts or excludes, and describing the constraints - it adds to the current specification. - -

Invalidity is caused by a parsing error, e.g. an unrecognized token or a - token - which is not allowed at the current parsing point. - -

User agents must observe the rules for handling parsing errors: -

    -
  • a simple selector containing an undeclared namespace prefix is invalid -
  • -
  • a selector containing an invalid simple selector, an invalid combinator - or an invalid token is invalid. -
  • -
  • a group of selectors containing an invalid selector is invalid.
  • -
- -

Specifications reusing Selectors must define how to handle parsing - errors. (In the case of CSS, the entire rule in which the selector is - used is dropped.)

- - - -

14. Tests

- -

This specification has a test - suite allowing user agents to verify their basic conformance to - the specification. This test suite does not pretend to be exhaustive - and does not cover all possible combined cases of Selectors.

- -

15. Acknowledgements

- -

The CSS working group would like to thank everyone who has sent - comments on this specification over the years.

- -

The working group would like to extend special thanks to Donna - McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed - the final editorial review.

- -

16. References

- -
- -
[CSS1] -
Bert Bos, Håkon Wium Lie; "Cascading - Style Sheets, level 1", W3C Recommendation, 17 Dec 1996, revised - 11 Jan 1999 -
(http://www.w3.org/TR/REC-CSS1) - -
[CSS21] -
Bert Bos, Tantek Çelik, Ian Hickson, Håkon - Wium Lie, editors; "Cascading Style Sheets, level 2 revision - 1", W3C Working Draft, 13 June 2005 -
(http://www.w3.org/TR/CSS21) - -
[CWWW] -
Martin J. Dürst, François Yergeau, - Misha Wolf, Asmus Freytag, Tex Texin, editors; "Character Model - for the World Wide Web", W3C Recommendation, 15 February 2005 -
(http://www.w3.org/TR/charmod/) - -
[FLEX] -
"Flex: The Lexical Scanner - Generator", Version 2.3.7, ISBN 1882114213 - -
[HTML4] -
Dave Ragget, Arnaud Le Hors, Ian Jacobs, - editors; "HTML 4.01 Specification", W3C Recommendation, 24 - December 1999 -
- (http://www.w3.org/TR/html4/) - -
[MATH] -
Patrick Ion, Robert Miner, editors; "Mathematical - Markup Language (MathML) 1.01", W3C Recommendation, revision of 7 - July 1999 -
(http://www.w3.org/TR/REC-MathML/) - -
[RFC3066] -
H. Alvestrand; "Tags for the - Identification of Languages", Request for Comments 3066, January - 2001 -
(http://www.ietf.org/rfc/rfc3066.txt) - -
[STTS] -
Daniel Glazman; "Simple Tree Transformation - Sheets 3", Electricité de France, submission to the W3C, - 11 November 1998 -
(http://www.w3.org/TR/NOTE-STTS3) - -
[SVG] -
Jon Ferraiolo, 藤沢 淳, Dean - Jackson, editors; "Scalable Vector Graphics (SVG) 1.1 - Specification", W3C Recommendation, 14 January 2003 -
(http://www.w3.org/TR/SVG/) - -
[UNICODE]
-
The Unicode - Standard, Version 4.1, The Unicode Consortium. Boston, MA, - Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by Unicode - 4.0.1 and Unicode - 4.1.0. -
(http://www.unicode.org/versions/) -
- -
[XML10] -
Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, - Eve Maler, François Yergeau, editors; "Extensible Markup - Language (XML) 1.0 (Third Edition)", W3C Recommendation, 4 - February 2004 -
(http://www.w3.org/TR/REC-xml/) - -
[XMLNAMES] -
Tim Bray, Dave Hollander, Andrew Layman, - editors; "Namespaces in XML", W3C Recommendation, 14 - January 1999 -
(http://www.w3.org/TR/REC-xml-names/) - -
[YACC] -
S. C. Johnson; "YACC — Yet another - compiler compiler", Technical Report, Murray Hill, 1975 - -
- -
+

+ GWTSpeed - GWT Query benchmarks +
Start Race
+

+ +
+
+
+
+ +
+ +
+
+ + diff --git a/samples/src/main/java/gwtquery/samples/public/dojobench.html b/samples/src/main/java/gwtquery/samples/public/dojobench.html deleted file mode 100644 index 8f225a54..00000000 --- a/samples/src/main/java/gwtquery/samples/public/dojobench.html +++ /dev/null @@ -1,3172 +0,0 @@ - - - JQuery - - - - -
- - -

Abstract

- -

Selectors are patterns that match against elements in a - tree. Selectors have been optimized for use with HTML and XML, and - are designed to be usable in performance-critical code.

- -

CSS (Cascading - Style Sheets) is a language for describing the rendering of HTML and XML documents on - screen, on paper, in speech, etc. CSS uses Selectors for binding - style properties to elements in the document. This document - describes extensions to the selectors defined in CSS level 2. These - extended selectors will be used by CSS level 3. - -

Selectors define the following function:

- -
expression ∗ element → boolean
- -

That is, given an element and a selector, this specification - defines whether that element matches the selector.

- -

These expressions can also be used, for instance, to select a set - of elements, or a single element from a set of elements, by - evaluating the expression across all the elements in a - subtree. STTS (Simple Tree Transformation Sheets), a - language for transforming XML trees, uses this mechanism. [STTS]

- -

Status of this document

- -

This section describes the status of this document at the - time of its publication. Other documents may supersede this - document. A list of current W3C publications and the latest revision - of this technical report can be found in the W3C technical reports index at - http://www.w3.org/TR/.

- -

This document describes the selectors that already exist in CSS1 and CSS2, and - also proposes new selectors for CSS3 and other languages that may need them.

- -

The CSS Working Group doesn't expect that all implementations of - CSS3 will have to implement all selectors. Instead, there will - probably be a small number of variants of CSS3, called profiles. For - example, it may be that only a profile for interactive user agents - will include all of the selectors.

- -

This specification is a last call working draft for the the CSS Working Group - (Style Activity). This - document is a revision of the Candidate - Recommendation dated 2001 November 13, and has incorporated - implementation feedback received in the past few years. It is - expected that this last call will proceed straight to Proposed - Recommendation stage since it is believed that interoperability will - be demonstrable.

- -

All persons are encouraged to review and implement this - specification and return comments to the (archived) - public mailing list www-style - (see instructions). W3C - Members can also send comments directly to the CSS Working - Group. - The deadline for comments is 14 January 2006.

- -

This is still a draft document and may be updated, replaced, or - obsoleted by other documents at any time. It is inappropriate to - cite a W3C Working Draft as other than "work in progress". - -

This document may be available in translation. - The English version of this specification is the only normative - version. - -

- -

Table of contents

- - - -
- -

1. Introduction

- -

1.1. Dependencies

- -

Some features of this specification are specific to CSS, or have - particular limitations or rules specific to CSS. In this - specification, these have been described in terms of CSS2.1. [CSS21]

- -

1.2. Terminology

- -

All of the text of this specification is normative except - examples, notes, and sections explicitly marked as - non-normative.

- -

1.3. Changes from CSS2

- -

This section is non-normative.

- -

The main differences between the selectors in CSS2 and those in - Selectors are: - -

    - -
  • the list of basic definitions (selector, group of selectors, - simple selector, etc.) has been changed; in particular, what was - referred to in CSS2 as a simple selector is now called a sequence - of simple selectors, and the term "simple selector" is now used for - the components of this sequence -
  • - -
  • an optional namespace component is now allowed in type element - selectors, the universal selector and attribute selectors -
  • - -
  • a new combinator has been - introduced -
  • - -
  • new simple selectors including substring matching attribute - selectors, and new pseudo-classes -
  • - -
  • new pseudo-elements, and introduction of the "::" convention - for pseudo-elements -
  • - -
  • the grammar has been rewritten
  • - -
  • profiles to be added to specifications integrating Selectors - and defining the set of selectors which is actually supported by - each specification -
  • - -
  • Selectors are now a CSS3 Module and an independent - specification; other specifications can now refer to this document - independently of CSS -
  • - -
  • the specification now has its own test suite
  • - -
- -

2. Selectors

- -

This section is non-normative, as it merely summarizes the - following sections.

- -

A Selector represents a structure. This structure can be used as a - condition (e.g. in a CSS rule) that determines which elements a - selector matches in the document tree, or as a flat description of the - HTML or XML fragment corresponding to that structure.

- -

Selectors may range from simple element names to rich contextual - representations.

- -

The following table summarizes the Selector syntax:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PatternMeaningDescribed in sectionFirst defined in CSS level
*any elementUniversal - selector2
Ean element of type EType selector1
E[foo]an E element with a "foo" attributeAttribute - selectors2
E[foo="bar"]an E element whose "foo" attribute value is exactly - equal to "bar" - Attribute - selectors2
E[foo~="bar"]an E element whose "foo" attribute value is a list of - space-separated values, one of which is exactly equal to "bar" - Attribute - selectors2
E[foo^="bar"]an E element whose "foo" attribute value begins exactly - with the string "bar" - Attribute - selectors3
E[foo$="bar"]an E element whose "foo" attribute value ends exactly - with the string "bar" - Attribute - selectors3
E[foo*="bar"]an E element whose "foo" attribute value contains the - substring "bar" - Attribute - selectors3
E[hreflang|="en"]an E element whose "hreflang" attribute has a - hyphen-separated - list of values beginning (from the left) with "en" - Attribute - selectors2
E:rootan E element, root of the documentStructural - pseudo-classes3
E:nth-child(n)an E element, the n-th child of its parentStructural - pseudo-classes3
E:nth-last-child(n)an E element, the n-th child of its parent, counting - from the last one - Structural - pseudo-classes3
E:nth-of-type(n)an E element, the n-th sibling of its typeStructural - pseudo-classes3
E:nth-last-of-type(n)an E element, the n-th sibling of its type, counting - from the last one - Structural - pseudo-classes3
E:first-childan E element, first child of its parentStructural - pseudo-classes2
E:last-childan E element, last child of its parentStructural - pseudo-classes3
E:first-of-typean E element, first sibling of its typeStructural - pseudo-classes3
E:last-of-typean E element, last sibling of its typeStructural - pseudo-classes3
E:only-childan E element, only child of its parentStructural - pseudo-classes3
E:only-of-typean E element, only sibling of its typeStructural - pseudo-classes3
E:emptyan E element that has no children (including text - nodes) - Structural - pseudo-classes3
E:link
E:visited
an E element being the source anchor of a hyperlink of - which the target is not yet visited (:link) or already visited - (:visited) - The link - pseudo-classes1
E:active
E:hover
E:focus
an E element during certain user actionsThe user - action pseudo-classes1 and 2
E:targetan E element being the target of the referring URIThe target - pseudo-class3
E:lang(fr)an element of type E in language "fr" (the document - language specifies how language is determined) - The :lang() - pseudo-class2
E:enabled
E:disabled
a user interface element E which is enabled or - disabled - The UI element states - pseudo-classes3
E:checkeda user interface element E which is checked (for instance a radio-button or checkbox) - The UI element states - pseudo-classes3
E::first-linethe first formatted line of an E elementThe ::first-line - pseudo-element1
E::first-letterthe first formatted letter of an E elementThe ::first-letter - pseudo-element1
E::selectionthe portion of an E element that is currently - selected/highlighted by the user - The UI element - fragments pseudo-elements3
E::beforegenerated content before an E elementThe ::before - pseudo-element2
E::aftergenerated content after an E elementThe ::after - pseudo-element2
E.warningan E element whose class is - "warning" (the document language specifies how class is determined). - Class - selectors1
E#myidan E element with ID equal to "myid".ID - selectors1
E:not(s)an E element that does not match simple selector sNegation - pseudo-class3
E Fan F element descendant of an E elementDescendant - combinator1
E > Fan F element child of an E elementChild - combinator2
E + Fan F element immediately preceded by an E elementAdjacent sibling combinator - 2
E ~ Fan F element preceded by an E elementGeneral sibling combinator - 3
- -

The meaning of each selector is derived from the table above by - prepending "matches" to the contents of each cell in the "Meaning" - column.

- -

3. Case sensitivity

- -

The case sensitivity of document language element names, attribute - names, and attribute values in selectors depends on the document - language. For example, in HTML, element names are case-insensitive, - but in XML, they are case-sensitive.

- -

4. Selector syntax

- -

A selector is a chain of one - or more sequences of simple selectors - separated by combinators.

- -

A sequence of simple selectors - is a chain of simple selectors - that are not separated by a combinator. It - always begins with a type selector or a - universal selector. No other type - selector or universal selector is allowed in the sequence.

- -

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, content selector, or pseudo-class. One pseudo-element may be appended to the last - sequence of simple selectors.

- -

Combinators are: white space, "greater-than - sign" (U+003E, >), "plus sign" (U+002B, - +) and "tilde" (U+007E, ~). White - space may appear between a combinator and the simple selectors around - it. Only the characters "space" (U+0020), "tab" - (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form - feed" (U+000C) can occur in white space. Other space-like characters, - such as "em-space" (U+2003) and "ideographic space" (U+3000), are - never part of white space.

- -

The elements of a document tree that are represented by a selector - are the subjects of the selector. A - selector consisting of a single sequence of simple selectors - represents any element satisfying its requirements. Prepending another - sequence of simple selectors and a combinator to a sequence imposes - additional matching constraints, so the subjects of a selector are - always a subset of the elements represented by the last sequence of - simple selectors.

- -

An empty selector, containing no sequence of simple selectors and - no pseudo-element, is an invalid - selector.

- -

5. Groups of selectors

- -

When several selectors share the same declarations, they may be - grouped into a comma-separated list. (A comma is U+002C.)

- -
-

CSS examples:

- -

In this example, we condense three rules with identical - declarations into one. Thus,

-
h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }
-

is equivalent to:

-
h1, h2, h3 { font-family: sans-serif }
-
- -

Warning: the equivalence is true in this example - because all the selectors are valid selectors. If just one of these - selectors were invalid, the entire group of selectors would be - invalid. This would invalidate the rule for all three heading - elements, whereas in the former case only one of the three individual - heading rules would be invalidated.

- - -

6. Simple selectors

- -

6.1. Type selector

- -

A type selector is the name of a document language - element type. A type selector represents an instance of the element - type in the document tree.

- -
-

Example:

- -

The following selector represents an h1 element in the - document tree:

-
h1
-
- - -

6.1.1. Type selectors and namespaces

- -

Type selectors allow an optional namespace ([XMLNAMES]) component. A namespace prefix - that has been previously declared may be prepended to the element name - separated by the namespace separator "vertical bar" - (U+007C, |).

- -

The namespace component may be left empty to indicate that the - selector is only to represent elements with no declared namespace.

- -

An asterisk may be used for the namespace prefix, indicating that - the selector represents elements in any namespace (including elements - with no namespace).

- -

Element type selectors that have no namespace component (no - namespace separator), represent elements without regard to the - element's namespace (equivalent to "*|") unless a default - namespace has been declared. If a default namespace has been declared, - the selector will represent only elements in the default - namespace.

- -

A type selector containing a namespace prefix that has not been - previously declared is an invalid selector. - The mechanism for declaring a namespace prefix is left up to the - language implementing Selectors. In CSS, such a mechanism is defined - in the General Syntax module.

- -

In a namespace-aware client, element type selectors will only match - against the local - part - of the element's qualified - name. See below for notes about matching - behaviors in down-level clients.

- -

In summary:

- -
-
ns|E
-
elements with name E in namespace ns
-
*|E
-
elements with name E in any namespace, including those without any - declared namespace -
-
|E
-
elements with name E without any declared namespace
-
E
-
if no default namespace has been specified, this is equivalent to *|E. - Otherwise it is equivalent to ns|E where ns is the default namespace. -
-
- -
-

CSS examples:

- -
@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }
- -

The first rule will match only h1 elements in the - "http://www.example.com" namespace.

- -

The second rule will match all elements in the - "http://www.example.com" namespace.

- -

The third rule will match only h1 elements without - any declared namespace.

- -

The fourth rule will match h1 elements in any - namespace (including those without any declared namespace).

- -

The last rule is equivalent to the fourth rule because no default - namespace has been defined.

- -
- -

6.2. Universal selector

- -

The universal selector, written "asterisk" - (*), represents the qualified name of any element - type. It represents any single element in the document tree in any - namespace (including those without any declared namespace) if no - default namespace has been specified. If a default namespace has been - specified, see Universal selector and - Namespaces below.

- -

If the universal selector is not the only component of a sequence - of simple selectors, the * may be omitted.

- -
-

Examples:

-
    -
  • *[hreflang|=en] and [hreflang|=en] are - equivalent, -
  • -
  • *.warning and .warning are equivalent, -
  • -
  • *#myid and #myid are equivalent.
  • -
-
- -

Note: it is recommended that the - *, representing the universal selector, not be - omitted.

- -

6.2.1. Universal selector and namespaces

- -

The universal selector allows an optional namespace component. It - is used as follows:

- -
-
ns|*
-
all elements in namespace ns
-
*|*
-
all elements
-
|*
-
all elements without any declared namespace
-
*
-
if no default namespace has been specified, this is equivalent to *|*. - Otherwise it is equivalent to ns|* where ns is the default namespace. -
-
- -

A universal selector containing a namespace prefix that has not - been previously declared is an invalid - selector. The mechanism for declaring a namespace prefix is left up - to the language implementing Selectors. In CSS, such a mechanism is - defined in the General Syntax module.

- - -

6.3. Attribute selectors

- -

Selectors allow the representation of an element's attributes. When - a selector is used as an expression to match against an element, - attribute selectors must be considered to match an element if that - element has an attribute that matches the attribute represented by the - attribute selector.

- -

6.3.1. Attribute presence and values - selectors

- -

CSS2 introduced four attribute selectors:

- -
-
[att] -
Represents an element with the att attribute, whatever the - value of - the attribute. -
-
[att=val]
-
Represents an element with the att attribute whose value is - exactly - "val". -
-
[att~=val]
-
Represents an element with the att attribute whose value is - a whitespace-separated list of words, one - of - which is exactly "val". If "val" contains whitespace, it will never - represent anything (since the words are separated by - spaces). -
-
[att|=val] -
Represents an element with the att attribute, its value - either - being exactly "val" or beginning with "val" immediately followed by - "-" (U+002D). This is primarily intended to allow language subcode - matches (e.g., the hreflang attribute on the - link element in HTML) as described in RFC 3066 ([RFC3066]). For lang (or - xml:lang) language subcode matching, please see the :lang pseudo-class. -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names and values in selectors depends on - the document language.

- -
- -

Examples:

- -

The following attribute selector represents an h1 - element that carries the title attribute, whatever its - value:

- -
h1[title]
- -

In the following example, the selector represents a - span element whose class attribute has - exactly the value "example":

- -
span[class="example"]
- -

Multiple attribute selectors can be used to represent several - attributes of an element, or several conditions on the same - attribute. Here, the selector represents a span element - whose hello attribute has exactly the value "Cleveland" - and whose goodbye attribute has exactly the value - "Columbus":

- -
span[hello="Cleveland"][goodbye="Columbus"]
- -

The following selectors illustrate the differences between "=" - and "~=". The first selector will represent, for example, the value - "copyright copyleft copyeditor" on a rel attribute. The - second selector will only represent an a element with - an href attribute having the exact value - "http://www.w3.org/".

- -
a[rel~="copyright"]
-a[href="http://www.w3.org/"]
- -

The following selector represents a link element - whose hreflang attribute is exactly "fr".

- -
link[hreflang=fr]
- -

The following selector represents a link element for - which the values of the hreflang attribute begins with - "en", including "en", "en-US", and "en-cockney":

- -
link[hreflang|="en"]
- -

Similarly, the following selectors represents a - DIALOGUE element whenever it has one of two different - values for an attribute character:

- -
DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]
- -
- -

6.3.2. Substring matching attribute - selectors

- -

Three additional attribute selectors are provided for matching - substrings in the value of an attribute:

- -
-
[att^=val]
-
Represents an element with the att attribute whose value - begins - with the prefix "val". -
-
[att$=val] -
Represents an element with the att attribute whose value - ends with - the suffix "val". -
-
[att*=val] -
Represents an element with the att attribute whose value - contains - at least one instance of the substring "val". -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names in selectors depends on the - document language.

- -
-

Examples:

- -

The following selector represents an HTML object, - referencing an - image:

-
object[type^="image/"]
-

The following selector represents an HTML anchor a with an - href attribute whose value ends with ".html".

-
a[href$=".html"]
-

The following selector represents an HTML paragraph with a - title - attribute whose value contains the substring "hello"

-
p[title*="hello"]
-
- -

6.3.3. Attribute selectors and namespaces

- -

Attribute selectors allow an optional namespace component to the - attribute name. A namespace prefix that has been previously declared - may be prepended to the attribute name separated by the namespace - separator "vertical bar" (|). In keeping with - the Namespaces in the XML recommendation, default namespaces do not - apply to attributes, therefore attribute selectors without a namespace - component apply only to attributes that have no declared namespace - (equivalent to "|attr"). An asterisk may be used for the - namespace prefix indicating that the selector is to match all - attribute names without regard to the attribute's namespace. - -

An attribute selector with an attribute name containing a namespace - prefix that has not been previously declared is an invalid selector. The mechanism for - declaring - a namespace prefix is left up to the language implementing Selectors. - In CSS, such a mechanism is defined in the General Syntax module. - -

-

CSS examples:

-
@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }
- -

The first rule will match only elements with the attribute - att in the "http://www.example.com" namespace with the - value "val".

- -

The second rule will match only elements with the attribute - att regardless of the namespace of the attribute - (including no declared namespace).

- -

The last two rules are equivalent and will match only elements - with the attribute att where the attribute is not - declared to be in a namespace.

- -
- -

6.3.4. Default attribute values in DTDs

- -

Attribute selectors represent explicitly set attribute values in - the document tree. Default attribute values may be defined in a DTD or - elsewhere, but cannot always be selected by attribute - selectors. Selectors should be designed so that they work even if the - default values are not included in the document tree.

- -

More precisely, a UA is not required to read an "external - subset" of the DTD but is required to look for default - attribute values in the document's "internal subset." (See [XML10] for definitions of these subsets.)

- -

A UA that recognizes an XML namespace [XMLNAMES] is not required to use its - knowledge of that namespace to treat default attribute values as if - they were present in the document. (For example, an XHTML UA is not - required to use its built-in knowledge of the XHTML DTD.)

- -

Note: Typically, implementations - choose to ignore external subsets.

- -
-

Example:

- -

Consider an element EXAMPLE with an attribute "notation" that has a - default value of "decimal". The DTD fragment might be

- -
<!ATTLIST EXAMPLE notation (decimal,octal) "decimal">
- -

If the style sheet contains the rules

- -
EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

the first rule will not match elements whose "notation" attribute - is set by default, i.e. not set explicitly. To catch all cases, the - attribute selector for the default value must be dropped:

- -
EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

Here, because the selector EXAMPLE[notation=octal] is - more specific than the tag - selector alone, the style declarations in the second rule will override - those in the first for elements that have a "notation" attribute value - of "octal". Care has to be taken that all property declarations that - are to apply only to the default case are overridden in the non-default - cases' style rules.

- -
- -

6.4. Class selectors

- -

Working with HTML, authors may use the period (U+002E, - .) notation as an alternative to the ~= - notation when representing the class attribute. Thus, for - HTML, div.value and div[class~=value] have - the same meaning. The attribute value must immediately follow the - "period" (.).

- -

UAs may apply selectors using the period (.) notation in XML - documents if the UA has namespace-specific knowledge that allows it to - determine which attribute is the "class" attribute for the - respective namespace. One such example of namespace-specific knowledge - is the prose in the specification for a particular namespace (e.g. SVG - 1.0 [SVG] describes the SVG - "class" attribute and how a UA should interpret it, and - similarly MathML 1.01 [MATH] describes the MathML - "class" attribute.)

- -
-

CSS examples:

- -

We can assign style information to all elements with - class~="pastoral" as follows:

- -
*.pastoral { color: green }  /* all elements with class~=pastoral */
- -

or just

- -
.pastoral { color: green }  /* all elements with class~=pastoral */
- -

The following assigns style only to H1 elements with - class~="pastoral":

- -
H1.pastoral { color: green }  /* H1 elements with class~=pastoral */
- -

Given these rules, the first H1 instance below would not have - green text, while the second would:

- -
<H1>Not green</H1>
-<H1 class="pastoral">Very green</H1>
- -
- -

To represent a subset of "class" values, each value must be preceded - by a ".", in any order.

- -
- -

CSS example:

- -

The following rule matches any P element whose "class" attribute - has been assigned a list of whitespace-separated values that includes - "pastoral" and "marine":

- -
p.pastoral.marine { color: green }
- -

This rule matches when class="pastoral blue aqua - marine" but does not match for class="pastoral - blue".

- -
- -

Note: Because CSS gives considerable - power to the "class" attribute, authors could conceivably design their - own "document language" based on elements with almost no associated - presentation (such as DIV and SPAN in HTML) and assigning style - information through the "class" attribute. Authors should avoid this - practice since the structural elements of a document language often - have recognized and accepted meanings and author-defined classes may - not.

- -

Note: If an element has multiple - class attributes, their values must be concatenated with spaces - between the values before searching for the class. As of this time the - working group is not aware of any manner in which this situation can - be reached, however, so this behavior is explicitly non-normative in - this specification.

- -

6.5. ID selectors

- -

Document languages may contain attributes that are declared to be - of type ID. What makes attributes of type ID special is that no two - such attributes can have the same value in a document, regardless of - the type of the elements that carry them; whatever the document - language, an ID typed attribute can be used to uniquely identify its - element. In HTML all ID attributes are named "id"; XML applications - may name ID attributes differently, but the same restriction - applies.

- -

An ID-typed attribute of a document language allows authors to - assign an identifier to one element instance in the document tree. W3C - ID selectors represent an element instance based on its identifier. An - ID selector contains a "number sign" (U+0023, - #) immediately followed by the ID value, which must be an - identifier.

- -

Selectors does not specify how a UA knows the ID-typed attribute of - an element. The UA may, e.g., read a document's DTD, have the - information hard-coded or ask the user. - -

-

Examples:

- -

The following ID selector represents an h1 element - whose ID-typed attribute has the value "chapter1":

-
h1#chapter1
-

The following ID selector represents any element whose ID-typed - attribute has the value "chapter1":

-
#chapter1
-

The following selector represents any element whose ID-typed - attribute has the value "z98y".

-
*#z98y
-
- -

Note. In XML 1.0 [XML10], the information about which attribute - contains an element's IDs is contained in a DTD or a schema. When - parsing XML, UAs do not always read the DTD, and thus may not know - what the ID of an element is (though a UA may have namespace-specific - knowledge that allows it to determine which attribute is the ID - attribute for that namespace). If a style sheet designer knows or - suspects that a UA may not know what the ID of an element is, he - should use normal attribute selectors instead: - [name=p371] instead of #p371. Elements in - XML 1.0 documents without a DTD do not have IDs at all.

- -

If an element has multiple ID attributes, all of them must be - treated as IDs for that element for the purposes of the ID - selector. Such a situation could be reached using mixtures of xml:id, - DOM3 Core, XML DTDs, and namespace-specific knowledge.

- -

6.6. Pseudo-classes

- -

The pseudo-class concept is introduced to permit selection based on - information that lies outside of the document tree or that cannot be - expressed using the other simple selectors.

- -

A pseudo-class always consists of a "colon" - (:) followed by the name of the pseudo-class and - optionally by a value between parentheses.

- -

Pseudo-classes are allowed in all sequences of simple selectors - contained in a selector. Pseudo-classes are allowed anywhere in - sequences of simple selectors, after the leading type selector or - universal selector (possibly omitted). Pseudo-class names are - case-insensitive. Some pseudo-classes are mutually exclusive, while - others can be applied simultaneously to the same - element. Pseudo-classes may be dynamic, in the sense that an element - may acquire or lose a pseudo-class while a user interacts with the - document.

- - -

6.6.1. Dynamic pseudo-classes

- -

Dynamic pseudo-classes classify elements on characteristics other - than their name, attributes, or content, in principle characteristics - that cannot be deduced from the document tree.

- -

Dynamic pseudo-classes do not appear in the document source or - document tree.

- - -
The link pseudo-classes: :link and :visited
- -

User agents commonly display unvisited links differently from - previously visited ones. Selectors - provides the pseudo-classes :link and - :visited to distinguish them:

- -
    -
  • The :link pseudo-class applies to links that have - not yet been visited. -
  • -
  • The :visited pseudo-class applies once the link has - been visited by the user. -
  • -
- -

After some amount of time, user agents may choose to return a - visited link to the (unvisited) ':link' state.

- -

The two states are mutually exclusive.

- -
- -

Example:

- -

The following selector represents links carrying class - external and already visited:

- -
a.external:visited
- -
- -

Note: It is possible for style sheet - authors to abuse the :link and :visited pseudo-classes to determine - which sites a user has visited without the user's consent. - -

UAs may therefore treat all links as unvisited links, or implement - other measures to preserve the user's privacy while rendering visited - and unvisited links differently.

- -
The user action pseudo-classes - :hover, :active, and :focus
- -

Interactive user agents sometimes change the rendering in response - to user actions. Selectors provides - three pseudo-classes for the selection of an element the user is - acting on.

- -
    - -
  • The :hover pseudo-class applies while the user - designates an element with a pointing device, but does not activate - it. For example, a visual user agent could apply this pseudo-class - when the cursor (mouse pointer) hovers over a box generated by the - element. User agents not that do not support interactive - media do not have to support this pseudo-class. Some conforming - user agents that support interactive - media may not be able to support this pseudo-class (e.g., a pen - device that does not detect hovering). -
  • - -
  • The :active pseudo-class applies while an element - is being activated by the user. For example, between the times the - user presses the mouse button and releases it. -
  • - -
  • The :focus pseudo-class applies while an element - has the focus (accepts keyboard or mouse events, or other forms of - input). -
  • - -
- -

There may be document language or implementation specific limits on - which elements can become :active or acquire - :focus.

- -

These pseudo-classes are not mutually exclusive. An element may - match several pseudo-classes at the same time.

- -

Selectors doesn't define if the parent of an element that is - ':active' or ':hover' is also in that state.

- -
-

Examples:

-
a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */
-

An example of combining dynamic pseudo-classes:

-
a:focus
-a:focus:hover
-

The last selector matches a elements that are in - the pseudo-class :focus and in the pseudo-class :hover.

-
- -

Note: An element can be both ':visited' - and ':active' (or ':link' and ':active').

- -

6.6.2. The target pseudo-class :target

- -

Some URIs refer to a location within a resource. This kind of URI - ends with a "number sign" (#) followed by an anchor - identifier (called the fragment identifier).

- -

URIs with fragment identifiers link to a certain element within the - document, known as the target element. For instance, here is a URI - pointing to an anchor named section_2 in an HTML - document:

- -
http://example.com/html/top.html#section_2
- -

A target element can be represented by the :target - pseudo-class. If the document's URI has no fragment identifier, then - the document has no target element.

- -
-

Example:

-
p.note:target
-

This selector represents a p element of class - note that is the target element of the referring - URI.

-
- -
-

CSS example:

- -

Here, the :target pseudo-class is used to make the - target element red and place an image before it, if there is one:

-
*:target { color : red }
-*:target::before { content : url(target.png) }
-
- -

6.6.3. The language pseudo-class :lang

- -

If the document language specifies how the human language of an - element is determined, it is possible to write selectors that - represent an element based on its language. For example, in HTML [HTML4], the language is determined by a - combination of the lang attribute, the meta - element, and possibly by information from the protocol (such as HTTP - headers). XML uses an attribute called xml:lang, and - there may be other document language-specific methods for determining - the language.

- -

The pseudo-class :lang(C) represents an element that - is in language C. Whether an element is represented by a - :lang() selector is based solely on the identifier C - being either equal to, or a hyphen-separated substring of, the - element's language value, in the same way as if performed by the '|=' operator in attribute - selectors. The identifier C does not have to be a valid language - name.

- -

C must not be empty. (If it is, the selector is invalid.)

- -

Note: It is recommended that - documents and protocols indicate language using codes from RFC 3066 [RFC3066] or its successor, and by means of - "xml:lang" attributes in the case of XML-based documents [XML10]. See - "FAQ: Two-letter or three-letter language codes."

- -
-

Examples:

- -

The two following selectors represent an HTML document that is in - Belgian, French, or German. The two next selectors represent - q quotations in an arbitrary element in Belgian, French, - or German.

-
html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) > q
-:lang(de) > q
-
- -

6.6.4. The UI element states pseudo-classes

- -
The :enabled and :disabled pseudo-classes
- -

The :enabled pseudo-class allows authors to customize - the look of user interface elements that are enabled — which the - user can select or activate in some fashion (e.g. clicking on a button - with a mouse). There is a need for such a pseudo-class because there - is no way to programmatically specify the default appearance of say, - an enabled input element without also specifying what it - would look like when it was disabled.

- -

Similar to :enabled, :disabled allows the - author to specify precisely how a disabled or inactive user interface - element should look.

- -

Most elements will be neither enabled nor disabled. An element is - enabled if the user can either activate it or transfer the focus to - it. An element is disabled if it could be enabled, but the user cannot - presently activate it or transfer focus to it.

- - -
The :checked pseudo-class
- -

Radio and checkbox elements can be toggled by the user. Some menu - items are "checked" when the user selects them. When such elements are - toggled "on" the :checked pseudo-class applies. The - :checked pseudo-class initially applies to such elements - that have the HTML4 selected and checked - attributes as described in Section - 17.2.1 of HTML4, but of course the user can toggle "off" such - elements in which case the :checked pseudo-class would no - longer apply. While the :checked pseudo-class is dynamic - in nature, and is altered by user action, since it can also be based - on the presence of the semantic HTML4 selected and - checked attributes, it applies to all media. - - -

The :indeterminate pseudo-class
- -
- -

Radio and checkbox elements can be toggled by the user, but are - sometimes in an indeterminate state, neither checked nor unchecked. - This can be due to an element attribute, or DOM manipulation.

- -

A future version of this specification may introduce an - :indeterminate pseudo-class that applies to such elements. -

- -
- - -

6.6.5. Structural pseudo-classes

- -

Selectors introduces the concept of structural - pseudo-classes to permit selection based on extra information that - lies in - the document tree but cannot be represented by other simple selectors or - combinators. - -

Note that standalone pieces of PCDATA (text nodes in the DOM) are - not counted when calculating the position of an element in the list of - children of its parent. When calculating the position of an element in - the list of children of its parent, the index numbering starts at 1. - - -

:root pseudo-class
- -

The :root pseudo-class represents an element that is - the root of the document. In HTML 4, this is always the - HTML element. - - -

:nth-child() pseudo-class
- -

The - :nth-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - before it in the document tree, for a given positive - integer or zero value of n, and has a parent element. In - other words, this matches the bth child of an element after - all the children have been split into groups of a elements - each. For example, this allows the selectors to address every other - row in a table, and could be used to alternate the color - of paragraph text in a cycle of four. The a and - b values must be zero, negative integers or positive - integers. The index of the first child of an element is 1. - -

In addition to this, :nth-child() can take - 'odd' and 'even' as arguments instead. - 'odd' has the same signification as 2n+1, - and 'even' has the same signification as 2n. - - -

-

Examples:

-
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }
-
- -

When a=0, no repeating is used, so for example - :nth-child(0n+5) matches only the fifth child. When - a=0, the an part need not be - included, so the syntax simplifies to - :nth-child(b) and the last example simplifies - to :nth-child(5). - -

-

Examples:

-
foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */
-
- -

When a=1, the number may be omitted from the rule. - -

-

Examples:

- -

The following selectors are therefore equivalent:

-
bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */
-
- -

If b=0, then every ath element is picked. In - such a case, the b part may be omitted. - -

-

Examples:

-
tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */
-
- -

If both a and b are equal to zero, the - pseudo-class represents no element in the document tree.

- -

The value a can be negative, but only the positive - values of an+b, for - n≥0, may represent an element in the document - tree.

- -
-

Example:

-
html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
-
- -

When the value b is negative, the "+" character in the - expression must be removed (it is effectively replaced by the "-" - character indicating the negative value of b).

- -
-

Examples:

-
:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */
-
- - -
:nth-last-child() pseudo-class
- -

The :nth-last-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - after it in the document tree, for a given positive - integer or zero value of n, and has a parent element. See - :nth-child() pseudo-class for the syntax of its argument. - It also accepts the 'even' and 'odd' values - as arguments. - - -

-

Examples:

-
tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */
-
- - -
:nth-of-type() pseudo-class
- -

The :nth-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name before it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. In other words, this matches the bth child - of that type after all the children of that type have been split into - groups of a elements each. See :nth-child() pseudo-class - for the syntax of its argument. It also accepts the - 'even' and 'odd' values. - - -

-

CSS example:

- -

This allows an author to alternate the position of floated images:

-
img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }
-
- - -
:nth-last-of-type() pseudo-class
- -

The :nth-last-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name after it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. See :nth-child() pseudo-class for the - syntax of its argument. It also accepts the 'even' and 'odd' - values. - - -

-

Example:

- -

To represent all h2 children of an XHTML - body except the first and last, one could use the - following selector:

-
body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
-

In this case, one could also use :not(), although the - selector ends up being just as long:

-
body > h2:not(:first-of-type):not(:last-of-type)
-
- - -
:first-child pseudo-class
- -

Same as :nth-child(1). The :first-child - pseudo-class - represents an element that is the first child of some other element. - - -

-

Examples:

- -

The following selector represents a p element that is - the first child of a div element:

-
div > p:first-child
-

This selector can represent the p inside the - div of the following fragment:

-
<p> The last P before the note.</p>
-<div class="note">
-   <p> The first P inside the note.</p>
-</div>
- but cannot represent the second p in the following - fragment: -
<p> The last P before the note.</p>
-<div class="note">
-   <h2> Note </h2>
-   <p> The first P inside the note.</p>
-</div>
-

The following two selectors are usually equivalent:

-
* > a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */
-
- -
:last-child pseudo-class
- -

Same as :nth-last-child(1). The :last-child - pseudo-class - represents an element that is the last child of some other element. - -

-

Example:

- -

The following selector represents a list item li that - is the last child of an ordered list ol. -

ol > li:last-child
-
- -
:first-of-type pseudo-class
- -

Same as :nth-of-type(1). The :first-of-type - pseudo-class - represents an element that is the first sibling of its type in the list of - children of its parent element. - -

-

Example:

- -

The following selector represents a definition title - dt inside a definition list dl, this - dt being the first of its type in the list of children of - its parent element.

-
dl dt:first-of-type
-

It is a valid description for the first two dt - elements in the following example but not for the third one:

-
<dl>
- <dt>gigogne</dt>
- <dd>
-  <dl>
-   <dt>fusée</dt>
-   <dd>multistage rocket</dd>
-   <dt>table</dt>
-   <dd>nest of tables</dd>
-  </dl>
- </dd>
-</dl>
-
- -
:last-of-type pseudo-class
- -

Same as :nth-last-of-type(1). The - :last-of-type pseudo-class represents an element that is - the last sibling of its type in the list of children of its parent - element.

- -
-

Example:

- -

The following selector represents the last data cell - td of a table row.

-
tr > td:last-of-type
-
- -
:only-child pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children. Same as - :first-child:last-child or - :nth-child(1):nth-last-child(1), but with a lower - specificity.

- -
:only-of-type pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children with the same element name. Same - as :first-of-type:last-of-type or - :nth-of-type(1):nth-last-of-type(1), but with a lower - specificity.

- - -
:empty pseudo-class
- -

The :empty pseudo-class represents an element that has - no children at all. In terms of the DOM, only element nodes and text - nodes (including CDATA nodes and entity references) whose data has a - non-zero length must be considered as affecting emptiness; comments, - PIs, and other nodes must not affect whether an element is considered - empty or not.

- -
-

Examples:

- -

p:empty is a valid representation of the following fragment: -

-
<p></p>
-

foo:empty is not a valid representation for the - following fragments:

-
<foo>bar</foo>
-
<foo><bar>bla</bar></foo>
-
<foo>this is not <bar>:empty</bar></foo>
-
- -

6.6.6. Blank

- - -

This section intentionally left blank.

- - -

6.6.7. The negation pseudo-class

- -

The negation pseudo-class, :not(X), is a - functional notation taking a simple - selector (excluding the negation pseudo-class itself and - pseudo-elements) as an argument. It represents an element that is not - represented by the argument. - - - -

-

Examples:

- -

The following CSS selector matches all button - elements in an HTML document that are not disabled.

-
button:not([DISABLED])
-

The following selector represents all but FOO - elements.

-
*:not(FOO)
-

The following group of selectors represents all HTML elements - except links.

-
html|*:not(:link):not(:visited)
-
- -

Default namespace declarations do not affect the argument of the - negation pseudo-class unless the argument is a universal selector or a - type selector.

- -
-

Examples:

- -

Assuming that the default namespace is bound to - "http://example.com/", the following selector represents all - elements that are not in that namespace:

-
*|*:not(*)
-

The following CSS selector matches any element being hovered, - regardless of its namespace. In particular, it is not limited to - only matching elements in the default namespace that are not being - hovered, and elements not in the default namespace don't match the - rule when they are being hovered.

-
*|*:not(:hover)
-
- -

Note: the :not() pseudo allows - useless selectors to be written. For instance :not(*|*), - which represents no element at all, or foo:not(bar), - which is equivalent to foo but with a higher - specificity.

- -

7. Pseudo-elements

- -

Pseudo-elements create abstractions about the document tree beyond - those specified by the document language. For instance, document - languages do not offer mechanisms to access the first letter or first - line of an element's content. Pseudo-elements allow designers to refer - to this otherwise inaccessible information. Pseudo-elements may also - provide designers a way to refer to content that does not exist in the - source document (e.g., the ::before and - ::after pseudo-elements give access to generated - content).

- -

A pseudo-element is made of two colons (::) followed - by the name of the pseudo-element.

- -

This :: notation is introduced by the current document - in order to establish a discrimination between pseudo-classes and - pseudo-elements. For compatibility with existing style sheets, user - agents must also accept the previous one-colon notation for - pseudo-elements introduced in CSS levels 1 and 2 (namely, - :first-line, :first-letter, - :before and :after). This compatibility is - not allowed for the new pseudo-elements introduced in CSS level 3.

- -

Only one pseudo-element may appear per selector, and if present it - must appear after the sequence of simple selectors that represents the - subjects of the selector. A -future version of this specification may allow multiple -pesudo-elements per selector.

- -

7.1. The ::first-line pseudo-element

- -

The ::first-line pseudo-element describes the contents - of the first formatted line of an element. - -

-

CSS example:

-
p::first-line { text-transform: uppercase }
-

The above rule means "change the letters of the first line of every - paragraph to uppercase".

-
- -

The selector p::first-line does not match any real - HTML element. It does match a pseudo-element that conforming user - agents will insert at the beginning of every paragraph.

- -

Note that the length of the first line depends on a number of - factors, including the width of the page, the font size, etc. Thus, - an ordinary HTML paragraph such as:

- -
-<P>This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the lines of which happen to be broken as follows: - -

-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-
- -

This paragraph might be "rewritten" by user agents to include the - fictional tag sequence for ::first-line. This - fictional tag sequence helps to show how properties are inherited.

- -
-<P><P::first-line> This is a somewhat long HTML 
-paragraph that </P::first-line> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

If a pseudo-element breaks up a real element, the desired effect - can often be described by a fictional tag sequence that closes and - then re-opens the element. Thus, if we mark up the previous paragraph - with a span element:

- -
-<P><SPAN class="test"> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the user agent could simulate start and end tags for - span when inserting the fictional tag sequence for - ::first-line. - -

-<P><P::first-line><SPAN class="test"> This is a
-somewhat long HTML
-paragraph that will </SPAN></P::first-line><SPAN
-    class="test"> be
-broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

In CSS, the ::first-line pseudo-element can only be - attached to a block-level element, an inline-block, a table-caption, - or a table-cell.

- -

The "first formatted line" of an - element may occur inside a - block-level descendant in the same flow (i.e., a block-level - descendant that is not positioned and not a float). E.g., the first - line of the div in <DIV><P>This - line...</P></DIV> is the first line of the p - (assuming - that both p and div are block-level). - -

The first line of a table-cell or inline-block cannot be the first - formatted line of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first formatted line of the - div is not the line "Hello". - -

Note that the first line of the p in this - fragment: <p><br>First... doesn't contain any - letters (assuming the default style for br in HTML - 4). The word "First" is not on the first formatted line. - -

A UA should act as if the fictional start tags of the - ::first-line pseudo-elements were nested just inside the - innermost enclosing block-level element. (Since CSS1 and CSS2 were - silent on this case, authors should not rely on this behavior.) Here - is an example. The fictional tag sequence for

- -
-<DIV>
-  <P>First paragraph</P>
-  <P>Second paragraph</P>
-</DIV>
-
- -

is

- -
-<DIV>
-  <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
-  <P><P::first-line>Second paragraph</P::first-line></P>
-</DIV>
-
- -

The ::first-line pseudo-element is similar to an - inline-level element, but with certain restrictions. In CSS, the - following properties apply to a ::first-line - pseudo-element: font properties, color property, background - properties, 'word-spacing', 'letter-spacing', 'text-decoration', - 'vertical-align', 'text-transform', 'line-height'. UAs may apply other - properties as well.

- - -

7.2. The ::first-letter pseudo-element

- -

The ::first-letter pseudo-element represents the first - letter of the first line of a block, if it is not preceded by any - other content (such as images or inline tables) on its line. The - ::first-letter pseudo-element may be used for "initial caps" and "drop - caps", which are common typographical effects. This type of initial - letter is similar to an inline-level element if its 'float' property - is 'none'; otherwise, it is similar to a floated element.

- -

In CSS, these are the properties that apply to ::first-letter - pseudo-elements: font properties, 'text-decoration', 'text-transform', - 'letter-spacing', 'word-spacing' (when appropriate), 'line-height', - 'float', 'vertical-align' (only if 'float' is 'none'), margin - properties, padding properties, border properties, color property, - background properties. UAs may apply other properties as well. To - allow UAs to render a typographically correct drop cap or initial cap, - the UA may choose a line-height, width and height based on the shape - of the letter, unlike for normal elements.

- -
-

Example:

- -

This example shows a possible rendering of an initial cap. Note - that the 'line-height' that is inherited by the - ::first-letter - pseudo-element is 1.1, but the UA in this example has computed the - height of the first letter differently, so that it doesn't cause any - unnecessary space between the first two lines. Also note that the - fictional start tag of the first letter is inside the span, - and thus - the font weight of the first letter is normal, not bold as the span: -

-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>
-Erbarremt over my en mijn benaeuwde vesten<br>
-En arme burgery, en op mijn volcx gebed<br>
-En dagelix geschrey de bange stad ontzet.
-
-
-

Image illustrating the ::first-letter pseudo-element -

-
- -
-

The following CSS will make a drop cap initial letter span about two - lines:

- -
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<HTML>
- <HEAD>
-  <TITLE>Drop cap initial letter</TITLE>
-  <STYLE type="text/css">
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  </STYLE>
- </HEAD>
- <BODY>
-  <P><SPAN>The first</SPAN> few words of an article
-    in The Economist.</P>
- </BODY>
-</HTML>
-
- -

This example might be formatted as follows:

- -
-

Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements -

-
- -

The fictional tag sequence is:

- -
-<P>
-<SPAN>
-<P::first-letter>
-T
-</P::first-letter>he first
-</SPAN> 
-few words of an article in the Economist.
-</P>
-
- -

Note that the ::first-letter pseudo-element tags abut - the content (i.e., the initial character), while the ::first-line - pseudo-element start tag is inserted right after the start tag of the - block element.

- -

In order to achieve traditional drop caps formatting, user agents - may approximate font sizes, for example to align baselines. Also, the - glyph outline may be taken into account when formatting.

- -

Punctuation (i.e, characters defined in Unicode in the "open" (Ps), - "close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) - punctuation classes), that precedes or follows the first letter should - be included. [UNICODE]

- -
-

Quotes that precede the
-first letter should be included.

-
- -

The ::first-letter also applies if the first letter is - in fact a digit, e.g., the "6" in "67 million dollars is a lot of - money."

- -

In CSS, the ::first-letter pseudo-element applies to - block, list-item, table-cell, table-caption, and inline-block - elements. A future version of this specification -may allow this pesudo-element to apply to more element -types.

- -

The ::first-letter pseudo-element can be used with all - such elements that contain text, or that have a descendant in the same - flow that contains text. A UA should act as if the fictional start tag - of the ::first-letter pseudo-element is just before the first text of - the element, even if that first text is in a descendant.

- -
-

Example:

- -

The fictional tag sequence for this HTMLfragment: -

<div>
-<p>The first text.
-

is: -

<div>
-<p><div::first-letter><p::first-letter>T</...></...>he first text.
-
- -

The first letter of a table-cell or inline-block cannot be the - first letter of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first letter of the div is - not the - letter "H". In fact, the div doesn't have a first letter. - -

The first letter must occur on the first formatted line. For example, in - this fragment: <p><br>First... the first line - doesn't contain any letters and ::first-letter doesn't - match anything (assuming the default style for br in HTML - 4). In particular, it does not match the "F" of "First." - -

In CSS, if an element is a list item ('display: list-item'), the - ::first-letter applies to the first letter in the - principal box after the marker. UAs may ignore - ::first-letter on list items with 'list-style-position: - inside'. If an element has ::before or - ::after content, the ::first-letter applies - to the first letter of the element including that content. - -

-

Example:

- -

After the rule 'p::before {content: "Note: "}', the selector - 'p::first-letter' matches the "N" of "Note".

-
- -

Some languages may have specific rules about how to treat certain - letter combinations. In Dutch, for example, if the letter combination - "ij" appears at the beginning of a word, both letters should be - considered within the ::first-letter pseudo-element. - -

If the letters that would form the ::first-letter are not in the - same element, such as "'T" in <p>'<em>T..., the UA - may create a ::first-letter pseudo-element from one of the elements, - both elements, or simply not create a pseudo-element.

- -

Similarly, if the first letter(s) of the block are not at the start - of the line (for example due to bidirectional reordering), then the UA - need not create the pseudo-element(s). - -

-

Example:

- -

The following example illustrates - how overlapping pseudo-elements may interact. The first letter of - each P element will be green with a font size of '24pt'. The rest of - the first formatted line will be 'blue' while the rest of the - paragraph will be 'red'.

- -
p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-<P>Some text that ends up on two lines</P>
- -

Assuming that a line break will occur before the word "ends", the -fictional tag -sequence for this fragment might be:

- -
<P>
-<P::first-line>
-<P::first-letter> 
-S 
-</P::first-letter>ome text that 
-</P::first-line> 
-ends up on two lines 
-</P>
- -

Note that the ::first-letter element is inside the ::first-line - element. Properties set on ::first-line are inherited by - ::first-letter, but are overridden if the same property is - set on - ::first-letter.

-
- - -

7.3. The ::selection - pseudo-element

- -

The ::selection pseudo-element applies to the portion - of a document that has been highlighted by the user. This also - applies, for example, to selected text within an editable text - field. This pseudo-element should not be confused with the :checked pseudo-class (which used to be - named :selected) - -

Although the ::selection pseudo-element is dynamic in - nature, and is altered by user action, it is reasonable to expect that - when a UA re-renders to a static medium (such as a printed page, see - [CSS21]) which was originally rendered to a - dynamic medium (like screen), the UA may wish to transfer the current - ::selection state to that other medium, and have all the - appropriate formatting and rendering take effect as well. This is not - required — UAs may omit the ::selection - pseudo-element for static media. - -

These are the CSS properties that apply to ::selection - pseudo-elements: color, background, cursor (optional), outline - (optional). The computed value of the 'background-image' property on - ::selection may be ignored. - - -

7.4. The ::before and ::after pseudo-elements

- -

The ::before and ::after pseudo-elements - can be used to describe generated content before or after an element's - content. They are explained in CSS 2.1 [CSS21].

- -

When the ::first-letter and ::first-line - pseudo-elements are combined with ::before and - ::after, they apply to the first letter or line of the - element including the inserted text.

- -

8. Combinators

- -

8.1. Descendant combinator

- -

At times, authors may want selectors to describe an element that is - the descendant of another element in the document tree (e.g., "an - EM element that is contained within an H1 - element"). Descendant combinators express such a relationship. A - descendant combinator is white space that - separates two sequences of simple selectors. A selector of the form - "A B" represents an element B that is an - arbitrary descendant of some ancestor element A. - -

-

Examples:

- -

For example, consider the following selector:

-
h1 em
-

It represents an em element being the descendant of - an h1 element. It is a correct and valid, but partial, - description of the following fragment:

-
<h1>This <span class="myclass">headline
-is <em>very</em> important</span></h1>
-

The following selector:

-
div * p
-

represents a p element that is a grandchild or later - descendant of a div element. Note the whitespace on - either side of the "*" is not part of the universal selector; the - whitespace is a combinator indicating that the DIV must be the - ancestor of some element, and that that element must be an ancestor - of the P.

- -

The following selector, which combines descendant combinators and - attribute selectors, represents an - element that (1) has the href attribute set and (2) is - inside a p that is itself inside a div:

-
div p *[href]
-
- -

8.2. Child combinators

- -

A child combinator describes a childhood relationship - between two elements. A child combinator is made of the - "greater-than sign" (>) character and - separates two sequences of simple selectors. - - -

-

Examples:

- -

The following selector represents a p element that is - child of body:

-
body > p
-

The following example combines descendant combinators and child - combinators.

-
div ol>li p
- -

It represents a p element that is a descendant of an - li element; the li element must be the - child of an ol element; the ol element must - be a descendant of a div. Notice that the optional white - space around the ">" combinator has been left out.

-
- -

For information on selecting the first child of an element, please - see the section on the :first-child pseudo-class - above.

- -

8.3. Sibling combinators

- -

There are two different sibling combinators: the adjacent sibling - combinator and the general sibling combinator. In both cases, - non-element nodes (e.g. text between elements) are ignored when - considering adjacency of elements.

- -

8.3.1. Adjacent sibling combinator -

- -

The adjacent sibling combinator is made of the "plus - sign" (U+002B, +) character that separates two - sequences of simple selectors. The elements represented by the two - sequences share the same parent in the document tree and the element - represented by the first sequence immediately precedes the element - represented by the second one.

- -
-

Examples:

- -

The following selector represents a p element - immediately following a math element:

-
math + p
-

The following selector is conceptually similar to the one in the - previous example, except that it adds an attribute selector — it - adds a constraint to the h1 element, that it must have - class="opener":

-
h1.opener + h2
-
- - -

8.3.2. General sibling combinator -

- -

The general sibling combinator is made of the "tilde" - (U+007E, ~) character that separates two sequences of - simple selectors. The elements represented by the two sequences share - the same parent in the document tree and the element represented by - the first sequence precedes (not necessarily immediately) the element - represented by the second one.

- -
-

Example:

-
h1 ~ pre
-

represents a pre element following an h1. It - is a correct and valid, but partial, description of:

-
<h1>Definition of the function a</h1>
-<p>Function a(x) has to be applied to all figures in the table.</p>
-<pre>function a(x) = 12x/13.5</pre>
-
- -

9. Calculating a selector's specificity

- -

A selector's specificity is calculated as follows:

- -
    -
  • count the number of ID selectors in the selector (= a)
  • -
  • count the number of class selectors, attributes selectors, and - pseudo-classes in the selector (= b) -
  • -
  • count the number of element names in the selector (= c)
  • -
  • ignore pseudo-elements
  • -
- -

Selectors inside the negation pseudo-class - are counted like any other, but the negation itself does not count as - a pseudo-class.

- -

Concatenating the three numbers a-b-c (in a number system with a - large base) gives the specificity.

- -
-

Examples:

-
*               /* a=0 b=0 c=0 -> specificity =   0 */
-LI              /* a=0 b=0 c=1 -> specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -> specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */
-
-
- -

Note: the specificity of the styles - specified in an HTML style attribute is described in CSS - 2.1. [CSS21].

- -

10. The grammar of Selectors

- -

10.1. Grammar

- -

The grammar below defines the syntax of Selectors. It is globally - LL(1) and can be locally LL(2) (but note that most UA's should not use - it directly, since it doesn't express the parsing conventions). The - format of the productions is optimized for human consumption and some - shorthand notations beyond Yacc (see [YACC]) - are used:

- -
    -
  • *: 0 or more -
  • +: 1 or more -
  • ?: 0 or 1 -
  • |: separates alternatives -
  • [ ]: grouping
  • -
- -

The productions are:

- -
selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;
- - -

10.2. Lexical scanner

- -

The following is the tokenizer, written in Flex (see - [FLEX]) notation. The tokenizer is - case-insensitive.

- -

The two occurrences of "\377" represent the highest character - number that current versions of Flex can deal with (decimal 255). They - should be read as "\4177777" (decimal 1114111), which is the highest - possible code point in Unicode/ISO-10646. [UNICODE]

- -
%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}">"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"<!--"           return CDO;
-"-->"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;
- - -

11. Namespaces and down-level clients

- -

An important issue is the interaction of CSS selectors with XML - documents in web clients that were produced prior to this - document. Unfortunately, due to the fact that namespaces must be - matched based on the URI which identifies the namespace, not the - namespace prefix, some mechanism is required to identify namespaces in - CSS by their URI as well. Without such a mechanism, it is impossible - to construct a CSS style sheet which will properly match selectors in - all cases against a random set of XML documents. However, given - complete knowledge of the XML document to which a style sheet is to be - applied, and a limited use of namespaces within the XML document, it - is possible to construct a style sheet in which selectors would match - elements and attributes correctly.

- -

It should be noted that a down-level CSS client will (if it - properly conforms to CSS forward compatible parsing rules) ignore all - @namespace at-rules, as well as all style rules that make - use of namespace qualified element type or attribute selectors. The - syntax of delimiting namespace prefixes in CSS was deliberately chosen - so that down-level CSS clients would ignore the style rules rather - than possibly match them incorrectly.

- -

The use of default namespaces in CSS makes it possible to write - element type selectors that will function in both namespace aware CSS - clients as well as down-level clients. It should be noted that - down-level clients may incorrectly match selectors against XML - elements in other namespaces.

- -

The following are scenarios and examples in which it is possible to - construct style sheets which would function properly in web clients - that do not implement this proposal.

- -
    -
  1. - -

    The XML document does not use namespaces.

    - -
      - -
    • In this case, it is obviously not necessary to declare or use - namespaces in the style sheet. Standard CSS element type and - attribute selectors will function adequately in a down-level - client. -
    • - -
    • In a CSS namespace aware client, the default behavior of - element selectors matching without regard to namespace will - function properly against all elements, since no namespaces are - present. However, the use of specific element type selectors - that - match only elements that have no namespace ("|name") - will guarantee that selectors will match only XML elements that - do - not have a declared namespace. -
    • - -
    - -
  2. - -
  3. - -

    The XML document defines a single, default namespace used - throughout the document. No namespace prefixes are used in element - names.

    - -
      - -
    • In this case, a down-level client will function as if - namespaces were not used in the XML document at all. Standard - CSS - element type and attribute selectors will match against all - elements. -
    • - -
    - -
  4. - -
  5. - -

    The XML document does not use a default namespace, all - namespace prefixes used are known to the style sheet author, and - there is a direct mapping between namespace prefixes and namespace - URIs. (A given prefix may only be mapped to one namespace URI - throughout the XML document; there may be multiple prefixes mapped - to the same URI).

    - -
      - -
    • In this case, the down-level client will view and match - element type and attribute selectors based on their fully - qualified name, not the local part as outlined in the Type selectors and Namespaces - section. CSS - selectors may be declared using an escaped colon - "\:" - to describe the fully qualified names, e.g. - "html\:h1" will match - <html:h1>. Selectors using the qualified name - will only match XML elements that use the same prefix. Other - namespace prefixes used in the XML that are mapped to the same - URI - will not match as expected unless additional CSS style rules are - declared for them. -
    • - -
    • Note that selectors declared in this fashion will - only match in down-level clients. A CSS namespace aware - client will match element type and attribute selectors based on - the name's local part. Selectors declared with the fully - qualified name will not match (unless there is no namespace - prefix - in the fully qualified name). -
    • - -
    - -
  6. - -
- -

In other scenarios: when the namespace prefixes used in the XML are - not known in advance by the style sheet author; or a combination of - elements with no namespace are used in conjunction with elements using - a default namespace; or the same namespace prefix is mapped to - different namespace URIs within the same document, or in - different documents; it is impossible to construct a CSS style sheet - that will function properly against all elements in those documents, - unless, the style sheet is written using a namespace URI syntax (as - outlined in this document or similar) and the document is processed by - a CSS and XML namespace aware client.

- -

12. Profiles

- -

Each specification using Selectors must define the subset of W3C - Selectors it allows and excludes, and describe the local meaning of - all the components of that subset.

- -

Non normative examples: - -

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 1
Acceptstype selectors
class selectors
ID selectors
:link, - :visited and :active pseudo-classes
descendant combinator -
::first-line and ::first-letter pseudo-elements -
Excludes - -

universal selector
attribute selectors
:hover and - :focus - pseudo-classes
:target pseudo-class
:lang() - pseudo-class
all UI - element states pseudo-classes
all structural - pseudo-classes
negation pseudo-class
all - UI element fragments pseudo-elements
::before and ::after - pseudo-elements
child combinators
sibling combinators - -

namespaces

Extra constraintsonly one class selector allowed per sequence of simple - selectors -
-

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 2
Acceptstype selectors
universal selector
attribute presence and - values selectors
class selectors
ID selectors
:link, - :visited, - :active, :hover, :focus, :lang() and :first-child pseudo-classes -
descendant combinator
child combinator
adjacent - sibling - combinator
::first-line and ::first-letter - pseudo-elements
::before - and ::after pseudo-elements -
Excludes - -

content selectors
substring matching attribute - selectors
:target pseudo-classes
all UI element - states pseudo-classes
all structural pseudo-classes other - than :first-child
negation pseudo-class
all UI element - fragments pseudo-elements
general sibling combinators - -

namespaces

Extra constraintsmore than one class selector per sequence of simple selectors - (CSS1 - constraint) allowed -
- -

In CSS, selectors express pattern matching rules that determine which - style - rules apply to elements in the document tree. - -

The following selector (CSS level 2) will match all anchors a - with attribute name set inside a section 1 header - h1: -

h1 a[name]
- -

All CSS declarations attached to such a selector are applied to elements - matching it.

- -
- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationSTTS 3
Accepts - -

type selectors
universal selectors
attribute - selectors
class - selectors
ID selectors
all structural - pseudo-classes
- all combinators - -

namespaces

Excludesnon-accepted pseudo-classes
pseudo-elements
Extra constraintssome selectors and combinators are not allowed in fragment - descriptions on the right side of STTS declarations. -
- -

Selectors can be used in STTS 3 in two different - manners: -

    -
  1. a selection mechanism equivalent to CSS selection mechanism: - declarations - attached to a given selector are applied to elements matching that - selector, -
  2. fragment descriptions that appear on the right side of declarations. -
  3. -
-
- -

13. Conformance and requirements

- -

This section defines conformance with the present specification only. - -

The inability of a user agent to implement part of this specification due to - the limitations of a particular device (e.g., non interactive user agents - will - probably not implement dynamic pseudo-classes because they make no sense - without - interactivity) does not imply non-conformance. - -

All specifications reusing Selectors must contain a Profile listing the - subset of Selectors it accepts or excludes, and describing the constraints - it adds to the current specification. - -

Invalidity is caused by a parsing error, e.g. an unrecognized token or a - token - which is not allowed at the current parsing point. - -

User agents must observe the rules for handling parsing errors: -

    -
  • a simple selector containing an undeclared namespace prefix is invalid -
  • -
  • a selector containing an invalid simple selector, an invalid combinator - or an invalid token is invalid. -
  • -
  • a group of selectors containing an invalid selector is invalid.
  • -
- -

Specifications reusing Selectors must define how to handle parsing - errors. (In the case of CSS, the entire rule in which the selector is - used is dropped.)

- - - -

14. Tests

- -

This specification has a test - suite allowing user agents to verify their basic conformance to - the specification. This test suite does not pretend to be exhaustive - and does not cover all possible combined cases of Selectors.

- -

15. Acknowledgements

- -

The CSS working group would like to thank everyone who has sent - comments on this specification over the years.

- -

The working group would like to extend special thanks to Donna - McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed - the final editorial review.

- -

16. References

- -
- -
[CSS1] -
Bert Bos, Håkon Wium Lie; "Cascading - Style Sheets, level 1", W3C Recommendation, 17 Dec 1996, revised - 11 Jan 1999 -
(http://www.w3.org/TR/REC-CSS1) - -
[CSS21] -
Bert Bos, Tantek Çelik, Ian Hickson, Håkon - Wium Lie, editors; "Cascading Style Sheets, level 2 revision - 1", W3C Working Draft, 13 June 2005 -
(http://www.w3.org/TR/CSS21) - -
[CWWW] -
Martin J. Dürst, François Yergeau, - Misha Wolf, Asmus Freytag, Tex Texin, editors; "Character Model - for the World Wide Web", W3C Recommendation, 15 February 2005 -
(http://www.w3.org/TR/charmod/) - -
[FLEX] -
"Flex: The Lexical Scanner - Generator", Version 2.3.7, ISBN 1882114213 - -
[HTML4] -
Dave Ragget, Arnaud Le Hors, Ian Jacobs, - editors; "HTML 4.01 Specification", W3C Recommendation, 24 - December 1999 -
- (http://www.w3.org/TR/html4/) - -
[MATH] -
Patrick Ion, Robert Miner, editors; "Mathematical - Markup Language (MathML) 1.01", W3C Recommendation, revision of 7 - July 1999 -
(http://www.w3.org/TR/REC-MathML/) - -
[RFC3066] -
H. Alvestrand; "Tags for the - Identification of Languages", Request for Comments 3066, January - 2001 -
(http://www.ietf.org/rfc/rfc3066.txt) - -
[STTS] -
Daniel Glazman; "Simple Tree Transformation - Sheets 3", Electricité de France, submission to the W3C, - 11 November 1998 -
(http://www.w3.org/TR/NOTE-STTS3) - -
[SVG] -
Jon Ferraiolo, 藤沢 淳, Dean - Jackson, editors; "Scalable Vector Graphics (SVG) 1.1 - Specification", W3C Recommendation, 14 January 2003 -
(http://www.w3.org/TR/SVG/) - -
[UNICODE]
-
The Unicode - Standard, Version 4.1, The Unicode Consortium. Boston, MA, - Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by Unicode - 4.0.1 and Unicode - 4.1.0. -
(http://www.unicode.org/versions/) -
- -
[XML10] -
Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, - Eve Maler, François Yergeau, editors; "Extensible Markup - Language (XML) 1.0 (Third Edition)", W3C Recommendation, 4 - February 2004 -
(http://www.w3.org/TR/REC-xml/) - -
[XMLNAMES] -
Tim Bray, Dave Hollander, Andrew Layman, - editors; "Namespaces in XML", W3C Recommendation, 14 - January 1999 -
(http://www.w3.org/TR/REC-xml-names/) - -
[YACC] -
S. C. Johnson; "YACC — Yet another - compiler compiler", Technical Report, Murray Hill, 1975 - -
-
- - diff --git a/samples/src/main/java/gwtquery/samples/public/html/dojobench.html b/samples/src/main/java/gwtquery/samples/public/html/dojobench.html new file mode 100644 index 00000000..4f4e94db --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/dojobench.html @@ -0,0 +1,13 @@ + + + Dojo + + + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/html/domassistantbench.html b/samples/src/main/java/gwtquery/samples/public/html/domassistantbench.html new file mode 100644 index 00000000..fc1dab7a --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/domassistantbench.html @@ -0,0 +1,13 @@ + + + DomAssistant + + + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/html/gwtbench.html b/samples/src/main/java/gwtquery/samples/public/html/gwtbench.html new file mode 100644 index 00000000..deb7ac1e --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/gwtbench.html @@ -0,0 +1,7 @@ + + + Gwt + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/html/iframebench.html b/samples/src/main/java/gwtquery/samples/public/html/iframebench.html new file mode 100644 index 00000000..44f42393 --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/iframebench.html @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/html/jquerybench.html b/samples/src/main/java/gwtquery/samples/public/html/jquerybench.html new file mode 100644 index 00000000..c8da3471 --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/jquerybench.html @@ -0,0 +1,13 @@ + + + JQuery + + + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/html/prototypebench.html b/samples/src/main/java/gwtquery/samples/public/html/prototypebench.html new file mode 100644 index 00000000..448e031b --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/prototypebench.html @@ -0,0 +1,13 @@ + + + Prototype + + + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/html/sizzlebench.html b/samples/src/main/java/gwtquery/samples/public/html/sizzlebench.html new file mode 100644 index 00000000..acc7c326 --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/html/sizzlebench.html @@ -0,0 +1,13 @@ + + + Sizzle + + + + + + diff --git a/samples/src/main/java/gwtquery/samples/public/animated-flag.gif b/samples/src/main/java/gwtquery/samples/public/images/bench/animated-flag.gif similarity index 100% rename from samples/src/main/java/gwtquery/samples/public/animated-flag.gif rename to samples/src/main/java/gwtquery/samples/public/images/bench/animated-flag.gif diff --git a/samples/src/main/java/gwtquery/samples/public/grass-texture-small.jpg b/samples/src/main/java/gwtquery/samples/public/images/bench/grass-texture-small.jpg similarity index 100% rename from samples/src/main/java/gwtquery/samples/public/grass-texture-small.jpg rename to samples/src/main/java/gwtquery/samples/public/images/bench/grass-texture-small.jpg diff --git a/samples/src/main/java/gwtquery/samples/public/grass-texture.jpg b/samples/src/main/java/gwtquery/samples/public/images/bench/grass-texture.jpg similarity index 100% rename from samples/src/main/java/gwtquery/samples/public/grass-texture.jpg rename to samples/src/main/java/gwtquery/samples/public/images/bench/grass-texture.jpg diff --git a/samples/src/main/java/gwtquery/samples/public/horse.gif b/samples/src/main/java/gwtquery/samples/public/images/bench/horse.gif similarity index 100% rename from samples/src/main/java/gwtquery/samples/public/horse.gif rename to samples/src/main/java/gwtquery/samples/public/images/bench/horse.gif diff --git a/samples/src/main/java/gwtquery/samples/public/horse.png b/samples/src/main/java/gwtquery/samples/public/images/bench/horse.png similarity index 100% rename from samples/src/main/java/gwtquery/samples/public/horse.png rename to samples/src/main/java/gwtquery/samples/public/images/bench/horse.png diff --git a/samples/src/main/java/gwtquery/samples/public/dojo-logo-text.gif b/samples/src/main/java/gwtquery/samples/public/images/bench/logo-dojo.gif similarity index 100% rename from samples/src/main/java/gwtquery/samples/public/dojo-logo-text.gif rename to samples/src/main/java/gwtquery/samples/public/images/bench/logo-dojo.gif diff --git a/samples/src/main/java/gwtquery/samples/public/images/bench/logo-domassistant.gif b/samples/src/main/java/gwtquery/samples/public/images/bench/logo-domassistant.gif new file mode 100644 index 0000000000000000000000000000000000000000..bfe8b9719db1b0cb4ff6ce4aa1baef0953ed3450 GIT binary patch literal 805 zcmZ?wbhEHb3}E16I2OkM1gfg4>gwtm8X8(!TH4y$IyySKy1IILdiwhM1_lO(hK5E) zM#jd*W@cvQ=H?a_7M7NlR#sNl*48#QHnz65c6N65_Vx}A4vvnFPEJnF&dx3_F0QVw z9v&WEUS8hb-abA)etv%b{{8_00fB*mK|w*m!NDORA)%q65fKs5(a|w6F|o0+adC0+ z@$m@>35kh`Nl8h`$;l}xDXFQcX=!Qc>FF668QIy{IXOAGxw-lI`2__9g@uL1#leI>6_u5hwY9Z%b#?Xi^$iUT&CSg%EiJ9Bt!-^>?d|PdU0uDsy?uRs z{r&xuCQX_=dGf4Tv*ym7yLj>9<;$0^Sg~T&s#R;&tXa2i-G&Vt{?i30{u6XAN=+h9_7>z^=j(&Uzy zDbr_kaJINfwO9qWD9bmqX}0lOwee06o!Q0Kw$6`#Q?ssItG8O4t)0zG#^?!*?HgM; zyg1qwOq->=TI|)^eCs7!eVlZgUF|KKwOSnYniZp3wC*%J)En+>WsftUZ##5 zfm05T`zP3|a0&h~PMW`)vn8WKi6wbLlXOd#s8UeE1y-lo{}!0I6kSl`(C0a8aHTQ8 z$BCOgQTj=|;MUr@=UGH$n+fBj!$1E zQ`a;#v5uD#MDx-O&8!|T`>F|OX?Ur$VVTpXxlp-D+&P~A;rw`Bf5Q9ud|3OVBR)To z0Qdv%ssMmxcTBdsrr0q@ZP>#$e434L+~$4U>XU9Ivn_#HmThOupK{D$Ip&BwQ{?yN zr~-2|WR5K~e^FvcEHWIrX#DDu=~$)t>+%oBEA%J%rVPIRRITZBjXtM-J?FalA0qP) z&87m8?n0{xYB6(f=y>g>qIT`icTB(B)|PjgsyZ~)-NvgAjWylcx*lWwBh7W#ChRwe z`ZUc0#v8DvZP<8gNPBx|?e3UeEH!pY);cAs&QVj>h_-uV?a`Q_@9ApaxT7TqZJl!y}BA?SvDORR_w@gn@|F&UK|N3|3!iJ^y3(NYY zKa@+WmgUv;Wvxj$KcjrNs8lLf)a$D+rE4!`Yno-%aGUD+kZSe4<{@9x^Kb2lSgTfQ zwOZZH0-g9Lo!+1`+typot+(c_8`kyLGxUON{o`i++R}#yWgq^0V|db- zj8k1E?kWvPs_)E>3;mRh8Z);wQp9@$zDYF!++ z8vnFft+wG>`;y$gs<8jx|Dpidh;#q|I}i$N`0pnGlnt=E5L1I(altX0LypPB!l7bp zKp54#c@+KyiHZK%zgZ+LCq-Q(?(b}pmBojo<5Pp0`5`+`j@IwLcVnzB;#@2xQ=R_g zDy0wQ8{5@7A&RLA*%NZewdy)p(@Si>(f<5q>b>l_(fiw83X|*I6-St@FYjeewciiv z65zSSu{+o5K6$2i#Q3LeTdMxfR}5x^T-Eae{pMPZ%c-D@t5_i#@XjPBRd+7jW_<3i z&pC4QO8a?KM?SzP`+8SHIF1-Jhg68fcvBpm5yt?ge<`uC*sqj!*|EZNMh>Gc zWnl;KUMP|Sn!FVPv%lc?hA zJ^*)Yhv=KZXY;_4M-z=%lb!qOb;3`P;z1mhNSVeR#Il*2J`1GqUq3(-oP08J$#^Z# zPYpTGj$2_I-IC^*2(Kkj6HogdNbQ8Qowb=Zs%&I<`Qqs7k&bJ6td1XIB)Do_7M}s zFbJ^!0tOowFU7~4{{~%kxdX~LXZFM+Jo$1eNuLlzpe(pe!TW;7 z#UyaH6xR~N6mc?0XWJS*TUxJ{CUFlv`mNEs@^VkR$}!;Y1J|-&r+z)9{nX;B!M6|5Fp4S2@nB6gcuuMnj3-%kKhJKSOQ2%FcN5aSR;Z`Nq7V( z4~iIw{@nqweGClZq5Cb&i)B|=FFKn=hOLc zjygw`l4{g~0KWSHfC0b+1_4Y@2I0l@WD#C$PnM6DH;3ip>&@}=Sx<8OxW1&nA2)#X z=Wzpg{=C3|z#v`_KQNdd#19D$3FU7H3keO|5H1Ld5QGba5kiqb6eWy|7DYuzMvJ4w zG0`!x8)M^QHYLQxZ{C!!Iev3u!j|O3tx^dB{EypYQUosqwk-9jlvG(-dTRRiw2U3; z+vOQMsO@rU2c?iJGAV^pq1>67rBd!xXVHA1`CjTA6^24?UJix>hVpVXxhMe5t~`v0 zC@9hv>I#Z5KHmI!u7#KkG3Oic8is*icqdT5iCk*z$@pl)>(&%P|!yDtBWV zqtf)Wv8s|z+h*Ehq$#K}n=lhl$*i{QwbWFjGRjh0UGt0uvy$mtCgypd2I?A~#cWl> zzIrSKcY!|^0q)vH7xGXCs0*?-?WYZZrGRD7)O>(0jcq=3u;p+wz1GK&hekjXpfSX~ z7wBqevmZeVU=7&X+t8@PS|(b;(45iUX{YO<)6szqOsvhoMgkjnj-D>}er9*C18b`2 zh9tBCS_wP=y?s5jH4vKs>r46uUZ7h54*?zqY=uGR0Ji$lZEIHS96IW5BQe*{N4>$b^IaI4YfP^7NI&PUkjpN35NIDG8148e;fr^G$1=Hdv;=>gB7r; zd}(&_dN&!Bdn)_VnVW52jSauGbg62=`f`XstNQ5JF2$CCs`!AtG3QQ?MYNI= z&;2uuDb|eKkEX8IU7mLuE<1dU*Bu;vz*3I?`O?AsdoQ%i&e;q=A#^*8)>R%A`x*8_^-{1v5w z@t=d)AbsfaU{$&QMG@3Pr_yYCa`_Ckm8f*Z-<9%v)x&&~xBgSUwaff~ty6)JM|AbC z>mn%*lWTLyzt>NEl=l4ve_L$C)yQl;`+2RQ30))=Oc);RR^(YzoF|8mDaC0E2dw$V z_D_3zGEKU@f0J)u$wm)Zv_43p_t4l z_p>D-V zN#%QTt+dB5&YUD+oyTsMOYU1CS`ql9bmV}TW&Kv3d)Gz^v(Fy>F%qZkKfZM+aa6M#MKh3<>u$)?fSSaYkp9cdyoik;7~u z7e5g-Cy}@FI^sz$BAlDa@s&wCZ-$;v_e`$*`Nnc+x!>f?JBg%mr_6Z8{ddW{ - - JQuery - - - - -
- - -

Abstract

- -

Selectors are patterns that match against elements in a - tree. Selectors have been optimized for use with HTML and XML, and - are designed to be usable in performance-critical code.

- -

CSS (Cascading - Style Sheets) is a language for describing the rendering of HTML and XML documents on - screen, on paper, in speech, etc. CSS uses Selectors for binding - style properties to elements in the document. This document - describes extensions to the selectors defined in CSS level 2. These - extended selectors will be used by CSS level 3. - -

Selectors define the following function:

- -
expression ∗ element → boolean
- -

That is, given an element and a selector, this specification - defines whether that element matches the selector.

- -

These expressions can also be used, for instance, to select a set - of elements, or a single element from a set of elements, by - evaluating the expression across all the elements in a - subtree. STTS (Simple Tree Transformation Sheets), a - language for transforming XML trees, uses this mechanism. [STTS]

- -

Status of this document

- -

This section describes the status of this document at the - time of its publication. Other documents may supersede this - document. A list of current W3C publications and the latest revision - of this technical report can be found in the W3C technical reports index at - http://www.w3.org/TR/.

- -

This document describes the selectors that already exist in CSS1 and CSS2, and - also proposes new selectors for CSS3 and other languages that may need them.

- -

The CSS Working Group doesn't expect that all implementations of - CSS3 will have to implement all selectors. Instead, there will - probably be a small number of variants of CSS3, called profiles. For - example, it may be that only a profile for interactive user agents - will include all of the selectors.

- -

This specification is a last call working draft for the the CSS Working Group - (Style Activity). This - document is a revision of the Candidate - Recommendation dated 2001 November 13, and has incorporated - implementation feedback received in the past few years. It is - expected that this last call will proceed straight to Proposed - Recommendation stage since it is believed that interoperability will - be demonstrable.

- -

All persons are encouraged to review and implement this - specification and return comments to the (archived) - public mailing list www-style - (see instructions). W3C - Members can also send comments directly to the CSS Working - Group. - The deadline for comments is 14 January 2006.

- -

This is still a draft document and may be updated, replaced, or - obsoleted by other documents at any time. It is inappropriate to - cite a W3C Working Draft as other than "work in progress". - -

This document may be available in translation. - The English version of this specification is the only normative - version. - -

- -

Table of contents

- - - -
- -

1. Introduction

- -

1.1. Dependencies

- -

Some features of this specification are specific to CSS, or have - particular limitations or rules specific to CSS. In this - specification, these have been described in terms of CSS2.1. [CSS21]

- -

1.2. Terminology

- -

All of the text of this specification is normative except - examples, notes, and sections explicitly marked as - non-normative.

- -

1.3. Changes from CSS2

- -

This section is non-normative.

- -

The main differences between the selectors in CSS2 and those in - Selectors are: - -

    - -
  • the list of basic definitions (selector, group of selectors, - simple selector, etc.) has been changed; in particular, what was - referred to in CSS2 as a simple selector is now called a sequence - of simple selectors, and the term "simple selector" is now used for - the components of this sequence -
  • - -
  • an optional namespace component is now allowed in type element - selectors, the universal selector and attribute selectors -
  • - -
  • a new combinator has been - introduced -
  • - -
  • new simple selectors including substring matching attribute - selectors, and new pseudo-classes -
  • - -
  • new pseudo-elements, and introduction of the "::" convention - for pseudo-elements -
  • - -
  • the grammar has been rewritten
  • - -
  • profiles to be added to specifications integrating Selectors - and defining the set of selectors which is actually supported by - each specification -
  • - -
  • Selectors are now a CSS3 Module and an independent - specification; other specifications can now refer to this document - independently of CSS -
  • - -
  • the specification now has its own test suite
  • - -
- -

2. Selectors

- -

This section is non-normative, as it merely summarizes the - following sections.

- -

A Selector represents a structure. This structure can be used as a - condition (e.g. in a CSS rule) that determines which elements a - selector matches in the document tree, or as a flat description of the - HTML or XML fragment corresponding to that structure.

- -

Selectors may range from simple element names to rich contextual - representations.

- -

The following table summarizes the Selector syntax:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PatternMeaningDescribed in sectionFirst defined in CSS level
*any elementUniversal - selector2
Ean element of type EType selector1
E[foo]an E element with a "foo" attributeAttribute - selectors2
E[foo="bar"]an E element whose "foo" attribute value is exactly - equal to "bar" - Attribute - selectors2
E[foo~="bar"]an E element whose "foo" attribute value is a list of - space-separated values, one of which is exactly equal to "bar" - Attribute - selectors2
E[foo^="bar"]an E element whose "foo" attribute value begins exactly - with the string "bar" - Attribute - selectors3
E[foo$="bar"]an E element whose "foo" attribute value ends exactly - with the string "bar" - Attribute - selectors3
E[foo*="bar"]an E element whose "foo" attribute value contains the - substring "bar" - Attribute - selectors3
E[hreflang|="en"]an E element whose "hreflang" attribute has a - hyphen-separated - list of values beginning (from the left) with "en" - Attribute - selectors2
E:rootan E element, root of the documentStructural - pseudo-classes3
E:nth-child(n)an E element, the n-th child of its parentStructural - pseudo-classes3
E:nth-last-child(n)an E element, the n-th child of its parent, counting - from the last one - Structural - pseudo-classes3
E:nth-of-type(n)an E element, the n-th sibling of its typeStructural - pseudo-classes3
E:nth-last-of-type(n)an E element, the n-th sibling of its type, counting - from the last one - Structural - pseudo-classes3
E:first-childan E element, first child of its parentStructural - pseudo-classes2
E:last-childan E element, last child of its parentStructural - pseudo-classes3
E:first-of-typean E element, first sibling of its typeStructural - pseudo-classes3
E:last-of-typean E element, last sibling of its typeStructural - pseudo-classes3
E:only-childan E element, only child of its parentStructural - pseudo-classes3
E:only-of-typean E element, only sibling of its typeStructural - pseudo-classes3
E:emptyan E element that has no children (including text - nodes) - Structural - pseudo-classes3
E:link
E:visited
an E element being the source anchor of a hyperlink of - which the target is not yet visited (:link) or already visited - (:visited) - The link - pseudo-classes1
E:active
E:hover
E:focus
an E element during certain user actionsThe user - action pseudo-classes1 and 2
E:targetan E element being the target of the referring URIThe target - pseudo-class3
E:lang(fr)an element of type E in language "fr" (the document - language specifies how language is determined) - The :lang() - pseudo-class2
E:enabled
E:disabled
a user interface element E which is enabled or - disabled - The UI element states - pseudo-classes3
E:checkeda user interface element E which is checked (for instance a radio-button or checkbox) - The UI element states - pseudo-classes3
E::first-linethe first formatted line of an E elementThe ::first-line - pseudo-element1
E::first-letterthe first formatted letter of an E elementThe ::first-letter - pseudo-element1
E::selectionthe portion of an E element that is currently - selected/highlighted by the user - The UI element - fragments pseudo-elements3
E::beforegenerated content before an E elementThe ::before - pseudo-element2
E::aftergenerated content after an E elementThe ::after - pseudo-element2
E.warningan E element whose class is - "warning" (the document language specifies how class is determined). - Class - selectors1
E#myidan E element with ID equal to "myid".ID - selectors1
E:not(s)an E element that does not match simple selector sNegation - pseudo-class3
E Fan F element descendant of an E elementDescendant - combinator1
E > Fan F element child of an E elementChild - combinator2
E + Fan F element immediately preceded by an E elementAdjacent sibling combinator - 2
E ~ Fan F element preceded by an E elementGeneral sibling combinator - 3
- -

The meaning of each selector is derived from the table above by - prepending "matches" to the contents of each cell in the "Meaning" - column.

- -

3. Case sensitivity

- -

The case sensitivity of document language element names, attribute - names, and attribute values in selectors depends on the document - language. For example, in HTML, element names are case-insensitive, - but in XML, they are case-sensitive.

- -

4. Selector syntax

- -

A selector is a chain of one - or more sequences of simple selectors - separated by combinators.

- -

A sequence of simple selectors - is a chain of simple selectors - that are not separated by a combinator. It - always begins with a type selector or a - universal selector. No other type - selector or universal selector is allowed in the sequence.

- -

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, content selector, or pseudo-class. One pseudo-element may be appended to the last - sequence of simple selectors.

- -

Combinators are: white space, "greater-than - sign" (U+003E, >), "plus sign" (U+002B, - +) and "tilde" (U+007E, ~). White - space may appear between a combinator and the simple selectors around - it. Only the characters "space" (U+0020), "tab" - (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form - feed" (U+000C) can occur in white space. Other space-like characters, - such as "em-space" (U+2003) and "ideographic space" (U+3000), are - never part of white space.

- -

The elements of a document tree that are represented by a selector - are the subjects of the selector. A - selector consisting of a single sequence of simple selectors - represents any element satisfying its requirements. Prepending another - sequence of simple selectors and a combinator to a sequence imposes - additional matching constraints, so the subjects of a selector are - always a subset of the elements represented by the last sequence of - simple selectors.

- -

An empty selector, containing no sequence of simple selectors and - no pseudo-element, is an invalid - selector.

- -

5. Groups of selectors

- -

When several selectors share the same declarations, they may be - grouped into a comma-separated list. (A comma is U+002C.)

- -
-

CSS examples:

- -

In this example, we condense three rules with identical - declarations into one. Thus,

-
h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }
-

is equivalent to:

-
h1, h2, h3 { font-family: sans-serif }
-
- -

Warning: the equivalence is true in this example - because all the selectors are valid selectors. If just one of these - selectors were invalid, the entire group of selectors would be - invalid. This would invalidate the rule for all three heading - elements, whereas in the former case only one of the three individual - heading rules would be invalidated.

- - -

6. Simple selectors

- -

6.1. Type selector

- -

A type selector is the name of a document language - element type. A type selector represents an instance of the element - type in the document tree.

- -
-

Example:

- -

The following selector represents an h1 element in the - document tree:

-
h1
-
- - -

6.1.1. Type selectors and namespaces

- -

Type selectors allow an optional namespace ([XMLNAMES]) component. A namespace prefix - that has been previously declared may be prepended to the element name - separated by the namespace separator "vertical bar" - (U+007C, |).

- -

The namespace component may be left empty to indicate that the - selector is only to represent elements with no declared namespace.

- -

An asterisk may be used for the namespace prefix, indicating that - the selector represents elements in any namespace (including elements - with no namespace).

- -

Element type selectors that have no namespace component (no - namespace separator), represent elements without regard to the - element's namespace (equivalent to "*|") unless a default - namespace has been declared. If a default namespace has been declared, - the selector will represent only elements in the default - namespace.

- -

A type selector containing a namespace prefix that has not been - previously declared is an invalid selector. - The mechanism for declaring a namespace prefix is left up to the - language implementing Selectors. In CSS, such a mechanism is defined - in the General Syntax module.

- -

In a namespace-aware client, element type selectors will only match - against the local - part - of the element's qualified - name. See below for notes about matching - behaviors in down-level clients.

- -

In summary:

- -
-
ns|E
-
elements with name E in namespace ns
-
*|E
-
elements with name E in any namespace, including those without any - declared namespace -
-
|E
-
elements with name E without any declared namespace
-
E
-
if no default namespace has been specified, this is equivalent to *|E. - Otherwise it is equivalent to ns|E where ns is the default namespace. -
-
- -
-

CSS examples:

- -
@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }
- -

The first rule will match only h1 elements in the - "http://www.example.com" namespace.

- -

The second rule will match all elements in the - "http://www.example.com" namespace.

- -

The third rule will match only h1 elements without - any declared namespace.

- -

The fourth rule will match h1 elements in any - namespace (including those without any declared namespace).

- -

The last rule is equivalent to the fourth rule because no default - namespace has been defined.

- -
- -

6.2. Universal selector

- -

The universal selector, written "asterisk" - (*), represents the qualified name of any element - type. It represents any single element in the document tree in any - namespace (including those without any declared namespace) if no - default namespace has been specified. If a default namespace has been - specified, see Universal selector and - Namespaces below.

- -

If the universal selector is not the only component of a sequence - of simple selectors, the * may be omitted.

- -
-

Examples:

-
    -
  • *[hreflang|=en] and [hreflang|=en] are - equivalent, -
  • -
  • *.warning and .warning are equivalent, -
  • -
  • *#myid and #myid are equivalent.
  • -
-
- -

Note: it is recommended that the - *, representing the universal selector, not be - omitted.

- -

6.2.1. Universal selector and namespaces

- -

The universal selector allows an optional namespace component. It - is used as follows:

- -
-
ns|*
-
all elements in namespace ns
-
*|*
-
all elements
-
|*
-
all elements without any declared namespace
-
*
-
if no default namespace has been specified, this is equivalent to *|*. - Otherwise it is equivalent to ns|* where ns is the default namespace. -
-
- -

A universal selector containing a namespace prefix that has not - been previously declared is an invalid - selector. The mechanism for declaring a namespace prefix is left up - to the language implementing Selectors. In CSS, such a mechanism is - defined in the General Syntax module.

- - -

6.3. Attribute selectors

- -

Selectors allow the representation of an element's attributes. When - a selector is used as an expression to match against an element, - attribute selectors must be considered to match an element if that - element has an attribute that matches the attribute represented by the - attribute selector.

- -

6.3.1. Attribute presence and values - selectors

- -

CSS2 introduced four attribute selectors:

- -
-
[att] -
Represents an element with the att attribute, whatever the - value of - the attribute. -
-
[att=val]
-
Represents an element with the att attribute whose value is - exactly - "val". -
-
[att~=val]
-
Represents an element with the att attribute whose value is - a whitespace-separated list of words, one - of - which is exactly "val". If "val" contains whitespace, it will never - represent anything (since the words are separated by - spaces). -
-
[att|=val] -
Represents an element with the att attribute, its value - either - being exactly "val" or beginning with "val" immediately followed by - "-" (U+002D). This is primarily intended to allow language subcode - matches (e.g., the hreflang attribute on the - link element in HTML) as described in RFC 3066 ([RFC3066]). For lang (or - xml:lang) language subcode matching, please see the :lang pseudo-class. -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names and values in selectors depends on - the document language.

- -
- -

Examples:

- -

The following attribute selector represents an h1 - element that carries the title attribute, whatever its - value:

- -
h1[title]
- -

In the following example, the selector represents a - span element whose class attribute has - exactly the value "example":

- -
span[class="example"]
- -

Multiple attribute selectors can be used to represent several - attributes of an element, or several conditions on the same - attribute. Here, the selector represents a span element - whose hello attribute has exactly the value "Cleveland" - and whose goodbye attribute has exactly the value - "Columbus":

- -
span[hello="Cleveland"][goodbye="Columbus"]
- -

The following selectors illustrate the differences between "=" - and "~=". The first selector will represent, for example, the value - "copyright copyleft copyeditor" on a rel attribute. The - second selector will only represent an a element with - an href attribute having the exact value - "http://www.w3.org/".

- -
a[rel~="copyright"]
-a[href="http://www.w3.org/"]
- -

The following selector represents a link element - whose hreflang attribute is exactly "fr".

- -
link[hreflang=fr]
- -

The following selector represents a link element for - which the values of the hreflang attribute begins with - "en", including "en", "en-US", and "en-cockney":

- -
link[hreflang|="en"]
- -

Similarly, the following selectors represents a - DIALOGUE element whenever it has one of two different - values for an attribute character:

- -
DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]
- -
- -

6.3.2. Substring matching attribute - selectors

- -

Three additional attribute selectors are provided for matching - substrings in the value of an attribute:

- -
-
[att^=val]
-
Represents an element with the att attribute whose value - begins - with the prefix "val". -
-
[att$=val] -
Represents an element with the att attribute whose value - ends with - the suffix "val". -
-
[att*=val] -
Represents an element with the att attribute whose value - contains - at least one instance of the substring "val". -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names in selectors depends on the - document language.

- -
-

Examples:

- -

The following selector represents an HTML object, - referencing an - image:

-
object[type^="image/"]
-

The following selector represents an HTML anchor a with an - href attribute whose value ends with ".html".

-
a[href$=".html"]
-

The following selector represents an HTML paragraph with a - title - attribute whose value contains the substring "hello"

-
p[title*="hello"]
-
- -

6.3.3. Attribute selectors and namespaces

- -

Attribute selectors allow an optional namespace component to the - attribute name. A namespace prefix that has been previously declared - may be prepended to the attribute name separated by the namespace - separator "vertical bar" (|). In keeping with - the Namespaces in the XML recommendation, default namespaces do not - apply to attributes, therefore attribute selectors without a namespace - component apply only to attributes that have no declared namespace - (equivalent to "|attr"). An asterisk may be used for the - namespace prefix indicating that the selector is to match all - attribute names without regard to the attribute's namespace. - -

An attribute selector with an attribute name containing a namespace - prefix that has not been previously declared is an invalid selector. The mechanism for - declaring - a namespace prefix is left up to the language implementing Selectors. - In CSS, such a mechanism is defined in the General Syntax module. - -

-

CSS examples:

-
@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }
- -

The first rule will match only elements with the attribute - att in the "http://www.example.com" namespace with the - value "val".

- -

The second rule will match only elements with the attribute - att regardless of the namespace of the attribute - (including no declared namespace).

- -

The last two rules are equivalent and will match only elements - with the attribute att where the attribute is not - declared to be in a namespace.

- -
- -

6.3.4. Default attribute values in DTDs

- -

Attribute selectors represent explicitly set attribute values in - the document tree. Default attribute values may be defined in a DTD or - elsewhere, but cannot always be selected by attribute - selectors. Selectors should be designed so that they work even if the - default values are not included in the document tree.

- -

More precisely, a UA is not required to read an "external - subset" of the DTD but is required to look for default - attribute values in the document's "internal subset." (See [XML10] for definitions of these subsets.)

- -

A UA that recognizes an XML namespace [XMLNAMES] is not required to use its - knowledge of that namespace to treat default attribute values as if - they were present in the document. (For example, an XHTML UA is not - required to use its built-in knowledge of the XHTML DTD.)

- -

Note: Typically, implementations - choose to ignore external subsets.

- -
-

Example:

- -

Consider an element EXAMPLE with an attribute "notation" that has a - default value of "decimal". The DTD fragment might be

- -
<!ATTLIST EXAMPLE notation (decimal,octal) "decimal">
- -

If the style sheet contains the rules

- -
EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

the first rule will not match elements whose "notation" attribute - is set by default, i.e. not set explicitly. To catch all cases, the - attribute selector for the default value must be dropped:

- -
EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

Here, because the selector EXAMPLE[notation=octal] is - more specific than the tag - selector alone, the style declarations in the second rule will override - those in the first for elements that have a "notation" attribute value - of "octal". Care has to be taken that all property declarations that - are to apply only to the default case are overridden in the non-default - cases' style rules.

- -
- -

6.4. Class selectors

- -

Working with HTML, authors may use the period (U+002E, - .) notation as an alternative to the ~= - notation when representing the class attribute. Thus, for - HTML, div.value and div[class~=value] have - the same meaning. The attribute value must immediately follow the - "period" (.).

- -

UAs may apply selectors using the period (.) notation in XML - documents if the UA has namespace-specific knowledge that allows it to - determine which attribute is the "class" attribute for the - respective namespace. One such example of namespace-specific knowledge - is the prose in the specification for a particular namespace (e.g. SVG - 1.0 [SVG] describes the SVG - "class" attribute and how a UA should interpret it, and - similarly MathML 1.01 [MATH] describes the MathML - "class" attribute.)

- -
-

CSS examples:

- -

We can assign style information to all elements with - class~="pastoral" as follows:

- -
*.pastoral { color: green }  /* all elements with class~=pastoral */
- -

or just

- -
.pastoral { color: green }  /* all elements with class~=pastoral */
- -

The following assigns style only to H1 elements with - class~="pastoral":

- -
H1.pastoral { color: green }  /* H1 elements with class~=pastoral */
- -

Given these rules, the first H1 instance below would not have - green text, while the second would:

- -
<H1>Not green</H1>
-<H1 class="pastoral">Very green</H1>
- -
- -

To represent a subset of "class" values, each value must be preceded - by a ".", in any order.

- -
- -

CSS example:

- -

The following rule matches any P element whose "class" attribute - has been assigned a list of whitespace-separated values that includes - "pastoral" and "marine":

- -
p.pastoral.marine { color: green }
- -

This rule matches when class="pastoral blue aqua - marine" but does not match for class="pastoral - blue".

- -
- -

Note: Because CSS gives considerable - power to the "class" attribute, authors could conceivably design their - own "document language" based on elements with almost no associated - presentation (such as DIV and SPAN in HTML) and assigning style - information through the "class" attribute. Authors should avoid this - practice since the structural elements of a document language often - have recognized and accepted meanings and author-defined classes may - not.

- -

Note: If an element has multiple - class attributes, their values must be concatenated with spaces - between the values before searching for the class. As of this time the - working group is not aware of any manner in which this situation can - be reached, however, so this behavior is explicitly non-normative in - this specification.

- -

6.5. ID selectors

- -

Document languages may contain attributes that are declared to be - of type ID. What makes attributes of type ID special is that no two - such attributes can have the same value in a document, regardless of - the type of the elements that carry them; whatever the document - language, an ID typed attribute can be used to uniquely identify its - element. In HTML all ID attributes are named "id"; XML applications - may name ID attributes differently, but the same restriction - applies.

- -

An ID-typed attribute of a document language allows authors to - assign an identifier to one element instance in the document tree. W3C - ID selectors represent an element instance based on its identifier. An - ID selector contains a "number sign" (U+0023, - #) immediately followed by the ID value, which must be an - identifier.

- -

Selectors does not specify how a UA knows the ID-typed attribute of - an element. The UA may, e.g., read a document's DTD, have the - information hard-coded or ask the user. - -

-

Examples:

- -

The following ID selector represents an h1 element - whose ID-typed attribute has the value "chapter1":

-
h1#chapter1
-

The following ID selector represents any element whose ID-typed - attribute has the value "chapter1":

-
#chapter1
-

The following selector represents any element whose ID-typed - attribute has the value "z98y".

-
*#z98y
-
- -

Note. In XML 1.0 [XML10], the information about which attribute - contains an element's IDs is contained in a DTD or a schema. When - parsing XML, UAs do not always read the DTD, and thus may not know - what the ID of an element is (though a UA may have namespace-specific - knowledge that allows it to determine which attribute is the ID - attribute for that namespace). If a style sheet designer knows or - suspects that a UA may not know what the ID of an element is, he - should use normal attribute selectors instead: - [name=p371] instead of #p371. Elements in - XML 1.0 documents without a DTD do not have IDs at all.

- -

If an element has multiple ID attributes, all of them must be - treated as IDs for that element for the purposes of the ID - selector. Such a situation could be reached using mixtures of xml:id, - DOM3 Core, XML DTDs, and namespace-specific knowledge.

- -

6.6. Pseudo-classes

- -

The pseudo-class concept is introduced to permit selection based on - information that lies outside of the document tree or that cannot be - expressed using the other simple selectors.

- -

A pseudo-class always consists of a "colon" - (:) followed by the name of the pseudo-class and - optionally by a value between parentheses.

- -

Pseudo-classes are allowed in all sequences of simple selectors - contained in a selector. Pseudo-classes are allowed anywhere in - sequences of simple selectors, after the leading type selector or - universal selector (possibly omitted). Pseudo-class names are - case-insensitive. Some pseudo-classes are mutually exclusive, while - others can be applied simultaneously to the same - element. Pseudo-classes may be dynamic, in the sense that an element - may acquire or lose a pseudo-class while a user interacts with the - document.

- - -

6.6.1. Dynamic pseudo-classes

- -

Dynamic pseudo-classes classify elements on characteristics other - than their name, attributes, or content, in principle characteristics - that cannot be deduced from the document tree.

- -

Dynamic pseudo-classes do not appear in the document source or - document tree.

- - -
The link pseudo-classes: :link and :visited
- -

User agents commonly display unvisited links differently from - previously visited ones. Selectors - provides the pseudo-classes :link and - :visited to distinguish them:

- -
    -
  • The :link pseudo-class applies to links that have - not yet been visited. -
  • -
  • The :visited pseudo-class applies once the link has - been visited by the user. -
  • -
- -

After some amount of time, user agents may choose to return a - visited link to the (unvisited) ':link' state.

- -

The two states are mutually exclusive.

- -
- -

Example:

- -

The following selector represents links carrying class - external and already visited:

- -
a.external:visited
- -
- -

Note: It is possible for style sheet - authors to abuse the :link and :visited pseudo-classes to determine - which sites a user has visited without the user's consent. - -

UAs may therefore treat all links as unvisited links, or implement - other measures to preserve the user's privacy while rendering visited - and unvisited links differently.

- -
The user action pseudo-classes - :hover, :active, and :focus
- -

Interactive user agents sometimes change the rendering in response - to user actions. Selectors provides - three pseudo-classes for the selection of an element the user is - acting on.

- -
    - -
  • The :hover pseudo-class applies while the user - designates an element with a pointing device, but does not activate - it. For example, a visual user agent could apply this pseudo-class - when the cursor (mouse pointer) hovers over a box generated by the - element. User agents not that do not support interactive - media do not have to support this pseudo-class. Some conforming - user agents that support interactive - media may not be able to support this pseudo-class (e.g., a pen - device that does not detect hovering). -
  • - -
  • The :active pseudo-class applies while an element - is being activated by the user. For example, between the times the - user presses the mouse button and releases it. -
  • - -
  • The :focus pseudo-class applies while an element - has the focus (accepts keyboard or mouse events, or other forms of - input). -
  • - -
- -

There may be document language or implementation specific limits on - which elements can become :active or acquire - :focus.

- -

These pseudo-classes are not mutually exclusive. An element may - match several pseudo-classes at the same time.

- -

Selectors doesn't define if the parent of an element that is - ':active' or ':hover' is also in that state.

- -
-

Examples:

-
a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */
-

An example of combining dynamic pseudo-classes:

-
a:focus
-a:focus:hover
-

The last selector matches a elements that are in - the pseudo-class :focus and in the pseudo-class :hover.

-
- -

Note: An element can be both ':visited' - and ':active' (or ':link' and ':active').

- -

6.6.2. The target pseudo-class :target

- -

Some URIs refer to a location within a resource. This kind of URI - ends with a "number sign" (#) followed by an anchor - identifier (called the fragment identifier).

- -

URIs with fragment identifiers link to a certain element within the - document, known as the target element. For instance, here is a URI - pointing to an anchor named section_2 in an HTML - document:

- -
http://example.com/html/top.html#section_2
- -

A target element can be represented by the :target - pseudo-class. If the document's URI has no fragment identifier, then - the document has no target element.

- -
-

Example:

-
p.note:target
-

This selector represents a p element of class - note that is the target element of the referring - URI.

-
- -
-

CSS example:

- -

Here, the :target pseudo-class is used to make the - target element red and place an image before it, if there is one:

-
*:target { color : red }
-*:target::before { content : url(target.png) }
-
- -

6.6.3. The language pseudo-class :lang

- -

If the document language specifies how the human language of an - element is determined, it is possible to write selectors that - represent an element based on its language. For example, in HTML [HTML4], the language is determined by a - combination of the lang attribute, the meta - element, and possibly by information from the protocol (such as HTTP - headers). XML uses an attribute called xml:lang, and - there may be other document language-specific methods for determining - the language.

- -

The pseudo-class :lang(C) represents an element that - is in language C. Whether an element is represented by a - :lang() selector is based solely on the identifier C - being either equal to, or a hyphen-separated substring of, the - element's language value, in the same way as if performed by the '|=' operator in attribute - selectors. The identifier C does not have to be a valid language - name.

- -

C must not be empty. (If it is, the selector is invalid.)

- -

Note: It is recommended that - documents and protocols indicate language using codes from RFC 3066 [RFC3066] or its successor, and by means of - "xml:lang" attributes in the case of XML-based documents [XML10]. See - "FAQ: Two-letter or three-letter language codes."

- -
-

Examples:

- -

The two following selectors represent an HTML document that is in - Belgian, French, or German. The two next selectors represent - q quotations in an arbitrary element in Belgian, French, - or German.

-
html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) > q
-:lang(de) > q
-
- -

6.6.4. The UI element states pseudo-classes

- -
The :enabled and :disabled pseudo-classes
- -

The :enabled pseudo-class allows authors to customize - the look of user interface elements that are enabled — which the - user can select or activate in some fashion (e.g. clicking on a button - with a mouse). There is a need for such a pseudo-class because there - is no way to programmatically specify the default appearance of say, - an enabled input element without also specifying what it - would look like when it was disabled.

- -

Similar to :enabled, :disabled allows the - author to specify precisely how a disabled or inactive user interface - element should look.

- -

Most elements will be neither enabled nor disabled. An element is - enabled if the user can either activate it or transfer the focus to - it. An element is disabled if it could be enabled, but the user cannot - presently activate it or transfer focus to it.

- - -
The :checked pseudo-class
- -

Radio and checkbox elements can be toggled by the user. Some menu - items are "checked" when the user selects them. When such elements are - toggled "on" the :checked pseudo-class applies. The - :checked pseudo-class initially applies to such elements - that have the HTML4 selected and checked - attributes as described in Section - 17.2.1 of HTML4, but of course the user can toggle "off" such - elements in which case the :checked pseudo-class would no - longer apply. While the :checked pseudo-class is dynamic - in nature, and is altered by user action, since it can also be based - on the presence of the semantic HTML4 selected and - checked attributes, it applies to all media. - - -

The :indeterminate pseudo-class
- -
- -

Radio and checkbox elements can be toggled by the user, but are - sometimes in an indeterminate state, neither checked nor unchecked. - This can be due to an element attribute, or DOM manipulation.

- -

A future version of this specification may introduce an - :indeterminate pseudo-class that applies to such elements. -

- -
- - -

6.6.5. Structural pseudo-classes

- -

Selectors introduces the concept of structural - pseudo-classes to permit selection based on extra information that - lies in - the document tree but cannot be represented by other simple selectors or - combinators. - -

Note that standalone pieces of PCDATA (text nodes in the DOM) are - not counted when calculating the position of an element in the list of - children of its parent. When calculating the position of an element in - the list of children of its parent, the index numbering starts at 1. - - -

:root pseudo-class
- -

The :root pseudo-class represents an element that is - the root of the document. In HTML 4, this is always the - HTML element. - - -

:nth-child() pseudo-class
- -

The - :nth-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - before it in the document tree, for a given positive - integer or zero value of n, and has a parent element. In - other words, this matches the bth child of an element after - all the children have been split into groups of a elements - each. For example, this allows the selectors to address every other - row in a table, and could be used to alternate the color - of paragraph text in a cycle of four. The a and - b values must be zero, negative integers or positive - integers. The index of the first child of an element is 1. - -

In addition to this, :nth-child() can take - 'odd' and 'even' as arguments instead. - 'odd' has the same signification as 2n+1, - and 'even' has the same signification as 2n. - - -

-

Examples:

-
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }
-
- -

When a=0, no repeating is used, so for example - :nth-child(0n+5) matches only the fifth child. When - a=0, the an part need not be - included, so the syntax simplifies to - :nth-child(b) and the last example simplifies - to :nth-child(5). - -

-

Examples:

-
foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */
-
- -

When a=1, the number may be omitted from the rule. - -

-

Examples:

- -

The following selectors are therefore equivalent:

-
bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */
-
- -

If b=0, then every ath element is picked. In - such a case, the b part may be omitted. - -

-

Examples:

-
tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */
-
- -

If both a and b are equal to zero, the - pseudo-class represents no element in the document tree.

- -

The value a can be negative, but only the positive - values of an+b, for - n≥0, may represent an element in the document - tree.

- -
-

Example:

-
html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
-
- -

When the value b is negative, the "+" character in the - expression must be removed (it is effectively replaced by the "-" - character indicating the negative value of b).

- -
-

Examples:

-
:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */
-
- - -
:nth-last-child() pseudo-class
- -

The :nth-last-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - after it in the document tree, for a given positive - integer or zero value of n, and has a parent element. See - :nth-child() pseudo-class for the syntax of its argument. - It also accepts the 'even' and 'odd' values - as arguments. - - -

-

Examples:

-
tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */
-
- - -
:nth-of-type() pseudo-class
- -

The :nth-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name before it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. In other words, this matches the bth child - of that type after all the children of that type have been split into - groups of a elements each. See :nth-child() pseudo-class - for the syntax of its argument. It also accepts the - 'even' and 'odd' values. - - -

-

CSS example:

- -

This allows an author to alternate the position of floated images:

-
img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }
-
- - -
:nth-last-of-type() pseudo-class
- -

The :nth-last-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name after it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. See :nth-child() pseudo-class for the - syntax of its argument. It also accepts the 'even' and 'odd' - values. - - -

-

Example:

- -

To represent all h2 children of an XHTML - body except the first and last, one could use the - following selector:

-
body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
-

In this case, one could also use :not(), although the - selector ends up being just as long:

-
body > h2:not(:first-of-type):not(:last-of-type)
-
- - -
:first-child pseudo-class
- -

Same as :nth-child(1). The :first-child - pseudo-class - represents an element that is the first child of some other element. - - -

-

Examples:

- -

The following selector represents a p element that is - the first child of a div element:

-
div > p:first-child
-

This selector can represent the p inside the - div of the following fragment:

-
<p> The last P before the note.</p>
-<div class="note">
-   <p> The first P inside the note.</p>
-</div>
- but cannot represent the second p in the following - fragment: -
<p> The last P before the note.</p>
-<div class="note">
-   <h2> Note </h2>
-   <p> The first P inside the note.</p>
-</div>
-

The following two selectors are usually equivalent:

-
* > a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */
-
- -
:last-child pseudo-class
- -

Same as :nth-last-child(1). The :last-child - pseudo-class - represents an element that is the last child of some other element. - -

-

Example:

- -

The following selector represents a list item li that - is the last child of an ordered list ol. -

ol > li:last-child
-
- -
:first-of-type pseudo-class
- -

Same as :nth-of-type(1). The :first-of-type - pseudo-class - represents an element that is the first sibling of its type in the list of - children of its parent element. - -

-

Example:

- -

The following selector represents a definition title - dt inside a definition list dl, this - dt being the first of its type in the list of children of - its parent element.

-
dl dt:first-of-type
-

It is a valid description for the first two dt - elements in the following example but not for the third one:

-
<dl>
- <dt>gigogne</dt>
- <dd>
-  <dl>
-   <dt>fusée</dt>
-   <dd>multistage rocket</dd>
-   <dt>table</dt>
-   <dd>nest of tables</dd>
-  </dl>
- </dd>
-</dl>
-
- -
:last-of-type pseudo-class
- -

Same as :nth-last-of-type(1). The - :last-of-type pseudo-class represents an element that is - the last sibling of its type in the list of children of its parent - element.

- -
-

Example:

- -

The following selector represents the last data cell - td of a table row.

-
tr > td:last-of-type
-
- -
:only-child pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children. Same as - :first-child:last-child or - :nth-child(1):nth-last-child(1), but with a lower - specificity.

- -
:only-of-type pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children with the same element name. Same - as :first-of-type:last-of-type or - :nth-of-type(1):nth-last-of-type(1), but with a lower - specificity.

- - -
:empty pseudo-class
- -

The :empty pseudo-class represents an element that has - no children at all. In terms of the DOM, only element nodes and text - nodes (including CDATA nodes and entity references) whose data has a - non-zero length must be considered as affecting emptiness; comments, - PIs, and other nodes must not affect whether an element is considered - empty or not.

- -
-

Examples:

- -

p:empty is a valid representation of the following fragment: -

-
<p></p>
-

foo:empty is not a valid representation for the - following fragments:

-
<foo>bar</foo>
-
<foo><bar>bla</bar></foo>
-
<foo>this is not <bar>:empty</bar></foo>
-
- -

6.6.6. Blank

- - -

This section intentionally left blank.

- - -

6.6.7. The negation pseudo-class

- -

The negation pseudo-class, :not(X), is a - functional notation taking a simple - selector (excluding the negation pseudo-class itself and - pseudo-elements) as an argument. It represents an element that is not - represented by the argument. - - - -

-

Examples:

- -

The following CSS selector matches all button - elements in an HTML document that are not disabled.

-
button:not([DISABLED])
-

The following selector represents all but FOO - elements.

-
*:not(FOO)
-

The following group of selectors represents all HTML elements - except links.

-
html|*:not(:link):not(:visited)
-
- -

Default namespace declarations do not affect the argument of the - negation pseudo-class unless the argument is a universal selector or a - type selector.

- -
-

Examples:

- -

Assuming that the default namespace is bound to - "http://example.com/", the following selector represents all - elements that are not in that namespace:

-
*|*:not(*)
-

The following CSS selector matches any element being hovered, - regardless of its namespace. In particular, it is not limited to - only matching elements in the default namespace that are not being - hovered, and elements not in the default namespace don't match the - rule when they are being hovered.

-
*|*:not(:hover)
-
- -

Note: the :not() pseudo allows - useless selectors to be written. For instance :not(*|*), - which represents no element at all, or foo:not(bar), - which is equivalent to foo but with a higher - specificity.

- -

7. Pseudo-elements

- -

Pseudo-elements create abstractions about the document tree beyond - those specified by the document language. For instance, document - languages do not offer mechanisms to access the first letter or first - line of an element's content. Pseudo-elements allow designers to refer - to this otherwise inaccessible information. Pseudo-elements may also - provide designers a way to refer to content that does not exist in the - source document (e.g., the ::before and - ::after pseudo-elements give access to generated - content).

- -

A pseudo-element is made of two colons (::) followed - by the name of the pseudo-element.

- -

This :: notation is introduced by the current document - in order to establish a discrimination between pseudo-classes and - pseudo-elements. For compatibility with existing style sheets, user - agents must also accept the previous one-colon notation for - pseudo-elements introduced in CSS levels 1 and 2 (namely, - :first-line, :first-letter, - :before and :after). This compatibility is - not allowed for the new pseudo-elements introduced in CSS level 3.

- -

Only one pseudo-element may appear per selector, and if present it - must appear after the sequence of simple selectors that represents the - subjects of the selector. A -future version of this specification may allow multiple -pesudo-elements per selector.

- -

7.1. The ::first-line pseudo-element

- -

The ::first-line pseudo-element describes the contents - of the first formatted line of an element. - -

-

CSS example:

-
p::first-line { text-transform: uppercase }
-

The above rule means "change the letters of the first line of every - paragraph to uppercase".

-
- -

The selector p::first-line does not match any real - HTML element. It does match a pseudo-element that conforming user - agents will insert at the beginning of every paragraph.

- -

Note that the length of the first line depends on a number of - factors, including the width of the page, the font size, etc. Thus, - an ordinary HTML paragraph such as:

- -
-<P>This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the lines of which happen to be broken as follows: - -

-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-
- -

This paragraph might be "rewritten" by user agents to include the - fictional tag sequence for ::first-line. This - fictional tag sequence helps to show how properties are inherited.

- -
-<P><P::first-line> This is a somewhat long HTML 
-paragraph that </P::first-line> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

If a pseudo-element breaks up a real element, the desired effect - can often be described by a fictional tag sequence that closes and - then re-opens the element. Thus, if we mark up the previous paragraph - with a span element:

- -
-<P><SPAN class="test"> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the user agent could simulate start and end tags for - span when inserting the fictional tag sequence for - ::first-line. - -

-<P><P::first-line><SPAN class="test"> This is a
-somewhat long HTML
-paragraph that will </SPAN></P::first-line><SPAN
-    class="test"> be
-broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

In CSS, the ::first-line pseudo-element can only be - attached to a block-level element, an inline-block, a table-caption, - or a table-cell.

- -

The "first formatted line" of an - element may occur inside a - block-level descendant in the same flow (i.e., a block-level - descendant that is not positioned and not a float). E.g., the first - line of the div in <DIV><P>This - line...</P></DIV> is the first line of the p - (assuming - that both p and div are block-level). - -

The first line of a table-cell or inline-block cannot be the first - formatted line of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first formatted line of the - div is not the line "Hello". - -

Note that the first line of the p in this - fragment: <p><br>First... doesn't contain any - letters (assuming the default style for br in HTML - 4). The word "First" is not on the first formatted line. - -

A UA should act as if the fictional start tags of the - ::first-line pseudo-elements were nested just inside the - innermost enclosing block-level element. (Since CSS1 and CSS2 were - silent on this case, authors should not rely on this behavior.) Here - is an example. The fictional tag sequence for

- -
-<DIV>
-  <P>First paragraph</P>
-  <P>Second paragraph</P>
-</DIV>
-
- -

is

- -
-<DIV>
-  <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
-  <P><P::first-line>Second paragraph</P::first-line></P>
-</DIV>
-
- -

The ::first-line pseudo-element is similar to an - inline-level element, but with certain restrictions. In CSS, the - following properties apply to a ::first-line - pseudo-element: font properties, color property, background - properties, 'word-spacing', 'letter-spacing', 'text-decoration', - 'vertical-align', 'text-transform', 'line-height'. UAs may apply other - properties as well.

- - -

7.2. The ::first-letter pseudo-element

- -

The ::first-letter pseudo-element represents the first - letter of the first line of a block, if it is not preceded by any - other content (such as images or inline tables) on its line. The - ::first-letter pseudo-element may be used for "initial caps" and "drop - caps", which are common typographical effects. This type of initial - letter is similar to an inline-level element if its 'float' property - is 'none'; otherwise, it is similar to a floated element.

- -

In CSS, these are the properties that apply to ::first-letter - pseudo-elements: font properties, 'text-decoration', 'text-transform', - 'letter-spacing', 'word-spacing' (when appropriate), 'line-height', - 'float', 'vertical-align' (only if 'float' is 'none'), margin - properties, padding properties, border properties, color property, - background properties. UAs may apply other properties as well. To - allow UAs to render a typographically correct drop cap or initial cap, - the UA may choose a line-height, width and height based on the shape - of the letter, unlike for normal elements.

- -
-

Example:

- -

This example shows a possible rendering of an initial cap. Note - that the 'line-height' that is inherited by the - ::first-letter - pseudo-element is 1.1, but the UA in this example has computed the - height of the first letter differently, so that it doesn't cause any - unnecessary space between the first two lines. Also note that the - fictional start tag of the first letter is inside the span, - and thus - the font weight of the first letter is normal, not bold as the span: -

-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>
-Erbarremt over my en mijn benaeuwde vesten<br>
-En arme burgery, en op mijn volcx gebed<br>
-En dagelix geschrey de bange stad ontzet.
-
-
-

Image illustrating the ::first-letter pseudo-element -

-
- -
-

The following CSS will make a drop cap initial letter span about two - lines:

- -
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<HTML>
- <HEAD>
-  <TITLE>Drop cap initial letter</TITLE>
-  <STYLE type="text/css">
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  </STYLE>
- </HEAD>
- <BODY>
-  <P><SPAN>The first</SPAN> few words of an article
-    in The Economist.</P>
- </BODY>
-</HTML>
-
- -

This example might be formatted as follows:

- -
-

Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements -

-
- -

The fictional tag sequence is:

- -
-<P>
-<SPAN>
-<P::first-letter>
-T
-</P::first-letter>he first
-</SPAN> 
-few words of an article in the Economist.
-</P>
-
- -

Note that the ::first-letter pseudo-element tags abut - the content (i.e., the initial character), while the ::first-line - pseudo-element start tag is inserted right after the start tag of the - block element.

- -

In order to achieve traditional drop caps formatting, user agents - may approximate font sizes, for example to align baselines. Also, the - glyph outline may be taken into account when formatting.

- -

Punctuation (i.e, characters defined in Unicode in the "open" (Ps), - "close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) - punctuation classes), that precedes or follows the first letter should - be included. [UNICODE]

- -
-

Quotes that precede the
-first letter should be included.

-
- -

The ::first-letter also applies if the first letter is - in fact a digit, e.g., the "6" in "67 million dollars is a lot of - money."

- -

In CSS, the ::first-letter pseudo-element applies to - block, list-item, table-cell, table-caption, and inline-block - elements. A future version of this specification -may allow this pesudo-element to apply to more element -types.

- -

The ::first-letter pseudo-element can be used with all - such elements that contain text, or that have a descendant in the same - flow that contains text. A UA should act as if the fictional start tag - of the ::first-letter pseudo-element is just before the first text of - the element, even if that first text is in a descendant.

- -
-

Example:

- -

The fictional tag sequence for this HTMLfragment: -

<div>
-<p>The first text.
-

is: -

<div>
-<p><div::first-letter><p::first-letter>T</...></...>he first text.
-
- -

The first letter of a table-cell or inline-block cannot be the - first letter of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first letter of the div is - not the - letter "H". In fact, the div doesn't have a first letter. - -

The first letter must occur on the first formatted line. For example, in - this fragment: <p><br>First... the first line - doesn't contain any letters and ::first-letter doesn't - match anything (assuming the default style for br in HTML - 4). In particular, it does not match the "F" of "First." - -

In CSS, if an element is a list item ('display: list-item'), the - ::first-letter applies to the first letter in the - principal box after the marker. UAs may ignore - ::first-letter on list items with 'list-style-position: - inside'. If an element has ::before or - ::after content, the ::first-letter applies - to the first letter of the element including that content. - -

-

Example:

- -

After the rule 'p::before {content: "Note: "}', the selector - 'p::first-letter' matches the "N" of "Note".

-
- -

Some languages may have specific rules about how to treat certain - letter combinations. In Dutch, for example, if the letter combination - "ij" appears at the beginning of a word, both letters should be - considered within the ::first-letter pseudo-element. - -

If the letters that would form the ::first-letter are not in the - same element, such as "'T" in <p>'<em>T..., the UA - may create a ::first-letter pseudo-element from one of the elements, - both elements, or simply not create a pseudo-element.

- -

Similarly, if the first letter(s) of the block are not at the start - of the line (for example due to bidirectional reordering), then the UA - need not create the pseudo-element(s). - -

-

Example:

- -

The following example illustrates - how overlapping pseudo-elements may interact. The first letter of - each P element will be green with a font size of '24pt'. The rest of - the first formatted line will be 'blue' while the rest of the - paragraph will be 'red'.

- -
p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-<P>Some text that ends up on two lines</P>
- -

Assuming that a line break will occur before the word "ends", the -fictional tag -sequence for this fragment might be:

- -
<P>
-<P::first-line>
-<P::first-letter> 
-S 
-</P::first-letter>ome text that 
-</P::first-line> 
-ends up on two lines 
-</P>
- -

Note that the ::first-letter element is inside the ::first-line - element. Properties set on ::first-line are inherited by - ::first-letter, but are overridden if the same property is - set on - ::first-letter.

-
- - -

7.3. The ::selection - pseudo-element

- -

The ::selection pseudo-element applies to the portion - of a document that has been highlighted by the user. This also - applies, for example, to selected text within an editable text - field. This pseudo-element should not be confused with the :checked pseudo-class (which used to be - named :selected) - -

Although the ::selection pseudo-element is dynamic in - nature, and is altered by user action, it is reasonable to expect that - when a UA re-renders to a static medium (such as a printed page, see - [CSS21]) which was originally rendered to a - dynamic medium (like screen), the UA may wish to transfer the current - ::selection state to that other medium, and have all the - appropriate formatting and rendering take effect as well. This is not - required — UAs may omit the ::selection - pseudo-element for static media. - -

These are the CSS properties that apply to ::selection - pseudo-elements: color, background, cursor (optional), outline - (optional). The computed value of the 'background-image' property on - ::selection may be ignored. - - -

7.4. The ::before and ::after pseudo-elements

- -

The ::before and ::after pseudo-elements - can be used to describe generated content before or after an element's - content. They are explained in CSS 2.1 [CSS21].

- -

When the ::first-letter and ::first-line - pseudo-elements are combined with ::before and - ::after, they apply to the first letter or line of the - element including the inserted text.

- -

8. Combinators

- -

8.1. Descendant combinator

- -

At times, authors may want selectors to describe an element that is - the descendant of another element in the document tree (e.g., "an - EM element that is contained within an H1 - element"). Descendant combinators express such a relationship. A - descendant combinator is white space that - separates two sequences of simple selectors. A selector of the form - "A B" represents an element B that is an - arbitrary descendant of some ancestor element A. - -

-

Examples:

- -

For example, consider the following selector:

-
h1 em
-

It represents an em element being the descendant of - an h1 element. It is a correct and valid, but partial, - description of the following fragment:

-
<h1>This <span class="myclass">headline
-is <em>very</em> important</span></h1>
-

The following selector:

-
div * p
-

represents a p element that is a grandchild or later - descendant of a div element. Note the whitespace on - either side of the "*" is not part of the universal selector; the - whitespace is a combinator indicating that the DIV must be the - ancestor of some element, and that that element must be an ancestor - of the P.

- -

The following selector, which combines descendant combinators and - attribute selectors, represents an - element that (1) has the href attribute set and (2) is - inside a p that is itself inside a div:

-
div p *[href]
-
- -

8.2. Child combinators

- -

A child combinator describes a childhood relationship - between two elements. A child combinator is made of the - "greater-than sign" (>) character and - separates two sequences of simple selectors. - - -

-

Examples:

- -

The following selector represents a p element that is - child of body:

-
body > p
-

The following example combines descendant combinators and child - combinators.

-
div ol>li p
- -

It represents a p element that is a descendant of an - li element; the li element must be the - child of an ol element; the ol element must - be a descendant of a div. Notice that the optional white - space around the ">" combinator has been left out.

-
- -

For information on selecting the first child of an element, please - see the section on the :first-child pseudo-class - above.

- -

8.3. Sibling combinators

- -

There are two different sibling combinators: the adjacent sibling - combinator and the general sibling combinator. In both cases, - non-element nodes (e.g. text between elements) are ignored when - considering adjacency of elements.

- -

8.3.1. Adjacent sibling combinator -

- -

The adjacent sibling combinator is made of the "plus - sign" (U+002B, +) character that separates two - sequences of simple selectors. The elements represented by the two - sequences share the same parent in the document tree and the element - represented by the first sequence immediately precedes the element - represented by the second one.

- -
-

Examples:

- -

The following selector represents a p element - immediately following a math element:

-
math + p
-

The following selector is conceptually similar to the one in the - previous example, except that it adds an attribute selector — it - adds a constraint to the h1 element, that it must have - class="opener":

-
h1.opener + h2
-
- - -

8.3.2. General sibling combinator -

- -

The general sibling combinator is made of the "tilde" - (U+007E, ~) character that separates two sequences of - simple selectors. The elements represented by the two sequences share - the same parent in the document tree and the element represented by - the first sequence precedes (not necessarily immediately) the element - represented by the second one.

- -
-

Example:

-
h1 ~ pre
-

represents a pre element following an h1. It - is a correct and valid, but partial, description of:

-
<h1>Definition of the function a</h1>
-<p>Function a(x) has to be applied to all figures in the table.</p>
-<pre>function a(x) = 12x/13.5</pre>
-
- -

9. Calculating a selector's specificity

- -

A selector's specificity is calculated as follows:

- -
    -
  • count the number of ID selectors in the selector (= a)
  • -
  • count the number of class selectors, attributes selectors, and - pseudo-classes in the selector (= b) -
  • -
  • count the number of element names in the selector (= c)
  • -
  • ignore pseudo-elements
  • -
- -

Selectors inside the negation pseudo-class - are counted like any other, but the negation itself does not count as - a pseudo-class.

- -

Concatenating the three numbers a-b-c (in a number system with a - large base) gives the specificity.

- -
-

Examples:

-
*               /* a=0 b=0 c=0 -> specificity =   0 */
-LI              /* a=0 b=0 c=1 -> specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -> specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */
-
-
- -

Note: the specificity of the styles - specified in an HTML style attribute is described in CSS - 2.1. [CSS21].

- -

10. The grammar of Selectors

- -

10.1. Grammar

- -

The grammar below defines the syntax of Selectors. It is globally - LL(1) and can be locally LL(2) (but note that most UA's should not use - it directly, since it doesn't express the parsing conventions). The - format of the productions is optimized for human consumption and some - shorthand notations beyond Yacc (see [YACC]) - are used:

- -
    -
  • *: 0 or more -
  • +: 1 or more -
  • ?: 0 or 1 -
  • |: separates alternatives -
  • [ ]: grouping
  • -
- -

The productions are:

- -
selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;
- - -

10.2. Lexical scanner

- -

The following is the tokenizer, written in Flex (see - [FLEX]) notation. The tokenizer is - case-insensitive.

- -

The two occurrences of "\377" represent the highest character - number that current versions of Flex can deal with (decimal 255). They - should be read as "\4177777" (decimal 1114111), which is the highest - possible code point in Unicode/ISO-10646. [UNICODE]

- -
%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}">"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"<!--"           return CDO;
-"-->"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;
- - -

11. Namespaces and down-level clients

- -

An important issue is the interaction of CSS selectors with XML - documents in web clients that were produced prior to this - document. Unfortunately, due to the fact that namespaces must be - matched based on the URI which identifies the namespace, not the - namespace prefix, some mechanism is required to identify namespaces in - CSS by their URI as well. Without such a mechanism, it is impossible - to construct a CSS style sheet which will properly match selectors in - all cases against a random set of XML documents. However, given - complete knowledge of the XML document to which a style sheet is to be - applied, and a limited use of namespaces within the XML document, it - is possible to construct a style sheet in which selectors would match - elements and attributes correctly.

- -

It should be noted that a down-level CSS client will (if it - properly conforms to CSS forward compatible parsing rules) ignore all - @namespace at-rules, as well as all style rules that make - use of namespace qualified element type or attribute selectors. The - syntax of delimiting namespace prefixes in CSS was deliberately chosen - so that down-level CSS clients would ignore the style rules rather - than possibly match them incorrectly.

- -

The use of default namespaces in CSS makes it possible to write - element type selectors that will function in both namespace aware CSS - clients as well as down-level clients. It should be noted that - down-level clients may incorrectly match selectors against XML - elements in other namespaces.

- -

The following are scenarios and examples in which it is possible to - construct style sheets which would function properly in web clients - that do not implement this proposal.

- -
    -
  1. - -

    The XML document does not use namespaces.

    - -
      - -
    • In this case, it is obviously not necessary to declare or use - namespaces in the style sheet. Standard CSS element type and - attribute selectors will function adequately in a down-level - client. -
    • - -
    • In a CSS namespace aware client, the default behavior of - element selectors matching without regard to namespace will - function properly against all elements, since no namespaces are - present. However, the use of specific element type selectors - that - match only elements that have no namespace ("|name") - will guarantee that selectors will match only XML elements that - do - not have a declared namespace. -
    • - -
    - -
  2. - -
  3. - -

    The XML document defines a single, default namespace used - throughout the document. No namespace prefixes are used in element - names.

    - -
      - -
    • In this case, a down-level client will function as if - namespaces were not used in the XML document at all. Standard - CSS - element type and attribute selectors will match against all - elements. -
    • - -
    - -
  4. - -
  5. - -

    The XML document does not use a default namespace, all - namespace prefixes used are known to the style sheet author, and - there is a direct mapping between namespace prefixes and namespace - URIs. (A given prefix may only be mapped to one namespace URI - throughout the XML document; there may be multiple prefixes mapped - to the same URI).

    - -
      - -
    • In this case, the down-level client will view and match - element type and attribute selectors based on their fully - qualified name, not the local part as outlined in the Type selectors and Namespaces - section. CSS - selectors may be declared using an escaped colon - "\:" - to describe the fully qualified names, e.g. - "html\:h1" will match - <html:h1>. Selectors using the qualified name - will only match XML elements that use the same prefix. Other - namespace prefixes used in the XML that are mapped to the same - URI - will not match as expected unless additional CSS style rules are - declared for them. -
    • - -
    • Note that selectors declared in this fashion will - only match in down-level clients. A CSS namespace aware - client will match element type and attribute selectors based on - the name's local part. Selectors declared with the fully - qualified name will not match (unless there is no namespace - prefix - in the fully qualified name). -
    • - -
    - -
  6. - -
- -

In other scenarios: when the namespace prefixes used in the XML are - not known in advance by the style sheet author; or a combination of - elements with no namespace are used in conjunction with elements using - a default namespace; or the same namespace prefix is mapped to - different namespace URIs within the same document, or in - different documents; it is impossible to construct a CSS style sheet - that will function properly against all elements in those documents, - unless, the style sheet is written using a namespace URI syntax (as - outlined in this document or similar) and the document is processed by - a CSS and XML namespace aware client.

- -

12. Profiles

- -

Each specification using Selectors must define the subset of W3C - Selectors it allows and excludes, and describe the local meaning of - all the components of that subset.

- -

Non normative examples: - -

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 1
Acceptstype selectors
class selectors
ID selectors
:link, - :visited and :active pseudo-classes
descendant combinator -
::first-line and ::first-letter pseudo-elements -
Excludes - -

universal selector
attribute selectors
:hover and - :focus - pseudo-classes
:target pseudo-class
:lang() - pseudo-class
all UI - element states pseudo-classes
all structural - pseudo-classes
negation pseudo-class
all - UI element fragments pseudo-elements
::before and ::after - pseudo-elements
child combinators
sibling combinators - -

namespaces

Extra constraintsonly one class selector allowed per sequence of simple - selectors -
-

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 2
Acceptstype selectors
universal selector
attribute presence and - values selectors
class selectors
ID selectors
:link, - :visited, - :active, :hover, :focus, :lang() and :first-child pseudo-classes -
descendant combinator
child combinator
adjacent - sibling - combinator
::first-line and ::first-letter - pseudo-elements
::before - and ::after pseudo-elements -
Excludes - -

content selectors
substring matching attribute - selectors
:target pseudo-classes
all UI element - states pseudo-classes
all structural pseudo-classes other - than :first-child
negation pseudo-class
all UI element - fragments pseudo-elements
general sibling combinators - -

namespaces

Extra constraintsmore than one class selector per sequence of simple selectors - (CSS1 - constraint) allowed -
- -

In CSS, selectors express pattern matching rules that determine which - style - rules apply to elements in the document tree. - -

The following selector (CSS level 2) will match all anchors a - with attribute name set inside a section 1 header - h1: -

h1 a[name]
- -

All CSS declarations attached to such a selector are applied to elements - matching it.

- -
- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationSTTS 3
Accepts - -

type selectors
universal selectors
attribute - selectors
class - selectors
ID selectors
all structural - pseudo-classes
- all combinators - -

namespaces

Excludesnon-accepted pseudo-classes
pseudo-elements
Extra constraintssome selectors and combinators are not allowed in fragment - descriptions on the right side of STTS declarations. -
- -

Selectors can be used in STTS 3 in two different - manners: -

    -
  1. a selection mechanism equivalent to CSS selection mechanism: - declarations - attached to a given selector are applied to elements matching that - selector, -
  2. fragment descriptions that appear on the right side of declarations. -
  3. -
-
- -

13. Conformance and requirements

- -

This section defines conformance with the present specification only. - -

The inability of a user agent to implement part of this specification due to - the limitations of a particular device (e.g., non interactive user agents - will - probably not implement dynamic pseudo-classes because they make no sense - without - interactivity) does not imply non-conformance. - -

All specifications reusing Selectors must contain a Profile listing the - subset of Selectors it accepts or excludes, and describing the constraints - it adds to the current specification. - -

Invalidity is caused by a parsing error, e.g. an unrecognized token or a - token - which is not allowed at the current parsing point. - -

User agents must observe the rules for handling parsing errors: -

    -
  • a simple selector containing an undeclared namespace prefix is invalid -
  • -
  • a selector containing an invalid simple selector, an invalid combinator - or an invalid token is invalid. -
  • -
  • a group of selectors containing an invalid selector is invalid.
  • -
- -

Specifications reusing Selectors must define how to handle parsing - errors. (In the case of CSS, the entire rule in which the selector is - used is dropped.)

- - - -

14. Tests

- -

This specification has a test - suite allowing user agents to verify their basic conformance to - the specification. This test suite does not pretend to be exhaustive - and does not cover all possible combined cases of Selectors.

- -

15. Acknowledgements

- -

The CSS working group would like to thank everyone who has sent - comments on this specification over the years.

- -

The working group would like to extend special thanks to Donna - McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed - the final editorial review.

- -

16. References

- -
- -
[CSS1] -
Bert Bos, Håkon Wium Lie; "Cascading - Style Sheets, level 1", W3C Recommendation, 17 Dec 1996, revised - 11 Jan 1999 -
(http://www.w3.org/TR/REC-CSS1) - -
[CSS21] -
Bert Bos, Tantek Çelik, Ian Hickson, Håkon - Wium Lie, editors; "Cascading Style Sheets, level 2 revision - 1", W3C Working Draft, 13 June 2005 -
(http://www.w3.org/TR/CSS21) - -
[CWWW] -
Martin J. Dürst, François Yergeau, - Misha Wolf, Asmus Freytag, Tex Texin, editors; "Character Model - for the World Wide Web", W3C Recommendation, 15 February 2005 -
(http://www.w3.org/TR/charmod/) - -
[FLEX] -
"Flex: The Lexical Scanner - Generator", Version 2.3.7, ISBN 1882114213 - -
[HTML4] -
Dave Ragget, Arnaud Le Hors, Ian Jacobs, - editors; "HTML 4.01 Specification", W3C Recommendation, 24 - December 1999 -
- (http://www.w3.org/TR/html4/) - -
[MATH] -
Patrick Ion, Robert Miner, editors; "Mathematical - Markup Language (MathML) 1.01", W3C Recommendation, revision of 7 - July 1999 -
(http://www.w3.org/TR/REC-MathML/) - -
[RFC3066] -
H. Alvestrand; "Tags for the - Identification of Languages", Request for Comments 3066, January - 2001 -
(http://www.ietf.org/rfc/rfc3066.txt) - -
[STTS] -
Daniel Glazman; "Simple Tree Transformation - Sheets 3", Electricité de France, submission to the W3C, - 11 November 1998 -
(http://www.w3.org/TR/NOTE-STTS3) - -
[SVG] -
Jon Ferraiolo, 藤沢 淳, Dean - Jackson, editors; "Scalable Vector Graphics (SVG) 1.1 - Specification", W3C Recommendation, 14 January 2003 -
(http://www.w3.org/TR/SVG/) - -
[UNICODE]
-
The Unicode - Standard, Version 4.1, The Unicode Consortium. Boston, MA, - Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by Unicode - 4.0.1 and Unicode - 4.1.0. -
(http://www.unicode.org/versions/) -
- -
[XML10] -
Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, - Eve Maler, François Yergeau, editors; "Extensible Markup - Language (XML) 1.0 (Third Edition)", W3C Recommendation, 4 - February 2004 -
(http://www.w3.org/TR/REC-xml/) - -
[XMLNAMES] -
Tim Bray, Dave Hollander, Andrew Layman, - editors; "Namespaces in XML", W3C Recommendation, 14 - January 1999 -
(http://www.w3.org/TR/REC-xml-names/) - -
[YACC] -
S. C. Johnson; "YACC — Yet another - compiler compiler", Technical Report, Murray Hill, 1975 - -
-
- - diff --git a/samples/src/main/java/gwtquery/samples/public/js/DOMAssistantComplete-2.7.js b/samples/src/main/java/gwtquery/samples/public/js/DOMAssistantComplete-2.7.js new file mode 100644 index 00000000..ddca30ed --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/js/DOMAssistantComplete-2.7.js @@ -0,0 +1,1529 @@ +// Developed by Robert Nyman/DOMAssistant team, code/licensing: http://domassistant.googlecode.com/, documentation: http://www.domassistant.com/documentation, version 2.8 +var DOMAssistant = function () { + var HTMLArray = function () { + // Constructor + }, + w = window, _$ = w.$, _$$ = w.$$, + isIE = /*@cc_on!@*/false, + isIE5 = isIE && parseFloat(navigator.appVersion) < 6, + sort, tagCache = {}, lastCache = {}, useCache = true, + slice = Array.prototype.slice, + camel = { + "accesskey": "accessKey", + "class": "className", + "colspan": "colSpan", + "for": "htmlFor", + "maxlength": "maxLength", + "readonly": "readOnly", + "rowspan": "rowSpan", + "tabindex": "tabIndex", + "valign": "vAlign", + "cellspacing": "cellSpacing", + "cellpadding": "cellPadding" + }, + regex = { + rules: /\s*,\s*/g, + selector: /^(\w+|\*)?(#[\w\u00C0-\uFFFF\-=$]+)?((\.[\w\u00C0-\uFFFF\-]+)*)?((\[\w+\s*([~^$*|])?(=\s*([-\w\u00C0-\uFFFF\s.]+|"[^"]*"|'[^']*'))?\]+)*)?((:\w[-\w]*(\((odd|even|\-?\d*n?([-+]\d+)?|[:#]?[-\w\u00C0-\uFFFF.]+|"[^"]*"|'[^']*'|((\w*\.[-\w\u00C0-\uFFFF]+)*)?|(\[#?\w+([~^$*|])?=?[-\w\u00C0-\uFFFF\s.'"]+\]+)|(:\w[-\w]*\(.+\)))\))?)*)?([+>~])?/, + selectorSplit: /(?:\[.*\]|\(.*\)|[^\s+>~[(])+|[+>~]/g, + id: /^#([-\w\u00C0-\uFFFF=$]+)$/, + tag: /^\w+/, + relation: /^[+>~]$/, + pseudo: /^:(\w[-\w]*)(\((.+)\))?$/, + pseudos: /:(\w[-\w]*)(\((([^(]+)|([^(]+\([^(]+)\))\))?/g, + attribs: /\[(\w+)\s*([~^$*|])?(=)?\s*([^\[\]]*|"[^"]*"|'[^']*')?\](?=$|\[|:|\s)/g, + classes: /\.([-\w\u00C0-\uFFFF]+)/g, + quoted: /^["'](.*)["']$/, + nth: /^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n([-+]\d+)?)|(-(([1-9]\d*)?)n\+(\d+)))$/, + special: /(:check|:enabl|\bselect)ed\b/ + }, + navigate = function (node, direction, checkTagName) { + var oldName = node.tagName; + while ((node = node[direction + "Sibling"]) && (node.nodeType !== 1 || (checkTagName? node.tagName !== oldName : node.tagName === "!"))) {} + return node; + }, + def = function (obj) { + return typeof obj !== "undefined"; + }, + sortDocumentOrder = function (elmArray) { + return (sortDocumentOrder = elmArray[0].compareDocumentPosition? function (elmArray) { return elmArray.sort( function (a, b) { return 3 - (a.compareDocumentPosition(b) & 6); } ); } : + isIE? function (elmArray) { return elmArray.sort( function (a, b) { return a.sourceIndex - b.sourceIndex; } ); } : + function (elmArray) { return elmArray.sort( function (a, b) { + var range1 = document.createRange(), range2 = document.createRange(); + range1.setStart(a, 0); + range1.setEnd(a, 0); + range2.setStart(b, 0); + range2.setEnd(b, 0); + return range1.compareBoundaryPoints(Range.START_TO_END, range2); + } ); })(elmArray); + }; + var pushAll = function (set1, set2) { + set1.push.apply(set1, slice.apply(set2)); + return set1; + }; + if (isIE) { + pushAll = function (set1, set2) { + if (set2.slice) { + return set1.concat(set2); + } + var i=0, item; + while ((item = set2[i++])) { + set1[set1.length] = item; + } + return set1; + }; + } + return { + isIE : isIE, + camel : camel, + def : def, + allMethods : [], + publicMethods : [ + "prev", + "next", + "hasChild", + "cssSelect", + "elmsByClass", + "elmsByAttribute", + "elmsByTag" + ], + + harmonize : function () { + w.$ = _$; + w.$$ = _$$; + return this; + }, + + initCore : function () { + this.applyMethod.call(w, "$", this.$); + this.applyMethod.call(w, "$$", this.$$); + w.DOMAssistant = this; + if (isIE) { + HTMLArray = Array; + } + HTMLArray.prototype = []; + (function (H) { + H.each = function (fn, context) { + for (var i=0, il=this.length; i= add)? (start - add) % add : start; + } + else if (pseudoVal[8]) { // -an+b + add = pseudoVal[10]? parseInt(pseudoVal[10], 10) : 1; + start = max = parseInt(pseudoVal[11], 10); + while (start > add) { + start -= add; + } + modVal = (max >= add)? (max - add) % add : max; + } + return { start: start, add: add, max: max, modVal: modVal }; + }, + + cssByDOM : function (cssRule) { + var prevParents, currentRule, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, current, previous, prevParent, notElm, addElm, iteratorNext, childElm, sequence, anyTag, + elm = new HTMLArray(), index = elm.indexOf, prevElm = [], matchingElms = [], cssRules = cssRule.replace(regex.rules, ",").split(","), splitRule = {}; + function clearAdded (elm) { + elm = elm || prevElm; + for (var n=elm.length; n--;) { + elm[n].added = null; + elm[n].removeAttribute("added"); + } + } + function clearChildElms () { + for (var n=prevParents.length; n--;) { + prevParents[n].childElms = null; + } + } + function subtractArray (arr1, arr2) { + for (var i=0, src1; (src1=arr1[i]); i++) { + var found = false; + for (var j=0, src2; (src2=arr2[j]); j++) { + if (src2 === src1) { + found = true; + arr2.splice(j, 1); + break; + } + } + if (found) { + arr1.splice(i--, 1); + } + } + return arr1; + } + function getAttr (elm, attr) { + return (isIE || regex.special.test(attr))? elm[camel[attr.toLowerCase()] || attr] : elm.getAttribute(attr, 2); + } + function attrToRegExp (attrVal, substrOperator) { + attrVal = attrVal? attrVal.replace(regex.quoted, "$1").replace(/(\.|\[|\])/g, "\\$1") : null; + return { + "^": "^" + attrVal, + "$": attrVal + "$", + "*": attrVal, + "|": "^" + attrVal + "(\\-\\w+)*$", + "~": "\\b" + attrVal + "\\b" + }[substrOperator] || (attrVal !== null? "^" + attrVal + "$" : attrVal); + } + function notComment(el) { + return (el || this).tagName !== "!"; + } + function getTags (tag, context) { + return isIE5? (tag === "*"? context.all : context.all.tags(tag)) : context.getElementsByTagName(tag); + } + function getElementsByTagName (tag, parent) { + tag = tag || "*"; + parent = parent || document; + return (parent === document || parent.lastModified)? tagCache[tag] || (tagCache[tag] = getTags(tag, document)) : getTags(tag, parent); + } + function getElementsByPseudo (previousMatch, pseudoClass, pseudoValue) { + prevParents = []; + var pseudo = pseudoClass.split("-"), matchingElms = [], idx = 0, checkNodeName = /\-of\-type$/.test(pseudoClass), recur, + match = { + first: function(el) { return !navigate(el, "previous", checkNodeName); }, + last: function(el) { return !navigate(el, "next", checkNodeName); }, + empty: function(el) { return !el.firstChild; }, + enabled: function(el) { return !el.disabled && el.type !== "hidden"; }, + disabled: function(el) { return el.disabled; }, + checked: function(el) { return el.checked; }, + contains: function(el) { return (el.innerText || el.textContent || "").indexOf(pseudoValue.replace(regex.quoted, "$1")) > -1; }, + other: function(el) { return getAttr(el, pseudoClass) === pseudoValue; } + }; + function basicMatch(key) { + while ((previous=previousMatch[idx++])) { + if (notComment(previous) && match[key](previous)) { + matchingElms[matchingElms.length] = previous; + } + } + return matchingElms; + } + var word = pseudo[0] || null; + if (word && match[word]) { + return basicMatch(word); + } + switch (word) { + case "only": + var kParent, kTag; + while ((previous=previousMatch[idx++])) { + prevParent = previous.parentNode; + var q = previous.nodeName; + if (prevParent !== kParent || q !== kTag) { + if (match.first(previous) && match.last(previous)) { + matchingElms[matchingElms.length] = previous; + } + kParent = prevParent; + kTag = q; + } + } + break; + case "nth": + if (pseudoValue === "n") { + matchingElms = previousMatch; + } + else { + var direction = (pseudo[1] === "last")? ["lastChild", "previousSibling"] : ["firstChild", "nextSibling"]; + sequence = DOMAssistant.getSequence(pseudoValue); + if (sequence) { + while ((previous=previousMatch[idx++])) { + prevParent = previous.parentNode; + prevParent.childElms = prevParent.childElms || {}; + var p = previous.nodeName; + if (!prevParent.childElms[p]) { + var childCount = 0; + iteratorNext = sequence.start; + childElm = prevParent[direction[0]]; + while (childElm && (sequence.max < 0 || iteratorNext <= sequence.max)) { + var c = childElm.nodeName; + if ((checkNodeName && c === p) || (!checkNodeName && childElm.nodeType === 1 && c !== "!")) { + if (++childCount === iteratorNext) { + if (c === p) { matchingElms[matchingElms.length] = childElm; } + iteratorNext += sequence.add; + } + } + childElm = childElm[direction[1]]; + } + if (anyTag) { sort++; } + prevParent.childElms[p] = true; + prevParents[prevParents.length] = prevParent; + } + } + clearChildElms(); + } + } + break; + case "target": + var hash = document.location.hash.slice(1); + if (hash) { + while ((previous=previousMatch[idx++])) { + if (getAttr(previous, "name") === hash || getAttr(previous, "id") === hash) { + matchingElms[matchingElms.length] = previous; + break; + } + } + } + break; + case "not": + if ((recur = regex.pseudo.exec(pseudoValue))) { + matchingElms = subtractArray(previousMatch, getElementsByPseudo(previousMatch, recur[1]? recur[1].toLowerCase() : null, recur[3] || null)); + } + else { + for (var re in regex) { + if (regex[re].lastIndex) { + regex[re].lastIndex = 0; + } + } + pseudoValue = pseudoValue.replace(regex.id, "[id=$1]"); + var notTag = regex.tag.exec(pseudoValue); + var notClass = regex.classes.exec(pseudoValue); + var notAttr = regex.attribs.exec(pseudoValue); + var notRegExp = new RegExp(notAttr? attrToRegExp(notAttr[4], notAttr[2]) : "(^|\\s)" + (notTag? notTag[0] : notClass? notClass[1] : "") + "(\\s|$)", "i"); + while ((notElm=previousMatch[idx++])) { + addElm = null; + if (notTag && !notRegExp.test(notElm.nodeName) || notClass && !notRegExp.test(notElm.className)) { + addElm = notElm; + } + else if (notAttr) { + var att = getAttr(notElm, notAttr[1]); + if (!def(att) || att === false || typeof att === "string" && !notRegExp.test(att)) { + addElm = notElm; + } + } + if (addElm && !addElm.added) { + addElm.added = true; + matchingElms[matchingElms.length] = addElm; + } + } + } + break; + default: return basicMatch("other"); + } + return matchingElms; + } + function pushUnique(set1, set2) { + var i=0, s=set1, item; + while ((item = set2[i++])) { + if (!s.length || s.indexOf(item) < 0) { + set1.push(item); + } + } + return set1; + } + sort = -1; + for (var a=0, tagBin=[]; (currentRule=cssRules[a]); a++) { + if (!(cssSelectors = currentRule.match(regex.selectorSplit)) || a && index.call(cssRules.slice(0, a), currentRule) > -1) { continue; } + prevElm = [this]; + for (var i=0, rule; (rule=cssSelectors[i]); i++) { + matchingElms = []; + if ((childOrSiblingRef = regex.relation.exec(rule))) { + var idElm = null, nextWord = cssSelectors[i+1]; + if ((nextTag = regex.tag.exec(nextWord))) { + nextTag = nextTag[0]; + nextRegExp = new RegExp("(^|\\s)" + nextTag + "(\\s|$)", "i"); + } + else if (regex.id.test(nextWord)) { + idElm = DOMAssistant.$(nextWord) || null; + } + for (var j=0, prevRef; (prevRef=prevElm[j]); j++) { + switch (childOrSiblingRef[0]) { + case ">": + var children = idElm || getElementsByTagName(nextTag, prevRef); + for (var k=0, child; (child=children[k]); k++) { + if (child.parentNode === prevRef) { + matchingElms[matchingElms.length] = child; + } + } + break; + case "+": + if ((prevRef = navigate(prevRef, "next"))) { + if ((idElm && idElm[0] === prevRef) || (!idElm && (!nextTag || nextRegExp.test(prevRef.nodeName)))) { + matchingElms[matchingElms.length] = prevRef; + } + } + break; + case "~": + while ((prevRef = prevRef.nextSibling) && !prevRef.added) { + if ((idElm && idElm[0] === prevRef) || (!idElm && (!nextTag || nextRegExp.test(prevRef.nodeName)))) { + prevRef.added = true; + matchingElms[matchingElms.length] = prevRef; + } + } + break; + } + } + prevElm = matchingElms; + clearAdded(); + rule = cssSelectors[++i]; + if (/^\w+$/.test(rule) || regex.id.test(rule)) { + continue; + } + prevElm.skipTag = true; + } + var cssSelector = regex.selector.exec(rule); + splitRule = { + tag : cssSelector[1]? cssSelector[1] : "*", + id : cssSelector[2], + allClasses : cssSelector[3], + allAttr : cssSelector[5], + allPseudos : cssSelector[10] + }; + anyTag = (splitRule.tag === "*"); + if (splitRule.id) { + var u = 0, DOMElm = document.getElementById(splitRule.id.slice(1)); + if (DOMElm) { + while (prevElm[u] && !DOMAssistant.hasChild.call(prevElm[u], DOMElm)) { u++; } + matchingElms = (u < prevElm.length && (anyTag || splitRule.tag === DOMElm.tagName.toLowerCase()))? [DOMElm] : []; + } + prevElm = matchingElms; + } + else if (splitRule.tag && !prevElm.skipTag) { + if (i===0 && !matchingElms.length && prevElm.length === 1) { + prevElm = matchingElms = pushAll([], getElementsByTagName(splitRule.tag, prevElm[0])); + } + else { + for (var l=0, ll=prevElm.length, tagCollectionMatches, tagMatch; l= 0 || index.call(tagBin, "*") >= 0))? pushUnique : pushAll)(elm, prevElm); + tagBin.push(splitRule.tag); + if (isIE && anyTag) { elm = elm.filter(notComment); } + } + return ((elm.length > 1 && cssRules.length > 1) || sort > 0)? sortDocumentOrder(elm) : elm; + }, + + cssByXpath : function (cssRule) { + var ns = { xhtml: "http://www.w3.org/1999/xhtml" }, + prefix = (document.documentElement.namespaceURI === ns.xhtml)? "xhtml:" : "", + nsResolver = function lookupNamespaceURI (prefix) { + return ns[prefix] || null; + }; + DOMAssistant.cssByXpath = function (cssRule) { + var currentRule, cssSelectors, xPathExpression, cssSelector, splitRule, sequence, + elm = new HTMLArray(), cssRules = cssRule.replace(regex.rules, ",").split(","); + function attrToXPath (wrap) { + var pre = wrap? "[" : "", post = wrap? "]" : ""; + return function (match, p1, p2, p3, p4) { + p4 = (p4 || "").replace(regex.quoted, "$1"); + if (p1 === p4 && p1 === "readonly") { p3 = null; } + return pre + ({ + "^": "starts-with(@" + p1 + ", \"" + p4 + "\")", + "$": "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p4.length - 1) + "), " + p4.length + ") = \"" + p4 + "\"", + "*": "contains(concat(\" \", @" + p1 + ", \" \"), \"" + p4 + "\")", + "|": "@" + p1 + "=\"" + p4 + "\" or starts-with(@" + p1 + ", \"" + p4 + "-\")", + "~": "contains(concat(\" \", @" + p1 + ", \" \"), \" " + p4 + " \")" + }[p2] || ("@" + p1 + (p3? "=\"" + p4 + "\"" : ""))) + post; + }; + } + function pseudoToXPath (tag, pseudoClass, pseudoValue) { + tag = /\-child$/.test(pseudoClass)? "*" : tag; + var pseudo = pseudoClass.split("-"), position = ((pseudo[1] === "last")? "(count(following-sibling::" : "(count(preceding-sibling::") + tag + ") + 1)", recur, hash; + switch (pseudo[0]) { + case "nth": return (pseudoValue !== "n" && (sequence = DOMAssistant.getSequence(pseudoValue)))? ((sequence.start === sequence.max)? position + " = " + sequence.start : position + " mod " + sequence.add + " = " + sequence.modVal + ((sequence.start > 1)? " and " + position + " >= " + sequence.start : "") + ((sequence.max > 0)? " and " + position + " <= " + sequence.max: "")) : ""; + case "not": return "not(" + ((recur = regex.pseudo.exec(pseudoValue))? pseudoToXPath(tag, recur[1]? recur[1].toLowerCase() : null, recur[3] || null) : pseudoValue.replace(regex.id, "[id=$1]").replace(regex.tag, "self::$0").replace(regex.classes, "contains(concat(\" \", @class, \" \"), \" $1 \")").replace(regex.attribs, attrToXPath())) + ")"; + case "first": return "not(preceding-sibling::" + tag + ")"; + case "last": return "not(following-sibling::" + tag + ")"; + case "only": return "not(preceding-sibling::" + tag + " or following-sibling::" + tag + ")"; + case "empty": return "not(child::*) and not(text())"; + case "contains": return "contains(., \"" + pseudoValue.replace(regex.quoted, "$1") + "\")"; + case "enabled": return "not(@disabled) and not(@type=\"hidden\")"; + case "disabled": return "@disabled"; + case "target": return "@name=\"" + (hash = document.location.hash.slice(1)) + "\" or @id=\"" + hash + "\""; + default: return "@" + pseudoClass + "=\"" + pseudoValue + "\""; + } + } + for (var i=0; (currentRule=cssRules[i]); i++) { + if (!(cssSelectors = currentRule.match(regex.selectorSplit)) || i && elm.indexOf.call(cssRules.slice(0, i), currentRule) > -1) { continue; } + xPathExpression = xPathExpression? xPathExpression + " | ." : "."; + for (var j=0, jl=cssSelectors.length; j": "/", "+": "/following-sibling::*[1]/self::", "~": "/following-sibling::" }[splitRule.tagRelation] || "") : ((j > 0 && regex.relation.test(cssSelectors[j-1]))? splitRule.tag : ("//" + splitRule.tag))) + + (splitRule.id || "").replace(regex.id, "[@id = \"$1\"]") + + (splitRule.allClasses || "").replace(regex.classes, "[contains(concat(\" \", @class, \" \"), \" $1 \")]") + + (splitRule.allAttr || "").replace(regex.attribs, attrToXPath(true)); + if (splitRule.allPseudos) { + var allPseudos = splitRule.allPseudos.match(regex.pseudos); + for (var k=0, kl=allPseudos.length; k 0 && ajaxObj.params)? ("&" + ajaxObj.params) : ""); + } + return DOMAssistant.AJAX.makeCall.call(this, ajaxObj); + }, + + get : function (url, callback, addToContent) { + return DOMAssistant.AJAX.makeCall.call(this, createAjaxObj(url, "GET", callback, addToContent)); + }, + + post : function (url, callback) { + return DOMAssistant.AJAX.makeCall.call(this, createAjaxObj(url, "POST", callback)); + }, + + load : function (url, addToContent) { + this.get(url, DOMAssistant.AJAX.replaceWithAJAXContent, addToContent); + }, + + makeCall : function (ajaxObj) { + var XMLHttp = DOMAssistant.AJAX.initRequest(); + if (XMLHttp) { + globalXMLHttp = XMLHttp; + (function (elm) { + var url = ajaxObj.url, + method = ajaxObj.method || "GET", + callback = ajaxObj.callback, + params = ajaxObj.params, + headers = ajaxObj.headers, + responseType = ajaxObj.responseType || "text", + addToContent = ajaxObj.addToContent, + timeout = ajaxObj.timeout || null, + ex = ajaxObj.exception, + timeoutId = null, + done = false; + XMLHttp.open(method, url, true); + XMLHttp.setRequestHeader("AJAX", "true"); + XMLHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + if (method === "POST") { + XMLHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + XMLHttp.setRequestHeader("Content-length", params? params.length : 0); + if (XMLHttp.overrideMimeType) { + XMLHttp.setRequestHeader("Connection", "close"); + } + } + if (responseType === "json") { + XMLHttp.setRequestHeader("Accept", "application/json, text/javascript, */*"); + } + for (var i in headers) { + if (typeof i === "string") { + XMLHttp.setRequestHeader(i, headers[i]); + } + } + if (typeof callback === "function") { + XMLHttp.onreadystatechange = function () { + try { + if (XMLHttp.readyState === 4 && !done) { + window.clearTimeout(timeoutId); + done = true; + status = XMLHttp.status; + statusText = XMLHttp.statusText; + readyState = 4; + if ((status || location.protocol !== "file:") && (status < 200 || status >= 300)) { + throw new Error(statusText); + } + var response = /xml/i.test(responseType)? XMLHttp.responseXML : XMLHttp.responseText; + if (/json/i.test(responseType) && !!response) { + response = (typeof JSON === "object" && typeof JSON.parse === "function")? JSON.parse(response) : eval("(" + response + ")"); + } + globalXMLHttp = null; + XMLHttp.onreadystatechange = function () {}; + requestPool.push(XMLHttp); + callback.call(elm, response, addToContent); + } + } + catch (e) { + globalXMLHttp = XMLHttp = null; + if (typeof ex === "function") { + ex.call(elm, e); + ex = null; + } + } + }; + } + XMLHttp.send(params); + if (timeout) { + timeoutId = window.setTimeout( function () { + if (!done) { + XMLHttp.abort(); + done = true; + if (typeof ex === "function") { + readyState = 0; + status = 408; + statusText = "Request timeout"; + globalXMLHttp = XMLHttp = null; + ex.call(elm, new Error(statusText)); + ex = null; + } + } + }, timeout); + } + })(this); + } + return this; + }, + + replaceWithAJAXContent : function (content, add) { + if (add) { + this.innerHTML += content; + } + else { + DOMAssistant.cleanUp(this); + this.innerHTML = content; + } + }, + + getReadyState : function () { + return (globalXMLHttp && DOMAssistant.def(globalXMLHttp.readyState))? globalXMLHttp.readyState : readyState; + }, + + getStatus : function () { + return status; + }, + + getStatusText : function () { + return statusText; + } + }; +}(); +DOMAssistant.attach(DOMAssistant.AJAX); +DOMAssistant.CSS = function () { + var def = DOMAssistant.def, + direct = { display: true }; + return { + addClass : function (className) { + if (!this.hasClass(className)) { + var currentClass = this.className; + this.className = currentClass + (currentClass.length? " " : "") + className; + } + return this; + }, + + removeClass : function (className) { + return this.replaceClass(className); + }, + + replaceClass : function (className, newClass) { + var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i"); + this.className = this.className.replace(classToRemove, function (match, p1, p2) { + return newClass? (p1 + newClass + p2) : " "; + }).replace(/^\s+|\s+$/g, ""); + return this; + }, + + hasClass : function (className) { + return (" " + this.className + " ").indexOf(" " + className + " ") > -1; + }, + + setStyle : function (style, value) { + var css = this.style; + if ("filters" in this && (typeof style === "string"? /opacity/i.test(style) : def(style.opacity))) { + css.zoom = 1; + css.filter = (css.filter || "").replace(/alpha\([^)]*\)/, "") + "alpha(opacity=" + (def(style.opacity)? style.opacity : value) * 100 + ")"; + } + if (def(css.cssText)) { + var styleToSet = css.cssText; + if (typeof style === "object") { + for (var i in style) { + if (typeof i === "string") { + if (direct[i]) { css[i] = style[i]; } + styleToSet += ";" + i + ":" + style[i]; + } + } + } + else { + if (direct[style]) { css[style] = value; } + styleToSet += ";" + style + ":" + value; + } + css.cssText = styleToSet; + } + return this; + }, + + getStyle : function (cssRule) { + var val = "", f; + cssRule = cssRule.toLowerCase(); + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(this, "").getPropertyValue(cssRule); + } + else if (this.currentStyle) { + if ("filters" in this && cssRule === "opacity") { + val = (f = this.style.filter || this.currentStyle.filter) && f.indexOf("opacity=") >= 0? parseFloat(f.match(/opacity=([^)]*)/)[1]) / 100 : 1; + } + else { + cssRule = cssRule.replace(/^float$/, "styleFloat").replace(/\-(\w)/g, function (match, p1) { + return p1.toUpperCase(); + }); + val = this.currentStyle[cssRule]; + } + if (val === "auto" && /^(width|height)$/.test(cssRule) && this.currentStyle.display !== "none") { + val = this["offset" + cssRule.charAt(0).toUpperCase() + cssRule.substr(1)] + "px"; + } + } + return val; + } + }; +}(); +DOMAssistant.attach(DOMAssistant.CSS); +DOMAssistant.Content = function () { + var D$ = DOMAssistant.$$; + return { + init : function () { + DOMAssistant.setCache(false); + }, + + create : function (name, attr, append, content) { + var elm = D$(document.createElement(name)); + if (attr) { + elm = elm.setAttributes(attr); + } + if (DOMAssistant.def(content)) { + elm.addContent(content); + } + if (append) { + this.appendChild(elm); + } + return elm; + }, + + setAttributes : function (attr) { + if (DOMAssistant.isIE) { + var setAttr = function (elm, att, val) { + var attLower = att.toLowerCase(); + switch (attLower) { + case "name": + case "type": + case "multiple": + return D$(document.createElement(elm.outerHTML.replace(new RegExp(attLower + "(=[a-zA-Z]+)?"), " ").replace(">", " " + attLower + "=" + val + ">"))); + case "style": + elm.style.cssText = val; + return elm; + default: + elm[DOMAssistant.camel[attLower] || att] = val; + return elm; + } + }; + DOMAssistant.Content.setAttributes = function (attr) { + var elem = this; + var parent = this.parentNode; + for (var i in attr) { + if (typeof attr[i] === "string" || typeof attr[i] === "number") { + var newElem = setAttr(elem, i, attr[i]); + if (parent && /(name|type)/i.test(i)) { + if (elem.innerHTML) { + newElem.innerHTML = elem.innerHTML; + } + parent.replaceChild(newElem, elem); + } + elem = newElem; + } + } + return elem; + }; + } + else { + DOMAssistant.Content.setAttributes = function (attr) { + for (var i in attr) { + if (/class/i.test(i)) { + this.className = attr[i]; + } + else { + this.setAttribute(i, attr[i]); + } + } + return this; + }; + } + return DOMAssistant.Content.setAttributes.call(this, attr); + }, + + addContent : function (content) { + var type = typeof content; + if (type === "string" || type === "number") { + if (!this.firstChild) { + this.innerHTML = content; + } + else { + var tmp = document.createElement("div"); + tmp.innerHTML = content; + for (var i=tmp.childNodes.length-1, last=null; i>=0; i--) { + last = this.insertBefore(tmp.childNodes[i], last); + } + } + } + else if (type === "object" || (type === "function" && !!content.nodeName)) { + this.appendChild(content); + } + return this; + }, + + replaceContent : function (content) { + DOMAssistant.cleanUp(this); + return this.addContent(content); + }, + + replace : function (content, returnNew) { + var type = typeof content; + if (type === "string" || type === "number") { + var parent = this.parentNode; + var tmp = DOMAssistant.Content.create.call(parent, "div", null, false, content); + for (var i=tmp.childNodes.length; i--;) { + parent.insertBefore(tmp.childNodes[i], this.nextSibling); + } + content = this.nextSibling; + parent.removeChild(this); + } + else if (type === "object" || (type === "function" && !!content.nodeName)) { + this.parentNode.replaceChild(content, this); + } + return returnNew? content : this; + }, + + remove : function () { + DOMAssistant.cleanUp(this); + if (this.hasData()) { + if (this.removeEvent) { this.removeEvent(); } + this.unstore(); + } + this.parentNode.removeChild(this); + return null; + } + }; +}(); +DOMAssistant.attach(DOMAssistant.Content); +DOMAssistant.Events = function () { + var handler, + key = "_events", + w3cMode = !!document.addEventListener, + useCapture = { focus: true, blur: true }, + translate = DOMAssistant.isIE? { focus: "activate", blur: "deactivate", mouseenter: "mouseover", mouseleave: "mouseout" } : { mouseenter: "mouseover", mouseleave: "mouseout" }, + regex = { + special: /^submit|reset|change|select$/i, + mouseenterleave: /^mouse(enter|leave)$/i, + dom: /^DOM/, + on: /^on/i + }, + special = function (e) { + return DOMAssistant.isIE && regex.special.test(e); + }, + fix = function (e) { + return translate[e] || e; + }, + createEvent = function (e, type, target) { + e = e || window.event || {}; + if (e.event) { return e; } + var event = { + event: e, + type: type || e.type, + bubbles: e.bubbles || true, + cancelable: e.cancelable || false, + target: target || e.target || e.srcElement, + clientX: e.clientX || 0, + clientY: e.clientY || 0, + altKey: e.altKey || false, + ctrlKey: e.ctrlKey || false, + shiftKey: e.shiftKey || false, + button: e.button || null, + timeStamp: +new Date(), + preventDefault: function() { + if (e.preventDefault) { e.preventDefault(); } + this.returnValue = e.returnValue = false; + }, + stopPropagation: function() { + if (e.stopPropagation) { e.stopPropagation(); } + this.cancelBubble = e.cancelBubble = true; + } + }; + if (event.target && 3 === event.target.nodeType) { // Safari textnode bug + event.target = event.target.parentNode; + } + event.currentTarget = event.target; + event.relatedTarget = e.relatedTarget || (e.fromElement === event.target? e.toElement : e.fromElement) || null; + var de = document.documentElement, b = document.body; + event.pageX = DOMAssistant.def(e.pageX)? e.pageX : (event.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0)); + event.pageY = DOMAssistant.def(e.pageY)? e.pageY : (event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0)); + if ("number" === typeof e.which) { + event.keyCode = e.keyCode; + event.charCode = event.which = e.which; + } + else if (e.keyCode) { + event.keyCode = event.charCode = e.keyCode; + } + return event; + }; + + return { + publicMethods : [ + "triggerEvent", + "addEvent", + "removeEvent", + "relayEvent", + "unrelayEvent", + "preventDefault", + "cancelBubble" + ], + + init : function () { + DOMAssistant.preventDefault = this.preventDefault; + DOMAssistant.cancelBubble = this.cancelBubble; + handler = this.handleEvent; + }, + + triggerEvent : function (evt, target, e) { + var fevt = fix(evt), + events = this.retrieve(key), + event = e || createEvent(e, fevt, target || this); + event.currentTarget = this; + if (events && events[fevt]) { + for (var i=0, iL=events[fevt].length; i<\/script>"); + document.getElementById("ieScriptLoad").onreadystatechange = function() { + if (this.readyState === "complete") { + DOMHasLoaded(); + } + }; + @end @*/ + /* Mozilla, Chrome, Opera */ + if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", DOMHasLoaded, false); + } + /* Safari, iCab, Konqueror */ + if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) { + DOMLoadTimer = setInterval(function () { + if (/loaded|complete/i.test(document.readyState)) { + DOMHasLoaded(); + clearInterval(DOMLoadTimer); + } + }, 10); + } + /* Other web browsers */ + window.onload = DOMHasLoaded; + + return { + DOMReady : function () { + for (var i=0, il=arguments.length, funcRef; i + + This library 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 3 of the License, or + (at your option) any later version. + + This library 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. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ +/** + * A JavaScript implementation of a CSS3 Query Selector. + *

For more information, please visit + * http://www.w3.org/TR/css3-selectors/.

+ * @class Selector + * @version 0.6 + * @author Henrik Lindqvist <henrik.lindqvist@llamalab.com> + */ + +new function () { +/** + * Pre-compiles an Selector query. + *

When creating a new instance of the Selector, the query are + * pre-compiled for later execution with a call to {@link exec}.

+ *

The constructor can also be called as a function, without the new keyword. Then + * the query is executed against the optional context element, otherwise current document.

+ *

Example:

+ *
+ *   // Constructor syntax:
+ *   new Selector('div > p').exec(document).forEach(function (e) {
+ *     e.style.color = 'red';
+ *   });
+ *   // Or,  shorthand syntax:
+ *   Selector('div > p', document).forEach(function (e) {
+ *     e.style.color = 'red';
+ *   });
+ * 
+ * @constructor Selector + * @param {string} pattern - selector pattern. + * @param {optional Object} context - document or context element. + */ +function Selector (p, c) { + if (!(this instanceof Selector)) return new Selector(p).exec(c); + if (!qsa) this.exec = cache[p] || (cache[p] = new compile(p)); + this.pattern = p; +} +Selector.prototype = { + constructor : Selector, +/** + * Execute a selector query. + *

Example:

+ *
+ *   new Selector('div > p').exec(document).forEach(function (e) {
+ *     e.style.color = 'red';
+ *   });
+ * 
+ * @function {Array} exec + * @param {optional Object} context - document or context element, otherwise current document. + * @returns Non-live Array with matching elements. + */ + exec : function (c) { + var pe = this.patchElement, pa = this.patchArray, p = this.pattern, r = pe + ? map.call((c||d).querySelectorAll(p), pe, this) + : Array.prototype.slice.call((c||d).querySelectorAll(p)); + return pa ? pa.call(this, r) : r; + }, +/** + * Returns a string representing the query source pattern. + * @function {string} toString + * @returns source pattern. + */ + toString : function () { + return this.pattern; + }, +/** + * Returns a string representing the source code of the Selector. + * @function {string} toSource + * @returns source code. + */ + toSource : function () { + return 'new Selector("'+this.pattern+'")'; + } +/** + * Hook for patching result Element’s. + *

When using the {@link Selector} within you own framework you can add this function to + * extend the resulting Element’s before they are returned by {@link exec}. + *

This function is not defined by default, since calling it unneccesarily affects performance.

+ * @function {Element} patchElement + * @param {Element} e - the result element. + * @returns the patched Element. + * @see patchArray + */ + //patchElement : function (e) { return e; }, +/** + * Hook for patching result Array. + *

When using the {@link Selector} within you own framework you can add this function to + * extend the resulting Array before it’sthey are returned by {@link exec}. + *

This function is not defined by default, since calling it unneccesarily affects performance.

+ * @function {Array} patchArray + * @param {Array} a - the result array. + * @returns the patched Array. + * @see patchElement + */ + //patchArray : function (a) { return a; } +}; +window.Selector = Selector; +// ------------------------------------------ Private ------------------------------------------- // +function $ (s) { + var a = arguments; + return s.replace(/\$(\d)/g, function (m, i) { return a[i] }); +} +with (navigator.userAgent) { + var ie = indexOf('MSIE') != -1 && indexOf('Opera') == -1, + mz = indexOf('Gecko') != -1 && indexOf('KHTML') == -1, + wk = indexOf('AppleWebKit') != -1; +} +var d = document, + de = d.documentElement, + qsa = !!d.querySelectorAll, + bcn = !!d.getElementsByClassName, + cnl = !!de.children, + cnlt = cnl && de.children.tags && !wk, + ec = !!de.contains, + cdp = !!de.compareDocumentPosition, + si = typeof de.sourceIndex == 'number', + cache = {}, + cmp = { + '=': 'if($1($2=="$3")){$5}', + '^=': 'if($1((x=$2)&&!x.indexOf("$3"))){$5}', + '*=': 'if($1((x=$2)&&x.indexOf("$3")!=-1)){$5}', + '$=': 'if($1((x=$2)&&x.indexOf("$3",x.length-$4)!=-1)){$5}', + '~=': 'if($1((x=$2)&&(y=x.indexOf("$3"))!=-1&&(x.charCodeAt(y-1)||32)==32&&(x.charCodeAt(y+$4)||32)==32)){$5}', + '|=': 'if($1((x=$2)&&(x=="$3"||!x.indexOf("$3-")))){$5}' + }, + /* + cmp = { + '=': 'if($1($2=="$3")){$5}', + '^=': 'if($1((x=$2)&&!x.indexOf("$3"))){$5}', + '*=': 'if($1((x=$2)&&x.indexOf("$3")!=-1)){$5}', + '$=': 'if($1/$3$/.test($2)){$5}', + '~=': 'if($1/(^|\\s)$3(\\s|$)/.test($2)){$5}', + '|=': 'if($1/^$3(-|$)/.test($2)){$5}' + }, + */ + map = Array.prototype.map || function (fn, tp) { + var i = this.length, r = new Array(i); + while (--i >= 0) r[i] = fn.call(tp, this[i], i, this); + return r; + }; +with (d.implementation) { + var me = d.addEventListener + && (hasFeature('MutationEvents','2.0') + || hasFeature('Events','2.0') && hasFeature('Core','2.0')); +} +Selector.guid = 0; +Selector.nthIndex = function (LLi, c, r, tp, tv) { + var p = c.parentNode, ci = 'LLi#'+tv, pl = 'LLi$'+tv; + if (!p) return Number.NaN; + if (!c[ci] || c.LLi != LLi) { + for (var n = p.firstChild, i = 0; n; n = n.nextSibling) { + if (n[tp] == tv) { + n[ci] = ++i; + n.LLi = LLi; + } + } + p[pl] = i; + } + return r ? 1 + p[pl] - c[ci] : c[ci]; +}; +/* +//TODO: srt to slow in wk +Selector.srcIndex = function (h, n) { + var i = 0, x; + do { + if (x = n.previousSibling) { + n = x; + if (n.getElementsByTagName) { + if (x = h[n.LLn]) return x + i + 1; + i += n.getElementsByTagName('*').length + 1; + } + } + else if (n = n.parentNode) i++; + } while (n); + return i; +} +Selector.srcIndex = function (h, n) { + var i = -1, x; + do { + if (n.nodeType === 1) { + i++; + if (x = h[n.LLn]) return x + i; + } + if (x = n.previousSibling) do { n = x; } while (x = x.lastChild); + else n = n.parentNode; + } while (n); + return i; +} +*/ +if (me) { + function fn (e) { + with (e.target) { + if (nodeType !== 2) + ownerDocument.LLi = ++Selector.guid; + } + } + d.addEventListener('DOMNodeInserted', fn, false); + d.addEventListener('DOMNodeRemoved', fn, false); +} +if (ie) { + var am = { + acceptcharset: 'acceptCharset', + accesskey: 'accessKey', + cellpadding: 'cellPadding', + cellspacing: 'cellSpacing', + checked: 'defaultChecked', + selected: 'defaultSelected', + 'class': 'className', + colspan: 'colSpan', + 'for': 'htmlFor', + frameborder: 'frameBorder', + hspace: 'hSpace', + longdesc: 'longDesc', + marginwidth: 'marginWidth', + marginheight: 'marginHeight', + noresize: 'noResize', + noshade: 'noShade', + maxlength: 'maxLength', + readonly: 'readOnly', + rowspan: 'rowSpan', + tabindex: 'tabIndex', + usemap: 'useMap', + valign: 'vAlign', + vspace: 'vSpace' + }, ab = { + compact: 1, + nowrap: 1, + ismap: 1, + declare: 1, + noshade: 1, + checked: 1, + disabled: 1, + readonly: 1, + multiple: 1, + selected: 1, + noresize: 1, + defer: 1 + }; +} +function compile (qp) { + this.dup = this.srt = this.idx = this.i = this.nqp = 0; + with (this) { + var js = ''; + do { + i = nqp = 0; + js += $('n=c;$1q:do{$2}while(false);', srt?'s=0;':'', type(qp, $( + srt?'for(x=r.length;s0?',h={}':'', + idx?me?',LLi=d.LLi||(d.LLi=++Selector.guid)':',LLi=++Selector.guid':'', + js + ); + //console.log(js); + return new Function('c', js); + } +} +compile.prototype = { + type: function (qp, js, n, s, c) { + with (this) { + var m = /^\s*([\w-]+|\*)?(.*)/.exec(qp), t = m[1] || '*'; + if (!n && c==' ' && !dup) dup = 1; + js = pred(m[2], js, n, t, c); + switch (c) { + case '>': + return cnlt && t!='*' + ? $('for(var n$1=n.children.tags("$2"),i$1=0;n=n$1[i$1++];){$3}', ++i, t, js) + : $(cnl ? 'for(var n$1=n.children,i$1=0;n=n$1[i$1++];)$2{$3}' + : 'for(n=n.firstChild;n;n=n.nextSibling)$2{$3}', + ++i, t!='*'?'if(n.nodeName==="'+t.toUpperCase()+'")':!cnl||ie?'if(n.nodeType===1)':'', js); + case '+': + return $('while(n=n.nextSibling)if(n.node$1){$2break}else if(n.nodeType===1)break;', + t=='*'?'Type===1':'Name==="'+t.toUpperCase()+'"', js); + case '~': + return $('while(n=n.nextSibling)if(n.node$1){$3}else if(n.node$2)break;', + t=='*'?'Type===1':'Name==="'+t.toUpperCase()+'"', + s=='*'?'Type===1':'Name==="'+s.toUpperCase()+'"', js); + default: + return (typeof js == 'object') ? String(js) // handled by pred + : n ? t=='*' ? js : $('if(n.nodeName!="$1"){$2}', t.toUpperCase(), js) + : $('for(var n$1=n.getElementsByTagName("$2"),i$1=0;n=n$1[i$1++];)$3{$4}', + ++i, t, ie&&t=='*'?'if(n.nodeType===1)':'', js); + } + } + }, + pred: function (qp, js, n, t, c) { + with (this) { + var m = /^([#\.])([\w-]+)(.*)/.exec(qp) + || /^(\[)\s*([\w-]+)\s*(?:([~|^$*]?=)\s*(?:(['"])(.*?)\4|([\w-]+)))?\s*\](.*)/.exec(qp) + || /^:(first|last|only)-(?:(child)|of-type)(.*)/.exec(qp) + || /^:(nth)-(?:(last)-)?(?:(child)|of-type)\(\s*(?:(odd|even)|(-|\d*)n([+-]\d+)?|([1-9]\d*))\s*\)(.*)/.exec(qp) + || /^:(active|checked|(?:dis|en)abled|empty|focus|link|root|target)(.*)/.exec(qp) + || /^:(lang)\(\s*(['"])?(.*?)\2\s*\)(.*)/.exec(qp) + || (!n && /^:(not)\(\s*(.*)\s*\)(.*)/.exec(qp)), x = 0; + if (!m) { + if (m = /^\s*([+>~,\s])\s*(\S.*)/.exec(qp)) { + if (m[1] != ',') return type(m[2], js, n, t, m[1]); + nqp = m[2]; + dup = 2; + //srt = 1; + } + else if (/\S/.test(qp)) throw new Error('Illegal query near: '+qp); + return dup<1?js:$('if(!h[x=n.LLn||(n.LLn=++Selector.guid)]){h[x]=$1;$2}', + !srt||cdp?'true':si?'n.sourceIndex':'Selector.srcIndex(h,n)', js); + } + if (!n && m[1]=='#' && dup!=2) dup = -1; + js = pred(m[m.length-1], js, n, t, 1); + switch (m[1]) { + case '#': + return uniq(js, n, t, c, ie, 'n.id', '"'+m[2]+'"', 'd.getElementById("'+m[2]+'")'); + case '.': + return bcn && !n && (!c || c==' ') && (t=='*' || !mz) + ? Object($('for(var n$1=n.getElementsByClassName("$2"),i$1=0;n=n$1[i$1++];)$3{$4}', + ++i, m[2], t=='*'?'':'if(n.nodeName==="'+t.toUpperCase()+'")', js)) + : $(cmp['~='], n?'!':'', 'n.className', x=m[2], x.length, js); + case '[': + return (x = m[3]) + ? $(cmp[x], + n?'!':'', + ie ? (x = m[2].toLowerCase()) == 'style' ? 'style.cssText.toLowerCase()' + : ab[x] ? 'n.'+x+'&&"'+x+'"' + : 'n.getAttribute("'+(am[x]||x)+'",2)' + : 'n.getAttribute("'+m[2]+'")', + x=m[5]||m[6], x.length, + js + ) + : $(ie?'if($1((x=n.getAttributeNode("$2"))&&x.specified)){$3}':'if($1n.hasAttribute("$2")){$3}', + n?'!':'', m[2], js); + case 'active': + case 'focus': + return uniq(js, n, t, c, 0, 'n', 'd.activeElement'); + case 'checked': + return $('if($1(n.checked||n.selected)){$2}', n?'!':'', js); + case 'disabled': + x = 1; + case 'enabled': + return $( + 'if(n.disabled===$1$2){$3}', + !!(x ^ n), + ie?'&&((x=n.nodeName)==="BUTTON"||x==="INPUT"||x==="OPTION"||x==="OPTGROUP"||x==="SELECT"||x==="TEXTAREA"':'', + js + ); + case 'empty': + return $('for(x=n.firstChild;x&&x.nodeType>3;x=x.nextSibling);if($1x){$2}', n?'':'!', js); + case 'first': + return flo(js, n, m[2], 'previous'); + case 'lang': + return $(cmp['|='], n?'!':'', 'n.lang', x=m[3], x.length, js); + case 'last': + return flo(js, n, m[2], 'next'); + case 'link': + return $('if($1(n.nodeName==="A"&&n.href)){$2}', n?'!':'', js); + case 'nth': + var a = m[4] ? 2 : m[5]=='-' ? -1 : m[7] ? 0 : m[5] ? m[5]-0 : 1, + b = m[4]=='odd' ? 1 : (m[6]||m[7])-0 || 0; + if (a==1) return js; + if (a==0 && b==1) return flo(js, n, m[3], m[2]?'next':'previous'); + if (a==b) b = 0; + if (b<0) b = a+b; + idx = 1; + return $('if($1(Selector.nthIndex(LLi,n,$2,"node$3",$4)$5)){$6}', + n?'!':'', !!m[2], m[3]?'Type':'Name', m[3]?'1':'n.nodeName', + a<0 ? '<='+b : a ? '%'+a+'==='+b : '==='+b, js); + case 'not': + return type(m[2], js, 1, '*'); + case 'only': + return flo(js, n, m[2]); + case 'root': + return uniq(js, n, t, c, 0, 'n', 'd.documentElement'); + case 'target': + x = '(d.defaultView||d.parentWindow||window).location.hash.substr(1)'; + return uniq(js, n, t, c, ie, 'n.id', x, 'd.getElementById('+x+')'); + } + } + }, + uniq: function (js, n, t, c, d, p, v, w) { + return (n || (c && c!=' ') || d) + ? $(n?'if($1!==$2){$3}':'if($1===$2){$3break q}', p, v, js) + : Object($( + ec ? 'if((x=$1)===n||!n.contains||n.contains(x))$2' + : cdp ? 'if((x=$1)===n||!n.compareDocumentPosition||n.compareDocumentPosition(x)&16)$2' + : 'for(x=y=$1;y;y=y.parentNode)if(y===n)$2', + w||v, + t=='*'?'{n=x;'+js+'break q}':'{if((n=x).nodeName==="'+t.toUpperCase()+'"){'+js+'}break q}' + )); + }, + flo: function (js, n, t, s) { + return $(s?'for($2x=n.$1Sibling;x&&x.node$3;x=x.$1Sibling);if($4x){$5}' + :'for($2(x=n.parentNode)&&(x=x.firstChild);x&&(x.node$3||x===n);x=x.nextSibling);if($4x){$5}', + s, t?'':'y=n.nodeName,', t?'Type!==1':'Name!==y', n?'':'!', js); + } +}; + +} diff --git a/samples/src/main/java/gwtquery/samples/public/js/sizzle.js b/samples/src/main/java/gwtquery/samples/public/js/sizzle.js new file mode 100644 index 00000000..c52b77d1 --- /dev/null +++ b/samples/src/main/java/gwtquery/samples/public/js/sizzle.js @@ -0,0 +1,1068 @@ +/*! + * Sizzle CSS Selector Engine - v1.0 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function(){ + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function(selector, context, results, seed) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context), + soFar = selector, ret, cur, pop, i; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec(""); + m = chunker.exec(soFar); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context ); + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set ); + } + } + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray(set); + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function(results){ + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort(sortOrder); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[i-1] ) { + results.splice(i--, 1); + } + } + } + } + + return results; +}; + +Sizzle.matches = function(expr, set){ + return Sizzle(expr, null, null, set); +}; + +Sizzle.find = function(expr, context, isXML){ + var set; + + if ( !expr ) { + return []; + } + + for ( var i = 0, l = Expr.order.length; i < l; i++ ) { + var type = Expr.order[i], match; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + var left = match[1]; + match.splice(1,1); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace(/\\/g, ""); + set = Expr.find[ type ]( match, context, isXML ); + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = context.getElementsByTagName("*"); + } + + return {set: set, expr: expr}; +}; + +Sizzle.filter = function(expr, set, inplace, not){ + var old = expr, result = [], curLoop = set, match, anyFound, + isXMLFilter = set && set[0] && Sizzle.isXML(set[0]); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + var filter = Expr.filter[ type ], found, item, left = match[1]; + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( var i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + var pass = not ^ !!found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + } else { + curLoop[i] = false; + } + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + leftMatch: {}, + attrMap: { + "class": "className", + "for": "htmlFor" + }, + attrHandle: { + href: function(elem){ + return elem.getAttribute("href"); + } + }, + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !/\W/.test(part), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + ">": function(checkSet, part){ + var isPartStr = typeof part === "string", + elem, i = 0, l = checkSet.length; + + if ( isPartStr && !/\W/.test(part) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + "": function(checkSet, part, isXML){ + var doneName = done++, checkFn = dirCheck, nodeCheck; + + if ( typeof part === "string" && !/\W/.test(part) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); + }, + "~": function(checkSet, part, isXML){ + var doneName = done++, checkFn = dirCheck, nodeCheck; + + if ( typeof part === "string" && !/\W/.test(part) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); + } + }, + find: { + ID: function(match, context, isXML){ + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + return m ? [m] : []; + } + }, + NAME: function(match, context){ + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], results = context.getElementsByName(match[1]); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + TAG: function(match, context){ + return context.getElementsByTagName(match[1]); + } + }, + preFilter: { + CLASS: function(match, curLoop, inplace, result, not, isXML){ + match = " " + match[1].replace(/\\/g, "") + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + ID: function(match){ + return match[1].replace(/\\/g, ""); + }, + TAG: function(match, curLoop){ + return match[1].toLowerCase(); + }, + CHILD: function(match){ + if ( match[1] === "nth" ) { + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + ATTR: function(match, curLoop, inplace, result, not, isXML){ + var name = match[1].replace(/\\/g, ""); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + PSEUDO: function(match, curLoop, inplace, result, not){ + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + if ( !inplace ) { + result.push.apply( result, ret ); + } + return false; + } + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + POS: function(match){ + match.unshift( true ); + return match; + } + }, + filters: { + enabled: function(elem){ + return elem.disabled === false && elem.type !== "hidden"; + }, + disabled: function(elem){ + return elem.disabled === true; + }, + checked: function(elem){ + return elem.checked === true; + }, + selected: function(elem){ + // Accessing this property makes selected-by-default + // options in Safari work properly + elem.parentNode.selectedIndex; + return elem.selected === true; + }, + parent: function(elem){ + return !!elem.firstChild; + }, + empty: function(elem){ + return !elem.firstChild; + }, + has: function(elem, i, match){ + return !!Sizzle( match[3], elem ).length; + }, + header: function(elem){ + return (/h\d/i).test( elem.nodeName ); + }, + text: function(elem){ + return "text" === elem.type; + }, + radio: function(elem){ + return "radio" === elem.type; + }, + checkbox: function(elem){ + return "checkbox" === elem.type; + }, + file: function(elem){ + return "file" === elem.type; + }, + password: function(elem){ + return "password" === elem.type; + }, + submit: function(elem){ + return "submit" === elem.type; + }, + image: function(elem){ + return "image" === elem.type; + }, + reset: function(elem){ + return "reset" === elem.type; + }, + button: function(elem){ + return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; + }, + input: function(elem){ + return (/input|select|textarea|button/i).test(elem.nodeName); + } + }, + setFilters: { + first: function(elem, i){ + return i === 0; + }, + last: function(elem, i, match, array){ + return i === array.length - 1; + }, + even: function(elem, i){ + return i % 2 === 0; + }, + odd: function(elem, i){ + return i % 2 === 1; + }, + lt: function(elem, i, match){ + return i < match[3] - 0; + }, + gt: function(elem, i, match){ + return i > match[3] - 0; + }, + nth: function(elem, i, match){ + return match[3] - 0 === i; + }, + eq: function(elem, i, match){ + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function(elem, match, i, array){ + var name = match[1], filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + } else { + Sizzle.error( "Syntax error, unrecognized expression: " + name ); + } + }, + CHILD: function(elem, match){ + var type = match[1], node = elem; + switch (type) { + case 'only': + case 'first': + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + if ( type === "first" ) { + return true; + } + node = elem; + case 'last': + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + return true; + case 'nth': + var first = match[2], last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + var doneName = match[0], + parent = elem.parentNode; + + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { + var count = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + parent.sizcache = doneName; + } + + var diff = elem.nodeIndex - last; + if ( first === 0 ) { + return diff === 0; + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + ID: function(elem, match){ + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + TAG: function(elem, match){ + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; + }, + CLASS: function(elem, match){ + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + ATTR: function(elem, match){ + var name = match[1], + result = Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + POS: function(elem, match, i, array){ + var name = match[2], filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function(array, results) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch(e){ + makeArray = function(array, results) { + var ret = results || [], i = 0; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + if ( a == b ) { + hasDuplicate = true; + } + return a.compareDocumentPosition ? -1 : 1; + } + + var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; + if ( ret === 0 ) { + hasDuplicate = true; + } + return ret; + }; +} else if ( "sourceIndex" in document.documentElement ) { + sortOrder = function( a, b ) { + if ( !a.sourceIndex || !b.sourceIndex ) { + if ( a == b ) { + hasDuplicate = true; + } + return a.sourceIndex ? -1 : 1; + } + + var ret = a.sourceIndex - b.sourceIndex; + if ( ret === 0 ) { + hasDuplicate = true; + } + return ret; + }; +} else if ( document.createRange ) { + sortOrder = function( a, b ) { + if ( !a.ownerDocument || !b.ownerDocument ) { + if ( a == b ) { + hasDuplicate = true; + } + return a.ownerDocument ? -1 : 1; + } + + var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); + aRange.setStart(a, 0); + aRange.setEnd(a, 0); + bRange.setStart(b, 0); + bRange.setEnd(b, 0); + var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); + if ( ret === 0 ) { + hasDuplicate = true; + } + return ret; + }; +} + +// Utility function for retreiving the text value of an array of DOM nodes +Sizzle.getText = function( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += Sizzle.getText( elem.childNodes ); + } + } + + return ret; +}; + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(); + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + var root = document.documentElement; + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function(match, context, isXML){ + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; + } + }; + + Expr.filter.ID = function(elem, match){ + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + root = form = null; // release memory in IE +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function(match, context){ + var results = context.getElementsByTagName(match[1]); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + Expr.attrHandle.href = function(elem){ + return elem.getAttribute("href", 2); + }; + } + + div = null; // release memory in IE +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, div = document.createElement("div"); + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function(query, context, extra, seed){ + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) { + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(e){} + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + div = null; // release memory in IE + })(); +} + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function(match, context, isXML) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + div = null; // release memory in IE +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + if ( elem ) { + elem = elem[dir]; + var match = false; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +Sizzle.contains = document.compareDocumentPosition ? function(a, b){ + return !!(a.compareDocumentPosition(b) & 16); +} : function(a, b){ + return a !== b && (a.contains ? a.contains(b) : true); +}; + +Sizzle.isXML = function(elem){ + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function(selector, context){ + var tmpSet = [], later = "", match, + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE + +window.Sizzle = Sizzle; + +})(); diff --git a/samples/src/main/java/gwtquery/samples/public/prototype_logo.gif b/samples/src/main/java/gwtquery/samples/public/prototype_logo.gif deleted file mode 100644 index 0d4f8b50d4a74b0238a3633b1318ff5a7c9f0852..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2659 zcmeH{c~H~W7RPTk5(1b+gF-||XwXp67q(VMYzZ-h#n%QzK~TyP3PHpez@5h;C`D8# z_(VVj5elvm1#w&&wisL^Sj1L*EYgBTNJt1-$@@h*<4mXX-XHJ%*)wzR?{mKQ+?V^<)GR)HmKZZ@8$D|mZ6w7RDG3HD&#-*Eeg$9e zA<(bN(5>00XJ+dCv-Lp-^9&;Uw;rE~E>_2v>9}R;Z56tdQ))rg zwBU?>SFL`3oi4LhmDQlj{z0EpugbfiJ9I($-4)%D%gW8TeYWJl$E!& zRkx(fADe{twN2v5Cb7Kff$m1PvZZ_S)?>}x zM-z9S$nQQ=-Rse|_e^y>*L3#07mLN+eG?CVRzLh%^9Zv3_tF7n@2mH{BZlYCpZ@~c z8};iE*)U|I?}o?Kqhqqs3B&lr^te(d8|;_;_C_X?y;n?6ytqI4LNYluF7IlT|I{I$ zcsJErHg&sP*)3EmWJ;w{bum*V%vY&3D*f#A4{6g48Pl3+^%<_ZI$7OWr=A?0xp{Qv z?Y}fX-P5R5+8uPyA)wn*3u0PAw*CguY!+M>{aFlH*2{u$j8SWGr z?w>PeEHP$KjG1o6H&2Y(w??CJwyVN4Dm6{Kg0Ai_``;@-(IS!NQz#}wAd?x&_G7!# z-8}$+i(>iw6gaf9JvChb>Ewvbk!18sfC9F2S!3hV_zVtb{haq_v$_w!%zEz%^I3lu z@gFp60hAB`7!isgCeAU<%yDzIazuU2?Re1>4xhgc{Y?g_wu^XEQp?)14!Fz5MwnB_mPH1$IP%qxHn zKurJu;aC8I^8u(B0$|w{02Z_Wz_9@!Y&C#GFaGuW8-}?f zWrrY*9~+_MlmhI+spVgAVj zj0red5*zA+h)dTO)3!*2H64fXp9G~8(1UEf5uR8t2{nl5N@f;11U8-TE~N$UlSQyb z#K%G}NU8#_*FUaYmG<_P>uAiwqK)O9RpWIH&uRloKi&G^Mq_A2Xu09Q8&;BSZE{oc zz=P(CFRsRP)s|wv-{s9oe2o>bOQMvWxX!)G`qFRq)yCjHpS%bk(DwO7Ue6Zh!J_%M zmM1>^$E|(8-mWYrSbpJiv%9DMIsx0Z`{u+&anttEYph<2ZF|!u-}P0_*vWIRSF*Dl zZ<%;kI(%n-E&b7JMs{Fr(s*<8{EE1^JPQn|kYE3-JulxSd5i-?I?xyx0v;*%#T_3c z1W*pk6d0oAXW8v&i}}M$%myLI#S#L9b_wC-j6)5f@>|Fe?fzJC_t0@e+=; zF0VdQnESGR9m1)TA+gmowlRwHl5);g278HeNWNrW1m%#O;P7G|riV>kOC>WMW*T?0 z5R`^k2HZdFW%dFOX_CFA6|tmpi@Z^rZCy1=Xs>ff5^g3~z8XAbfm?4HLcrYvdJZp% zd{%>@uBHy=l00ejPP|oXWDfH5K()w*KG)!F7-Er@x$)Pb7e^@2 zIE1#J~?k8Ch3V_-q)VGr}B|}{czqxb`jF+0 z+A+pmzF@JNG#wkR7x~&8c@eX|*f3#% zDt)tkMk`{uPg@7Uf32c3WD{{GbH2ag^!||8YKH$J*6JM^0&Y+B_5qv^p%b^s!NoA| zz7y)xA$A=>fz6T*gxT|~Ww*6=pMDdDeb}>AjKsx+>;B@}k4X3dcTaWS({ix1%>3<>K>o!Iw8ATl;d?5$cD&`}?IDMnC)%EmBb! zsKxkS%I{hk9YRM?)=$cYyF6BQt=vp0@*it=?r(K>i{=~&ZWu19DOVihx*lOa@nGNR j-1(WK<#{qXP~u0LDlTx~2K4u^kKR#~#Ei%L0 - - JQuery - - - - -
- - -

Abstract

- -

Selectors are patterns that match against elements in a - tree. Selectors have been optimized for use with HTML and XML, and - are designed to be usable in performance-critical code.

- -

CSS (Cascading - Style Sheets) is a language for describing the rendering of HTML and XML documents on - screen, on paper, in speech, etc. CSS uses Selectors for binding - style properties to elements in the document. This document - describes extensions to the selectors defined in CSS level 2. These - extended selectors will be used by CSS level 3. - -

Selectors define the following function:

- -
expression ∗ element → boolean
- -

That is, given an element and a selector, this specification - defines whether that element matches the selector.

- -

These expressions can also be used, for instance, to select a set - of elements, or a single element from a set of elements, by - evaluating the expression across all the elements in a - subtree. STTS (Simple Tree Transformation Sheets), a - language for transforming XML trees, uses this mechanism. [STTS]

- -

Status of this document

- -

This section describes the status of this document at the - time of its publication. Other documents may supersede this - document. A list of current W3C publications and the latest revision - of this technical report can be found in the W3C technical reports index at - http://www.w3.org/TR/.

- -

This document describes the selectors that already exist in CSS1 and CSS2, and - also proposes new selectors for CSS3 and other languages that may need them.

- -

The CSS Working Group doesn't expect that all implementations of - CSS3 will have to implement all selectors. Instead, there will - probably be a small number of variants of CSS3, called profiles. For - example, it may be that only a profile for interactive user agents - will include all of the selectors.

- -

This specification is a last call working draft for the the CSS Working Group - (Style Activity). This - document is a revision of the Candidate - Recommendation dated 2001 November 13, and has incorporated - implementation feedback received in the past few years. It is - expected that this last call will proceed straight to Proposed - Recommendation stage since it is believed that interoperability will - be demonstrable.

- -

All persons are encouraged to review and implement this - specification and return comments to the (archived) - public mailing list www-style - (see instructions). W3C - Members can also send comments directly to the CSS Working - Group. - The deadline for comments is 14 January 2006.

- -

This is still a draft document and may be updated, replaced, or - obsoleted by other documents at any time. It is inappropriate to - cite a W3C Working Draft as other than "work in progress". - -

This document may be available in translation. - The English version of this specification is the only normative - version. - -

- -

Table of contents

- - - -
- -

1. Introduction

- -

1.1. Dependencies

- -

Some features of this specification are specific to CSS, or have - particular limitations or rules specific to CSS. In this - specification, these have been described in terms of CSS2.1. [CSS21]

- -

1.2. Terminology

- -

All of the text of this specification is normative except - examples, notes, and sections explicitly marked as - non-normative.

- -

1.3. Changes from CSS2

- -

This section is non-normative.

- -

The main differences between the selectors in CSS2 and those in - Selectors are: - -

    - -
  • the list of basic definitions (selector, group of selectors, - simple selector, etc.) has been changed; in particular, what was - referred to in CSS2 as a simple selector is now called a sequence - of simple selectors, and the term "simple selector" is now used for - the components of this sequence -
  • - -
  • an optional namespace component is now allowed in type element - selectors, the universal selector and attribute selectors -
  • - -
  • a new combinator has been - introduced -
  • - -
  • new simple selectors including substring matching attribute - selectors, and new pseudo-classes -
  • - -
  • new pseudo-elements, and introduction of the "::" convention - for pseudo-elements -
  • - -
  • the grammar has been rewritten
  • - -
  • profiles to be added to specifications integrating Selectors - and defining the set of selectors which is actually supported by - each specification -
  • - -
  • Selectors are now a CSS3 Module and an independent - specification; other specifications can now refer to this document - independently of CSS -
  • - -
  • the specification now has its own test suite
  • - -
- -

2. Selectors

- -

This section is non-normative, as it merely summarizes the - following sections.

- -

A Selector represents a structure. This structure can be used as a - condition (e.g. in a CSS rule) that determines which elements a - selector matches in the document tree, or as a flat description of the - HTML or XML fragment corresponding to that structure.

- -

Selectors may range from simple element names to rich contextual - representations.

- -

The following table summarizes the Selector syntax:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PatternMeaningDescribed in sectionFirst defined in CSS level
*any elementUniversal - selector2
Ean element of type EType selector1
E[foo]an E element with a "foo" attributeAttribute - selectors2
E[foo="bar"]an E element whose "foo" attribute value is exactly - equal to "bar" - Attribute - selectors2
E[foo~="bar"]an E element whose "foo" attribute value is a list of - space-separated values, one of which is exactly equal to "bar" - Attribute - selectors2
E[foo^="bar"]an E element whose "foo" attribute value begins exactly - with the string "bar" - Attribute - selectors3
E[foo$="bar"]an E element whose "foo" attribute value ends exactly - with the string "bar" - Attribute - selectors3
E[foo*="bar"]an E element whose "foo" attribute value contains the - substring "bar" - Attribute - selectors3
E[hreflang|="en"]an E element whose "hreflang" attribute has a - hyphen-separated - list of values beginning (from the left) with "en" - Attribute - selectors2
E:rootan E element, root of the documentStructural - pseudo-classes3
E:nth-child(n)an E element, the n-th child of its parentStructural - pseudo-classes3
E:nth-last-child(n)an E element, the n-th child of its parent, counting - from the last one - Structural - pseudo-classes3
E:nth-of-type(n)an E element, the n-th sibling of its typeStructural - pseudo-classes3
E:nth-last-of-type(n)an E element, the n-th sibling of its type, counting - from the last one - Structural - pseudo-classes3
E:first-childan E element, first child of its parentStructural - pseudo-classes2
E:last-childan E element, last child of its parentStructural - pseudo-classes3
E:first-of-typean E element, first sibling of its typeStructural - pseudo-classes3
E:last-of-typean E element, last sibling of its typeStructural - pseudo-classes3
E:only-childan E element, only child of its parentStructural - pseudo-classes3
E:only-of-typean E element, only sibling of its typeStructural - pseudo-classes3
E:emptyan E element that has no children (including text - nodes) - Structural - pseudo-classes3
E:link
E:visited
an E element being the source anchor of a hyperlink of - which the target is not yet visited (:link) or already visited - (:visited) - The link - pseudo-classes1
E:active
E:hover
E:focus
an E element during certain user actionsThe user - action pseudo-classes1 and 2
E:targetan E element being the target of the referring URIThe target - pseudo-class3
E:lang(fr)an element of type E in language "fr" (the document - language specifies how language is determined) - The :lang() - pseudo-class2
E:enabled
E:disabled
a user interface element E which is enabled or - disabled - The UI element states - pseudo-classes3
E:checkeda user interface element E which is checked (for instance a radio-button or checkbox) - The UI element states - pseudo-classes3
E::first-linethe first formatted line of an E elementThe ::first-line - pseudo-element1
E::first-letterthe first formatted letter of an E elementThe ::first-letter - pseudo-element1
E::selectionthe portion of an E element that is currently - selected/highlighted by the user - The UI element - fragments pseudo-elements3
E::beforegenerated content before an E elementThe ::before - pseudo-element2
E::aftergenerated content after an E elementThe ::after - pseudo-element2
E.warningan E element whose class is - "warning" (the document language specifies how class is determined). - Class - selectors1
E#myidan E element with ID equal to "myid".ID - selectors1
E:not(s)an E element that does not match simple selector sNegation - pseudo-class3
E Fan F element descendant of an E elementDescendant - combinator1
E > Fan F element child of an E elementChild - combinator2
E + Fan F element immediately preceded by an E elementAdjacent sibling combinator - 2
E ~ Fan F element preceded by an E elementGeneral sibling combinator - 3
- -

The meaning of each selector is derived from the table above by - prepending "matches" to the contents of each cell in the "Meaning" - column.

- -

3. Case sensitivity

- -

The case sensitivity of document language element names, attribute - names, and attribute values in selectors depends on the document - language. For example, in HTML, element names are case-insensitive, - but in XML, they are case-sensitive.

- -

4. Selector syntax

- -

A selector is a chain of one - or more sequences of simple selectors - separated by combinators.

- -

A sequence of simple selectors - is a chain of simple selectors - that are not separated by a combinator. It - always begins with a type selector or a - universal selector. No other type - selector or universal selector is allowed in the sequence.

- -

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, content selector, or pseudo-class. One pseudo-element may be appended to the last - sequence of simple selectors.

- -

Combinators are: white space, "greater-than - sign" (U+003E, >), "plus sign" (U+002B, - +) and "tilde" (U+007E, ~). White - space may appear between a combinator and the simple selectors around - it. Only the characters "space" (U+0020), "tab" - (U+0009), "line feed" (U+000A), "carriage return" (U+000D), and "form - feed" (U+000C) can occur in white space. Other space-like characters, - such as "em-space" (U+2003) and "ideographic space" (U+3000), are - never part of white space.

- -

The elements of a document tree that are represented by a selector - are the subjects of the selector. A - selector consisting of a single sequence of simple selectors - represents any element satisfying its requirements. Prepending another - sequence of simple selectors and a combinator to a sequence imposes - additional matching constraints, so the subjects of a selector are - always a subset of the elements represented by the last sequence of - simple selectors.

- -

An empty selector, containing no sequence of simple selectors and - no pseudo-element, is an invalid - selector.

- -

5. Groups of selectors

- -

When several selectors share the same declarations, they may be - grouped into a comma-separated list. (A comma is U+002C.)

- -
-

CSS examples:

- -

In this example, we condense three rules with identical - declarations into one. Thus,

-
h1 { font-family: sans-serif }
-h2 { font-family: sans-serif }
-h3 { font-family: sans-serif }
-

is equivalent to:

-
h1, h2, h3 { font-family: sans-serif }
-
- -

Warning: the equivalence is true in this example - because all the selectors are valid selectors. If just one of these - selectors were invalid, the entire group of selectors would be - invalid. This would invalidate the rule for all three heading - elements, whereas in the former case only one of the three individual - heading rules would be invalidated.

- - -

6. Simple selectors

- -

6.1. Type selector

- -

A type selector is the name of a document language - element type. A type selector represents an instance of the element - type in the document tree.

- -
-

Example:

- -

The following selector represents an h1 element in the - document tree:

-
h1
-
- - -

6.1.1. Type selectors and namespaces

- -

Type selectors allow an optional namespace ([XMLNAMES]) component. A namespace prefix - that has been previously declared may be prepended to the element name - separated by the namespace separator "vertical bar" - (U+007C, |).

- -

The namespace component may be left empty to indicate that the - selector is only to represent elements with no declared namespace.

- -

An asterisk may be used for the namespace prefix, indicating that - the selector represents elements in any namespace (including elements - with no namespace).

- -

Element type selectors that have no namespace component (no - namespace separator), represent elements without regard to the - element's namespace (equivalent to "*|") unless a default - namespace has been declared. If a default namespace has been declared, - the selector will represent only elements in the default - namespace.

- -

A type selector containing a namespace prefix that has not been - previously declared is an invalid selector. - The mechanism for declaring a namespace prefix is left up to the - language implementing Selectors. In CSS, such a mechanism is defined - in the General Syntax module.

- -

In a namespace-aware client, element type selectors will only match - against the local - part - of the element's qualified - name. See below for notes about matching - behaviors in down-level clients.

- -

In summary:

- -
-
ns|E
-
elements with name E in namespace ns
-
*|E
-
elements with name E in any namespace, including those without any - declared namespace -
-
|E
-
elements with name E without any declared namespace
-
E
-
if no default namespace has been specified, this is equivalent to *|E. - Otherwise it is equivalent to ns|E where ns is the default namespace. -
-
- -
-

CSS examples:

- -
@namespace foo url(http://www.example.com);
- foo|h1 { color: blue }
- foo|* { color: yellow }
- |h1 { color: red }
- *|h1 { color: green }
- h1 { color: green }
- -

The first rule will match only h1 elements in the - "http://www.example.com" namespace.

- -

The second rule will match all elements in the - "http://www.example.com" namespace.

- -

The third rule will match only h1 elements without - any declared namespace.

- -

The fourth rule will match h1 elements in any - namespace (including those without any declared namespace).

- -

The last rule is equivalent to the fourth rule because no default - namespace has been defined.

- -
- -

6.2. Universal selector

- -

The universal selector, written "asterisk" - (*), represents the qualified name of any element - type. It represents any single element in the document tree in any - namespace (including those without any declared namespace) if no - default namespace has been specified. If a default namespace has been - specified, see Universal selector and - Namespaces below.

- -

If the universal selector is not the only component of a sequence - of simple selectors, the * may be omitted.

- -
-

Examples:

-
    -
  • *[hreflang|=en] and [hreflang|=en] are - equivalent, -
  • -
  • *.warning and .warning are equivalent, -
  • -
  • *#myid and #myid are equivalent.
  • -
-
- -

Note: it is recommended that the - *, representing the universal selector, not be - omitted.

- -

6.2.1. Universal selector and namespaces

- -

The universal selector allows an optional namespace component. It - is used as follows:

- -
-
ns|*
-
all elements in namespace ns
-
*|*
-
all elements
-
|*
-
all elements without any declared namespace
-
*
-
if no default namespace has been specified, this is equivalent to *|*. - Otherwise it is equivalent to ns|* where ns is the default namespace. -
-
- -

A universal selector containing a namespace prefix that has not - been previously declared is an invalid - selector. The mechanism for declaring a namespace prefix is left up - to the language implementing Selectors. In CSS, such a mechanism is - defined in the General Syntax module.

- - -

6.3. Attribute selectors

- -

Selectors allow the representation of an element's attributes. When - a selector is used as an expression to match against an element, - attribute selectors must be considered to match an element if that - element has an attribute that matches the attribute represented by the - attribute selector.

- -

6.3.1. Attribute presence and values - selectors

- -

CSS2 introduced four attribute selectors:

- -
-
[att] -
Represents an element with the att attribute, whatever the - value of - the attribute. -
-
[att=val]
-
Represents an element with the att attribute whose value is - exactly - "val". -
-
[att~=val]
-
Represents an element with the att attribute whose value is - a whitespace-separated list of words, one - of - which is exactly "val". If "val" contains whitespace, it will never - represent anything (since the words are separated by - spaces). -
-
[att|=val] -
Represents an element with the att attribute, its value - either - being exactly "val" or beginning with "val" immediately followed by - "-" (U+002D). This is primarily intended to allow language subcode - matches (e.g., the hreflang attribute on the - link element in HTML) as described in RFC 3066 ([RFC3066]). For lang (or - xml:lang) language subcode matching, please see the :lang pseudo-class. -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names and values in selectors depends on - the document language.

- -
- -

Examples:

- -

The following attribute selector represents an h1 - element that carries the title attribute, whatever its - value:

- -
h1[title]
- -

In the following example, the selector represents a - span element whose class attribute has - exactly the value "example":

- -
span[class="example"]
- -

Multiple attribute selectors can be used to represent several - attributes of an element, or several conditions on the same - attribute. Here, the selector represents a span element - whose hello attribute has exactly the value "Cleveland" - and whose goodbye attribute has exactly the value - "Columbus":

- -
span[hello="Cleveland"][goodbye="Columbus"]
- -

The following selectors illustrate the differences between "=" - and "~=". The first selector will represent, for example, the value - "copyright copyleft copyeditor" on a rel attribute. The - second selector will only represent an a element with - an href attribute having the exact value - "http://www.w3.org/".

- -
a[rel~="copyright"]
-a[href="http://www.w3.org/"]
- -

The following selector represents a link element - whose hreflang attribute is exactly "fr".

- -
link[hreflang=fr]
- -

The following selector represents a link element for - which the values of the hreflang attribute begins with - "en", including "en", "en-US", and "en-cockney":

- -
link[hreflang|="en"]
- -

Similarly, the following selectors represents a - DIALOGUE element whenever it has one of two different - values for an attribute character:

- -
DIALOGUE[character=romeo]
-DIALOGUE[character=juliet]
- -
- -

6.3.2. Substring matching attribute - selectors

- -

Three additional attribute selectors are provided for matching - substrings in the value of an attribute:

- -
-
[att^=val]
-
Represents an element with the att attribute whose value - begins - with the prefix "val". -
-
[att$=val] -
Represents an element with the att attribute whose value - ends with - the suffix "val". -
-
[att*=val] -
Represents an element with the att attribute whose value - contains - at least one instance of the substring "val". -
-
- -

Attribute values must be identifiers or strings. The - case-sensitivity of attribute names in selectors depends on the - document language.

- -
-

Examples:

- -

The following selector represents an HTML object, - referencing an - image:

-
object[type^="image/"]
-

The following selector represents an HTML anchor a with an - href attribute whose value ends with ".html".

-
a[href$=".html"]
-

The following selector represents an HTML paragraph with a - title - attribute whose value contains the substring "hello"

-
p[title*="hello"]
-
- -

6.3.3. Attribute selectors and namespaces

- -

Attribute selectors allow an optional namespace component to the - attribute name. A namespace prefix that has been previously declared - may be prepended to the attribute name separated by the namespace - separator "vertical bar" (|). In keeping with - the Namespaces in the XML recommendation, default namespaces do not - apply to attributes, therefore attribute selectors without a namespace - component apply only to attributes that have no declared namespace - (equivalent to "|attr"). An asterisk may be used for the - namespace prefix indicating that the selector is to match all - attribute names without regard to the attribute's namespace. - -

An attribute selector with an attribute name containing a namespace - prefix that has not been previously declared is an invalid selector. The mechanism for - declaring - a namespace prefix is left up to the language implementing Selectors. - In CSS, such a mechanism is defined in the General Syntax module. - -

-

CSS examples:

-
@namespace foo "http://www.example.com";
-[foo|att=val] { color: blue }
-[*|att] { color: yellow }
-[|att] { color: green }
-[att] { color: green }
- -

The first rule will match only elements with the attribute - att in the "http://www.example.com" namespace with the - value "val".

- -

The second rule will match only elements with the attribute - att regardless of the namespace of the attribute - (including no declared namespace).

- -

The last two rules are equivalent and will match only elements - with the attribute att where the attribute is not - declared to be in a namespace.

- -
- -

6.3.4. Default attribute values in DTDs

- -

Attribute selectors represent explicitly set attribute values in - the document tree. Default attribute values may be defined in a DTD or - elsewhere, but cannot always be selected by attribute - selectors. Selectors should be designed so that they work even if the - default values are not included in the document tree.

- -

More precisely, a UA is not required to read an "external - subset" of the DTD but is required to look for default - attribute values in the document's "internal subset." (See [XML10] for definitions of these subsets.)

- -

A UA that recognizes an XML namespace [XMLNAMES] is not required to use its - knowledge of that namespace to treat default attribute values as if - they were present in the document. (For example, an XHTML UA is not - required to use its built-in knowledge of the XHTML DTD.)

- -

Note: Typically, implementations - choose to ignore external subsets.

- -
-

Example:

- -

Consider an element EXAMPLE with an attribute "notation" that has a - default value of "decimal". The DTD fragment might be

- -
<!ATTLIST EXAMPLE notation (decimal,octal) "decimal">
- -

If the style sheet contains the rules

- -
EXAMPLE[notation=decimal] { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

the first rule will not match elements whose "notation" attribute - is set by default, i.e. not set explicitly. To catch all cases, the - attribute selector for the default value must be dropped:

- -
EXAMPLE                   { /*... default property settings ...*/ }
-EXAMPLE[notation=octal]   { /*... other settings...*/ }
- -

Here, because the selector EXAMPLE[notation=octal] is - more specific than the tag - selector alone, the style declarations in the second rule will override - those in the first for elements that have a "notation" attribute value - of "octal". Care has to be taken that all property declarations that - are to apply only to the default case are overridden in the non-default - cases' style rules.

- -
- -

6.4. Class selectors

- -

Working with HTML, authors may use the period (U+002E, - .) notation as an alternative to the ~= - notation when representing the class attribute. Thus, for - HTML, div.value and div[class~=value] have - the same meaning. The attribute value must immediately follow the - "period" (.).

- -

UAs may apply selectors using the period (.) notation in XML - documents if the UA has namespace-specific knowledge that allows it to - determine which attribute is the "class" attribute for the - respective namespace. One such example of namespace-specific knowledge - is the prose in the specification for a particular namespace (e.g. SVG - 1.0 [SVG] describes the SVG - "class" attribute and how a UA should interpret it, and - similarly MathML 1.01 [MATH] describes the MathML - "class" attribute.)

- -
-

CSS examples:

- -

We can assign style information to all elements with - class~="pastoral" as follows:

- -
*.pastoral { color: green }  /* all elements with class~=pastoral */
- -

or just

- -
.pastoral { color: green }  /* all elements with class~=pastoral */
- -

The following assigns style only to H1 elements with - class~="pastoral":

- -
H1.pastoral { color: green }  /* H1 elements with class~=pastoral */
- -

Given these rules, the first H1 instance below would not have - green text, while the second would:

- -
<H1>Not green</H1>
-<H1 class="pastoral">Very green</H1>
- -
- -

To represent a subset of "class" values, each value must be preceded - by a ".", in any order.

- -
- -

CSS example:

- -

The following rule matches any P element whose "class" attribute - has been assigned a list of whitespace-separated values that includes - "pastoral" and "marine":

- -
p.pastoral.marine { color: green }
- -

This rule matches when class="pastoral blue aqua - marine" but does not match for class="pastoral - blue".

- -
- -

Note: Because CSS gives considerable - power to the "class" attribute, authors could conceivably design their - own "document language" based on elements with almost no associated - presentation (such as DIV and SPAN in HTML) and assigning style - information through the "class" attribute. Authors should avoid this - practice since the structural elements of a document language often - have recognized and accepted meanings and author-defined classes may - not.

- -

Note: If an element has multiple - class attributes, their values must be concatenated with spaces - between the values before searching for the class. As of this time the - working group is not aware of any manner in which this situation can - be reached, however, so this behavior is explicitly non-normative in - this specification.

- -

6.5. ID selectors

- -

Document languages may contain attributes that are declared to be - of type ID. What makes attributes of type ID special is that no two - such attributes can have the same value in a document, regardless of - the type of the elements that carry them; whatever the document - language, an ID typed attribute can be used to uniquely identify its - element. In HTML all ID attributes are named "id"; XML applications - may name ID attributes differently, but the same restriction - applies.

- -

An ID-typed attribute of a document language allows authors to - assign an identifier to one element instance in the document tree. W3C - ID selectors represent an element instance based on its identifier. An - ID selector contains a "number sign" (U+0023, - #) immediately followed by the ID value, which must be an - identifier.

- -

Selectors does not specify how a UA knows the ID-typed attribute of - an element. The UA may, e.g., read a document's DTD, have the - information hard-coded or ask the user. - -

-

Examples:

- -

The following ID selector represents an h1 element - whose ID-typed attribute has the value "chapter1":

-
h1#chapter1
-

The following ID selector represents any element whose ID-typed - attribute has the value "chapter1":

-
#chapter1
-

The following selector represents any element whose ID-typed - attribute has the value "z98y".

-
*#z98y
-
- -

Note. In XML 1.0 [XML10], the information about which attribute - contains an element's IDs is contained in a DTD or a schema. When - parsing XML, UAs do not always read the DTD, and thus may not know - what the ID of an element is (though a UA may have namespace-specific - knowledge that allows it to determine which attribute is the ID - attribute for that namespace). If a style sheet designer knows or - suspects that a UA may not know what the ID of an element is, he - should use normal attribute selectors instead: - [name=p371] instead of #p371. Elements in - XML 1.0 documents without a DTD do not have IDs at all.

- -

If an element has multiple ID attributes, all of them must be - treated as IDs for that element for the purposes of the ID - selector. Such a situation could be reached using mixtures of xml:id, - DOM3 Core, XML DTDs, and namespace-specific knowledge.

- -

6.6. Pseudo-classes

- -

The pseudo-class concept is introduced to permit selection based on - information that lies outside of the document tree or that cannot be - expressed using the other simple selectors.

- -

A pseudo-class always consists of a "colon" - (:) followed by the name of the pseudo-class and - optionally by a value between parentheses.

- -

Pseudo-classes are allowed in all sequences of simple selectors - contained in a selector. Pseudo-classes are allowed anywhere in - sequences of simple selectors, after the leading type selector or - universal selector (possibly omitted). Pseudo-class names are - case-insensitive. Some pseudo-classes are mutually exclusive, while - others can be applied simultaneously to the same - element. Pseudo-classes may be dynamic, in the sense that an element - may acquire or lose a pseudo-class while a user interacts with the - document.

- - -

6.6.1. Dynamic pseudo-classes

- -

Dynamic pseudo-classes classify elements on characteristics other - than their name, attributes, or content, in principle characteristics - that cannot be deduced from the document tree.

- -

Dynamic pseudo-classes do not appear in the document source or - document tree.

- - -
The link pseudo-classes: :link and :visited
- -

User agents commonly display unvisited links differently from - previously visited ones. Selectors - provides the pseudo-classes :link and - :visited to distinguish them:

- -
    -
  • The :link pseudo-class applies to links that have - not yet been visited. -
  • -
  • The :visited pseudo-class applies once the link has - been visited by the user. -
  • -
- -

After some amount of time, user agents may choose to return a - visited link to the (unvisited) ':link' state.

- -

The two states are mutually exclusive.

- -
- -

Example:

- -

The following selector represents links carrying class - external and already visited:

- -
a.external:visited
- -
- -

Note: It is possible for style sheet - authors to abuse the :link and :visited pseudo-classes to determine - which sites a user has visited without the user's consent. - -

UAs may therefore treat all links as unvisited links, or implement - other measures to preserve the user's privacy while rendering visited - and unvisited links differently.

- -
The user action pseudo-classes - :hover, :active, and :focus
- -

Interactive user agents sometimes change the rendering in response - to user actions. Selectors provides - three pseudo-classes for the selection of an element the user is - acting on.

- -
    - -
  • The :hover pseudo-class applies while the user - designates an element with a pointing device, but does not activate - it. For example, a visual user agent could apply this pseudo-class - when the cursor (mouse pointer) hovers over a box generated by the - element. User agents not that do not support interactive - media do not have to support this pseudo-class. Some conforming - user agents that support interactive - media may not be able to support this pseudo-class (e.g., a pen - device that does not detect hovering). -
  • - -
  • The :active pseudo-class applies while an element - is being activated by the user. For example, between the times the - user presses the mouse button and releases it. -
  • - -
  • The :focus pseudo-class applies while an element - has the focus (accepts keyboard or mouse events, or other forms of - input). -
  • - -
- -

There may be document language or implementation specific limits on - which elements can become :active or acquire - :focus.

- -

These pseudo-classes are not mutually exclusive. An element may - match several pseudo-classes at the same time.

- -

Selectors doesn't define if the parent of an element that is - ':active' or ':hover' is also in that state.

- -
-

Examples:

-
a:link    /* unvisited links */
-a:visited /* visited links */
-a:hover   /* user hovers */
-a:active  /* active links */
-

An example of combining dynamic pseudo-classes:

-
a:focus
-a:focus:hover
-

The last selector matches a elements that are in - the pseudo-class :focus and in the pseudo-class :hover.

-
- -

Note: An element can be both ':visited' - and ':active' (or ':link' and ':active').

- -

6.6.2. The target pseudo-class :target

- -

Some URIs refer to a location within a resource. This kind of URI - ends with a "number sign" (#) followed by an anchor - identifier (called the fragment identifier).

- -

URIs with fragment identifiers link to a certain element within the - document, known as the target element. For instance, here is a URI - pointing to an anchor named section_2 in an HTML - document:

- -
http://example.com/html/top.html#section_2
- -

A target element can be represented by the :target - pseudo-class. If the document's URI has no fragment identifier, then - the document has no target element.

- -
-

Example:

-
p.note:target
-

This selector represents a p element of class - note that is the target element of the referring - URI.

-
- -
-

CSS example:

- -

Here, the :target pseudo-class is used to make the - target element red and place an image before it, if there is one:

-
*:target { color : red }
-*:target::before { content : url(target.png) }
-
- -

6.6.3. The language pseudo-class :lang

- -

If the document language specifies how the human language of an - element is determined, it is possible to write selectors that - represent an element based on its language. For example, in HTML [HTML4], the language is determined by a - combination of the lang attribute, the meta - element, and possibly by information from the protocol (such as HTTP - headers). XML uses an attribute called xml:lang, and - there may be other document language-specific methods for determining - the language.

- -

The pseudo-class :lang(C) represents an element that - is in language C. Whether an element is represented by a - :lang() selector is based solely on the identifier C - being either equal to, or a hyphen-separated substring of, the - element's language value, in the same way as if performed by the '|=' operator in attribute - selectors. The identifier C does not have to be a valid language - name.

- -

C must not be empty. (If it is, the selector is invalid.)

- -

Note: It is recommended that - documents and protocols indicate language using codes from RFC 3066 [RFC3066] or its successor, and by means of - "xml:lang" attributes in the case of XML-based documents [XML10]. See - "FAQ: Two-letter or three-letter language codes."

- -
-

Examples:

- -

The two following selectors represent an HTML document that is in - Belgian, French, or German. The two next selectors represent - q quotations in an arbitrary element in Belgian, French, - or German.

-
html:lang(fr-be)
-html:lang(de)
-:lang(fr-be) > q
-:lang(de) > q
-
- -

6.6.4. The UI element states pseudo-classes

- -
The :enabled and :disabled pseudo-classes
- -

The :enabled pseudo-class allows authors to customize - the look of user interface elements that are enabled — which the - user can select or activate in some fashion (e.g. clicking on a button - with a mouse). There is a need for such a pseudo-class because there - is no way to programmatically specify the default appearance of say, - an enabled input element without also specifying what it - would look like when it was disabled.

- -

Similar to :enabled, :disabled allows the - author to specify precisely how a disabled or inactive user interface - element should look.

- -

Most elements will be neither enabled nor disabled. An element is - enabled if the user can either activate it or transfer the focus to - it. An element is disabled if it could be enabled, but the user cannot - presently activate it or transfer focus to it.

- - -
The :checked pseudo-class
- -

Radio and checkbox elements can be toggled by the user. Some menu - items are "checked" when the user selects them. When such elements are - toggled "on" the :checked pseudo-class applies. The - :checked pseudo-class initially applies to such elements - that have the HTML4 selected and checked - attributes as described in Section - 17.2.1 of HTML4, but of course the user can toggle "off" such - elements in which case the :checked pseudo-class would no - longer apply. While the :checked pseudo-class is dynamic - in nature, and is altered by user action, since it can also be based - on the presence of the semantic HTML4 selected and - checked attributes, it applies to all media. - - -

The :indeterminate pseudo-class
- -
- -

Radio and checkbox elements can be toggled by the user, but are - sometimes in an indeterminate state, neither checked nor unchecked. - This can be due to an element attribute, or DOM manipulation.

- -

A future version of this specification may introduce an - :indeterminate pseudo-class that applies to such elements. -

- -
- - -

6.6.5. Structural pseudo-classes

- -

Selectors introduces the concept of structural - pseudo-classes to permit selection based on extra information that - lies in - the document tree but cannot be represented by other simple selectors or - combinators. - -

Note that standalone pieces of PCDATA (text nodes in the DOM) are - not counted when calculating the position of an element in the list of - children of its parent. When calculating the position of an element in - the list of children of its parent, the index numbering starts at 1. - - -

:root pseudo-class
- -

The :root pseudo-class represents an element that is - the root of the document. In HTML 4, this is always the - HTML element. - - -

:nth-child() pseudo-class
- -

The - :nth-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - before it in the document tree, for a given positive - integer or zero value of n, and has a parent element. In - other words, this matches the bth child of an element after - all the children have been split into groups of a elements - each. For example, this allows the selectors to address every other - row in a table, and could be used to alternate the color - of paragraph text in a cycle of four. The a and - b values must be zero, negative integers or positive - integers. The index of the first child of an element is 1. - -

In addition to this, :nth-child() can take - 'odd' and 'even' as arguments instead. - 'odd' has the same signification as 2n+1, - and 'even' has the same signification as 2n. - - -

-

Examples:

-
tr:nth-child(2n+1) /* represents every odd row of an HTML table */
-tr:nth-child(odd)  /* same */
-tr:nth-child(2n)   /* represents every even row of an HTML table */
-tr:nth-child(even) /* same */
-
-/* Alternate paragraph colours in CSS */
-p:nth-child(4n+1) { color: navy; }
-p:nth-child(4n+2) { color: green; }
-p:nth-child(4n+3) { color: maroon; }
-p:nth-child(4n+4) { color: purple; }
-
- -

When a=0, no repeating is used, so for example - :nth-child(0n+5) matches only the fifth child. When - a=0, the an part need not be - included, so the syntax simplifies to - :nth-child(b) and the last example simplifies - to :nth-child(5). - -

-

Examples:

-
foo:nth-child(0n+1)   /* represents an element foo, first child of its parent element */
-foo:nth-child(1)      /* same */
-
- -

When a=1, the number may be omitted from the rule. - -

-

Examples:

- -

The following selectors are therefore equivalent:

-
bar:nth-child(1n+0)   /* represents all bar elements, specificity (0,1,1) */
-bar:nth-child(n+0)    /* same */
-bar:nth-child(n)      /* same */
-bar                   /* same but lower specificity (0,0,1) */
-
- -

If b=0, then every ath element is picked. In - such a case, the b part may be omitted. - -

-

Examples:

-
tr:nth-child(2n+0) /* represents every even row of an HTML table */
-tr:nth-child(2n) /* same */
-
- -

If both a and b are equal to zero, the - pseudo-class represents no element in the document tree.

- -

The value a can be negative, but only the positive - values of an+b, for - n≥0, may represent an element in the document - tree.

- -
-

Example:

-
html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */
-
- -

When the value b is negative, the "+" character in the - expression must be removed (it is effectively replaced by the "-" - character indicating the negative value of b).

- -
-

Examples:

-
:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc, element */
-:nth-child(10n+9)  /* Same */
-:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */
-
- - -
:nth-last-child() pseudo-class
- -

The :nth-last-child(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings - after it in the document tree, for a given positive - integer or zero value of n, and has a parent element. See - :nth-child() pseudo-class for the syntax of its argument. - It also accepts the 'even' and 'odd' values - as arguments. - - -

-

Examples:

-
tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */
-
-foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
-                              counting from the last one */
-
- - -
:nth-of-type() pseudo-class
- -

The :nth-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name before it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. In other words, this matches the bth child - of that type after all the children of that type have been split into - groups of a elements each. See :nth-child() pseudo-class - for the syntax of its argument. It also accepts the - 'even' and 'odd' values. - - -

-

CSS example:

- -

This allows an author to alternate the position of floated images:

-
img:nth-of-type(2n+1) { float: right; }
-img:nth-of-type(2n) { float: left; }
-
- - -
:nth-last-of-type() pseudo-class
- -

The :nth-last-of-type(an+b) - pseudo-class notation represents an element that has - an+b-1 siblings with the same - element name after it in the document tree, for a - given zero or positive integer value of n, and has a - parent element. See :nth-child() pseudo-class for the - syntax of its argument. It also accepts the 'even' and 'odd' - values. - - -

-

Example:

- -

To represent all h2 children of an XHTML - body except the first and last, one could use the - following selector:

-
body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
-

In this case, one could also use :not(), although the - selector ends up being just as long:

-
body > h2:not(:first-of-type):not(:last-of-type)
-
- - -
:first-child pseudo-class
- -

Same as :nth-child(1). The :first-child - pseudo-class - represents an element that is the first child of some other element. - - -

-

Examples:

- -

The following selector represents a p element that is - the first child of a div element:

-
div > p:first-child
-

This selector can represent the p inside the - div of the following fragment:

-
<p> The last P before the note.</p>
-<div class="note">
-   <p> The first P inside the note.</p>
-</div>
- but cannot represent the second p in the following - fragment: -
<p> The last P before the note.</p>
-<div class="note">
-   <h2> Note </h2>
-   <p> The first P inside the note.</p>
-</div>
-

The following two selectors are usually equivalent:

-
* > a:first-child /* a is first child of any element */
-a:first-child /* Same (assuming a is not the root element) */
-
- -
:last-child pseudo-class
- -

Same as :nth-last-child(1). The :last-child - pseudo-class - represents an element that is the last child of some other element. - -

-

Example:

- -

The following selector represents a list item li that - is the last child of an ordered list ol. -

ol > li:last-child
-
- -
:first-of-type pseudo-class
- -

Same as :nth-of-type(1). The :first-of-type - pseudo-class - represents an element that is the first sibling of its type in the list of - children of its parent element. - -

-

Example:

- -

The following selector represents a definition title - dt inside a definition list dl, this - dt being the first of its type in the list of children of - its parent element.

-
dl dt:first-of-type
-

It is a valid description for the first two dt - elements in the following example but not for the third one:

-
<dl>
- <dt>gigogne</dt>
- <dd>
-  <dl>
-   <dt>fusée</dt>
-   <dd>multistage rocket</dd>
-   <dt>table</dt>
-   <dd>nest of tables</dd>
-  </dl>
- </dd>
-</dl>
-
- -
:last-of-type pseudo-class
- -

Same as :nth-last-of-type(1). The - :last-of-type pseudo-class represents an element that is - the last sibling of its type in the list of children of its parent - element.

- -
-

Example:

- -

The following selector represents the last data cell - td of a table row.

-
tr > td:last-of-type
-
- -
:only-child pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children. Same as - :first-child:last-child or - :nth-child(1):nth-last-child(1), but with a lower - specificity.

- -
:only-of-type pseudo-class
- -

Represents an element that has a parent element and whose parent - element has no other element children with the same element name. Same - as :first-of-type:last-of-type or - :nth-of-type(1):nth-last-of-type(1), but with a lower - specificity.

- - -
:empty pseudo-class
- -

The :empty pseudo-class represents an element that has - no children at all. In terms of the DOM, only element nodes and text - nodes (including CDATA nodes and entity references) whose data has a - non-zero length must be considered as affecting emptiness; comments, - PIs, and other nodes must not affect whether an element is considered - empty or not.

- -
-

Examples:

- -

p:empty is a valid representation of the following fragment: -

-
<p></p>
-

foo:empty is not a valid representation for the - following fragments:

-
<foo>bar</foo>
-
<foo><bar>bla</bar></foo>
-
<foo>this is not <bar>:empty</bar></foo>
-
- -

6.6.6. Blank

- - -

This section intentionally left blank.

- - -

6.6.7. The negation pseudo-class

- -

The negation pseudo-class, :not(X), is a - functional notation taking a simple - selector (excluding the negation pseudo-class itself and - pseudo-elements) as an argument. It represents an element that is not - represented by the argument. - - - -

-

Examples:

- -

The following CSS selector matches all button - elements in an HTML document that are not disabled.

-
button:not([DISABLED])
-

The following selector represents all but FOO - elements.

-
*:not(FOO)
-

The following group of selectors represents all HTML elements - except links.

-
html|*:not(:link):not(:visited)
-
- -

Default namespace declarations do not affect the argument of the - negation pseudo-class unless the argument is a universal selector or a - type selector.

- -
-

Examples:

- -

Assuming that the default namespace is bound to - "http://example.com/", the following selector represents all - elements that are not in that namespace:

-
*|*:not(*)
-

The following CSS selector matches any element being hovered, - regardless of its namespace. In particular, it is not limited to - only matching elements in the default namespace that are not being - hovered, and elements not in the default namespace don't match the - rule when they are being hovered.

-
*|*:not(:hover)
-
- -

Note: the :not() pseudo allows - useless selectors to be written. For instance :not(*|*), - which represents no element at all, or foo:not(bar), - which is equivalent to foo but with a higher - specificity.

- -

7. Pseudo-elements

- -

Pseudo-elements create abstractions about the document tree beyond - those specified by the document language. For instance, document - languages do not offer mechanisms to access the first letter or first - line of an element's content. Pseudo-elements allow designers to refer - to this otherwise inaccessible information. Pseudo-elements may also - provide designers a way to refer to content that does not exist in the - source document (e.g., the ::before and - ::after pseudo-elements give access to generated - content).

- -

A pseudo-element is made of two colons (::) followed - by the name of the pseudo-element.

- -

This :: notation is introduced by the current document - in order to establish a discrimination between pseudo-classes and - pseudo-elements. For compatibility with existing style sheets, user - agents must also accept the previous one-colon notation for - pseudo-elements introduced in CSS levels 1 and 2 (namely, - :first-line, :first-letter, - :before and :after). This compatibility is - not allowed for the new pseudo-elements introduced in CSS level 3.

- -

Only one pseudo-element may appear per selector, and if present it - must appear after the sequence of simple selectors that represents the - subjects of the selector. A -future version of this specification may allow multiple -pesudo-elements per selector.

- -

7.1. The ::first-line pseudo-element

- -

The ::first-line pseudo-element describes the contents - of the first formatted line of an element. - -

-

CSS example:

-
p::first-line { text-transform: uppercase }
-

The above rule means "change the letters of the first line of every - paragraph to uppercase".

-
- -

The selector p::first-line does not match any real - HTML element. It does match a pseudo-element that conforming user - agents will insert at the beginning of every paragraph.

- -

Note that the length of the first line depends on a number of - factors, including the width of the page, the font size, etc. Thus, - an ordinary HTML paragraph such as:

- -
-<P>This is a somewhat long HTML 
-paragraph that will be broken into several 
-lines. The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the lines of which happen to be broken as follows: - -

-THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
-will be broken into several lines. The first
-line will be identified by a fictional tag 
-sequence. The other lines will be treated as 
-ordinary lines in the paragraph.
-
- -

This paragraph might be "rewritten" by user agents to include the - fictional tag sequence for ::first-line. This - fictional tag sequence helps to show how properties are inherited.

- -
-<P><P::first-line> This is a somewhat long HTML 
-paragraph that </P::first-line> will be broken into several
-lines. The first line will be identified 
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

If a pseudo-element breaks up a real element, the desired effect - can often be described by a fictional tag sequence that closes and - then re-opens the element. Thus, if we mark up the previous paragraph - with a span element:

- -
-<P><SPAN class="test"> This is a somewhat long HTML
-paragraph that will be broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines 
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

the user agent could simulate start and end tags for - span when inserting the fictional tag sequence for - ::first-line. - -

-<P><P::first-line><SPAN class="test"> This is a
-somewhat long HTML
-paragraph that will </SPAN></P::first-line><SPAN
-    class="test"> be
-broken into several
-lines.</SPAN> The first line will be identified
-by a fictional tag sequence. The other lines
-will be treated as ordinary lines in the 
-paragraph.</P>
-
- -

In CSS, the ::first-line pseudo-element can only be - attached to a block-level element, an inline-block, a table-caption, - or a table-cell.

- -

The "first formatted line" of an - element may occur inside a - block-level descendant in the same flow (i.e., a block-level - descendant that is not positioned and not a float). E.g., the first - line of the div in <DIV><P>This - line...</P></DIV> is the first line of the p - (assuming - that both p and div are block-level). - -

The first line of a table-cell or inline-block cannot be the first - formatted line of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first formatted line of the - div is not the line "Hello". - -

Note that the first line of the p in this - fragment: <p><br>First... doesn't contain any - letters (assuming the default style for br in HTML - 4). The word "First" is not on the first formatted line. - -

A UA should act as if the fictional start tags of the - ::first-line pseudo-elements were nested just inside the - innermost enclosing block-level element. (Since CSS1 and CSS2 were - silent on this case, authors should not rely on this behavior.) Here - is an example. The fictional tag sequence for

- -
-<DIV>
-  <P>First paragraph</P>
-  <P>Second paragraph</P>
-</DIV>
-
- -

is

- -
-<DIV>
-  <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
-  <P><P::first-line>Second paragraph</P::first-line></P>
-</DIV>
-
- -

The ::first-line pseudo-element is similar to an - inline-level element, but with certain restrictions. In CSS, the - following properties apply to a ::first-line - pseudo-element: font properties, color property, background - properties, 'word-spacing', 'letter-spacing', 'text-decoration', - 'vertical-align', 'text-transform', 'line-height'. UAs may apply other - properties as well.

- - -

7.2. The ::first-letter pseudo-element

- -

The ::first-letter pseudo-element represents the first - letter of the first line of a block, if it is not preceded by any - other content (such as images or inline tables) on its line. The - ::first-letter pseudo-element may be used for "initial caps" and "drop - caps", which are common typographical effects. This type of initial - letter is similar to an inline-level element if its 'float' property - is 'none'; otherwise, it is similar to a floated element.

- -

In CSS, these are the properties that apply to ::first-letter - pseudo-elements: font properties, 'text-decoration', 'text-transform', - 'letter-spacing', 'word-spacing' (when appropriate), 'line-height', - 'float', 'vertical-align' (only if 'float' is 'none'), margin - properties, padding properties, border properties, color property, - background properties. UAs may apply other properties as well. To - allow UAs to render a typographically correct drop cap or initial cap, - the UA may choose a line-height, width and height based on the shape - of the letter, unlike for normal elements.

- -
-

Example:

- -

This example shows a possible rendering of an initial cap. Note - that the 'line-height' that is inherited by the - ::first-letter - pseudo-element is 1.1, but the UA in this example has computed the - height of the first letter differently, so that it doesn't cause any - unnecessary space between the first two lines. Also note that the - fictional start tag of the first letter is inside the span, - and thus - the font weight of the first letter is normal, not bold as the span: -

-p { line-height: 1.1 }
-p::first-letter { font-size: 3em; font-weight: normal }
-span { font-weight: bold }
-...
-<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>
-Erbarremt over my en mijn benaeuwde vesten<br>
-En arme burgery, en op mijn volcx gebed<br>
-En dagelix geschrey de bange stad ontzet.
-
-
-

Image illustrating the ::first-letter pseudo-element -

-
- -
-

The following CSS will make a drop cap initial letter span about two - lines:

- -
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
-<HTML>
- <HEAD>
-  <TITLE>Drop cap initial letter</TITLE>
-  <STYLE type="text/css">
-   P               { font-size: 12pt; line-height: 1.2 }
-   P::first-letter { font-size: 200%; font-weight: bold; float: left }
-   SPAN            { text-transform: uppercase }
-  </STYLE>
- </HEAD>
- <BODY>
-  <P><SPAN>The first</SPAN> few words of an article
-    in The Economist.</P>
- </BODY>
-</HTML>
-
- -

This example might be formatted as follows:

- -
-

Image illustrating the combined effect of the ::first-letter and ::first-line pseudo-elements -

-
- -

The fictional tag sequence is:

- -
-<P>
-<SPAN>
-<P::first-letter>
-T
-</P::first-letter>he first
-</SPAN> 
-few words of an article in the Economist.
-</P>
-
- -

Note that the ::first-letter pseudo-element tags abut - the content (i.e., the initial character), while the ::first-line - pseudo-element start tag is inserted right after the start tag of the - block element.

- -

In order to achieve traditional drop caps formatting, user agents - may approximate font sizes, for example to align baselines. Also, the - glyph outline may be taken into account when formatting.

- -

Punctuation (i.e, characters defined in Unicode in the "open" (Ps), - "close" (Pe), "initial" (Pi). "final" (Pf) and "other" (Po) - punctuation classes), that precedes or follows the first letter should - be included. [UNICODE]

- -
-

Quotes that precede the
-first letter should be included.

-
- -

The ::first-letter also applies if the first letter is - in fact a digit, e.g., the "6" in "67 million dollars is a lot of - money."

- -

In CSS, the ::first-letter pseudo-element applies to - block, list-item, table-cell, table-caption, and inline-block - elements. A future version of this specification -may allow this pesudo-element to apply to more element -types.

- -

The ::first-letter pseudo-element can be used with all - such elements that contain text, or that have a descendant in the same - flow that contains text. A UA should act as if the fictional start tag - of the ::first-letter pseudo-element is just before the first text of - the element, even if that first text is in a descendant.

- -
-

Example:

- -

The fictional tag sequence for this HTMLfragment: -

<div>
-<p>The first text.
-

is: -

<div>
-<p><div::first-letter><p::first-letter>T</...></...>he first text.
-
- -

The first letter of a table-cell or inline-block cannot be the - first letter of an ancestor element. Thus, in <DIV><P - STYLE="display: inline-block">Hello<BR>Goodbye</P> - etcetera</DIV> the first letter of the div is - not the - letter "H". In fact, the div doesn't have a first letter. - -

The first letter must occur on the first formatted line. For example, in - this fragment: <p><br>First... the first line - doesn't contain any letters and ::first-letter doesn't - match anything (assuming the default style for br in HTML - 4). In particular, it does not match the "F" of "First." - -

In CSS, if an element is a list item ('display: list-item'), the - ::first-letter applies to the first letter in the - principal box after the marker. UAs may ignore - ::first-letter on list items with 'list-style-position: - inside'. If an element has ::before or - ::after content, the ::first-letter applies - to the first letter of the element including that content. - -

-

Example:

- -

After the rule 'p::before {content: "Note: "}', the selector - 'p::first-letter' matches the "N" of "Note".

-
- -

Some languages may have specific rules about how to treat certain - letter combinations. In Dutch, for example, if the letter combination - "ij" appears at the beginning of a word, both letters should be - considered within the ::first-letter pseudo-element. - -

If the letters that would form the ::first-letter are not in the - same element, such as "'T" in <p>'<em>T..., the UA - may create a ::first-letter pseudo-element from one of the elements, - both elements, or simply not create a pseudo-element.

- -

Similarly, if the first letter(s) of the block are not at the start - of the line (for example due to bidirectional reordering), then the UA - need not create the pseudo-element(s). - -

-

Example:

- -

The following example illustrates - how overlapping pseudo-elements may interact. The first letter of - each P element will be green with a font size of '24pt'. The rest of - the first formatted line will be 'blue' while the rest of the - paragraph will be 'red'.

- -
p { color: red; font-size: 12pt }
-p::first-letter { color: green; font-size: 200% }
-p::first-line { color: blue }
-
-<P>Some text that ends up on two lines</P>
- -

Assuming that a line break will occur before the word "ends", the -fictional tag -sequence for this fragment might be:

- -
<P>
-<P::first-line>
-<P::first-letter> 
-S 
-</P::first-letter>ome text that 
-</P::first-line> 
-ends up on two lines 
-</P>
- -

Note that the ::first-letter element is inside the ::first-line - element. Properties set on ::first-line are inherited by - ::first-letter, but are overridden if the same property is - set on - ::first-letter.

-
- - -

7.3. The ::selection - pseudo-element

- -

The ::selection pseudo-element applies to the portion - of a document that has been highlighted by the user. This also - applies, for example, to selected text within an editable text - field. This pseudo-element should not be confused with the :checked pseudo-class (which used to be - named :selected) - -

Although the ::selection pseudo-element is dynamic in - nature, and is altered by user action, it is reasonable to expect that - when a UA re-renders to a static medium (such as a printed page, see - [CSS21]) which was originally rendered to a - dynamic medium (like screen), the UA may wish to transfer the current - ::selection state to that other medium, and have all the - appropriate formatting and rendering take effect as well. This is not - required — UAs may omit the ::selection - pseudo-element for static media. - -

These are the CSS properties that apply to ::selection - pseudo-elements: color, background, cursor (optional), outline - (optional). The computed value of the 'background-image' property on - ::selection may be ignored. - - -

7.4. The ::before and ::after pseudo-elements

- -

The ::before and ::after pseudo-elements - can be used to describe generated content before or after an element's - content. They are explained in CSS 2.1 [CSS21].

- -

When the ::first-letter and ::first-line - pseudo-elements are combined with ::before and - ::after, they apply to the first letter or line of the - element including the inserted text.

- -

8. Combinators

- -

8.1. Descendant combinator

- -

At times, authors may want selectors to describe an element that is - the descendant of another element in the document tree (e.g., "an - EM element that is contained within an H1 - element"). Descendant combinators express such a relationship. A - descendant combinator is white space that - separates two sequences of simple selectors. A selector of the form - "A B" represents an element B that is an - arbitrary descendant of some ancestor element A. - -

-

Examples:

- -

For example, consider the following selector:

-
h1 em
-

It represents an em element being the descendant of - an h1 element. It is a correct and valid, but partial, - description of the following fragment:

-
<h1>This <span class="myclass">headline
-is <em>very</em> important</span></h1>
-

The following selector:

-
div * p
-

represents a p element that is a grandchild or later - descendant of a div element. Note the whitespace on - either side of the "*" is not part of the universal selector; the - whitespace is a combinator indicating that the DIV must be the - ancestor of some element, and that that element must be an ancestor - of the P.

- -

The following selector, which combines descendant combinators and - attribute selectors, represents an - element that (1) has the href attribute set and (2) is - inside a p that is itself inside a div:

-
div p *[href]
-
- -

8.2. Child combinators

- -

A child combinator describes a childhood relationship - between two elements. A child combinator is made of the - "greater-than sign" (>) character and - separates two sequences of simple selectors. - - -

-

Examples:

- -

The following selector represents a p element that is - child of body:

-
body > p
-

The following example combines descendant combinators and child - combinators.

-
div ol>li p
- -

It represents a p element that is a descendant of an - li element; the li element must be the - child of an ol element; the ol element must - be a descendant of a div. Notice that the optional white - space around the ">" combinator has been left out.

-
- -

For information on selecting the first child of an element, please - see the section on the :first-child pseudo-class - above.

- -

8.3. Sibling combinators

- -

There are two different sibling combinators: the adjacent sibling - combinator and the general sibling combinator. In both cases, - non-element nodes (e.g. text between elements) are ignored when - considering adjacency of elements.

- -

8.3.1. Adjacent sibling combinator -

- -

The adjacent sibling combinator is made of the "plus - sign" (U+002B, +) character that separates two - sequences of simple selectors. The elements represented by the two - sequences share the same parent in the document tree and the element - represented by the first sequence immediately precedes the element - represented by the second one.

- -
-

Examples:

- -

The following selector represents a p element - immediately following a math element:

-
math + p
-

The following selector is conceptually similar to the one in the - previous example, except that it adds an attribute selector — it - adds a constraint to the h1 element, that it must have - class="opener":

-
h1.opener + h2
-
- - -

8.3.2. General sibling combinator -

- -

The general sibling combinator is made of the "tilde" - (U+007E, ~) character that separates two sequences of - simple selectors. The elements represented by the two sequences share - the same parent in the document tree and the element represented by - the first sequence precedes (not necessarily immediately) the element - represented by the second one.

- -
-

Example:

-
h1 ~ pre
-

represents a pre element following an h1. It - is a correct and valid, but partial, description of:

-
<h1>Definition of the function a</h1>
-<p>Function a(x) has to be applied to all figures in the table.</p>
-<pre>function a(x) = 12x/13.5</pre>
-
- -

9. Calculating a selector's specificity

- -

A selector's specificity is calculated as follows:

- -
    -
  • count the number of ID selectors in the selector (= a)
  • -
  • count the number of class selectors, attributes selectors, and - pseudo-classes in the selector (= b) -
  • -
  • count the number of element names in the selector (= c)
  • -
  • ignore pseudo-elements
  • -
- -

Selectors inside the negation pseudo-class - are counted like any other, but the negation itself does not count as - a pseudo-class.

- -

Concatenating the three numbers a-b-c (in a number system with a - large base) gives the specificity.

- -
-

Examples:

-
*               /* a=0 b=0 c=0 -> specificity =   0 */
-LI              /* a=0 b=0 c=1 -> specificity =   1 */
-UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
-UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
-H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
-UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
-LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
-#x34y           /* a=1 b=0 c=0 -> specificity = 100 */
-#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */
-
-
- -

Note: the specificity of the styles - specified in an HTML style attribute is described in CSS - 2.1. [CSS21].

- -

10. The grammar of Selectors

- -

10.1. Grammar

- -

The grammar below defines the syntax of Selectors. It is globally - LL(1) and can be locally LL(2) (but note that most UA's should not use - it directly, since it doesn't express the parsing conventions). The - format of the productions is optimized for human consumption and some - shorthand notations beyond Yacc (see [YACC]) - are used:

- -
    -
  • *: 0 or more -
  • +: 1 or more -
  • ?: 0 or 1 -
  • |: separates alternatives -
  • [ ]: grouping
  • -
- -

The productions are:

- -
selectors_group
-  : selector [ COMMA S* selector ]*
-  ;
-
-selector
-  : simple_selector_sequence [ combinator simple_selector_sequence ]*
-  ;
-
-combinator
-  /* combinators can be surrounded by white space */
-  : PLUS S* | GREATER S* | TILDE S* | S+
-  ;
-
-simple_selector_sequence
-  : [ type_selector | universal ]
-    [ HASH | class | attrib | pseudo | negation ]*
-  | [ HASH | class | attrib | pseudo | negation ]+
-  ;
-
-type_selector
-  : [ namespace_prefix ]? element_name
-  ;
-
-namespace_prefix
-  : [ IDENT | '*' ]? '|'
-  ;
-
-element_name
-  : IDENT
-  ;
-
-universal
-  : [ namespace_prefix ]? '*'
-  ;
-
-class
-  : '.' IDENT
-  ;
-
-attrib
-  : '[' S* [ namespace_prefix ]? IDENT S*
-        [ [ PREFIXMATCH |
-            SUFFIXMATCH |
-            SUBSTRINGMATCH |
-            '=' |
-            INCLUDES |
-            DASHMATCH ] S* [ IDENT | STRING ] S*
-        ]? ']'
-  ;
-
-pseudo
-  /* '::' starts a pseudo-element, ':' a pseudo-class */
-  /* Exceptions: :first-line, :first-letter, :before and :after. */
-  /* Note that pseudo-elements are restricted to one per selector and */
-  /* occur only in the last simple_selector_sequence. */
-  : ':' ':'? [ IDENT | functional_pseudo ]
-  ;
-
-functional_pseudo
-  : FUNCTION S* expression ')'
-  ;
-
-expression
-  /* In CSS3, the expressions are identifiers, strings, */
-  /* or of the form "an+b" */
-  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
-  ;
-
-negation
-  : NOT S* negation_arg S* ')'
-  ;
-
-negation_arg
-  : type_selector | universal | HASH | class | attrib | pseudo
-  ;
- - -

10.2. Lexical scanner

- -

The following is the tokenizer, written in Flex (see - [FLEX]) notation. The tokenizer is - case-insensitive.

- -

The two occurrences of "\377" represent the highest character - number that current versions of Flex can deal with (decimal 255). They - should be read as "\4177777" (decimal 1114111), which is the highest - possible code point in Unicode/ISO-10646. [UNICODE]

- -
%option case-insensitive
-
-ident     [-]?{nmstart}{nmchar}*
-name      {nmchar}+
-nmstart   [_a-z]|{nonascii}|{escape}
-nonascii  [^\0-\177]
-unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
-escape    {unicode}|\\[^\n\r\f0-9a-f]
-nmchar    [_a-z0-9-]|{nonascii}|{escape}
-num       [0-9]+|[0-9]*\.[0-9]+
-string    {string1}|{string2}
-string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
-string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
-invalid   {invalid1}|{invalid2}
-invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
-invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
-nl        \n|\r\n|\r|\f
-w         [ \t\r\n\f]*
-
-%%
-
-[ \t\r\n\f]+     return S;
-
-"~="             return INCLUDES;
-"|="             return DASHMATCH;
-"^="             return PREFIXMATCH;
-"$="             return SUFFIXMATCH;
-"*="             return SUBSTRINGMATCH;
-{ident}          return IDENT;
-{string}         return STRING;
-{ident}"("       return FUNCTION;
-{num}            return NUMBER;
-"#"{name}        return HASH;
-{w}"+"           return PLUS;
-{w}">"           return GREATER;
-{w}","           return COMMA;
-{w}"~"           return TILDE;
-":not("          return NOT;
-@{ident}         return ATKEYWORD;
-{invalid}        return INVALID;
-{num}%           return PERCENTAGE;
-{num}{ident}     return DIMENSION;
-"<!--"           return CDO;
-"-->"            return CDC;
-
-"url("{w}{string}{w}")"                           return URI;
-"url("{w}([!#$%&*-~]|{nonascii}|{escape})*{w}")"  return URI;
-U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?                return UNICODE_RANGE;
-
-\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */
-
-.                return *yytext;
- - -

11. Namespaces and down-level clients

- -

An important issue is the interaction of CSS selectors with XML - documents in web clients that were produced prior to this - document. Unfortunately, due to the fact that namespaces must be - matched based on the URI which identifies the namespace, not the - namespace prefix, some mechanism is required to identify namespaces in - CSS by their URI as well. Without such a mechanism, it is impossible - to construct a CSS style sheet which will properly match selectors in - all cases against a random set of XML documents. However, given - complete knowledge of the XML document to which a style sheet is to be - applied, and a limited use of namespaces within the XML document, it - is possible to construct a style sheet in which selectors would match - elements and attributes correctly.

- -

It should be noted that a down-level CSS client will (if it - properly conforms to CSS forward compatible parsing rules) ignore all - @namespace at-rules, as well as all style rules that make - use of namespace qualified element type or attribute selectors. The - syntax of delimiting namespace prefixes in CSS was deliberately chosen - so that down-level CSS clients would ignore the style rules rather - than possibly match them incorrectly.

- -

The use of default namespaces in CSS makes it possible to write - element type selectors that will function in both namespace aware CSS - clients as well as down-level clients. It should be noted that - down-level clients may incorrectly match selectors against XML - elements in other namespaces.

- -

The following are scenarios and examples in which it is possible to - construct style sheets which would function properly in web clients - that do not implement this proposal.

- -
    -
  1. - -

    The XML document does not use namespaces.

    - -
      - -
    • In this case, it is obviously not necessary to declare or use - namespaces in the style sheet. Standard CSS element type and - attribute selectors will function adequately in a down-level - client. -
    • - -
    • In a CSS namespace aware client, the default behavior of - element selectors matching without regard to namespace will - function properly against all elements, since no namespaces are - present. However, the use of specific element type selectors - that - match only elements that have no namespace ("|name") - will guarantee that selectors will match only XML elements that - do - not have a declared namespace. -
    • - -
    - -
  2. - -
  3. - -

    The XML document defines a single, default namespace used - throughout the document. No namespace prefixes are used in element - names.

    - -
      - -
    • In this case, a down-level client will function as if - namespaces were not used in the XML document at all. Standard - CSS - element type and attribute selectors will match against all - elements. -
    • - -
    - -
  4. - -
  5. - -

    The XML document does not use a default namespace, all - namespace prefixes used are known to the style sheet author, and - there is a direct mapping between namespace prefixes and namespace - URIs. (A given prefix may only be mapped to one namespace URI - throughout the XML document; there may be multiple prefixes mapped - to the same URI).

    - -
      - -
    • In this case, the down-level client will view and match - element type and attribute selectors based on their fully - qualified name, not the local part as outlined in the Type selectors and Namespaces - section. CSS - selectors may be declared using an escaped colon - "\:" - to describe the fully qualified names, e.g. - "html\:h1" will match - <html:h1>. Selectors using the qualified name - will only match XML elements that use the same prefix. Other - namespace prefixes used in the XML that are mapped to the same - URI - will not match as expected unless additional CSS style rules are - declared for them. -
    • - -
    • Note that selectors declared in this fashion will - only match in down-level clients. A CSS namespace aware - client will match element type and attribute selectors based on - the name's local part. Selectors declared with the fully - qualified name will not match (unless there is no namespace - prefix - in the fully qualified name). -
    • - -
    - -
  6. - -
- -

In other scenarios: when the namespace prefixes used in the XML are - not known in advance by the style sheet author; or a combination of - elements with no namespace are used in conjunction with elements using - a default namespace; or the same namespace prefix is mapped to - different namespace URIs within the same document, or in - different documents; it is impossible to construct a CSS style sheet - that will function properly against all elements in those documents, - unless, the style sheet is written using a namespace URI syntax (as - outlined in this document or similar) and the document is processed by - a CSS and XML namespace aware client.

- -

12. Profiles

- -

Each specification using Selectors must define the subset of W3C - Selectors it allows and excludes, and describe the local meaning of - all the components of that subset.

- -

Non normative examples: - -

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 1
Acceptstype selectors
class selectors
ID selectors
:link, - :visited and :active pseudo-classes
descendant combinator -
::first-line and ::first-letter pseudo-elements -
Excludes - -

universal selector
attribute selectors
:hover and - :focus - pseudo-classes
:target pseudo-class
:lang() - pseudo-class
all UI - element states pseudo-classes
all structural - pseudo-classes
negation pseudo-class
all - UI element fragments pseudo-elements
::before and ::after - pseudo-elements
child combinators
sibling combinators - -

namespaces

Extra constraintsonly one class selector allowed per sequence of simple - selectors -
-

- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationCSS level 2
Acceptstype selectors
universal selector
attribute presence and - values selectors
class selectors
ID selectors
:link, - :visited, - :active, :hover, :focus, :lang() and :first-child pseudo-classes -
descendant combinator
child combinator
adjacent - sibling - combinator
::first-line and ::first-letter - pseudo-elements
::before - and ::after pseudo-elements -
Excludes - -

content selectors
substring matching attribute - selectors
:target pseudo-classes
all UI element - states pseudo-classes
all structural pseudo-classes other - than :first-child
negation pseudo-class
all UI element - fragments pseudo-elements
general sibling combinators - -

namespaces

Extra constraintsmore than one class selector per sequence of simple selectors - (CSS1 - constraint) allowed -
- -

In CSS, selectors express pattern matching rules that determine which - style - rules apply to elements in the document tree. - -

The following selector (CSS level 2) will match all anchors a - with attribute name set inside a section 1 header - h1: -

h1 a[name]
- -

All CSS declarations attached to such a selector are applied to elements - matching it.

- -
- - - - - - - - - - - - - - - - - - - - - - -
Selectors profile
SpecificationSTTS 3
Accepts - -

type selectors
universal selectors
attribute - selectors
class - selectors
ID selectors
all structural - pseudo-classes
- all combinators - -

namespaces

Excludesnon-accepted pseudo-classes
pseudo-elements
Extra constraintssome selectors and combinators are not allowed in fragment - descriptions on the right side of STTS declarations. -
- -

Selectors can be used in STTS 3 in two different - manners: -

    -
  1. a selection mechanism equivalent to CSS selection mechanism: - declarations - attached to a given selector are applied to elements matching that - selector, -
  2. fragment descriptions that appear on the right side of declarations. -
  3. -
-
- -

13. Conformance and requirements

- -

This section defines conformance with the present specification only. - -

The inability of a user agent to implement part of this specification due to - the limitations of a particular device (e.g., non interactive user agents - will - probably not implement dynamic pseudo-classes because they make no sense - without - interactivity) does not imply non-conformance. - -

All specifications reusing Selectors must contain a Profile listing the - subset of Selectors it accepts or excludes, and describing the constraints - it adds to the current specification. - -

Invalidity is caused by a parsing error, e.g. an unrecognized token or a - token - which is not allowed at the current parsing point. - -

User agents must observe the rules for handling parsing errors: -

    -
  • a simple selector containing an undeclared namespace prefix is invalid -
  • -
  • a selector containing an invalid simple selector, an invalid combinator - or an invalid token is invalid. -
  • -
  • a group of selectors containing an invalid selector is invalid.
  • -
- -

Specifications reusing Selectors must define how to handle parsing - errors. (In the case of CSS, the entire rule in which the selector is - used is dropped.)

- - - -

14. Tests

- -

This specification has a test - suite allowing user agents to verify their basic conformance to - the specification. This test suite does not pretend to be exhaustive - and does not cover all possible combined cases of Selectors.

- -

15. Acknowledgements

- -

The CSS working group would like to thank everyone who has sent - comments on this specification over the years.

- -

The working group would like to extend special thanks to Donna - McManus, Justin Baker, Joel Sklar, and Molly Ives Brower who perfermed - the final editorial review.

- -

16. References

- -
- -
[CSS1] -
Bert Bos, Håkon Wium Lie; "Cascading - Style Sheets, level 1", W3C Recommendation, 17 Dec 1996, revised - 11 Jan 1999 -
(http://www.w3.org/TR/REC-CSS1) - -
[CSS21] -
Bert Bos, Tantek Çelik, Ian Hickson, Håkon - Wium Lie, editors; "Cascading Style Sheets, level 2 revision - 1", W3C Working Draft, 13 June 2005 -
(http://www.w3.org/TR/CSS21) - -
[CWWW] -
Martin J. Dürst, François Yergeau, - Misha Wolf, Asmus Freytag, Tex Texin, editors; "Character Model - for the World Wide Web", W3C Recommendation, 15 February 2005 -
(http://www.w3.org/TR/charmod/) - -
[FLEX] -
"Flex: The Lexical Scanner - Generator", Version 2.3.7, ISBN 1882114213 - -
[HTML4] -
Dave Ragget, Arnaud Le Hors, Ian Jacobs, - editors; "HTML 4.01 Specification", W3C Recommendation, 24 - December 1999 -
- (http://www.w3.org/TR/html4/) - -
[MATH] -
Patrick Ion, Robert Miner, editors; "Mathematical - Markup Language (MathML) 1.01", W3C Recommendation, revision of 7 - July 1999 -
(http://www.w3.org/TR/REC-MathML/) - -
[RFC3066] -
H. Alvestrand; "Tags for the - Identification of Languages", Request for Comments 3066, January - 2001 -
(http://www.ietf.org/rfc/rfc3066.txt) - -
[STTS] -
Daniel Glazman; "Simple Tree Transformation - Sheets 3", Electricité de France, submission to the W3C, - 11 November 1998 -
(http://www.w3.org/TR/NOTE-STTS3) - -
[SVG] -
Jon Ferraiolo, 藤沢 淳, Dean - Jackson, editors; "Scalable Vector Graphics (SVG) 1.1 - Specification", W3C Recommendation, 14 January 2003 -
(http://www.w3.org/TR/SVG/) - -
[UNICODE]
-
The Unicode - Standard, Version 4.1, The Unicode Consortium. Boston, MA, - Addison-Wesley, March 2005. ISBN 0-321-18578-1, as amended by Unicode - 4.0.1 and Unicode - 4.1.0. -
(http://www.unicode.org/versions/) -
- -
[XML10] -
Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, - Eve Maler, François Yergeau, editors; "Extensible Markup - Language (XML) 1.0 (Third Edition)", W3C Recommendation, 4 - February 2004 -
(http://www.w3.org/TR/REC-xml/) - -
[XMLNAMES] -
Tim Bray, Dave Hollander, Andrew Layman, - editors; "Namespaces in XML", W3C Recommendation, 14 - January 1999 -
(http://www.w3.org/TR/REC-xml-names/) - -
[YACC] -
S. C. Johnson; "YACC — Yet another - compiler compiler", Technical Report, Murray Hill, 1975 - -
-
- - diff --git a/samples/src/main/java/gwtquery/samples/public/racetrack.html b/samples/src/main/java/gwtquery/samples/public/racetrack.html deleted file mode 100644 index 3ed9adab..00000000 --- a/samples/src/main/java/gwtquery/samples/public/racetrack.html +++ /dev/null @@ -1,73 +0,0 @@ - - - Benchmark Racetrack - - - - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- -
- - \ No newline at end of file -- 2.39.5