diff options
1120 files changed, 22511 insertions, 5821 deletions
diff --git a/.classpath b/.classpath index c6230a2c55..130d4c0c49 100644 --- a/.classpath +++ b/.classpath @@ -2,6 +2,7 @@ <classpath> <classpathentry kind="src" path="server/tests/src"/> <classpathentry kind="src" path="client/tests/src"/> + <classpathentry kind="src" path="shared/tests/src"/> <classpathentry kind="src" path="theme-compiler/tests/src"/> <classpathentry kind="src" path="theme-compiler/src"/> <classpathentry kind="src" path="theme-compiler/tests/resources"/> diff --git a/WebContent/VAADIN/themes/base/base.scss b/WebContent/VAADIN/themes/base/base.scss index aa1e778d6f..fd3c5d067d 100644 --- a/WebContent/VAADIN/themes/base/base.scss +++ b/WebContent/VAADIN/themes/base/base.scss @@ -15,6 +15,7 @@ @import "inlinedatefield/inlinedatefield.scss"; @import "dragwrapper/dragwrapper.scss"; @import "embedded/embedded.scss"; +@import "fonts/fonts.scss"; @import "formlayout/formlayout.scss"; @import "gridlayout/gridlayout.scss"; @import "label/label.scss"; @@ -119,3 +120,4 @@ $line-height: normal; // always include, don't wrap in .themename{} @include debug-globals; +@include fonts; diff --git a/WebContent/VAADIN/themes/base/common/common.scss b/WebContent/VAADIN/themes/base/common/common.scss index 5cae1b26ce..6ec85e3c6d 100644 --- a/WebContent/VAADIN/themes/base/common/common.scss +++ b/WebContent/VAADIN/themes/base/common/common.scss @@ -243,6 +243,7 @@ input::-ms-clear { width: 0; height: 0; } + } /* Outside the base mixin because elements might be added directly to the body */ diff --git a/WebContent/VAADIN/themes/base/customcomponent/customcomponent.scss b/WebContent/VAADIN/themes/base/customcomponent/customcomponent.scss index 461e1b1246..d672254a86 100644 --- a/WebContent/VAADIN/themes/base/customcomponent/customcomponent.scss +++ b/WebContent/VAADIN/themes/base/customcomponent/customcomponent.scss @@ -1,7 +1,6 @@ @mixin base-customcomponent($primaryStyleName : v-customcomponent) { .#{$primaryStyleName} { - overflow: hidden; } }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/debug/debug.scss b/WebContent/VAADIN/themes/base/debug/debug.scss index 0992f19bb9..b50245a7be 100644 --- a/WebContent/VAADIN/themes/base/debug/debug.scss +++ b/WebContent/VAADIN/themes/base/debug/debug.scss @@ -251,6 +251,14 @@ width: 100%; } + .v-debugwindow-selector > span.value { + width: 100%; + } + + .v-debugwindow-selector :hover { + background: rgba(255,32,32,0.5); + } + /* LOG */ .v-debugwindow-log { font-family: monospace; diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg b/WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg deleted file mode 100644 index 24fa9ceeed..0000000000 --- a/WebContent/VAADIN/themes/base/debug/fonts/font.dev.svg +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > -<svg xmlns="http://www.w3.org/2000/svg"> -<metadata> -This is a custom SVG font generated by IcoMoon. -<iconset grid="14"></iconset> -</metadata> -<defs> -<font id="fontawesome" horiz-adv-x="448" > -<font-face units-per-em="448" ascent="384" descent="-64" /> -<missing-glyph horiz-adv-x="448" /> -<glyph unicode="" d="M 288.00,176.00q0.00,46.25 -32.875,79.125t-79.125,32.875t-79.125-32.875t-32.875-79.125t 32.875-79.125t 79.125-32.875t 79.125,32.875t 32.875,79.125zM 416.00-32.00q0.00-13.00 -9.50-22.50t-22.50-9.50q-13.50,0.00 -22.50,9.50l-85.75,85.50q-44.75-31.00 -99.75-31.00q-35.75,0.00 -68.375,13.875t-56.25,37.50t-37.50,56.25t-13.875,68.375 t 13.875,68.375t 37.50,56.25t 56.25,37.50t 68.375,13.875t 68.375-13.875t 56.25-37.50t 37.50-56.25t 13.875-68.375q0.00-55.00 -31.00-99.75l 85.75-85.75q 9.25-9.25 9.25-22.50z" horiz-adv-x="416" data-tags="search, magnifier, lookup, find" /> -<glyph unicode="" d="M 417.75,242.50q0.00-10.00 -7.00-17.00l-181.00-181.00l-34.00-34.00q-7.00-7.00 -17.00-7.00t-17.00,7.00l-34.00,34.00l-90.50,90.50q-7.00,7.00 -7.00,17.00t 7.00,17.00l 34.00,34.00q 7.00,7.00 17.00,7.00t 17.00-7.00l 73.50-73.75l 164.00,164.25q 7.00,7.00 17.00,7.00t 17.00-7.00l 34.00-34.00q 7.00-7.00 7.00-17.00z" data-tags="ok, checkmark, tick, correct" /> -<glyph unicode="" d="M 324.50,53.50q0.00-10.00 -7.00-17.00l-34.00-34.00q-7.00-7.00 -17.00-7.00t-17.00,7.00l-73.50,73.50l-73.50-73.50q-7.00-7.00 -17.00-7.00t-17.00,7.00l-34.00,34.00q-7.00,7.00 -7.00,17.00t 7.00,17.00l 73.50,73.50l-73.50,73.50q-7.00,7.00 -7.00,17.00t 7.00,17.00l 34.00,34.00q 7.00,7.00 17.00,7.00t 17.00-7.00l 73.50-73.50l 73.50,73.50q 7.00,7.00 17.00,7.00t 17.00-7.00l 34.00-34.00q 7.00-7.00 7.00-17.00 t-7.00-17.00l-73.50-73.50l 73.50-73.50q 7.00-7.00 7.00-17.00z" horiz-adv-x="352" data-tags="remove, cancel, close, delete, mutiply" /> -<glyph unicode="" d="M 384.00,160.00q0.00-39.00 -15.25-74.50t-41.00-61.25t-61.25-41.00t-74.50-15.25t-74.50,15.25t-61.25,41.00t-41.00,61.25t-15.25,74.50q0.00,45.50 20.125,85.75t 56.625,67.50q 10.75,8.00 23.875,6.25t 20.875-12.50q 8.00-10.50 6.125-23.625t-12.375-21.125q-24.50-18.50 -37.875-45.25t-13.375-57.00q0.00-26.00 10.125-49.625t 27.375-40.875t 40.875-27.375 t 49.625-10.125t 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625q0.00,30.25 -13.375,57.00t-37.875,45.25q-10.50,8.00 -12.375,21.125t 6.125,23.625q 7.75,10.75 21.00,12.50t 23.75-6.25q 36.50-27.25 56.625-67.50t 20.125-85.75zM 224.00,352.00l0.00-160.00 q0.00-13.00 -9.50-22.50t-22.50-9.50t-22.50,9.50t-9.50,22.50l0.00,160.00 q0.00,13.00 9.50,22.50t 22.50,9.50t 22.50-9.50t 9.50-22.50z" horiz-adv-x="384" data-tags="off, switch, power" /> -<glyph unicode="" d="M 128.00,200.00l0.00-144.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-16.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,144.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 16.00,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75zM 192.00,200.00l0.00-144.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-16.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,144.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 16.00,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75zM 256.00,200.00l0.00-144.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-16.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,144.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 16.00,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75zM 288.00,19.00l0.00,237.00 l-224.00,0.00 l0.00-237.00 q0.00-5.50 1.75-10.125t 3.625-6.75t 2.625-2.125l 208.00,0.00 q 0.75,0.00 2.625,2.125t 3.625,6.75t 1.75,10.125zM 120.00,288.00l 112.00,0.00 l-12.00,29.25q-1.75,2.25 -4.25,2.75l-79.25,0.00 q-2.50-0.50 -4.25-2.75zM 352.00,280.00l0.00-16.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-24.00,0.00 l0.00-237.00 q0.00-20.75 -11.75-35.875t-28.25-15.125l-208.00,0.00 q-16.50,0.00 -28.25,14.625t-11.75,35.375l0.00,238.00 l-24.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,16.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 77.25,0.00 l 17.50,41.75q 3.75,9.25 13.50,15.75t 19.75,6.50l 80.00,0.00 q 10.00,0.00 19.75-6.50t 13.50-15.75l 17.50-41.75l 77.25,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75z" horiz-adv-x="352" data-tags="trash, remove, delete, bin" /> -<glyph unicode="" d="M 272.00,152.00l0.00-16.00 q0.00-3.25 -2.375-5.625t-5.625-2.375l-96.00,0.00 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,112.00 q0.00,3.25 2.375,5.625t 5.625,2.375l 16.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625l0.00-88.00 l 72.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625zM 320.00,160.00q0.00,26.00 -10.125,49.625t-27.375,40.875t-40.875,27.375t-49.625,10.125t-49.625-10.125 t-40.875-27.375t-27.375-40.875t-10.125-49.625t 10.125-49.625t 27.375-40.875t 40.875-27.375t 49.625-10.125t 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625zM 384.00,160.00q0.00-52.25 -25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875 t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" data-tags="time, clock" /> -<glyph unicode="" d="M 192.00,144.00l0.00-112.00 q0.00-6.50 -4.75-11.25t-11.25-4.75t-11.25,4.75l-36.00,36.00l-83.00-83.00q-2.50-2.50 -5.75-2.50t-5.75,2.50l-28.50,28.50q-2.50,2.50 -2.50,5.75t 2.50,5.75l 83.00,83.00l-36.00,36.00q-4.75,4.75 -4.75,11.25t 4.75,11.25t 11.25,4.75l 112.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25zM 380.75,312.00q0.00-3.25 -2.50-5.75l-83.00-83.00l 36.00-36.00q 4.75-4.75 4.75-11.25t-4.75-11.25 t-11.25-4.75l-112.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,112.00 q0.00,6.50 4.75,11.25t 11.25,4.75t 11.25-4.75l 36.00-36.00l 83.00,83.00q 2.50,2.50 5.75,2.50t 5.75-2.50l 28.50-28.50q 2.50-2.50 2.50-5.75z" horiz-adv-x="384" data-tags="resize-small, contract, collapse" /> -<glyph unicode="" d="M 256.00,40.25l0.00,47.50 q0.00,3.50 -2.375,5.875t-5.625,2.375l-48.00,0.00 q-3.25,0.00 -5.625-2.375t-2.375-5.875l0.00-47.50 q0.00-3.50 2.375-5.875t 5.625-2.375l 48.00,0.00 q 3.25,0.00 5.625,2.375t 2.375,5.875zM 255.50,133.75l 4.50,114.75q0.00,3.00 -2.50,4.75q-3.25,2.75 -6.00,2.75l-55.00,0.00 q-2.75,0.00 -6.00-2.75q-2.50-1.75 -2.50-5.25l 4.25-114.25q0.00-2.50 2.50-4.125t 6.00-1.625l 46.25,0.00 q 3.50,0.00 5.875,1.625t 2.625,4.125zM 252.00,367.25l 192.00-352.00q 8.75-15.75 -0.50-31.50q-4.25-7.25 -11.625-11.50t-15.875-4.25l-384.00,0.00 q-8.50,0.00 -15.875,4.25t-11.625,11.50q-9.25,15.75 -0.50,31.50l 192.00,352.00q 4.25,7.75 11.75,12.25t 16.25,4.50t 16.25-4.50t 11.75-12.25z" data-tags="warning-sign, sign" /> -<glyph unicode="" d="M 256.00,40.00l0.00,16.00 q0.00,3.50 -2.25,5.75t-5.75,2.25l-24.00,0.00 l0.00,120.00 q0.00,3.50 -2.25,5.75t-5.75,2.25l-80.00,0.00 q-3.50,0.00 -5.75-2.25t-2.25-5.75l0.00-16.00 q0.00-3.50 2.25-5.75t 5.75-2.25l 24.00,0.00 l0.00-96.00 l-24.00,0.00 q-3.50,0.00 -5.75-2.25t-2.25-5.75l0.00-16.00 q0.00-3.50 2.25-5.75t 5.75-2.25l 112.00,0.00 q 3.50,0.00 5.75,2.25t 2.25,5.75zM 224.00,232.00l0.00,48.00 q0.00,3.50 -2.25,5.75t-5.75,2.25l-48.00,0.00 q-3.50,0.00 -5.75-2.25t-2.25-5.75l0.00-48.00 q0.00-3.50 2.25-5.75 t 5.75-2.25l 48.00,0.00 q 3.50,0.00 5.75,2.25t 2.25,5.75zM 384.00,160.00q0.00-52.25 -25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" data-tags="info-sign, information, sign" /> -<glyph unicode="" d="M 192.00,352.00q 52.25,0.00 96.375-25.75t 69.875-69.875t 25.75-96.375t-25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75zM 224.00,40.25l0.00,47.50 q0.00,3.50 -2.25,5.875t-5.50,2.375l-48.00,0.00 q-3.25,0.00 -5.75-2.50t-2.50-5.75l0.00-47.50 q0.00-3.25 2.50-5.75t 5.75-2.50l 48.00,0.00 q 3.25,0.00 5.50,2.375t 2.25,5.875zM 223.50,126.25l 4.50,155.25q0.00,3.00 -2.50,4.50q-2.50,2.00 -6.00,2.00l-55.00,0.00 q-3.50,0.00 -6.00-2.00q-2.50-1.50 -2.50-4.50l 4.25-155.25q0.00-2.50 2.50-4.375t 6.00-1.875l 46.25,0.00 q 3.50,0.00 5.875,1.875t 2.625,4.375z" horiz-adv-x="384" data-tags="exclamation-sign, sign, notification, attention, warning" /> -<glyph unicode="" d="M 299.25,128.00l-27.25,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 27.25,0.00 q-8.00,27.00 -28.125,47.125t-47.125,28.125l0.00-27.25 q0.00-6.50 -4.75-11.25t-11.25-4.75l-32.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,27.25 q-27.00-8.00 -47.125-28.125t-28.125-47.125l 27.25,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-27.25,0.00 q 8.00-27.00 28.125-47.125t 47.125-28.125l0.00,27.25 q0.00,6.50 4.75,11.25t 11.25,4.75l 32.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25l0.00-27.25 q 27.00,8.00 47.125,28.125t 28.125,47.125zM 384.00,176.00l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-35.75,0.00 q-9.25-40.25 -38.625-69.625t-69.625-38.625l0.00-35.75 q0.00-6.50 -4.75-11.25t-11.25-4.75l-32.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,35.75 q-40.25,9.25 -69.625,38.625t-38.625,69.625l-35.75,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 35.75,0.00 q 9.25,40.25 38.625,69.625t 69.625,38.625l0.00,35.75 q0.00,6.50 4.75,11.25t 11.25,4.75l 32.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25l0.00-35.75 q 40.25-9.25 69.625-38.625t 38.625-69.625l 35.75,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" data-tags="screenshot, target, goal, spot" /> -<glyph unicode="" d="M 384.00,48.00l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-352.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 352.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25zM 384.00,176.00l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-352.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 352.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25zM 384.00,304.00l0.00-32.00 q0.00-6.50 -4.75-11.25 t-11.25-4.75l-352.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 352.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" data-tags="reorder, list, menu" /> -<glyph unicode="" d="M 297.50,238.75l 73.25,73.25l-26.75,26.75l-73.25-73.25zM 409.25,312.00q0.00-6.75 -4.50-11.25l-321.50-321.50q-4.50-4.50 -11.25-4.50t-11.25,4.50l-49.50,49.50q-4.50,4.50 -4.50,11.25t 4.50,11.25l 321.50,321.50q 4.50,4.50 11.25,4.50t 11.25-4.50l 49.50-49.50q 4.50-4.50 4.50-11.25zM 71.50,359.50l 24.50-7.50l-24.50-7.50l-7.50-24.50l-7.50,24.50l-24.50,7.50l 24.50,7.50l 7.50,24.50zM 159.00,319.00 l 49.00-15.00l-49.00-15.00l-15.00-49.00l-15.00,49.00l-49.00,15.00l 49.00,15.00l 15.00,49.00zM 391.50,199.50l 24.50-7.50l-24.50-7.50l-7.50-24.50l-7.50,24.50l-24.50,7.50l 24.50,7.50l 7.50,24.50zM 231.50,359.50l 24.50-7.50l-24.50-7.50l-7.50-24.50l-7.50,24.50l-24.50,7.50l 24.50,7.50l 7.50,24.50z" horiz-adv-x="416" data-tags="magic, wand, wizard" /> -<glyph unicode="" d="M 448.00,72.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-80.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 24.00,0.00 l0.00,48.00 l-128.00,0.00 l0.00-48.00 l 24.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-80.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 24.00,0.00 l0.00,48.00 l-128.00,0.00 l0.00-48.00 l 24.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-80.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 24.00,0.00 l0.00,48.00 q0.00,13.00 9.50,22.50t 22.50,9.50l 128.00,0.00 l0.00,48.00 l-24.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 80.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-24.00,0.00 l0.00-48.00 l 128.00,0.00 q 13.00,0.00 22.50-9.50t 9.50-22.50l0.00-48.00 l 24.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00 z" data-tags="sitemap, tree" /> -<glyph unicode="" d="M 256.00,160.00q0.00,26.50 -18.75,45.25t-45.25,18.75t-45.25-18.75t-18.75-45.25t 18.75-45.25t 45.25-18.75t 45.25,18.75t 18.75,45.25zM 384.00,187.25l0.00-55.50 q0.00-3.00 -2.00-5.75t-5.00-3.25l-46.25-7.00q-4.75-13.50 -9.75-22.75q 8.75-12.50 26.75-34.50q 2.50-3.00 2.50-6.25t-2.25-5.75q-6.75-9.25 -24.75-27.00t-23.50-17.75q-3.00,0.00 -6.50,2.25l-34.50,27.00q-11.00-5.75 -22.75-9.50 q-4.00-34.00 -7.25-46.50q-1.75-7.00 -9.00-7.00l-55.50,0.00 q-3.50,0.00 -6.125,2.125t-2.875,5.375l-7.00,46.00q-12.25,4.00 -22.50,9.25l-35.25-26.75q-2.50-2.25 -6.25-2.25q-3.50,0.00 -6.25,2.75q-31.50,28.50 -41.25,42.00q-1.75,2.50 -1.75,5.75q0.00,3.00 2.00,5.75q 3.75,5.25 12.75,16.625t 13.50,17.625q-6.75,12.50 -10.25,24.75l-45.75,6.75q-3.25,0.50 -5.25,3.125t-2.00,5.875l0.00,55.50 q0.00,3.00 2.00,5.75t 4.75,3.25 l 46.50,7.00q 3.50,11.50 9.75,23.00q-10.00,14.25 -26.75,34.50q-2.50,3.00 -2.50,6.00q0.00,2.50 2.25,5.75q 6.50,9.00 24.625,26.875t 23.625,17.875q 3.25,0.00 6.50-2.50l 34.50-26.75q 11.00,5.75 22.75,9.50q 4.00,34.00 7.25,46.50q 1.75,7.00 9.00,7.00l 55.50,0.00 q 3.50,0.00 6.125-2.125t 2.875-5.375l 7.00-46.00q 12.25-4.00 22.50-9.25l 35.50,26.75q 2.25,2.25 6.00,2.25q 3.25,0.00 6.25-2.50q 32.25-29.75 41.25-42.50q 1.75-2.00 1.75-5.50 q0.00-3.00 -2.00-5.75q-3.75-5.25 -12.75-16.625t-13.50-17.625q 6.50-12.50 10.25-24.50l 45.75-7.00q 3.25-0.50 5.25-3.125t 2.00-5.875z" horiz-adv-x="384" data-tags="cog, settings, options, gear, preferences" /> -<glyph unicode="" d="M 448.00,88.00l0.00-48.00 q0.00-3.25 -2.375-5.625t-5.625-2.375l-344.00,0.00 l0.00-48.00 q0.00-3.25 -2.375-5.625t-5.625-2.375q-3.00,0.00 -6.00,2.50l-79.75,80.00q-2.25,2.25 -2.25,5.50q0.00,3.50 2.25,5.75l 80.00,80.00q 2.25,2.25 5.75,2.25q 3.25,0.00 5.625-2.375t 2.375-5.625l0.00-48.00 l 344.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625zM 448.00,224.00q0.00-3.50 -2.25-5.75l-80.00-80.00q-2.25-2.25 -5.75-2.25 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,48.00 l-344.00,0.00 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,48.00 q0.00,3.25 2.375,5.625t 5.625,2.375l 344.00,0.00 l0.00,48.00 q0.00,3.50 2.25,5.75t 5.75,2.25q 3.00,0.00 6.00-2.50l 79.75-79.75q 2.25-2.25 2.25-5.75z" data-tags="exchange, transfer, tab, traffic" /> -<glyph unicode="" d="M 96.00,48.00q0.00-6.50 -4.75-11.25t-11.25-4.75t-11.25,4.75t-4.75,11.25t 4.75,11.25t 11.25,4.75t 11.25-4.75t 4.75-11.25zM 352.00,32.75q0.00-30.25 -18.25-47.50t-48.50-17.25l-218.50,0.00 q-30.25,0.00 -48.50,17.25t-18.25,47.50q0.00,17.00 1.375,32.75t 6.00,34.50t 11.875,33.125t 20.25,25.75t 30.00,15.125q-5.50-13.00 -5.50-30.00l0.00-50.75 q-14.50-5.00 -23.25-17.50t-8.75-27.75q0.00-20.00 14.00-34.00t 34.00-14.00 t 34.00,14.00t 14.00,34.00q0.00,15.25 -8.875,27.75t-23.125,17.50l0.00,50.75 q0.00,15.50 6.25,23.25q 33.00-26.00 73.75-26.00t 73.75,26.00q 6.25-7.75 6.25-23.25l0.00-16.00 q-26.50,0.00 -45.25-18.75t-18.75-45.25l0.00-22.25 q-8.00-7.25 -8.00-17.75q0.00-10.00 7.00-17.00t 17.00-7.00t 17.00,7.00t 7.00,17.00q0.00,10.50 -8.00,17.75l0.00,22.25 q0.00,13.00 9.50,22.50t 22.50,9.50t 22.50-9.50t 9.50-22.50l0.00-22.25 q-8.00-7.25 -8.00-17.75q0.00-10.00 7.00-17.00 t 17.00-7.00t 17.00,7.00t 7.00,17.00q0.00,10.50 -8.00,17.75l0.00,22.25 q0.00,17.00 -8.625,31.875t-23.375,23.375q0.00,2.50 0.125,10.625t0.00,12.00t-0.625,10.375t-1.75,11.75t-3.25,10.00q 17.00-3.75 30.00-15.125t 20.25-25.75t 11.875-33.125t 6.00-34.50t 1.375-32.75zM 272.00,256.00q0.00-39.75 -28.125-67.875t-67.875-28.125t-67.875,28.125t-28.125,67.875t 28.125,67.875t 67.875,28.125 t 67.875-28.125t 28.125-67.875z" horiz-adv-x="352" data-tags="user-md, medic, doctor" /> -<glyph unicode="" d="M 176.00,128.00q0.00,13.25 -9.375,22.625t-22.625,9.375t-22.625-9.375t-9.375-22.625q0.00-9.25 4.75-16.75t 12.75-11.75l-17.25-57.25q-1.25-3.75 1.25-7.00t 6.50-3.25l 48.00,0.00 q 4.00,0.00 6.50,3.25t 1.25,7.00l-17.25,57.25q 8.00,4.25 12.75,11.75t 4.75,16.75zM 80.00,192.00l 128.00,0.00 l0.00,48.00 q0.00,26.50 -18.75,45.25t-45.25,18.75t-45.25-18.75t-18.75-45.25l0.00-48.00 zM 288.00,168.00l0.00-144.00 q0.00-10.00 -7.00-17.00 t-17.00-7.00l-240.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,144.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 8.00,0.00 l0.00,48.00 q0.00,46.00 33.00,79.00t 79.00,33.00t 79.00-33.00t 33.00-79.00l0.00-48.00 l 8.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00z" horiz-adv-x="288" data-tags="lock, password, secure, private, protected, encrypted" /> -<glyph unicode="" d="M 320.00,160.00q0.00,26.00 -10.125,49.625t-27.375,40.875t-40.875,27.375t-49.625,10.125t-49.625-10.125t-40.875-27.375t-27.375-40.875t-10.125-49.625t 10.125-49.625t 27.375-40.875t 40.875-27.375t 49.625-10.125t 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625zM 384.00,160.00q0.00-52.25 -25.75-96.375 t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" data-tags="circle-blank" /> -<glyph unicode="" d="M 384.00,160.00q0.00-52.25 -25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" data-tags="circle" /> -<glyph unicode="" d="M 124.00,48.00q0.00-15.00 -10.625-25.50t-25.375-10.50q-15.00,0.00 -25.50,10.50t-10.50,25.50t 10.50,25.50t 25.50,10.50q 14.75,0.00 25.375-10.50t 10.625-25.50zM 232.00,0.00q0.00-13.25 -9.375-22.625t-22.625-9.375t-22.625,9.375t-9.375,22.625t 9.375,22.625t 22.625,9.375t 22.625-9.375t 9.375-22.625zM 80.00,160.00q0.00-16.50 -11.75-28.25t-28.25-11.75t-28.25,11.75t-11.75,28.25 t 11.75,28.25t 28.25,11.75t 28.25-11.75t 11.75-28.25zM 340.00,48.00q0.00-11.50 -8.25-19.75t-19.75-8.25t-19.75,8.25t-8.25,19.75t 8.25,19.75t 19.75,8.25t 19.75-8.25t 8.25-19.75zM 132.00,272.00q0.00-18.25 -12.875-31.125t-31.125-12.875t-31.125,12.875t-12.875,31.125t 12.875,31.125t 31.125,12.875t 31.125-12.875t 12.875-31.125zM 248.00,320.00q0.00-20.00 -14.00-34.00t-34.00-14.00 t-34.00,14.00t-14.00,34.00t 14.00,34.00t 34.00,14.00t 34.00-14.00t 14.00-34.00zM 384.00,160.00q0.00-10.00 -7.00-17.00t-17.00-7.00t-17.00,7.00t-7.00,17.00t 7.00,17.00t 17.00,7.00t 17.00-7.00t 7.00-17.00zM 332.00,272.00q0.00-8.25 -5.875-14.125t-14.125-5.875t-14.125,5.875t-5.875,14.125t 5.875,14.125t 14.125,5.875t 14.125-5.875t 5.875-14.125z" horiz-adv-x="392" data-tags="spinner, loading, busy, progress" /> -<glyph unicode="" d="M 320.00,160.00q0.00,34.75 -17.75,65.00l-175.25-175.25q 30.25-17.75 65.00-17.75q 26.00,0.00 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625zM 81.75,95.00l 175.25,175.25q-30.25,17.75 -65.00,17.75q-26.00,0.00 -49.625-10.125t-40.875-27.375t-27.375-40.875t-10.125-49.625q0.00-34.75 17.75-65.00zM 384.00,160.00q0.00-52.25 -25.75-96.375 t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" data-tags="ban-circle, block, forbidden" /> -<glyph unicode="" d="M 188.75,120.00q0.00-3.25 -2.50-5.75l-83.00-83.00l 36.00-36.00q 4.75-4.75 4.75-11.25t-4.75-11.25t-11.25-4.75l-112.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,112.00 q0.00,6.50 4.75,11.25t 11.25,4.75t 11.25-4.75l 36.00-36.00l 83.00,83.00q 2.50,2.50 5.75,2.50t 5.75-2.50l 28.50-28.50q 2.50-2.50 2.50-5.75zM 384.00,336.00l0.00-112.00 q0.00-6.50 -4.75-11.25t-11.25-4.75t-11.25,4.75l-36.00,36.00l-83.00-83.00 q-2.50-2.50 -5.75-2.50t-5.75,2.50l-28.50,28.50q-2.50,2.50 -2.50,5.75t 2.50,5.75l 83.00,83.00l-36.00,36.00q-4.75,4.75 -4.75,11.25t 4.75,11.25t 11.25,4.75l 112.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" data-tags="resize-full, expand, enlarge" /> -<glyph unicode="" d="M 377.75,120.00q0.00-1.25 -0.25-1.75q-16.00-67.00 -67.00-108.625t-119.50-41.625q-36.50,0.00 -70.625,13.75t-60.875,39.25l-32.25-32.25q-4.75-4.75 -11.25-4.75t-11.25,4.75t-4.75,11.25l0.00,112.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 112.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25t-4.75-11.25l-34.25-34.25q 17.75-16.50 40.25-25.50t 46.75-9.00q 33.50,0.00 62.50,16.25t 46.50,44.75q 2.75,4.25 13.25,29.25 q 2.00,5.75 7.50,5.75l 48.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625zM 384.00,320.00l0.00-112.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-112.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25t 4.75,11.25l 34.50,34.50q-37.00,34.25 -87.25,34.25q-33.50,0.00 -62.50-16.25t-46.50-44.75q-2.75-4.25 -13.25-29.25q-2.00-5.75 -7.50-5.75l-49.75,0.00 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,1.75 q 16.25,67.00 67.50,108.625t 120.00,41.625 q 36.50,0.00 71.00-13.875t 61.25-39.125l 32.50,32.25q 4.75,4.75 11.25,4.75t 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" data-tags="refresh, synchronize" /> -<glyph unicode="" d="M 291.00,352.00q 5.75,0.00 11.00-2.25q 8.25-3.25 13.125-10.25t 4.875-15.50l0.00-322.25 q0.00-8.50 -4.875-15.50t-13.125-10.25q-4.75-2.00 -11.00-2.00q-12.00,0.00 -20.75,8.00l-110.25,106.00l-110.25-106.00q-9.00-8.25 -20.75-8.25q-5.75,0.00 -11.00,2.25q-8.25,3.25 -13.125,10.25t-4.875,15.50l0.00,322.25 q0.00,8.50 4.875,15.50t 13.125,10.25q 5.25,2.25 11.00,2.25l 262.00,0.00 z" horiz-adv-x="320" data-tags="bookmark, favorite, ribbon" /> -<glyph unicode=" " horiz-adv-x="224" /> -<glyph class="hidden" unicode="" d="M0,384L 448 -64L0 -64 z" horiz-adv-x="0" /> -</font></defs></svg>
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.eot b/WebContent/VAADIN/themes/base/debug/fonts/font.eot Binary files differindex 310a74dfce..c2a63b3f08 100644..100755 --- a/WebContent/VAADIN/themes/base/debug/fonts/font.eot +++ b/WebContent/VAADIN/themes/base/debug/fonts/font.eot diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.svg b/WebContent/VAADIN/themes/base/debug/fonts/font.svg index 8149b583fd..9d00e7b2fc 100644..100755 --- a/WebContent/VAADIN/themes/base/debug/fonts/font.svg +++ b/WebContent/VAADIN/themes/base/debug/fonts/font.svg @@ -1,39 +1,36 @@ <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > <svg xmlns="http://www.w3.org/2000/svg"> -<metadata> -This is a custom SVG font generated by IcoMoon. -<iconset grid="14"></iconset> -</metadata> +<metadata>Generated by IcoMoon</metadata> <defs> -<font id="fontawesome" horiz-adv-x="448" > -<font-face units-per-em="448" ascent="384" descent="-64" /> -<missing-glyph horiz-adv-x="448" /> -<glyph unicode="" d="M 288.00,176.00q0.00,46.25 -32.875,79.125t-79.125,32.875t-79.125-32.875t-32.875-79.125t 32.875-79.125t 79.125-32.875t 79.125,32.875t 32.875,79.125zM 416.00-32.00q0.00-13.00 -9.50-22.50t-22.50-9.50q-13.50,0.00 -22.50,9.50l-85.75,85.50q-44.75-31.00 -99.75-31.00q-35.75,0.00 -68.375,13.875t-56.25,37.50t-37.50,56.25t-13.875,68.375 t 13.875,68.375t 37.50,56.25t 56.25,37.50t 68.375,13.875t 68.375-13.875t 56.25-37.50t 37.50-56.25t 13.875-68.375q0.00-55.00 -31.00-99.75l 85.75-85.75q 9.25-9.25 9.25-22.50z" horiz-adv-x="416" /> -<glyph unicode="" d="M 417.75,242.50q0.00-10.00 -7.00-17.00l-181.00-181.00l-34.00-34.00q-7.00-7.00 -17.00-7.00t-17.00,7.00l-34.00,34.00l-90.50,90.50q-7.00,7.00 -7.00,17.00t 7.00,17.00l 34.00,34.00q 7.00,7.00 17.00,7.00t 17.00-7.00l 73.50-73.75l 164.00,164.25q 7.00,7.00 17.00,7.00t 17.00-7.00l 34.00-34.00q 7.00-7.00 7.00-17.00z" /> -<glyph unicode="" d="M 324.50,53.50q0.00-10.00 -7.00-17.00l-34.00-34.00q-7.00-7.00 -17.00-7.00t-17.00,7.00l-73.50,73.50l-73.50-73.50q-7.00-7.00 -17.00-7.00t-17.00,7.00l-34.00,34.00q-7.00,7.00 -7.00,17.00t 7.00,17.00l 73.50,73.50l-73.50,73.50q-7.00,7.00 -7.00,17.00t 7.00,17.00l 34.00,34.00q 7.00,7.00 17.00,7.00t 17.00-7.00l 73.50-73.50l 73.50,73.50q 7.00,7.00 17.00,7.00t 17.00-7.00l 34.00-34.00q 7.00-7.00 7.00-17.00 t-7.00-17.00l-73.50-73.50l 73.50-73.50q 7.00-7.00 7.00-17.00z" horiz-adv-x="352" /> -<glyph unicode="" d="M 384.00,160.00q0.00-39.00 -15.25-74.50t-41.00-61.25t-61.25-41.00t-74.50-15.25t-74.50,15.25t-61.25,41.00t-41.00,61.25t-15.25,74.50q0.00,45.50 20.125,85.75t 56.625,67.50q 10.75,8.00 23.875,6.25t 20.875-12.50q 8.00-10.50 6.125-23.625t-12.375-21.125q-24.50-18.50 -37.875-45.25t-13.375-57.00q0.00-26.00 10.125-49.625t 27.375-40.875t 40.875-27.375 t 49.625-10.125t 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625q0.00,30.25 -13.375,57.00t-37.875,45.25q-10.50,8.00 -12.375,21.125t 6.125,23.625q 7.75,10.75 21.00,12.50t 23.75-6.25q 36.50-27.25 56.625-67.50t 20.125-85.75zM 224.00,352.00l0.00-160.00 q0.00-13.00 -9.50-22.50t-22.50-9.50t-22.50,9.50t-9.50,22.50l0.00,160.00 q0.00,13.00 9.50,22.50t 22.50,9.50t 22.50-9.50t 9.50-22.50z" horiz-adv-x="384" /> -<glyph unicode="" d="M 128.00,200.00l0.00-144.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-16.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,144.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 16.00,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75zM 192.00,200.00l0.00-144.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-16.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,144.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 16.00,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75zM 256.00,200.00l0.00-144.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-16.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,144.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 16.00,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75zM 288.00,19.00l0.00,237.00 l-224.00,0.00 l0.00-237.00 q0.00-5.50 1.75-10.125t 3.625-6.75t 2.625-2.125l 208.00,0.00 q 0.75,0.00 2.625,2.125t 3.625,6.75t 1.75,10.125zM 120.00,288.00l 112.00,0.00 l-12.00,29.25q-1.75,2.25 -4.25,2.75l-79.25,0.00 q-2.50-0.50 -4.25-2.75zM 352.00,280.00l0.00-16.00 q0.00-3.50 -2.25-5.75t-5.75-2.25l-24.00,0.00 l0.00-237.00 q0.00-20.75 -11.75-35.875t-28.25-15.125l-208.00,0.00 q-16.50,0.00 -28.25,14.625t-11.75,35.375l0.00,238.00 l-24.00,0.00 q-3.50,0.00 -5.75,2.25t-2.25,5.75l0.00,16.00 q0.00,3.50 2.25,5.75t 5.75,2.25l 77.25,0.00 l 17.50,41.75q 3.75,9.25 13.50,15.75t 19.75,6.50l 80.00,0.00 q 10.00,0.00 19.75-6.50t 13.50-15.75l 17.50-41.75l 77.25,0.00 q 3.50,0.00 5.75-2.25t 2.25-5.75z" horiz-adv-x="352" /> -<glyph unicode="" d="M 272.00,152.00l0.00-16.00 q0.00-3.25 -2.375-5.625t-5.625-2.375l-96.00,0.00 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,112.00 q0.00,3.25 2.375,5.625t 5.625,2.375l 16.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625l0.00-88.00 l 72.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625zM 320.00,160.00q0.00,26.00 -10.125,49.625t-27.375,40.875t-40.875,27.375t-49.625,10.125t-49.625-10.125 t-40.875-27.375t-27.375-40.875t-10.125-49.625t 10.125-49.625t 27.375-40.875t 40.875-27.375t 49.625-10.125t 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625zM 384.00,160.00q0.00-52.25 -25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875 t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" /> -<glyph unicode="" d="M 192.00,144.00l0.00-112.00 q0.00-6.50 -4.75-11.25t-11.25-4.75t-11.25,4.75l-36.00,36.00l-83.00-83.00q-2.50-2.50 -5.75-2.50t-5.75,2.50l-28.50,28.50q-2.50,2.50 -2.50,5.75t 2.50,5.75l 83.00,83.00l-36.00,36.00q-4.75,4.75 -4.75,11.25t 4.75,11.25t 11.25,4.75l 112.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25zM 380.75,312.00q0.00-3.25 -2.50-5.75l-83.00-83.00l 36.00-36.00q 4.75-4.75 4.75-11.25t-4.75-11.25 t-11.25-4.75l-112.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,112.00 q0.00,6.50 4.75,11.25t 11.25,4.75t 11.25-4.75l 36.00-36.00l 83.00,83.00q 2.50,2.50 5.75,2.50t 5.75-2.50l 28.50-28.50q 2.50-2.50 2.50-5.75z" horiz-adv-x="384" /> -<glyph unicode="" d="M 256.00,40.25l0.00,47.50 q0.00,3.50 -2.375,5.875t-5.625,2.375l-48.00,0.00 q-3.25,0.00 -5.625-2.375t-2.375-5.875l0.00-47.50 q0.00-3.50 2.375-5.875t 5.625-2.375l 48.00,0.00 q 3.25,0.00 5.625,2.375t 2.375,5.875zM 255.50,133.75l 4.50,114.75q0.00,3.00 -2.50,4.75q-3.25,2.75 -6.00,2.75l-55.00,0.00 q-2.75,0.00 -6.00-2.75q-2.50-1.75 -2.50-5.25l 4.25-114.25q0.00-2.50 2.50-4.125t 6.00-1.625l 46.25,0.00 q 3.50,0.00 5.875,1.625t 2.625,4.125zM 252.00,367.25l 192.00-352.00q 8.75-15.75 -0.50-31.50q-4.25-7.25 -11.625-11.50t-15.875-4.25l-384.00,0.00 q-8.50,0.00 -15.875,4.25t-11.625,11.50q-9.25,15.75 -0.50,31.50l 192.00,352.00q 4.25,7.75 11.75,12.25t 16.25,4.50t 16.25-4.50t 11.75-12.25z" /> -<glyph unicode="" d="M 256.00,40.00l0.00,16.00 q0.00,3.50 -2.25,5.75t-5.75,2.25l-24.00,0.00 l0.00,120.00 q0.00,3.50 -2.25,5.75t-5.75,2.25l-80.00,0.00 q-3.50,0.00 -5.75-2.25t-2.25-5.75l0.00-16.00 q0.00-3.50 2.25-5.75t 5.75-2.25l 24.00,0.00 l0.00-96.00 l-24.00,0.00 q-3.50,0.00 -5.75-2.25t-2.25-5.75l0.00-16.00 q0.00-3.50 2.25-5.75t 5.75-2.25l 112.00,0.00 q 3.50,0.00 5.75,2.25t 2.25,5.75zM 224.00,232.00l0.00,48.00 q0.00,3.50 -2.25,5.75t-5.75,2.25l-48.00,0.00 q-3.50,0.00 -5.75-2.25t-2.25-5.75l0.00-48.00 q0.00-3.50 2.25-5.75 t 5.75-2.25l 48.00,0.00 q 3.50,0.00 5.75,2.25t 2.25,5.75zM 384.00,160.00q0.00-52.25 -25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" /> -<glyph unicode="" d="M 192.00,352.00q 52.25,0.00 96.375-25.75t 69.875-69.875t 25.75-96.375t-25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75zM 224.00,40.25l0.00,47.50 q0.00,3.50 -2.25,5.875t-5.50,2.375l-48.00,0.00 q-3.25,0.00 -5.75-2.50t-2.50-5.75l0.00-47.50 q0.00-3.25 2.50-5.75t 5.75-2.50l 48.00,0.00 q 3.25,0.00 5.50,2.375t 2.25,5.875zM 223.50,126.25l 4.50,155.25q0.00,3.00 -2.50,4.50q-2.50,2.00 -6.00,2.00l-55.00,0.00 q-3.50,0.00 -6.00-2.00q-2.50-1.50 -2.50-4.50l 4.25-155.25q0.00-2.50 2.50-4.375t 6.00-1.875l 46.25,0.00 q 3.50,0.00 5.875,1.875t 2.625,4.375z" horiz-adv-x="384" /> -<glyph unicode="" d="M 299.25,128.00l-27.25,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 27.25,0.00 q-8.00,27.00 -28.125,47.125t-47.125,28.125l0.00-27.25 q0.00-6.50 -4.75-11.25t-11.25-4.75l-32.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,27.25 q-27.00-8.00 -47.125-28.125t-28.125-47.125l 27.25,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-27.25,0.00 q 8.00-27.00 28.125-47.125t 47.125-28.125l0.00,27.25 q0.00,6.50 4.75,11.25t 11.25,4.75l 32.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25l0.00-27.25 q 27.00,8.00 47.125,28.125t 28.125,47.125zM 384.00,176.00l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-35.75,0.00 q-9.25-40.25 -38.625-69.625t-69.625-38.625l0.00-35.75 q0.00-6.50 -4.75-11.25t-11.25-4.75l-32.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,35.75 q-40.25,9.25 -69.625,38.625t-38.625,69.625l-35.75,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 35.75,0.00 q 9.25,40.25 38.625,69.625t 69.625,38.625l0.00,35.75 q0.00,6.50 4.75,11.25t 11.25,4.75l 32.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25l0.00-35.75 q 40.25-9.25 69.625-38.625t 38.625-69.625l 35.75,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" /> -<glyph unicode="" d="M 384.00,48.00l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-352.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 352.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25zM 384.00,176.00l0.00-32.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-352.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 352.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25zM 384.00,304.00l0.00-32.00 q0.00-6.50 -4.75-11.25 t-11.25-4.75l-352.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,32.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 352.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" /> -<glyph unicode="" d="M 297.50,238.75l 73.25,73.25l-26.75,26.75l-73.25-73.25zM 409.25,312.00q0.00-6.75 -4.50-11.25l-321.50-321.50q-4.50-4.50 -11.25-4.50t-11.25,4.50l-49.50,49.50q-4.50,4.50 -4.50,11.25t 4.50,11.25l 321.50,321.50q 4.50,4.50 11.25,4.50t 11.25-4.50l 49.50-49.50q 4.50-4.50 4.50-11.25zM 71.50,359.50l 24.50-7.50l-24.50-7.50l-7.50-24.50l-7.50,24.50l-24.50,7.50l 24.50,7.50l 7.50,24.50zM 159.00,319.00 l 49.00-15.00l-49.00-15.00l-15.00-49.00l-15.00,49.00l-49.00,15.00l 49.00,15.00l 15.00,49.00zM 391.50,199.50l 24.50-7.50l-24.50-7.50l-7.50-24.50l-7.50,24.50l-24.50,7.50l 24.50,7.50l 7.50,24.50zM 231.50,359.50l 24.50-7.50l-24.50-7.50l-7.50-24.50l-7.50,24.50l-24.50,7.50l 24.50,7.50l 7.50,24.50z" horiz-adv-x="416" /> -<glyph unicode="" d="M 448.00,72.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-80.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 24.00,0.00 l0.00,48.00 l-128.00,0.00 l0.00-48.00 l 24.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-80.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 24.00,0.00 l0.00,48.00 l-128.00,0.00 l0.00-48.00 l 24.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-80.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 24.00,0.00 l0.00,48.00 q0.00,13.00 9.50,22.50t 22.50,9.50l 128.00,0.00 l0.00,48.00 l-24.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,80.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 80.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00l0.00-80.00 q0.00-10.00 -7.00-17.00t-17.00-7.00l-24.00,0.00 l0.00-48.00 l 128.00,0.00 q 13.00,0.00 22.50-9.50t 9.50-22.50l0.00-48.00 l 24.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00 z" /> -<glyph unicode="" d="M 256.00,160.00q0.00,26.50 -18.75,45.25t-45.25,18.75t-45.25-18.75t-18.75-45.25t 18.75-45.25t 45.25-18.75t 45.25,18.75t 18.75,45.25zM 384.00,187.25l0.00-55.50 q0.00-3.00 -2.00-5.75t-5.00-3.25l-46.25-7.00q-4.75-13.50 -9.75-22.75q 8.75-12.50 26.75-34.50q 2.50-3.00 2.50-6.25t-2.25-5.75q-6.75-9.25 -24.75-27.00t-23.50-17.75q-3.00,0.00 -6.50,2.25l-34.50,27.00q-11.00-5.75 -22.75-9.50 q-4.00-34.00 -7.25-46.50q-1.75-7.00 -9.00-7.00l-55.50,0.00 q-3.50,0.00 -6.125,2.125t-2.875,5.375l-7.00,46.00q-12.25,4.00 -22.50,9.25l-35.25-26.75q-2.50-2.25 -6.25-2.25q-3.50,0.00 -6.25,2.75q-31.50,28.50 -41.25,42.00q-1.75,2.50 -1.75,5.75q0.00,3.00 2.00,5.75q 3.75,5.25 12.75,16.625t 13.50,17.625q-6.75,12.50 -10.25,24.75l-45.75,6.75q-3.25,0.50 -5.25,3.125t-2.00,5.875l0.00,55.50 q0.00,3.00 2.00,5.75t 4.75,3.25 l 46.50,7.00q 3.50,11.50 9.75,23.00q-10.00,14.25 -26.75,34.50q-2.50,3.00 -2.50,6.00q0.00,2.50 2.25,5.75q 6.50,9.00 24.625,26.875t 23.625,17.875q 3.25,0.00 6.50-2.50l 34.50-26.75q 11.00,5.75 22.75,9.50q 4.00,34.00 7.25,46.50q 1.75,7.00 9.00,7.00l 55.50,0.00 q 3.50,0.00 6.125-2.125t 2.875-5.375l 7.00-46.00q 12.25-4.00 22.50-9.25l 35.50,26.75q 2.25,2.25 6.00,2.25q 3.25,0.00 6.25-2.50q 32.25-29.75 41.25-42.50q 1.75-2.00 1.75-5.50 q0.00-3.00 -2.00-5.75q-3.75-5.25 -12.75-16.625t-13.50-17.625q 6.50-12.50 10.25-24.50l 45.75-7.00q 3.25-0.50 5.25-3.125t 2.00-5.875z" horiz-adv-x="384" /> -<glyph unicode="" d="M 448.00,88.00l0.00-48.00 q0.00-3.25 -2.375-5.625t-5.625-2.375l-344.00,0.00 l0.00-48.00 q0.00-3.25 -2.375-5.625t-5.625-2.375q-3.00,0.00 -6.00,2.50l-79.75,80.00q-2.25,2.25 -2.25,5.50q0.00,3.50 2.25,5.75l 80.00,80.00q 2.25,2.25 5.75,2.25q 3.25,0.00 5.625-2.375t 2.375-5.625l0.00-48.00 l 344.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625zM 448.00,224.00q0.00-3.50 -2.25-5.75l-80.00-80.00q-2.25-2.25 -5.75-2.25 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,48.00 l-344.00,0.00 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,48.00 q0.00,3.25 2.375,5.625t 5.625,2.375l 344.00,0.00 l0.00,48.00 q0.00,3.50 2.25,5.75t 5.75,2.25q 3.00,0.00 6.00-2.50l 79.75-79.75q 2.25-2.25 2.25-5.75z" /> -<glyph unicode="" d="M 96.00,48.00q0.00-6.50 -4.75-11.25t-11.25-4.75t-11.25,4.75t-4.75,11.25t 4.75,11.25t 11.25,4.75t 11.25-4.75t 4.75-11.25zM 352.00,32.75q0.00-30.25 -18.25-47.50t-48.50-17.25l-218.50,0.00 q-30.25,0.00 -48.50,17.25t-18.25,47.50q0.00,17.00 1.375,32.75t 6.00,34.50t 11.875,33.125t 20.25,25.75t 30.00,15.125q-5.50-13.00 -5.50-30.00l0.00-50.75 q-14.50-5.00 -23.25-17.50t-8.75-27.75q0.00-20.00 14.00-34.00t 34.00-14.00 t 34.00,14.00t 14.00,34.00q0.00,15.25 -8.875,27.75t-23.125,17.50l0.00,50.75 q0.00,15.50 6.25,23.25q 33.00-26.00 73.75-26.00t 73.75,26.00q 6.25-7.75 6.25-23.25l0.00-16.00 q-26.50,0.00 -45.25-18.75t-18.75-45.25l0.00-22.25 q-8.00-7.25 -8.00-17.75q0.00-10.00 7.00-17.00t 17.00-7.00t 17.00,7.00t 7.00,17.00q0.00,10.50 -8.00,17.75l0.00,22.25 q0.00,13.00 9.50,22.50t 22.50,9.50t 22.50-9.50t 9.50-22.50l0.00-22.25 q-8.00-7.25 -8.00-17.75q0.00-10.00 7.00-17.00 t 17.00-7.00t 17.00,7.00t 7.00,17.00q0.00,10.50 -8.00,17.75l0.00,22.25 q0.00,17.00 -8.625,31.875t-23.375,23.375q0.00,2.50 0.125,10.625t0.00,12.00t-0.625,10.375t-1.75,11.75t-3.25,10.00q 17.00-3.75 30.00-15.125t 20.25-25.75t 11.875-33.125t 6.00-34.50t 1.375-32.75zM 272.00,256.00q0.00-39.75 -28.125-67.875t-67.875-28.125t-67.875,28.125t-28.125,67.875t 28.125,67.875t 67.875,28.125 t 67.875-28.125t 28.125-67.875z" horiz-adv-x="352" /> -<glyph unicode="" d="M 176.00,128.00q0.00,13.25 -9.375,22.625t-22.625,9.375t-22.625-9.375t-9.375-22.625q0.00-9.25 4.75-16.75t 12.75-11.75l-17.25-57.25q-1.25-3.75 1.25-7.00t 6.50-3.25l 48.00,0.00 q 4.00,0.00 6.50,3.25t 1.25,7.00l-17.25,57.25q 8.00,4.25 12.75,11.75t 4.75,16.75zM 80.00,192.00l 128.00,0.00 l0.00,48.00 q0.00,26.50 -18.75,45.25t-45.25,18.75t-45.25-18.75t-18.75-45.25l0.00-48.00 zM 288.00,168.00l0.00-144.00 q0.00-10.00 -7.00-17.00 t-17.00-7.00l-240.00,0.00 q-10.00,0.00 -17.00,7.00t-7.00,17.00l0.00,144.00 q0.00,10.00 7.00,17.00t 17.00,7.00l 8.00,0.00 l0.00,48.00 q0.00,46.00 33.00,79.00t 79.00,33.00t 79.00-33.00t 33.00-79.00l0.00-48.00 l 8.00,0.00 q 10.00,0.00 17.00-7.00t 7.00-17.00z" horiz-adv-x="288" /> -<glyph unicode="" d="M 320.00,160.00q0.00,26.00 -10.125,49.625t-27.375,40.875t-40.875,27.375t-49.625,10.125t-49.625-10.125t-40.875-27.375t-27.375-40.875t-10.125-49.625t 10.125-49.625t 27.375-40.875t 40.875-27.375t 49.625-10.125t 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625zM 384.00,160.00q0.00-52.25 -25.75-96.375 t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" /> -<glyph unicode="" d="M 384.00,160.00q0.00-52.25 -25.75-96.375t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" /> -<glyph unicode="" d="M 124.00,48.00q0.00-15.00 -10.625-25.50t-25.375-10.50q-15.00,0.00 -25.50,10.50t-10.50,25.50t 10.50,25.50t 25.50,10.50q 14.75,0.00 25.375-10.50t 10.625-25.50zM 232.00,0.00q0.00-13.25 -9.375-22.625t-22.625-9.375t-22.625,9.375t-9.375,22.625t 9.375,22.625t 22.625,9.375t 22.625-9.375t 9.375-22.625zM 80.00,160.00q0.00-16.50 -11.75-28.25t-28.25-11.75t-28.25,11.75t-11.75,28.25 t 11.75,28.25t 28.25,11.75t 28.25-11.75t 11.75-28.25zM 340.00,48.00q0.00-11.50 -8.25-19.75t-19.75-8.25t-19.75,8.25t-8.25,19.75t 8.25,19.75t 19.75,8.25t 19.75-8.25t 8.25-19.75zM 132.00,272.00q0.00-18.25 -12.875-31.125t-31.125-12.875t-31.125,12.875t-12.875,31.125t 12.875,31.125t 31.125,12.875t 31.125-12.875t 12.875-31.125zM 248.00,320.00q0.00-20.00 -14.00-34.00t-34.00-14.00 t-34.00,14.00t-14.00,34.00t 14.00,34.00t 34.00,14.00t 34.00-14.00t 14.00-34.00zM 384.00,160.00q0.00-10.00 -7.00-17.00t-17.00-7.00t-17.00,7.00t-7.00,17.00t 7.00,17.00t 17.00,7.00t 17.00-7.00t 7.00-17.00zM 332.00,272.00q0.00-8.25 -5.875-14.125t-14.125-5.875t-14.125,5.875t-5.875,14.125t 5.875,14.125t 14.125,5.875t 14.125-5.875t 5.875-14.125z" horiz-adv-x="392" /> -<glyph unicode="" d="M 320.00,160.00q0.00,34.75 -17.75,65.00l-175.25-175.25q 30.25-17.75 65.00-17.75q 26.00,0.00 49.625,10.125t 40.875,27.375t 27.375,40.875t 10.125,49.625zM 81.75,95.00l 175.25,175.25q-30.25,17.75 -65.00,17.75q-26.00,0.00 -49.625-10.125t-40.875-27.375t-27.375-40.875t-10.125-49.625q0.00-34.75 17.75-65.00zM 384.00,160.00q0.00-52.25 -25.75-96.375 t-69.875-69.875t-96.375-25.75t-96.375,25.75t-69.875,69.875t-25.75,96.375t 25.75,96.375t 69.875,69.875t 96.375,25.75t 96.375-25.75t 69.875-69.875t 25.75-96.375z" horiz-adv-x="384" /> -<glyph unicode="" d="M 188.75,120.00q0.00-3.25 -2.50-5.75l-83.00-83.00l 36.00-36.00q 4.75-4.75 4.75-11.25t-4.75-11.25t-11.25-4.75l-112.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25l0.00,112.00 q0.00,6.50 4.75,11.25t 11.25,4.75t 11.25-4.75l 36.00-36.00l 83.00,83.00q 2.50,2.50 5.75,2.50t 5.75-2.50l 28.50-28.50q 2.50-2.50 2.50-5.75zM 384.00,336.00l0.00-112.00 q0.00-6.50 -4.75-11.25t-11.25-4.75t-11.25,4.75l-36.00,36.00l-83.00-83.00 q-2.50-2.50 -5.75-2.50t-5.75,2.50l-28.50,28.50q-2.50,2.50 -2.50,5.75t 2.50,5.75l 83.00,83.00l-36.00,36.00q-4.75,4.75 -4.75,11.25t 4.75,11.25t 11.25,4.75l 112.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" /> -<glyph unicode="" d="M 377.75,120.00q0.00-1.25 -0.25-1.75q-16.00-67.00 -67.00-108.625t-119.50-41.625q-36.50,0.00 -70.625,13.75t-60.875,39.25l-32.25-32.25q-4.75-4.75 -11.25-4.75t-11.25,4.75t-4.75,11.25l0.00,112.00 q0.00,6.50 4.75,11.25t 11.25,4.75l 112.00,0.00 q 6.50,0.00 11.25-4.75t 4.75-11.25t-4.75-11.25l-34.25-34.25q 17.75-16.50 40.25-25.50t 46.75-9.00q 33.50,0.00 62.50,16.25t 46.50,44.75q 2.75,4.25 13.25,29.25 q 2.00,5.75 7.50,5.75l 48.00,0.00 q 3.25,0.00 5.625-2.375t 2.375-5.625zM 384.00,320.00l0.00-112.00 q0.00-6.50 -4.75-11.25t-11.25-4.75l-112.00,0.00 q-6.50,0.00 -11.25,4.75t-4.75,11.25t 4.75,11.25l 34.50,34.50q-37.00,34.25 -87.25,34.25q-33.50,0.00 -62.50-16.25t-46.50-44.75q-2.75-4.25 -13.25-29.25q-2.00-5.75 -7.50-5.75l-49.75,0.00 q-3.25,0.00 -5.625,2.375t-2.375,5.625l0.00,1.75 q 16.25,67.00 67.50,108.625t 120.00,41.625 q 36.50,0.00 71.00-13.875t 61.25-39.125l 32.50,32.25q 4.75,4.75 11.25,4.75t 11.25-4.75t 4.75-11.25z" horiz-adv-x="384" /> -<glyph unicode="" d="M 291.00,352.00q 5.75,0.00 11.00-2.25q 8.25-3.25 13.125-10.25t 4.875-15.50l0.00-322.25 q0.00-8.50 -4.875-15.50t-13.125-10.25q-4.75-2.00 -11.00-2.00q-12.00,0.00 -20.75,8.00l-110.25,106.00l-110.25-106.00q-9.00-8.25 -20.75-8.25q-5.75,0.00 -11.00,2.25q-8.25,3.25 -13.125,10.25t-4.875,15.50l0.00,322.25 q0.00,8.50 4.875,15.50t 13.125,10.25q 5.25,2.25 11.00,2.25l 262.00,0.00 z" horiz-adv-x="320" /> -<glyph unicode=" " horiz-adv-x="224" /> -<glyph class="hidden" unicode="" d="M0,384L 448 -64L0 -64 z" horiz-adv-x="0" /> +<font id="icomoon" horiz-adv-x="512"> +<font-face units-per-em="512" ascent="480" descent="-32" /> +<missing-glyph horiz-adv-x="512" /> +<glyph unicode=" " d="" horiz-adv-x="256" /> +<glyph unicode="" d="M381.186 86.878l-19.971 158.833c-5.863 46.622-48.723 84.419-95.716 84.419h-14.532c-47.001 0-89.858-37.817-95.716-84.419l-19.97-158.833c-1.436-11.424 6.727-20.682 18.243-20.682h209.425c11.51 0 19.677 9.259 18.24 20.682zM258.649 282.012c-0.247-0.002-0.88-0.024-1.846-0.089-1.701-0.113-3.619-0.303-5.697-0.592-5.904-0.816-11.787-2.227-17.148-4.329-4.881-1.913-9.060-4.299-12.364-7.148-2.764-2.384-5.232-5.065-7.418-7.995-3.359-4.502-5.904-9.371-7.723-14.231-0.628-1.681-1.117-3.22-1.477-4.573-0.119-0.443-0.212-0.821-0.316-1.281-1.186-6.304-7.257-10.453-13.564-9.268-6.304 1.186-10.453 7.257-9.268 13.564 0.127 0.667 0.355 1.684 0.705 2.995 0.548 2.050 1.262 4.301 2.161 6.703 2.546 6.805 6.097 13.6 10.862 19.983 3.173 4.252 6.786 8.176 10.868 11.697 5.449 4.699 11.878 8.372 19.062 11.185 7.233 2.832 14.846 4.657 22.436 5.708 2.645 0.366 5.115 0.613 7.35 0.759 1.398 0.092 2.451 0.131 3.103 0.139 6.414 0.075 11.675-5.065 11.752-11.479 0.077-6.412-5.062-11.675-11.476-11.75zM240.26 405.353c0-9.469 7.678-17.147 17.147-17.147s17.147 7.678 17.147 17.147v55.31c0 9.469-7.678 17.147-17.147 17.147s-17.147-7.678-17.147-17.147v-55.31zM382.291 357.86c-8.071-4.954-10.599-15.509-5.649-23.581s15.509-10.6 23.581-5.649l47.144 28.922c8.071 4.953 10.599 15.509 5.649 23.581-4.954 8.071-15.509 10.6-23.581 5.649l-47.144-28.921zM109.74 327.524c8.071-4.953 18.629-2.422 23.581 5.649 4.953 8.071 2.422 18.63-5.649 23.581l-47.144 28.921c-8.071 4.954-18.63 2.422-23.581-5.649-4.953-8.071-2.422-18.63 5.649-23.581l47.145-28.921zM146.053 49.625c-11.511 0-20.84-9.339-20.84-20.836v-30.617c0-11.507 9.314-20.836 20.84-20.836h222.163c11.51 0 20.841 9.339 20.841 20.836v30.617c0 11.507-9.313 20.836-20.841 20.836h-222.163z" horiz-adv-x="536" /> +<glyph unicode="" d="M329.143 242.286q0 52.857-37.572 90.428t-90.428 37.572-90.428-37.572-37.572-90.428 37.572-90.428 90.428-37.572 90.428 37.572 37.572 90.428zM475.428 4.572q0-14.857-10.857-25.714t-25.714-10.857q-15.428 0-25.714 10.857l-98 97.714q-51.143-35.428-114-35.428-40.857 0-78.143 15.857t-64.285 42.857-42.857 64.286-15.857 78.143 15.857 78.143 42.857 64.286 64.285 42.857 78.143 15.857 78.143-15.857 64.286-42.857 42.857-64.286 15.857-78.143q0-62.857-35.428-114l98-98q10.572-10.572 10.572-25.714z" horiz-adv-x="476" /> +<glyph unicode="" d="M477.428 318.286q0-11.428-8-19.428l-245.714-245.714q-8-8-19.428-8t-19.428 8l-142.286 142.286q-8 8-8 19.428t8 19.428l38.857 38.857q8 8 19.428 8t19.428-8l84-84.286 187.429 187.714q8 8 19.428 8t19.428-8l38.857-38.857q8-8 8-19.429z" /> +<glyph unicode="" d="M370.857 102.286q0-11.428-8-19.428l-38.857-38.857q-8-8-19.428-8t-19.428 8l-84 84-84-84q-8-8-19.428-8t-19.428 8l-38.857 38.857q-8 8-8 19.428t8 19.428l84 84-84 84q-8 8-8 19.428t8 19.428l38.857 38.857q8 8 19.428 8t19.428-8l84-84 84 84q8 8 19.428 8t19.428-8l38.857-38.857q8-8 8-19.428t-8-19.428l-84-84 84-84q8-8 8-19.428z" horiz-adv-x="403" /> +<glyph unicode="" d="M438.857 224q0-44.572-17.428-85.143t-46.857-70-70-46.857-85.143-17.428-85.143 17.428-70 46.857-46.857 70-17.428 85.143q0 52 23 98t64.715 77.143q12.285 9.143 27.285 7.143t23.857-14.286q9.143-12 7-27t-14.143-24.143q-28-21.143-43.285-51.714t-15.285-65.143q0-29.715 11.572-56.715t31.285-46.714 46.715-31.286 56.714-11.572 56.714 11.572 46.714 31.286 31.286 46.714 11.572 56.714q0 34.572-15.286 65.143t-43.286 51.714q-12 9.143-14.143 24.143t7 27q8.857 12.286 24 14.286t27.143-7.143q41.714-31.143 64.714-77.143t23-98zM256 443.428v-182.857q0-14.857-10.857-25.714t-25.715-10.857-25.714 10.857-10.857 25.714v182.857q0 14.857 10.857 25.715t25.714 10.857 25.714-10.857 10.857-25.715z" horiz-adv-x="439" /> +<glyph unicode="" d="M292.572 224q0 30.286-21.428 51.714t-51.714 21.428-51.714-21.428-21.428-51.714 21.428-51.714 51.714-21.428 51.714 21.428 21.428 51.714zM438.857 255.143v-63.429q0-3.428-2.286-6.572t-5.714-3.714l-52.857-8q-5.428-15.428-11.143-26 10-14.286 30.572-39.428 2.857-3.428 2.857-7.143t-2.572-6.572q-7.714-10.572-28.286-30.857t-26.857-20.286q-3.428 0-7.428 2.572l-39.428 30.857q-12.572-6.572-26-10.857-4.572-38.857-8.286-53.143-2-8-10.286-8h-63.428q-4 0-7 2.428t-3.286 6.143l-8 52.572q-14 4.572-25.714 10.572l-40.285-30.572q-2.857-2.572-7.143-2.572-4 0-7.143 3.143-36 32.572-47.143 48-2 2.857-2 6.572 0 3.428 2.285 6.572 4.285 6 14.572 19t15.428 20.143q-7.715 14.286-11.715 28.286l-52.285 7.714q-3.715 0.572-6 3.572t-2.285 6.714v63.428q0 3.429 2.285 6.572t5.428 3.714l53.143 8q4 13.143 11.143 26.286-11.428 16.286-30.572 39.428-2.857 3.429-2.857 6.857 0 2.857 2.572 6.571 7.428 10.286 28.143 30.714t27 20.429q3.715 0 7.428-2.857l39.428-30.572q12.572 6.572 26 10.857 4.572 38.857 8.286 53.143 2 8 10.286 8h63.428q4 0 7-2.428t3.286-6.143l8-52.572q14-4.572 25.714-10.572l40.572 30.572q2.572 2.572 6.857 2.572 3.714 0 7.143-2.857 36.857-34 47.143-48.572 2-2.285 2-6.285 0-3.429-2.286-6.572-4.286-6-14.572-19t-15.428-20.143q7.428-14.285 11.714-28l52.286-8q3.714-0.571 6-3.571t2.286-6.714z" horiz-adv-x="439" /> +<glyph unicode="" d="M146.286 269.714v-164.571q0-4-2.571-6.572t-6.571-2.572h-18.285q-4 0-6.572 2.572t-2.572 6.572v164.572q0 4 2.572 6.571t6.572 2.571h18.285q4 0 6.572-2.571t2.571-6.572zM219.429 269.714v-164.571q0-4-2.571-6.572t-6.572-2.572h-18.286q-4 0-6.572 2.572t-2.571 6.572v164.572q0 4 2.571 6.571t6.572 2.571h18.286q4 0 6.572-2.571t2.571-6.572zM292.572 269.714v-164.571q0-4-2.572-6.572t-6.572-2.572h-18.286q-4 0-6.572 2.572t-2.571 6.572v164.572q0 4 2.571 6.571t6.572 2.571h18.286q4 0 6.572-2.571t2.572-6.572zM329.143 62.857v270.857h-256v-270.857q0-6.286 2-11.572t4.143-7.714 3-2.428h237.715q0.857 0 3 2.428t4.143 7.714 2 11.572zM137.143 370.286h128l-13.714 33.428q-2 2.572-4.857 3.143h-90.571q-2.857-0.571-4.857-3.143zM402.286 361.143v-18.286q0-4-2.572-6.572t-6.572-2.571h-27.428v-270.857q0-23.714-13.428-41t-32.286-17.286h-237.714q-18.857 0-32.285 16.714t-13.428 40.428v272h-27.428q-4 0-6.572 2.572t-2.571 6.571v18.286q0 4 2.571 6.572t6.572 2.571h88.285l20 47.714q4.285 10.572 15.429 18t22.572 7.429h91.428q11.428 0 22.572-7.429t15.428-18l20-47.714h88.286q4 0 6.572-2.571t2.572-6.572z" horiz-adv-x="403" /> +<glyph unicode="" d="M310.857 214.857v-18.286q0-3.714-2.714-6.428t-6.428-2.714h-109.714q-3.714 0-6.428 2.714t-2.714 6.428v128q0 3.714 2.714 6.428t6.428 2.714h18.286q3.714 0 6.428-2.714t2.714-6.428v-100.572h82.286q3.714 0 6.428-2.714t2.714-6.428zM365.714 224q0 29.714-11.572 56.714t-31.286 46.714-46.714 31.286-56.714 11.571-56.714-11.571-46.715-31.286-31.285-46.714-11.572-56.714 11.572-56.714 31.285-46.714 46.715-31.286 56.714-11.572 56.714 11.572 46.714 31.286 31.286 46.714 11.572 56.714zM438.857 224q0-59.714-29.428-110.143t-79.857-79.857-110.143-29.428-110.143 29.428-79.857 79.857-29.428 110.143 29.428 110.143 79.857 79.857 110.143 29.428 110.143-29.428 79.857-79.857 29.428-110.143z" horiz-adv-x="439" /> +<glyph unicode="" d="M431.714 178.286q0-1.428-0.286-2-18.286-76.572-76.572-124.143t-136.571-47.572q-41.715 0-80.715 15.714t-69.572 44.857l-36.857-36.857q-5.428-5.428-12.857-5.428t-12.857 5.428-5.428 12.857v128q0 7.428 5.428 12.857t12.857 5.428h128q7.428 0 12.857-5.428t5.429-12.857-5.428-12.857l-39.143-39.143q20.285-18.857 46-29.143t53.429-10.286q38.286 0 71.428 18.572t53.143 51.143q3.143 4.857 15.143 33.428 2.286 6.572 8.572 6.572h54.857q3.714 0 6.428-2.714t2.714-6.428zM438.857 406.857v-128q0-7.428-5.428-12.857t-12.857-5.428h-128q-7.428 0-12.857 5.428t-5.428 12.857 5.428 12.857l39.428 39.428q-42.286 39.143-99.714 39.143-38.286 0-71.428-18.571t-53.143-51.143q-3.143-4.857-15.143-33.429-2.285-6.572-8.572-6.572h-56.857q-3.715 0-6.428 2.714t-2.715 6.428v2q18.572 76.572 77.143 124.143t137.143 47.571q41.714 0 81.143-15.857t70-44.714l37.143 36.857q5.428 5.428 12.857 5.428t12.857-5.428 5.428-12.857z" horiz-adv-x="439" /> +<glyph unicode="" d="M201.143 187.428q0 15.143-10.714 25.857t-25.857 10.714-25.857-10.714-10.714-25.857q0-10.572 5.429-19.143t14.572-13.428l-19.714-65.428q-1.428-4.286 1.429-8t7.429-3.714h54.857q4.571 0 7.429 3.714t1.429 8l-19.715 65.428q9.143 4.857 14.572 13.428t5.428 19.143zM91.428 260.572h146.286v54.857q0 30.286-21.428 51.714t-51.714 21.429-51.715-21.429-21.428-51.714v-54.857zM329.143 233.143v-164.571q0-11.428-8-19.428t-19.428-8h-274.286q-11.428 0-19.428 8t-8 19.428v164.571q0 11.429 8 19.429t19.428 8h9.143v54.857q0 52.572 37.715 90.286t90.285 37.714 90.285-37.714 37.714-90.286v-54.857h9.143q11.428 0 19.428-8t8-19.428z" horiz-adv-x="329" /> +<glyph unicode="" d="M332.572 443.428q6.572 0 12.572-2.572 9.428-3.714 15-11.714t5.572-17.714v-368.286q0-9.714-5.572-17.714t-15-11.714q-5.428-2.286-12.572-2.286-13.714 0-23.714 9.143l-126 121.143-126-121.143q-10.285-9.428-23.715-9.428-6.572 0-12.572 2.572-9.428 3.714-15 11.714t-5.572 17.714v368.286q0 9.714 5.572 17.714t15 11.715q6 2.571 12.572 2.571h299.428z" horiz-adv-x="366" /> +<glyph unicode="" d="M292.572 86.857v18.286q0 4-2.572 6.572t-6.572 2.572h-27.428v137.143q0 4-2.571 6.571t-6.571 2.571h-91.428q-4 0-6.572-2.571t-2.571-6.572v-18.286q0-4 2.571-6.572t6.572-2.571h27.428v-109.715h-27.428q-4 0-6.572-2.572t-2.571-6.572v-18.286q0-4 2.571-6.572t6.572-2.572h128q4 0 6.572 2.572t2.572 6.572zM256 306.286v54.857q0 4-2.571 6.571t-6.571 2.572h-54.857q-4 0-6.571-2.572t-2.571-6.571v-54.857q0-4 2.571-6.572t6.572-2.571h54.857q4 0 6.571 2.571t2.572 6.572zM438.857 224q0-59.714-29.428-110.143t-79.857-79.857-110.143-29.428-110.143 29.428-79.857 79.857-29.428 110.143 29.428 110.143 79.857 79.857 110.143 29.428 110.143-29.428 79.857-79.857 29.428-110.143z" horiz-adv-x="439" /> +<glyph unicode="" d="M342 187.428h-31.143q-7.428 0-12.857 5.428t-5.428 12.857v36.572q0 7.428 5.428 12.857t12.857 5.429h31.143q-9.143 30.857-32.143 53.857t-53.857 32.143v-31.143q0-7.429-5.429-12.857t-12.857-5.428h-36.571q-7.428 0-12.857 5.428t-5.429 12.857v31.143q-30.857-9.143-53.857-32.143t-32.143-53.857h31.143q7.429 0 12.857-5.428t5.428-12.857v-36.571q0-7.428-5.428-12.857t-12.857-5.428h-31.143q9.143-30.857 32.143-53.857t53.857-32.143v31.143q0 7.428 5.428 12.857t12.857 5.428h36.571q7.428 0 12.857-5.428t5.429-12.857v-31.143q30.857 9.143 53.857 32.143t32.143 53.857zM438.857 242.286v-36.572q0-7.428-5.428-12.857t-12.857-5.428h-40.857q-10.572-46-44.143-79.572t-79.572-44.143v-40.857q0-7.428-5.428-12.857t-12.857-5.428h-36.571q-7.428 0-12.857 5.428t-5.429 12.857v40.857q-46 10.572-79.572 44.143t-44.143 79.572h-40.857q-7.428 0-12.857 5.428t-5.428 12.857v36.572q0 7.428 5.428 12.857t12.857 5.429h40.857q10.572 46 44.143 79.572t79.572 44.143v40.857q0 7.428 5.428 12.857t12.857 5.428h36.571q7.428 0 12.857-5.428t5.429-12.857v-40.857q46-10.571 79.572-44.143t44.143-79.572h40.857q7.428 0 12.857-5.428t5.428-12.857z" horiz-adv-x="439" /> +<glyph unicode="" d="M365.714 224q0 39.714-20.286 74.286l-200.286-200.286q34.572-20.286 74.286-20.286 29.714 0 56.714 11.572t46.714 31.286 31.286 46.714 11.572 56.714zM93.428 149.714l200.286 200.286q-34.572 20.286-74.286 20.286-29.714 0-56.714-11.572t-46.715-31.286-31.285-46.714-11.572-56.714q0-39.714 20.285-74.286zM438.857 224q0-59.714-29.428-110.143t-79.857-79.857-110.143-29.428-110.143 29.428-79.857 79.857-29.428 110.143 29.428 110.143 79.857 79.857 110.143 29.428 110.143-29.428 79.857-79.857 29.428-110.143z" horiz-adv-x="439" /> +<glyph unicode="" d="M215.714 178.286q0-3.714-2.857-6.572l-94.857-94.857 41.143-41.143q5.429-5.428 5.429-12.857t-5.428-12.857-12.857-5.428h-128q-7.428 0-12.857 5.428t-5.428 12.857v128q0 7.428 5.428 12.857t12.857 5.428 12.857-5.428l41.143-41.143 94.857 94.857q2.857 2.857 6.572 2.857t6.572-2.857l32.572-32.572q2.857-2.857 2.857-6.572zM438.857 425.143v-128q0-7.429-5.428-12.857t-12.857-5.428-12.857 5.428l-41.143 41.143-94.857-94.857q-2.857-2.857-6.572-2.857t-6.572 2.857l-32.572 32.572q-2.857 2.857-2.857 6.572t2.857 6.572l94.857 94.857-41.143 41.143q-5.428 5.428-5.428 12.857t5.428 12.857 12.857 5.428h128q7.428 0 12.857-5.428t5.428-12.857z" horiz-adv-x="439" /> +<glyph unicode="" d="M219.429 205.714v-128q0-7.428-5.429-12.857t-12.857-5.428-12.857 5.428l-41.143 41.143-94.857-94.857q-2.857-2.857-6.572-2.857t-6.572 2.857l-32.572 32.572q-2.857 2.857-2.857 6.572t2.857 6.572l94.857 94.857-41.143 41.143q-5.428 5.428-5.428 12.857t5.428 12.857 12.857 5.428h128q7.428 0 12.857-5.428t5.429-12.857zM435.143 397.714q0-3.714-2.857-6.571l-94.857-94.857 41.143-41.143q5.428-5.429 5.428-12.857t-5.428-12.857-12.857-5.429h-128q-7.428 0-12.857 5.428t-5.429 12.857v128q0 7.429 5.428 12.857t12.857 5.428 12.857-5.428l41.143-41.143 94.857 94.857q2.857 2.857 6.572 2.857t6.572-2.857l32.572-32.572q2.857-2.857 2.857-6.572z" horiz-adv-x="439" /> +<glyph unicode="" d="M219.429 443.428q59.715 0 110.143-29.428t79.857-79.857 29.428-110.143-29.428-110.143-79.857-79.857-110.143-29.428-110.143 29.428-79.857 79.857-29.428 110.143 29.428 110.143 79.857 79.857 110.143 29.428zM256 87.143v54.286q0 4-2.571 6.714t-6.286 2.714h-54.857q-3.714 0-6.572-2.857t-2.857-6.572v-54.286q0-3.714 2.857-6.572t6.572-2.857h54.857q3.714 0 6.286 2.714t2.571 6.714zM255.429 185.428l5.143 177.428q0 3.429-2.857 5.143-2.857 2.286-6.857 2.286h-62.857q-4 0-6.857-2.286-2.857-1.714-2.857-5.143l4.857-177.428q0-2.857 2.857-5t6.857-2.143h52.857q4 0 6.714 2.143t3 5z" horiz-adv-x="439" /> +<glyph unicode="" d="M292.572 87.143v54.286q0 4-2.714 6.714t-6.428 2.714h-54.857q-3.714 0-6.429-2.714t-2.714-6.714v-54.286q0-4 2.714-6.714t6.428-2.714h54.857q3.714 0 6.428 2.714t2.714 6.714zM292 194l5.143 131.143q0 3.428-2.857 5.428-3.714 3.143-6.857 3.143h-62.857q-3.143 0-6.857-3.143-2.857-2-2.857-6l4.857-130.572q0-2.857 2.857-4.714t6.857-1.857h52.857q4 0 6.714 1.857t3 4.714zM288 460.857l219.428-402.285q10-18-0.572-36-4.857-8.286-13.286-13.143t-18.143-4.857h-438.857q-9.715 0-18.143 4.857t-13.286 13.143q-10.572 18-0.572 36l219.429 402.286q4.857 8.857 13.429 14t18.572 5.143 18.572-5.143 13.428-14z" /> +<glyph unicode="" d="M438.857 96v-36.572q0-7.428-5.428-12.857t-12.857-5.428h-402.286q-7.428 0-12.857 5.428t-5.428 12.857v36.572q0 7.428 5.428 12.857t12.857 5.428h402.286q7.428 0 12.857-5.428t5.428-12.857zM438.857 242.286v-36.572q0-7.428-5.428-12.857t-12.857-5.428h-402.286q-7.428 0-12.857 5.428t-5.428 12.857v36.572q0 7.428 5.428 12.857t12.857 5.429h402.286q7.428 0 12.857-5.428t5.428-12.857zM438.857 388.572v-36.572q0-7.428-5.428-12.857t-12.857-5.429h-402.286q-7.428 0-12.857 5.428t-5.428 12.857v36.571q0 7.429 5.428 12.857t12.857 5.428h402.286q7.428 0 12.857-5.428t5.428-12.857z" horiz-adv-x="439" /> +<glyph unicode="" d="M340 314l83.714 83.714-30.572 30.572-83.714-83.714zM467.714 397.714q0-7.714-5.143-12.857l-367.428-367.428q-5.143-5.143-12.857-5.143t-12.857 5.143l-56.572 56.572q-5.143 5.143-5.143 12.857t5.143 12.857l367.428 367.428q5.143 5.143 12.857 5.143t12.857-5.143l56.572-56.572q5.143-5.143 5.143-12.857zM81.715 452l28-8.572-28-8.572-8.572-28-8.572 28-28 8.572 28 8.572 8.572 28zM181.714 405.714l56-17.143-56-17.143-17.143-56-17.143 56-56 17.143 56 17.143 17.143 56zM447.428 269.143l28-8.572-28-8.572-8.572-28-8.572 28-28 8.572 28 8.572 8.572 28zM264.572 452l28-8.572-28-8.572-8.572-28-8.572 28-28 8.572 28 8.572 8.572 28z" horiz-adv-x="476" /> +<glyph unicode="" d="M512 123.428v-91.428q0-11.428-8-19.428t-19.428-8h-91.428q-11.428 0-19.428 8t-8 19.428v91.428q0 11.428 8 19.428t19.428 8h27.428v54.857h-146.286v-54.857h27.428q11.428 0 19.428-8t8-19.428v-91.428q0-11.428-8-19.428t-19.428-8h-91.428q-11.428 0-19.428 8t-8 19.428v91.428q0 11.428 8 19.428t19.428 8h27.428v54.857h-146.286v-54.857h27.428q11.428 0 19.428-8t8-19.428v-91.428q0-11.428-8-19.428t-19.428-8h-91.428q-11.428 0-19.428 8t-8 19.428v91.428q0 11.428 8 19.428t19.428 8h27.428v54.857q0 14.857 10.857 25.714t25.715 10.857h146.286v54.857h-27.428q-11.428 0-19.428 8t-8 19.428v91.428q0 11.428 8 19.428t19.428 8h91.428q11.428 0 19.428-8t8-19.428v-91.428q0-11.428-8-19.428t-19.428-8h-27.428v-54.857h146.286q14.857 0 25.714-10.857t10.857-25.714v-54.857h27.428q11.428 0 19.428-8t8-19.428z" /> +<glyph unicode="" d="M512 141.714v-54.857q0-3.714-2.714-6.428t-6.428-2.714h-393.143v-54.857q0-3.714-2.715-6.428t-6.428-2.714q-3.428 0-6.857 2.857l-91.143 91.428q-2.571 2.572-2.571 6.286 0 4 2.571 6.572l91.428 91.428q2.572 2.572 6.572 2.572 3.715 0 6.428-2.714t2.715-6.428v-54.857h393.143q3.714 0 6.428-2.714t2.714-6.428zM512 297.143q0-4-2.572-6.572l-91.428-91.428q-2.572-2.572-6.572-2.572-3.714 0-6.428 2.714t-2.714 6.428v54.857h-393.143q-3.715 0-6.428 2.714t-2.715 6.429v54.857q0 3.714 2.715 6.428t6.428 2.714h393.143v54.857q0 4 2.572 6.571t6.572 2.572q3.428 0 6.857-2.857l91.143-91.143q2.572-2.571 2.572-6.572z" /> +<glyph unicode="" d="M109.715 96q0-7.428-5.428-12.857t-12.857-5.428-12.857 5.428-5.428 12.857 5.428 12.857 12.857 5.428 12.857-5.428 5.428-12.857zM402.286 78.572q0-34.572-20.857-54.286t-55.428-19.714h-249.714q-34.572 0-55.428 19.714t-20.857 54.286q0 19.428 1.571 37.428t6.857 39.428 13.572 37.857 23.143 29.428 34.285 17.286q-6.285-14.857-6.285-34.286v-58q-16.572-5.714-26.572-20t-10-31.714q0-22.857 16-38.857t38.857-16 38.857 16 16 38.857q0 17.428-10.143 31.714t-26.428 20v58q0 17.714 7.143 26.572 37.715-29.714 84.285-29.714t84.285 29.714q7.143-8.857 7.143-26.572v-18.286q-30.286 0-51.714-21.428t-21.428-51.714v-25.428q-9.143-8.286-9.143-20.286 0-11.428 8-19.428t19.429-8 19.428 8 8 19.428q0 12-9.143 20.286v25.428q0 14.857 10.857 25.714t25.714 10.857 25.714-10.857 10.857-25.714v-25.428q-9.143-8.286-9.143-20.286 0-11.428 8-19.428t19.428-8 19.428 8 8 19.428q0 12-9.143 20.286v25.428q0 19.428-9.857 36.428t-26.714 26.714q0 2.857 0.143 12.143t0 13.714-0.714 11.857-2 13.428-3.714 11.428q19.428-4.286 34.286-17.286t23.143-29.428 13.572-37.857 6.857-39.428 1.572-37.428zM310.857 333.714q0-45.428-32.143-77.572t-77.572-32.143-77.572 32.143-32.143 77.571 32.143 77.572 77.572 32.143 77.572-32.143 32.143-77.572z" horiz-adv-x="403" /> +<glyph unicode="" d="M365.714 224q0 29.714-11.572 56.714t-31.286 46.714-46.714 31.286-56.714 11.571-56.714-11.571-46.715-31.286-31.285-46.714-11.572-56.714 11.572-56.714 31.285-46.714 46.715-31.286 56.714-11.572 56.714 11.572 46.714 31.286 31.286 46.714 11.572 56.714zM438.857 224q0-59.714-29.428-110.143t-79.857-79.857-110.143-29.428-110.143 29.428-79.857 79.857-29.428 110.143 29.428 110.143 79.857 79.857 110.143 29.428 110.143-29.428 79.857-79.857 29.428-110.143z" horiz-adv-x="439" /> +<glyph unicode="" d="M141.714 96q0-17.143-12.143-29.143t-29-12q-17.143 0-29.143 12t-12 29.143 12 29.143 29.143 12q16.857 0 29-12t12.143-29.143zM265.143 41.143q0-15.143-10.714-25.857t-25.857-10.714-25.857 10.714-10.714 25.857 10.714 25.857 25.857 10.714 25.857-10.714 10.714-25.857zM91.428 224q0-18.857-13.428-32.286t-32.285-13.428-32.285 13.428-13.428 32.286 13.428 32.286 32.285 13.428 32.285-13.428 13.428-32.286zM388.572 96q0-13.143-9.428-22.572t-22.572-9.428-22.572 9.428-9.428 22.572 9.428 22.572 22.572 9.428 22.572-9.428 9.428-22.572zM150.857 352q0-20.857-14.714-35.572t-35.572-14.714-35.572 14.714-14.715 35.572 14.715 35.572 35.572 14.714 35.572-14.714 14.714-35.572zM283.428 406.857q0-22.857-16-38.857t-38.857-16-38.857 16-16 38.857 16 38.857 38.857 16 38.857-16 16-38.857zM438.857 224q0-11.428-8-19.428t-19.428-8-19.428 8-8 19.428 8 19.428 19.428 8 19.428-8 8-19.428zM379.428 352q0-9.428-6.714-16.143t-16.143-6.714-16.143 6.714-6.714 16.143 6.714 16.143 16.143 6.714 16.143-6.714 6.714-16.143z" horiz-adv-x="448" /> +<glyph unicode="" d="M438.857 224q0-59.714-29.428-110.143t-79.857-79.857-110.143-29.428-110.143 29.428-79.857 79.857-29.428 110.143 29.428 110.143 79.857 79.857 110.143 29.428 110.143-29.428 79.857-79.857 29.428-110.143z" horiz-adv-x="439" /> </font></defs></svg>
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.ttf b/WebContent/VAADIN/themes/base/debug/fonts/font.ttf Binary files differindex e26c910020..eee808e07e 100644..100755 --- a/WebContent/VAADIN/themes/base/debug/fonts/font.ttf +++ b/WebContent/VAADIN/themes/base/debug/fonts/font.ttf diff --git a/WebContent/VAADIN/themes/base/debug/fonts/font.woff b/WebContent/VAADIN/themes/base/debug/fonts/font.woff Binary files differindex e23e3807d0..2cd069ffdf 100644..100755 --- a/WebContent/VAADIN/themes/base/debug/fonts/font.woff +++ b/WebContent/VAADIN/themes/base/debug/fonts/font.woff diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot Binary files differnew file mode 100644 index 0000000000..7c79c6a6bc --- /dev/null +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.eot diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000000..45fdf33830 --- /dev/null +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.svg @@ -0,0 +1,414 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" > +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata></metadata> +<defs> +<font id="fontawesomeregular" horiz-adv-x="1536" > +<font-face units-per-em="1792" ascent="1536" descent="-256" /> +<missing-glyph horiz-adv-x="448" /> +<glyph unicode=" " horiz-adv-x="448" /> +<glyph unicode="	" horiz-adv-x="448" /> +<glyph unicode=" " horiz-adv-x="448" /> +<glyph unicode="¨" horiz-adv-x="1792" /> +<glyph unicode="©" horiz-adv-x="1792" /> +<glyph unicode="®" horiz-adv-x="1792" /> +<glyph unicode="´" horiz-adv-x="1792" /> +<glyph unicode="Æ" horiz-adv-x="1792" /> +<glyph unicode=" " horiz-adv-x="768" /> +<glyph unicode=" " /> +<glyph unicode=" " horiz-adv-x="768" /> +<glyph unicode=" " /> +<glyph unicode=" " horiz-adv-x="512" /> +<glyph unicode=" " horiz-adv-x="384" /> +<glyph unicode=" " horiz-adv-x="256" /> +<glyph unicode=" " horiz-adv-x="256" /> +<glyph unicode=" " horiz-adv-x="192" /> +<glyph unicode=" " horiz-adv-x="307" /> +<glyph unicode=" " horiz-adv-x="85" /> +<glyph unicode=" " horiz-adv-x="307" /> +<glyph unicode=" " horiz-adv-x="384" /> +<glyph unicode="™" horiz-adv-x="1792" /> +<glyph unicode="∞" horiz-adv-x="1792" /> +<glyph unicode="≠" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="500" d="M0 0z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1699 1350q0 -35 -43 -78l-632 -632v-768h320q26 0 45 -19t19 -45t-19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45t45 19h320v768l-632 632q-43 43 -43 78q0 23 18 36.5t38 17.5t43 4h1408q23 0 43 -4t38 -17.5t18 -36.5z" /> +<glyph unicode="" d="M1536 1312v-1120q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v537l-768 -237v-709q0 -50 -34 -89t-86 -60.5t-103.5 -32t-96.5 -10.5t-96.5 10.5t-103.5 32t-86 60.5t-34 89 t34 89t86 60.5t103.5 32t96.5 10.5q105 0 192 -39v967q0 31 19 56.5t49 35.5l832 256q12 4 28 4q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -52 -38 -90t-90 -38q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5 t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1664 32v768q-32 -36 -69 -66q-268 -206 -426 -338q-51 -43 -83 -67t-86.5 -48.5t-102.5 -24.5h-1h-1q-48 0 -102.5 24.5t-86.5 48.5t-83 67q-158 132 -426 338q-37 30 -69 66v-768q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1664 1083v11v13.5t-0.5 13 t-3 12.5t-5.5 9t-9 7.5t-14 2.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5q0 -168 147 -284q193 -152 401 -317q6 -5 35 -29.5t46 -37.5t44.5 -31.5t50.5 -27.5t43 -9h1h1q20 0 43 9t50.5 27.5t44.5 31.5t46 37.5t35 29.5q208 165 401 317q54 43 100.5 115.5t46.5 131.5z M1792 1120v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47t47 -113z" /> +<glyph unicode="" horiz-adv-x="1792" d="M896 -128q-26 0 -44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5q224 0 351 -124t127 -344q0 -221 -229 -450l-623 -600 q-18 -18 -44 -18z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -21 -10.5 -35.5t-30.5 -14.5q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455 l502 -73q56 -9 56 -46z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1137 532l306 297l-422 62l-189 382l-189 -382l-422 -62l306 -297l-73 -421l378 199l377 -199zM1664 889q0 -22 -26 -48l-363 -354l86 -500q1 -7 1 -20q0 -50 -41 -50q-19 0 -40 12l-449 236l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500 l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41t49 -41l225 -455l502 -73q56 -9 56 -46z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1408 131q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5t43 97.5t62 81t85.5 53.5t111.5 20q9 0 42 -21.5t74.5 -48t108 -48t133.5 -21.5t133.5 21.5t108 48t74.5 48t42 21.5q61 0 111.5 -20t85.5 -53.5t62 -81 t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M384 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 320v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM384 704v128q0 26 -19 45t-45 19h-128 q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 -64v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM384 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45 t45 -19h128q26 0 45 19t19 45zM1792 -64v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1408 704v512q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-512q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1792 320v128 q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 704v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1792 1088v128q0 26 -19 45t-45 19h-128q-26 0 -45 -19 t-19 -45v-128q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1920 1248v-1344q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1344q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> +<glyph unicode="" horiz-adv-x="1664" d="M768 512v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM768 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 512v-384q0 -52 -38 -90t-90 -38 h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90zM1664 1280v-384q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v384q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 288v-192q0 -40 -28 -68t-68 -28h-320 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1152 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M512 288v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM512 800v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 288v-192q0 -40 -28 -68t-68 -28h-960 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68zM512 1312v-192q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h320q40 0 68 -28t28 -68zM1792 800v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28 h960q40 0 68 -28t28 -68zM1792 1312v-192q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h960q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1671 970q0 -40 -28 -68l-724 -724l-136 -136q-28 -28 -68 -28t-68 28l-136 136l-362 362q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -295l656 657q28 28 68 28t68 -28l136 -136q28 -28 28 -68z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1298 214q0 -40 -28 -68l-136 -136q-28 -28 -68 -28t-68 28l-294 294l-294 -294q-28 -28 -68 -28t-68 28l-136 136q-28 28 -28 68t28 68l294 294l-294 294q-28 28 -28 68t28 68l136 136q28 28 68 28t68 -28l294 -294l294 294q28 28 68 28t68 -28l136 -136q28 -28 28 -68 t-28 -68l-294 -294l294 -294q28 -28 28 -68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-224q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v224h-224q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h224v224q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5v-224h224 q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5zM1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5 t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1024 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-576q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h576q13 0 22.5 -9.5t9.5 -22.5zM1152 704q0 185 -131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5t316.5 131.5t131.5 316.5z M1664 -128q0 -53 -37.5 -90.5t-90.5 -37.5q-54 0 -90 38l-343 342q-179 -124 -399 -124q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5t55.5 273.5t150 225t225 150t273.5 55.5t273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -220 -124 -399l343 -343q37 -37 37 -90z " /> +<glyph unicode="" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61t-298 61t-245 164t-164 245t-61 298q0 182 80.5 343t226.5 270q43 32 95.5 25t83.5 -50q32 -42 24.5 -94.5t-49.5 -84.5q-98 -74 -151.5 -181t-53.5 -228q0 -104 40.5 -198.5t109.5 -163.5t163.5 -109.5 t198.5 -40.5t198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5q0 121 -53.5 228t-151.5 181q-42 32 -49.5 84.5t24.5 94.5q31 43 84 50t95 -25q146 -109 226.5 -270t80.5 -343zM896 1408v-640q0 -52 -38 -90t-90 -38t-90 38t-38 90v640q0 52 38 90t90 38t90 -38t38 -90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M256 96v-192q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM640 224v-320q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1024 480v-576q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23 v576q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1408 864v-960q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v960q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1792 1376v-1472q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1472q0 14 9 23t23 9h192q14 0 23 -9t9 -23z" /> +<glyph unicode="" d="M1024 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1536 749v-222q0 -12 -8 -23t-20 -13l-185 -28q-19 -54 -39 -91q35 -50 107 -138q10 -12 10 -25t-9 -23q-27 -37 -99 -108t-94 -71q-12 0 -26 9l-138 108q-44 -23 -91 -38 q-16 -136 -29 -186q-7 -28 -36 -28h-222q-14 0 -24.5 8.5t-11.5 21.5l-28 184q-49 16 -90 37l-141 -107q-10 -9 -25 -9q-14 0 -25 11q-126 114 -165 168q-7 10 -7 23q0 12 8 23q15 21 51 66.5t54 70.5q-27 50 -41 99l-183 27q-13 2 -21 12.5t-8 23.5v222q0 12 8 23t19 13 l186 28q14 46 39 92q-40 57 -107 138q-10 12 -10 24q0 10 9 23q26 36 98.5 107.5t94.5 71.5q13 0 26 -10l138 -107q44 23 91 38q16 136 29 186q7 28 36 28h222q14 0 24.5 -8.5t11.5 -21.5l28 -184q49 -16 90 -37l142 107q9 9 24 9q13 0 25 -10q129 -119 165 -170q7 -8 7 -22 q0 -12 -8 -23q-15 -21 -51 -66.5t-54 -70.5q26 -50 41 -98l183 -28q13 -2 21 -12.5t8 -23.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M512 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM768 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1024 800v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1152 76v948h-896v-948q0 -22 7 -40.5t14.5 -27t10.5 -8.5h832q3 0 10.5 8.5t14.5 27t7 40.5zM480 1152h448l-48 117q-7 9 -17 11h-317q-10 -2 -17 -11zM1408 1120v-64q0 -14 -9 -23t-23 -9h-96v-948q0 -83 -47 -143.5t-113 -60.5h-832 q-66 0 -113 58.5t-47 141.5v952h-96q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h309l70 167q15 37 54 63t79 26h320q40 0 79 -26t54 -63l70 -167h309q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1408 544v-480q0 -26 -19 -45t-45 -19h-384v384h-256v-384h-384q-26 0 -45 19t-19 45v480q0 1 0.5 3t0.5 3l575 474l575 -474q1 -2 1 -6zM1631 613l-62 -74q-8 -9 -21 -11h-3q-13 0 -21 7l-692 577l-692 -577q-12 -8 -24 -7q-13 2 -21 11l-62 74q-8 10 -7 23.5t11 21.5 l719 599q32 26 76 26t76 -26l244 -204v195q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-408l219 -182q10 -8 11 -21.5t-7 -23.5z" /> +<glyph unicode="" horiz-adv-x="1280" d="M128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280zM768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z " /> +<glyph unicode="" d="M896 992v-448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1111 540v4l-24 320q-1 13 -11 22.5t-23 9.5h-186q-13 0 -23 -9.5t-11 -22.5l-24 -320v-4q-1 -12 8 -20t21 -8h244q12 0 21 8t8 20zM1870 73q0 -73 -46 -73h-704q13 0 22 9.5t8 22.5l-20 256q-1 13 -11 22.5t-23 9.5h-272q-13 0 -23 -9.5t-11 -22.5l-20 -256 q-1 -13 8 -22.5t22 -9.5h-704q-46 0 -46 73q0 54 26 116l417 1044q8 19 26 33t38 14h339q-13 0 -23 -9.5t-11 -22.5l-15 -192q-1 -14 8 -23t22 -9h166q13 0 22 9t8 23l-15 192q-1 13 -11 22.5t-23 9.5h339q20 0 38 -14t26 -33l417 -1044q26 -62 26 -116z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1280 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 416v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h465l135 -136 q58 -56 136 -56t136 56l136 136h464q40 0 68 -28t28 -68zM1339 985q17 -41 -14 -70l-448 -448q-18 -19 -45 -19t-45 19l-448 448q-31 29 -14 70q17 39 59 39h256v448q0 26 19 45t45 19h256q26 0 45 -19t19 -45v-448h256q42 0 59 -39z" /> +<glyph unicode="" d="M1120 608q0 -12 -10 -24l-319 -319q-11 -9 -23 -9t-23 9l-320 320q-15 16 -7 35q8 20 30 20h192v352q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-352h192q14 0 23 -9t9 -23zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273 t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1118 660q-8 -20 -30 -20h-192v-352q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v352h-192q-14 0 -23 9t-9 23q0 12 10 24l319 319q11 9 23 9t23 -9l320 -320q15 -16 7 -35zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198 t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1023 576h316q-1 3 -2.5 8t-2.5 8l-212 496h-708l-212 -496q-1 -2 -2.5 -8t-2.5 -8h316l95 -192h320zM1536 546v-482q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v482q0 62 25 123l238 552q10 25 36.5 42t52.5 17h832q26 0 52.5 -17t36.5 -42l238 -552 q25 -61 25 -123z" /> +<glyph unicode="" d="M1184 640q0 -37 -32 -55l-544 -320q-15 -9 -32 -9q-16 0 -32 8q-32 19 -32 56v640q0 37 32 56q33 18 64 -1l544 -320q32 -18 32 -55zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l138 138q-148 137 -349 137q-104 0 -198.5 -40.5t-163.5 -109.5t-109.5 -163.5t-40.5 -198.5t40.5 -198.5t109.5 -163.5t163.5 -109.5t198.5 -40.5q119 0 225 52t179 147q7 10 23 12q14 0 25 -9 l137 -138q9 -8 9.5 -20.5t-7.5 -22.5q-109 -132 -264 -204.5t-327 -72.5q-156 0 -298 61t-245 164t-164 245t-61 298t61 298t164 245t245 164t298 61q147 0 284.5 -55.5t244.5 -156.5l130 129q29 31 70 14q39 -17 39 -59z" /> +<glyph unicode="" d="M1511 480q0 -5 -1 -7q-64 -268 -268 -434.5t-478 -166.5q-146 0 -282.5 55t-243.5 157l-129 -129q-19 -19 -45 -19t-45 19t-19 45v448q0 26 19 45t45 19h448q26 0 45 -19t19 -45t-19 -45l-137 -137q71 -66 161 -102t187 -36q134 0 250 65t186 179q11 17 53 117 q8 23 30 23h192q13 0 22.5 -9.5t9.5 -22.5zM1536 1280v-448q0 -26 -19 -45t-45 -19h-448q-26 0 -45 19t-19 45t19 45l138 138q-148 137 -349 137q-134 0 -250 -65t-186 -179q-11 -17 -53 -117q-8 -23 -30 -23h-199q-13 0 -22.5 9.5t-9.5 22.5v7q65 268 270 434.5t480 166.5 q146 0 284 -55.5t245 -156.5l130 129q19 19 45 19t45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M384 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M384 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1536 352v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5z M1536 608v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5t9.5 -22.5zM1536 864v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h960q13 0 22.5 -9.5 t9.5 -22.5zM1664 160v832q0 13 -9.5 22.5t-22.5 9.5h-1472q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1472q13 0 22.5 9.5t9.5 22.5zM1792 1248v-1088q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1472q66 0 113 -47 t47 -113z" /> +<glyph unicode="" horiz-adv-x="1152" d="M320 768h512v192q0 106 -75 181t-181 75t-181 -75t-75 -181v-192zM1152 672v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v192q0 184 132 316t316 132t316 -132t132 -316v-192h32q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="1792" d="M320 1280q0 -72 -64 -110v-1266q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v1266q-64 38 -64 110q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -25 -12.5 -38.5t-39.5 -27.5q-215 -116 -369 -116q-61 0 -123.5 22t-108.5 48 t-115.5 48t-142.5 22q-192 0 -464 -146q-17 -9 -33 -9q-26 0 -45 19t-19 45v742q0 32 31 55q21 14 79 43q236 120 421 120q107 0 200 -29t219 -88q38 -19 88 -19q54 0 117.5 21t110 47t88 47t54.5 21q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1664 650q0 -166 -60 -314l-20 -49l-185 -33q-22 -83 -90.5 -136.5t-156.5 -53.5v-32q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v576q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-32q71 0 130 -35.5t93 -95.5l68 12q29 95 29 193q0 148 -88 279t-236.5 209t-315.5 78 t-315.5 -78t-236.5 -209t-88 -279q0 -98 29 -193l68 -12q34 60 93 95.5t130 35.5v32q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-576q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v32q-88 0 -156.5 53.5t-90.5 136.5l-185 33l-20 49q-60 148 -60 314q0 151 67 291t179 242.5 t266 163.5t320 61t320 -61t266 -163.5t179 -242.5t67 -291z" /> +<glyph unicode="" horiz-adv-x="768" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1152" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142z" /> +<glyph unicode="" horiz-adv-x="1664" d="M768 1184v-1088q0 -26 -19 -45t-45 -19t-45 19l-333 333h-262q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h262l333 333q19 19 45 19t45 -19t19 -45zM1152 640q0 -76 -42.5 -141.5t-112.5 -93.5q-10 -5 -25 -5q-26 0 -45 18.5t-19 45.5q0 21 12 35.5t29 25t34 23t29 35.5 t12 57t-12 57t-29 35.5t-34 23t-29 25t-12 35.5q0 27 19 45.5t45 18.5q15 0 25 -5q70 -27 112.5 -93t42.5 -142zM1408 640q0 -153 -85 -282.5t-225 -188.5q-13 -5 -25 -5q-27 0 -46 19t-19 45q0 39 39 59q56 29 76 44q74 54 115.5 135.5t41.5 173.5t-41.5 173.5 t-115.5 135.5q-20 15 -76 44q-39 20 -39 59q0 26 19 45t45 19q13 0 26 -5q140 -59 225 -188.5t85 -282.5zM1664 640q0 -230 -127 -422.5t-338 -283.5q-13 -5 -26 -5q-26 0 -45 19t-19 45q0 36 39 59q7 4 22.5 10.5t22.5 10.5q46 25 82 51q123 91 192 227t69 289t-69 289 t-192 227q-36 26 -82 51q-7 4 -22.5 10.5t-22.5 10.5q-39 23 -39 59q0 26 19 45t45 19q13 0 26 -5q211 -91 338 -283.5t127 -422.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M384 384v-128h-128v128h128zM384 1152v-128h-128v128h128zM1152 1152v-128h-128v128h128zM128 129h384v383h-384v-383zM128 896h384v384h-384v-384zM896 896h384v384h-384v-384zM640 640v-640h-640v640h640zM1152 128v-128h-128v128h128zM1408 128v-128h-128v128h128z M1408 640v-384h-384v128h-128v-384h-128v640h384v-128h128v128h128zM640 1408v-640h-640v640h640zM1408 1408v-640h-640v640h640z" /> +<glyph unicode="" horiz-adv-x="1792" d="M63 0h-63v1408h63v-1408zM126 1h-32v1407h32v-1407zM220 1h-31v1407h31v-1407zM377 1h-31v1407h31v-1407zM534 1h-62v1407h62v-1407zM660 1h-31v1407h31v-1407zM723 1h-31v1407h31v-1407zM786 1h-31v1407h31v-1407zM943 1h-63v1407h63v-1407zM1100 1h-63v1407h63v-1407z M1226 1h-63v1407h63v-1407zM1352 1h-63v1407h63v-1407zM1446 1h-63v1407h63v-1407zM1635 1h-94v1407h94v-1407zM1698 1h-32v1407h32v-1407zM1792 0h-63v1408h63v-1408z" /> +<glyph unicode="" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1920" d="M448 1088q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1515 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-53 0 -90 37l-715 716q-38 37 -64.5 101t-26.5 117v416q0 52 38 90t90 38h416q53 0 117 -26.5t102 -64.5 l715 -714q37 -39 37 -91zM1899 512q0 -53 -37 -90l-491 -492q-39 -37 -91 -37q-36 0 -59 14t-53 45l470 470q37 37 37 90q0 52 -37 91l-715 714q-38 38 -102 64.5t-117 26.5h224q53 0 117 -26.5t102 -64.5l715 -714q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1639 1058q40 -57 18 -129l-275 -906q-19 -64 -76.5 -107.5t-122.5 -43.5h-923q-77 0 -148.5 53.5t-99.5 131.5q-24 67 -2 127q0 4 3 27t4 37q1 8 -3 21.5t-3 19.5q2 11 8 21t16.5 23.5t16.5 23.5q23 38 45 91.5t30 91.5q3 10 0.5 30t-0.5 28q3 11 17 28t17 23 q21 36 42 92t25 90q1 9 -2.5 32t0.5 28q4 13 22 30.5t22 22.5q19 26 42.5 84.5t27.5 96.5q1 8 -3 25.5t-2 26.5q2 8 9 18t18 23t17 21q8 12 16.5 30.5t15 35t16 36t19.5 32t26.5 23.5t36 11.5t47.5 -5.5l-1 -3q38 9 51 9h761q74 0 114 -56t18 -130l-274 -906 q-36 -119 -71.5 -153.5t-128.5 -34.5h-869q-27 0 -38 -15q-11 -16 -1 -43q24 -70 144 -70h923q29 0 56 15.5t35 41.5l300 987q7 22 5 57q38 -15 59 -43zM575 1056q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5 t-16.5 -22.5zM492 800q-4 -13 2 -22.5t20 -9.5h608q13 0 25.5 9.5t16.5 22.5l21 64q4 13 -2 22.5t-20 9.5h-608q-13 0 -25.5 -9.5t-16.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> +<glyph unicode="" horiz-adv-x="1664" d="M384 0h896v256h-896v-256zM384 640h896v384h-160q-40 0 -68 28t-28 68v160h-640v-640zM1536 576q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 576v-416q0 -13 -9.5 -22.5t-22.5 -9.5h-224v-160q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68 v160h-224q-13 0 -22.5 9.5t-9.5 22.5v416q0 79 56.5 135.5t135.5 56.5h64v544q0 40 28 68t68 28h672q40 0 88 -20t76 -48l152 -152q28 -28 48 -76t20 -88v-256h64q79 0 135.5 -56.5t56.5 -135.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M960 864q119 0 203.5 -84.5t84.5 -203.5t-84.5 -203.5t-203.5 -84.5t-203.5 84.5t-84.5 203.5t84.5 203.5t203.5 84.5zM1664 1280q106 0 181 -75t75 -181v-896q0 -106 -75 -181t-181 -75h-1408q-106 0 -181 75t-75 181v896q0 106 75 181t181 75h224l51 136 q19 49 69.5 84.5t103.5 35.5h512q53 0 103.5 -35.5t69.5 -84.5l51 -136h224zM960 128q185 0 316.5 131.5t131.5 316.5t-131.5 316.5t-316.5 131.5t-316.5 -131.5t-131.5 -316.5t131.5 -316.5t316.5 -131.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M725 977l-170 -450q73 -1 153.5 -2t119 -1.5t52.5 -0.5l29 2q-32 95 -92 241q-53 132 -92 211zM21 -128h-21l2 79q22 7 80 18q89 16 110 31q20 16 48 68l237 616l280 724h75h53l11 -21l205 -480q103 -242 124 -297q39 -102 96 -235q26 -58 65 -164q24 -67 65 -149 q22 -49 35 -57q22 -19 69 -23q47 -6 103 -27q6 -39 6 -57q0 -14 -1 -26q-80 0 -192 8q-93 8 -189 8q-79 0 -135 -2l-200 -11l-58 -2q0 45 4 78l131 28q56 13 68 23q12 12 12 27t-6 32l-47 114l-92 228l-450 2q-29 -65 -104 -274q-23 -64 -23 -84q0 -31 17 -43 q26 -21 103 -32q3 0 13.5 -2t30 -5t40.5 -6q1 -28 1 -58q0 -17 -2 -27q-66 0 -349 20l-48 -8q-81 -14 -167 -14z" /> +<glyph unicode="" horiz-adv-x="1408" d="M555 15q76 -32 140 -32q131 0 216 41t122 113q38 70 38 181q0 114 -41 180q-58 94 -141 126q-80 32 -247 32q-74 0 -101 -10v-144l-1 -173l3 -270q0 -15 12 -44zM541 761q43 -7 109 -7q175 0 264 65t89 224q0 112 -85 187q-84 75 -255 75q-52 0 -130 -13q0 -44 2 -77 q7 -122 6 -279l-1 -98q0 -43 1 -77zM0 -128l2 94q45 9 68 12q77 12 123 31q17 27 21 51q9 66 9 194l-2 497q-5 256 -9 404q-1 87 -11 109q-1 4 -12 12q-18 12 -69 15q-30 2 -114 13l-4 83l260 6l380 13l45 1q5 0 14 0.5t14 0.5q1 0 21.5 -0.5t40.5 -0.5h74q88 0 191 -27 q43 -13 96 -39q57 -29 102 -76q44 -47 65 -104t21 -122q0 -70 -32 -128t-95 -105q-26 -20 -150 -77q177 -41 267 -146q92 -106 92 -236q0 -76 -29 -161q-21 -62 -71 -117q-66 -72 -140 -108q-73 -36 -203 -60q-82 -15 -198 -11l-197 4q-84 2 -298 -11q-33 -3 -272 -11z" /> +<glyph unicode="" horiz-adv-x="1024" d="M0 -126l17 85q4 1 77 20q76 19 116 39q29 37 41 101l27 139l56 268l12 64q8 44 17 84.5t16 67t12.5 46.5t9 30.5t3.5 11.5l29 157l16 63l22 135l8 50v38q-41 22 -144 28q-28 2 -38 4l19 103l317 -14q39 -2 73 -2q66 0 214 9q33 2 68 4.5t36 2.5q-2 -19 -6 -38 q-7 -29 -13 -51q-55 -19 -109 -31q-64 -16 -101 -31q-12 -31 -24 -88q-9 -44 -13 -82q-44 -199 -66 -306l-61 -311l-38 -158l-43 -235l-12 -45q-2 -7 1 -27q64 -15 119 -21q36 -5 66 -10q-1 -29 -7 -58q-7 -31 -9 -41q-18 0 -23 -1q-24 -2 -42 -2q-9 0 -28 3q-19 4 -145 17 l-198 2q-41 1 -174 -11q-74 -7 -98 -9z" /> +<glyph unicode="" horiz-adv-x="1792" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l215 -1h293l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -42.5 2t-103.5 -1t-111 -1 q-34 0 -67 -5q-10 -97 -8 -136l1 -152v-332l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-88 0 -233 -14q-48 -4 -70 -4q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q8 192 6 433l-5 428q-1 62 -0.5 118.5t0.5 102.5t-2 57t-6 15q-6 5 -14 6q-38 6 -148 6q-43 0 -100 -13.5t-73 -24.5q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1744 128q33 0 42 -18.5t-11 -44.5 l-126 -162q-20 -26 -49 -26t-49 26l-126 162q-20 26 -11 44.5t42 18.5h80v1024h-80q-33 0 -42 18.5t11 44.5l126 162q20 26 49 26t49 -26l126 -162q20 -26 11 -44.5t-42 -18.5h-80v-1024h80z" /> +<glyph unicode="" d="M81 1407l54 -27q20 -5 211 -5h130l19 3l115 1l446 -1h318l34 -2q14 -1 28 7t21 16l7 8l42 1q15 0 28 -1v-104.5t1 -131.5l1 -100l-1 -58q0 -32 -4 -51q-39 -15 -68 -18q-25 43 -54 128q-8 24 -15.5 62.5t-11.5 65.5t-6 29q-13 15 -27 19q-7 2 -58.5 2t-138.5 -1t-128 -1 q-94 0 -127 -5q-10 -97 -8 -136l1 -152v52l3 -359l-1 -147q-1 -46 11 -85q49 -25 89 -32q2 0 18 -5t44 -13t43 -12q30 -8 50 -18q5 -45 5 -50q0 -10 -3 -29q-14 -1 -34 -1q-110 0 -187 10q-72 8 -238 8q-82 0 -233 -13q-45 -5 -70 -5q-2 22 -2 26l-1 26v9q21 33 79 49 q139 38 159 50q9 21 12 56q6 137 6 433l-5 44q0 265 -2 278q-2 11 -6 15q-6 5 -14 6q-38 6 -148 6q-50 0 -168.5 -14t-132.5 -24q-13 -9 -22 -33t-22 -75t-24 -84q-6 -19 -19.5 -32t-20.5 -13q-44 27 -56 44v297v86zM1505 113q26 -20 26 -49t-26 -49l-162 -126 q-26 -20 -44.5 -11t-18.5 42v80h-1024v-80q0 -33 -18.5 -42t-44.5 11l-162 126q-26 20 -26 49t26 49l162 126q26 20 44.5 11t18.5 -42v-80h1024v80q0 33 18.5 42t44.5 -11z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1408 576v-128q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h896q26 0 45 -19t19 -45zM1664 960v-128q0 -26 -19 -45t-45 -19 h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1280 1344v-128q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h640q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1280q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1536q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1536q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1152q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 192v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 576v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 960v-128q0 -26 -19 -45 t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-128q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M256 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM256 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5 t9.5 -22.5zM256 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344 q13 0 22.5 -9.5t9.5 -22.5zM256 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-192q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h192q13 0 22.5 -9.5t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v192 q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M384 992v-576q0 -13 -9.5 -22.5t-22.5 -9.5q-14 0 -23 9l-288 288q-9 9 -9 23t9 23l288 288q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M352 704q0 -14 -9 -23l-288 -288q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v576q0 13 9.5 22.5t22.5 9.5q14 0 23 -9l288 -288q9 -9 9 -23zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5 t9.5 -22.5zM1792 608v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088q13 0 22.5 -9.5t9.5 -22.5zM1792 992v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1088q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1088 q13 0 22.5 -9.5t9.5 -22.5zM1792 1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1728q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1728q13 0 22.5 -9.5t9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 1184v-1088q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-403 403v-166q0 -119 -84.5 -203.5t-203.5 -84.5h-704q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h704q119 0 203.5 -84.5t84.5 -203.5v-165l403 402q18 19 45 19q12 0 25 -5 q39 -17 39 -59z" /> +<glyph unicode="" horiz-adv-x="1920" d="M640 960q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1664 576v-448h-1408v192l320 320l160 -160l512 512zM1760 1280h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5v1216 q0 13 -9.5 22.5t-22.5 9.5zM1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> +<glyph unicode="" d="M363 0l91 91l-235 235l-91 -91v-107h128v-128h107zM886 928q0 22 -22 22q-10 0 -17 -7l-542 -542q-7 -7 -7 -17q0 -22 22 -22q10 0 17 7l542 542q7 7 7 17zM832 1120l416 -416l-832 -832h-416v416zM1515 1024q0 -53 -37 -90l-166 -166l-416 416l166 165q36 38 90 38 q53 0 91 -38l235 -234q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1024" d="M768 896q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1024 896q0 -109 -33 -179l-364 -774q-16 -33 -47.5 -52t-67.5 -19t-67.5 19t-46.5 52l-365 774q-33 70 -33 179q0 212 150 362t362 150t362 -150t150 -362z" /> +<glyph unicode="" d="M768 96v1088q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M512 384q0 36 -20 69q-1 1 -15.5 22.5t-25.5 38t-25 44t-21 50.5q-4 16 -21 16t-21 -16q-7 -23 -21 -50.5t-25 -44t-25.5 -38t-15.5 -22.5q-20 -33 -20 -69q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 512q0 -212 -150 -362t-362 -150t-362 150t-150 362 q0 145 81 275q6 9 62.5 90.5t101 151t99.5 178t83 201.5q9 30 34 47t51 17t51.5 -17t33.5 -47q28 -93 83 -201.5t99.5 -178t101 -151t62.5 -90.5q81 -127 81 -275z" /> +<glyph unicode="" horiz-adv-x="1792" d="M888 352l116 116l-152 152l-116 -116v-56h96v-96h56zM1328 1072q-16 16 -33 -1l-350 -350q-17 -17 -1 -33t33 1l350 350q17 17 1 33zM1408 478v-190q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-14 -14 -32 -8q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v126q0 13 9 22l64 64q15 15 35 7t20 -29zM1312 1216l288 -288l-672 -672h-288v288zM1756 1084l-92 -92 l-288 288l92 92q28 28 68 28t68 -28l152 -152q28 -28 28 -68t-28 -68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1408 547v-259q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h255v0q13 0 22.5 -9.5t9.5 -22.5q0 -27 -26 -32q-77 -26 -133 -60q-10 -4 -16 -4h-112q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832 q66 0 113 47t47 113v214q0 19 18 29q28 13 54 37q16 16 35 8q21 -9 21 -29zM1645 1043l-384 -384q-18 -19 -45 -19q-12 0 -25 5q-39 17 -39 59v192h-160q-323 0 -438 -131q-119 -137 -74 -473q3 -23 -20 -34q-8 -2 -12 -2q-16 0 -26 13q-10 14 -21 31t-39.5 68.5t-49.5 99.5 t-38.5 114t-17.5 122q0 49 3.5 91t14 90t28 88t47 81.5t68.5 74t94.5 61.5t124.5 48.5t159.5 30.5t196.5 11h160v192q0 42 39 59q13 5 25 5q26 0 45 -19l384 -384q19 -19 19 -45t-19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1408 606v-318q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q63 0 117 -25q15 -7 18 -23q3 -17 -9 -29l-49 -49q-10 -10 -23 -10q-3 0 -9 2q-23 6 -45 6h-832q-66 0 -113 -47t-47 -113v-832 q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v254q0 13 9 22l64 64q10 10 23 10q6 0 12 -3q20 -8 20 -29zM1639 1095l-814 -814q-24 -24 -57 -24t-57 24l-430 430q-24 24 -24 57t24 57l110 110q24 24 57 24t57 -24l263 -263l647 647q24 24 57 24t57 -24l110 -110 q24 -24 24 -57t-24 -57z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-384v-384h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v384h-384v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45 t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h384v384h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45t-19 -45t-45 -19h-128v-384h384v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M979 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1747 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-9 9 -13 19v-678q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-678q4 11 13 19l710 710 q19 19 32 13t13 -32v-710q4 11 13 19z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1619 1395q19 19 32 13t13 -32v-1472q0 -26 -13 -32t-32 13l-710 710q-8 9 -13 19v-710q0 -26 -13 -32t-32 13l-710 710q-19 19 -19 45t19 45l710 710q19 19 32 13t13 -32v-710q5 11 13 19z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1384 609l-1328 -738q-23 -13 -39.5 -3t-16.5 36v1472q0 26 16.5 36t39.5 -3l1328 -738q23 -13 23 -31t-23 -31z" /> +<glyph unicode="" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45zM640 1344v-1408q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h512q26 0 45 -19t19 -45z" /> +<glyph unicode="" d="M1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q19 -19 19 -45t-19 -45l-710 -710q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" /> +<glyph unicode="" horiz-adv-x="1792" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v710q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19l-710 -710 q-19 -19 -32 -13t-13 32v710q-5 -10 -13 -19z" /> +<glyph unicode="" horiz-adv-x="1024" d="M45 -115q-19 -19 -32 -13t-13 32v1472q0 26 13 32t32 -13l710 -710q8 -8 13 -19v678q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-1408q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v678q-5 -10 -13 -19z" /> +<glyph unicode="" horiz-adv-x="1538" d="M14 557l710 710q19 19 45 19t45 -19l710 -710q19 -19 13 -32t-32 -13h-1472q-26 0 -32 13t13 32zM1473 0h-1408q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1408q26 0 45 -19t19 -45v-256q0 -26 -19 -45t-45 -19z" /> +<glyph unicode="" horiz-adv-x="1152" d="M742 -37l-652 651q-37 37 -37 90.5t37 90.5l652 651q37 37 90.5 37t90.5 -37l75 -75q37 -37 37 -90.5t-37 -90.5l-486 -486l486 -485q37 -38 37 -91t-37 -90l-75 -75q-37 -37 -90.5 -37t-90.5 37z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1099 704q0 -52 -37 -91l-652 -651q-37 -37 -90 -37t-90 37l-76 75q-37 39 -37 91q0 53 37 90l486 486l-486 485q-37 39 -37 91q0 53 37 90l76 75q36 38 90 38t90 -38l652 -651q37 -37 37 -90z" /> +<glyph unicode="" d="M1216 576v128q0 26 -19 45t-45 19h-256v256q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-256h-256q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h256v-256q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v256h256q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5 t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1216 576v128q0 26 -19 45t-45 19h-768q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h768q26 0 45 19t19 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5 t103 -385.5z" /> +<glyph unicode="" d="M1149 414q0 26 -19 45l-181 181l181 181q19 19 19 45q0 27 -19 46l-90 90q-19 19 -46 19q-26 0 -45 -19l-181 -181l-181 181q-19 19 -45 19q-27 0 -46 -19l-90 -90q-19 -19 -19 -46q0 -26 19 -45l181 -181l-181 -181q-19 -19 -19 -45q0 -27 19 -46l90 -90q19 -19 46 -19 q26 0 45 19l181 181l181 -181q19 -19 45 -19q27 0 46 19l90 90q19 19 19 46zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1284 802q0 28 -18 46l-91 90q-19 19 -45 19t-45 -19l-408 -407l-226 226q-19 19 -45 19t-45 -19l-91 -90q-18 -18 -18 -46q0 -27 18 -45l362 -362q19 -19 45 -19q27 0 46 19l543 543q18 18 18 45zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M896 160v192q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h192q14 0 23 9t9 23zM1152 832q0 88 -55.5 163t-138.5 116t-170 41q-243 0 -371 -213q-15 -24 8 -42l132 -100q7 -6 19 -6q16 0 25 12q53 68 86 92q34 24 86 24q48 0 85.5 -26t37.5 -59 q0 -38 -20 -61t-68 -45q-63 -28 -115.5 -86.5t-52.5 -125.5v-36q0 -14 9 -23t23 -9h192q14 0 23 9t9 23q0 19 21.5 49.5t54.5 49.5q32 18 49 28.5t46 35t44.5 48t28 60.5t12.5 81zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1024 160v160q0 14 -9 23t-23 9h-96v512q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h96v-320h-96q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23t23 -9h448q14 0 23 9t9 23zM896 1056v160q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-160q0 -14 9 -23 t23 -9h192q14 0 23 9t9 23zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1197 512h-109q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h109q-32 108 -112.5 188.5t-188.5 112.5v-109q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v109q-108 -32 -188.5 -112.5t-112.5 -188.5h109q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-109 q32 -108 112.5 -188.5t188.5 -112.5v109q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-109q108 32 188.5 112.5t112.5 188.5zM1536 704v-128q0 -26 -19 -45t-45 -19h-143q-37 -161 -154.5 -278.5t-278.5 -154.5v-143q0 -26 -19 -45t-45 -19h-128q-26 0 -45 19t-19 45v143 q-161 37 -278.5 154.5t-154.5 278.5h-143q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h143q37 161 154.5 278.5t278.5 154.5v143q0 26 19 45t45 19h128q26 0 45 -19t19 -45v-143q161 -37 278.5 -154.5t154.5 -278.5h143q26 0 45 -19t19 -45z" /> +<glyph unicode="" d="M1097 457l-146 -146q-10 -10 -23 -10t-23 10l-137 137l-137 -137q-10 -10 -23 -10t-23 10l-146 146q-10 10 -10 23t10 23l137 137l-137 137q-10 10 -10 23t10 23l146 146q10 10 23 10t23 -10l137 -137l137 137q10 10 23 10t23 -10l146 -146q10 -10 10 -23t-10 -23 l-137 -137l137 -137q10 -10 10 -23t-10 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5 t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1171 723l-422 -422q-19 -19 -45 -19t-45 19l-294 294q-19 19 -19 45t19 45l102 102q19 19 45 19t45 -19l147 -147l275 275q19 19 45 19t45 -19l102 -102q19 -19 19 -45t-19 -45zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198 t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1312 643q0 161 -87 295l-754 -753q137 -89 297 -89q111 0 211.5 43.5t173.5 116.5t116 174.5t43 212.5zM313 344l755 754q-135 91 -300 91q-148 0 -273 -73t-198 -199t-73 -274q0 -162 89 -299zM1536 643q0 -157 -61 -300t-163.5 -246t-245 -164t-298.5 -61t-298.5 61 t-245 164t-163.5 246t-61 300t61 299.5t163.5 245.5t245 164t298.5 61t298.5 -61t245 -164t163.5 -245.5t61 -299.5z" /> +<glyph unicode="" d="M1536 640v-128q0 -53 -32.5 -90.5t-84.5 -37.5h-704l293 -294q38 -36 38 -90t-38 -90l-75 -76q-37 -37 -90 -37q-52 0 -91 37l-651 652q-37 37 -37 90q0 52 37 91l651 650q38 38 91 38q52 0 90 -38l75 -74q38 -38 38 -91t-38 -91l-293 -293h704q52 0 84.5 -37.5 t32.5 -90.5z" /> +<glyph unicode="" d="M1472 576q0 -54 -37 -91l-651 -651q-39 -37 -91 -37q-51 0 -90 37l-75 75q-38 38 -38 91t38 91l293 293h-704q-52 0 -84.5 37.5t-32.5 90.5v128q0 53 32.5 90.5t84.5 37.5h704l-293 294q-38 36 -38 90t38 90l75 75q38 38 90 38q53 0 91 -38l651 -651q37 -35 37 -90z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1611 565q0 -51 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-294 293v-704q0 -52 -37.5 -84.5t-90.5 -32.5h-128q-53 0 -90.5 32.5t-37.5 84.5v704l-294 -293q-36 -38 -90 -38t-90 38l-75 75q-38 38 -38 90q0 53 38 91l651 651q35 37 90 37q54 0 91 -37l651 -651 q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1611 704q0 -53 -37 -90l-651 -652q-39 -37 -91 -37q-53 0 -90 37l-651 652q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l294 -294v704q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-704l294 294q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 896q0 -26 -19 -45l-512 -512q-19 -19 -45 -19t-45 19t-19 45v256h-224q-98 0 -175.5 -6t-154 -21.5t-133 -42.5t-105.5 -69.5t-80 -101t-48.5 -138.5t-17.5 -181q0 -55 5 -123q0 -6 2.5 -23.5t2.5 -26.5q0 -15 -8.5 -25t-23.5 -10q-16 0 -28 17q-7 9 -13 22 t-13.5 30t-10.5 24q-127 285 -127 451q0 199 53 333q162 403 875 403h224v256q0 26 19 45t45 19t45 -19l512 -512q19 -19 19 -45z" /> +<glyph unicode="" d="M755 480q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23zM1536 1344v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332 q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45z" /> +<glyph unicode="" d="M768 576v-448q0 -26 -19 -45t-45 -19t-45 19l-144 144l-332 -332q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l332 332l-144 144q-19 19 -19 45t19 45t45 19h448q26 0 45 -19t19 -45zM1523 1248q0 -13 -10 -23l-332 -332l144 -144q19 -19 19 -45t-19 -45 t-45 -19h-448q-26 0 -45 19t-19 45v448q0 26 19 45t45 19t45 -19l144 -144l332 332q10 10 23 10t23 -10l114 -114q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-416v-416q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v416h-416q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h416v416q0 40 28 68t68 28h192q40 0 68 -28t28 -68v-416h416q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1408 800v-192q0 -40 -28 -68t-68 -28h-1216q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h1216q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1482 486q46 -26 59.5 -77.5t-12.5 -97.5l-64 -110q-26 -46 -77.5 -59.5t-97.5 12.5l-266 153v-307q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v307l-266 -153q-46 -26 -97.5 -12.5t-77.5 59.5l-64 110q-26 46 -12.5 97.5t59.5 77.5l266 154l-266 154 q-46 26 -59.5 77.5t12.5 97.5l64 110q26 46 77.5 59.5t97.5 -12.5l266 -153v307q0 52 38 90t90 38h128q52 0 90 -38t38 -90v-307l266 153q46 26 97.5 12.5t77.5 -59.5l64 -110q26 -46 12.5 -97.5t-59.5 -77.5l-266 -154z" /> +<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM896 161v190q0 14 -9 23.5t-22 9.5h-192q-13 0 -23 -10t-10 -23v-190q0 -13 10 -23t23 -10h192 q13 0 22 9.5t9 23.5zM894 505l18 621q0 12 -10 18q-10 8 -24 8h-220q-14 0 -24 -8q-10 -6 -10 -18l17 -621q0 -10 10 -17.5t24 -7.5h185q14 0 23.5 7.5t10.5 17.5z" /> +<glyph unicode="" d="M928 180v56v468v192h-320v-192v-468v-56q0 -25 18 -38.5t46 -13.5h192q28 0 46 13.5t18 38.5zM472 1024h195l-126 161q-26 31 -69 31q-40 0 -68 -28t-28 -68t28 -68t68 -28zM1160 1120q0 40 -28 68t-68 28q-43 0 -69 -31l-125 -161h194q40 0 68 28t28 68zM1536 864v-320 q0 -14 -9 -23t-23 -9h-96v-416q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v416h-96q-14 0 -23 9t-9 23v320q0 14 9 23t23 9h440q-93 0 -158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5q107 0 168 -77l128 -165l128 165q61 77 168 77q93 0 158.5 -65.5t65.5 -158.5 t-65.5 -158.5t-158.5 -65.5h440q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1280 832q0 26 -19 45t-45 19q-172 0 -318 -49.5t-259.5 -134t-235.5 -219.5q-19 -21 -19 -45q0 -26 19 -45t45 -19q24 0 45 19q27 24 74 71t67 66q137 124 268.5 176t313.5 52q26 0 45 19t19 45zM1792 1030q0 -95 -20 -193q-46 -224 -184.5 -383t-357.5 -268 q-214 -108 -438 -108q-148 0 -286 47q-15 5 -88 42t-96 37q-16 0 -39.5 -32t-45 -70t-52.5 -70t-60 -32q-30 0 -51 11t-31 24t-27 42q-2 4 -6 11t-5.5 10t-3 9.5t-1.5 13.5q0 35 31 73.5t68 65.5t68 56t31 48q0 4 -14 38t-16 44q-9 51 -9 104q0 115 43.5 220t119 184.5 t170.5 139t204 95.5q55 18 145 25.5t179.5 9t178.5 6t163.5 24t113.5 56.5l29.5 29.5t29.5 28t27 20t36.5 16t43.5 4.5q39 0 70.5 -46t47.5 -112t24 -124t8 -96z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1408 -160v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-1344q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h1344q13 0 22.5 -9.5t9.5 -22.5zM1152 896q0 -78 -24.5 -144t-64 -112.5t-87.5 -88t-96 -77.5t-87.5 -72t-64 -81.5t-24.5 -96.5q0 -96 67 -224l-4 1l1 -1 q-90 41 -160 83t-138.5 100t-113.5 122.5t-72.5 150.5t-27.5 184q0 78 24.5 144t64 112.5t87.5 88t96 77.5t87.5 72t64 81.5t24.5 96.5q0 94 -66 224l3 -1l-1 1q90 -41 160 -83t138.5 -100t113.5 -122.5t72.5 -150.5t27.5 -184z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1664 576q-152 236 -381 353q61 -104 61 -225q0 -185 -131.5 -316.5t-316.5 -131.5t-316.5 131.5t-131.5 316.5q0 121 61 225q-229 -117 -381 -353q133 -205 333.5 -326.5t434.5 -121.5t434.5 121.5t333.5 326.5zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5 t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1792 576q0 -34 -20 -69q-140 -230 -376.5 -368.5t-499.5 -138.5t-499.5 139t-376.5 368q-20 35 -20 69t20 69q140 229 376.5 368t499.5 139t499.5 -139t376.5 -368q20 -35 20 -69z" /> +<glyph unicode="" horiz-adv-x="1792" d="M555 201l78 141q-87 63 -136 159t-49 203q0 121 61 225q-229 -117 -381 -353q167 -258 427 -375zM944 960q0 20 -14 34t-34 14q-125 0 -214.5 -89.5t-89.5 -214.5q0 -20 14 -34t34 -14t34 14t14 34q0 86 61 147t147 61q20 0 34 14t14 34zM1307 1151q0 -7 -1 -9 q-105 -188 -315 -566t-316 -567l-49 -89q-10 -16 -28 -16q-12 0 -134 70q-16 10 -16 28q0 12 44 87q-143 65 -263.5 173t-208.5 245q-20 31 -20 69t20 69q153 235 380 371t496 136q89 0 180 -17l54 97q10 16 28 16q5 0 18 -6t31 -15.5t33 -18.5t31.5 -18.5t19.5 -11.5 q16 -10 16 -27zM1344 704q0 -139 -79 -253.5t-209 -164.5l280 502q8 -45 8 -84zM1792 576q0 -35 -20 -69q-39 -64 -109 -145q-150 -172 -347.5 -267t-419.5 -95l74 132q212 18 392.5 137t301.5 307q-115 179 -282 294l63 112q95 -64 182.5 -153t144.5 -184q20 -34 20 -69z " /> +<glyph unicode="" horiz-adv-x="1792" d="M1024 161v190q0 14 -9.5 23.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -23.5v-190q0 -14 9.5 -23.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 23.5zM1022 535l18 459q0 12 -10 19q-13 11 -24 11h-220q-11 0 -24 -11q-10 -7 -10 -21l17 -457q0 -10 10 -16.5t24 -6.5h185 q14 0 23.5 6.5t10.5 16.5zM1008 1469l768 -1408q35 -63 -2 -126q-17 -29 -46.5 -46t-63.5 -17h-1536q-34 0 -63.5 17t-46.5 46q-37 63 -2 126l768 1408q17 31 47 49t65 18t65 -18t47 -49z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1376 1376q44 -52 12 -148t-108 -172l-161 -161l160 -696q5 -19 -12 -33l-128 -96q-7 -6 -19 -6q-4 0 -7 1q-15 3 -21 16l-279 508l-259 -259l53 -194q5 -17 -8 -31l-96 -96q-9 -9 -23 -9h-2q-15 2 -24 13l-189 252l-252 189q-11 7 -13 23q-1 13 9 25l96 97q9 9 23 9 q6 0 8 -1l194 -53l259 259l-508 279q-14 8 -17 24q-2 16 9 27l128 128q14 13 30 8l665 -159l160 160q76 76 172 108t148 -12z" /> +<glyph unicode="" horiz-adv-x="1664" d="M128 -128h288v288h-288v-288zM480 -128h320v288h-320v-288zM128 224h288v320h-288v-320zM480 224h320v320h-320v-320zM128 608h288v288h-288v-288zM864 -128h320v288h-320v-288zM480 608h320v288h-320v-288zM1248 -128h288v288h-288v-288zM864 224h320v320h-320v-320z M512 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1248 224h288v320h-288v-320zM864 608h320v288h-320v-288zM1248 608h288v288h-288v-288zM1280 1088v288q0 13 -9.5 22.5t-22.5 9.5h-64 q-13 0 -22.5 -9.5t-9.5 -22.5v-288q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1664 1152v-1280q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47 h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> +<glyph unicode="" horiz-adv-x="1792" d="M666 1055q-60 -92 -137 -273q-22 45 -37 72.5t-40.5 63.5t-51 56.5t-63 35t-81.5 14.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q250 0 410 -225zM1792 256q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192q-32 0 -85 -0.5t-81 -1t-73 1 t-71 5t-64 10.5t-63 18.5t-58 28.5t-59 40t-55 53.5t-56 69.5q59 93 136 273q22 -45 37 -72.5t40.5 -63.5t51 -56.5t63 -35t81.5 -14.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1792 1152q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5 v192h-256q-48 0 -87 -15t-69 -45t-51 -61.5t-45 -77.5q-32 -62 -78 -171q-29 -66 -49.5 -111t-54 -105t-64 -100t-74 -83t-90 -68.5t-106.5 -42t-128 -16.5h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224q48 0 87 15t69 45t51 61.5t45 77.5q32 62 78 171q29 66 49.5 111 t54 105t64 100t74 83t90 68.5t106.5 42t128 16.5h256v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22q-17 -2 -30.5 9t-17.5 29v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281 q0 130 71 248.5t191 204.5t286 136.5t348 50.5q244 0 450 -85.5t326 -233t120 -321.5z" /> +<glyph unicode="" d="M1536 704v-128q0 -201 -98.5 -362t-274 -251.5t-395.5 -90.5t-395.5 90.5t-274 251.5t-98.5 362v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-128q0 -52 23.5 -90t53.5 -57t71 -30t64 -13t44 -2t44 2t64 13t71 30t53.5 57t23.5 90v128q0 26 19 45t45 19h384 q26 0 45 -19t19 -45zM512 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45zM1536 1344v-384q0 -26 -19 -45t-45 -19h-384q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h384q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1611 320q0 -53 -37 -90l-75 -75q-38 -38 -91 -38q-54 0 -90 38l-486 485l-486 -485q-36 -38 -90 -38t-90 38l-75 75q-38 36 -38 90q0 53 38 91l651 651q37 37 90 37q52 0 91 -37l650 -651q38 -38 38 -91z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1611 832q0 -53 -37 -90l-651 -651q-38 -38 -91 -38q-54 0 -90 38l-651 651q-38 36 -38 90q0 53 38 91l74 75q39 37 91 37q53 0 90 -37l486 -486l486 486q37 37 90 37q52 0 91 -37l75 -75q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1280 32q0 -13 -9.5 -22.5t-22.5 -9.5h-960q-8 0 -13.5 2t-9 7t-5.5 8t-3 11.5t-1 11.5v13v11v160v416h-192q-26 0 -45 19t-19 45q0 24 15 41l320 384q19 22 49 22t49 -22l320 -384q15 -17 15 -41q0 -26 -19 -45t-45 -19h-192v-384h576q16 0 25 -11l160 -192q7 -11 7 -21 zM1920 448q0 -24 -15 -41l-320 -384q-20 -23 -49 -23t-49 23l-320 384q-15 17 -15 41q0 26 19 45t45 19h192v384h-576q-16 0 -25 12l-160 192q-7 9 -7 20q0 13 9.5 22.5t22.5 9.5h960q8 0 13.5 -2t9 -7t5.5 -8t3 -11.5t1 -11.5v-13v-11v-160v-416h192q26 0 45 -19t19 -45z " /> +<glyph unicode="" horiz-adv-x="1664" d="M640 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1536 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1664 1088v-512q0 -24 -16 -42.5t-41 -21.5 l-1044 -122q1 -7 4.5 -21.5t6 -26.5t2.5 -22q0 -16 -24 -64h920q26 0 45 -19t19 -45t-19 -45t-45 -19h-1024q-26 0 -45 19t-19 45q0 14 11 39.5t29.5 59.5t20.5 38l-177 823h-204q-26 0 -45 19t-19 45t19 45t45 19h256q16 0 28.5 -6.5t20 -15.5t13 -24.5t7.5 -26.5 t5.5 -29.5t4.5 -25.5h1201q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1879 584q0 -31 -31 -66l-336 -396q-43 -51 -120.5 -86.5t-143.5 -35.5h-1088q-34 0 -60.5 13t-26.5 43q0 31 31 66l336 396q43 51 120.5 86.5t143.5 35.5h1088q34 0 60.5 -13t26.5 -43zM1536 928v-160h-832q-94 0 -197 -47.5t-164 -119.5l-337 -396l-5 -6q0 4 -0.5 12.5 t-0.5 12.5v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158z" /> +<glyph unicode="" horiz-adv-x="768" d="M704 1216q0 -26 -19 -45t-45 -19h-128v-1024h128q26 0 45 -19t19 -45t-19 -45l-256 -256q-19 -19 -45 -19t-45 19l-256 256q-19 19 -19 45t19 45t45 19h128v1024h-128q-26 0 -45 19t-19 45t19 45l256 256q19 19 45 19t45 -19l256 -256q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 640q0 -26 -19 -45l-256 -256q-19 -19 -45 -19t-45 19t-19 45v128h-1024v-128q0 -26 -19 -45t-45 -19t-45 19l-256 256q-19 19 -19 45t19 45l256 256q19 19 45 19t45 -19t19 -45v-128h1024v128q0 26 19 45t45 19t45 -19l256 -256q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="1920" d="M512 512v-384h-256v384h256zM896 1024v-896h-256v896h256zM1280 768v-640h-256v640h256zM1664 1152v-1024h-256v1024h256zM1792 32v1216q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-1216q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5z M1920 1248v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> +<glyph unicode="" d="M1280 926q-56 -25 -121 -34q68 40 93 117q-65 -38 -134 -51q-61 66 -153 66q-87 0 -148.5 -61.5t-61.5 -148.5q0 -29 5 -48q-129 7 -242 65t-192 155q-29 -50 -29 -106q0 -114 91 -175q-47 1 -100 26v-2q0 -75 50 -133.5t123 -72.5q-29 -8 -51 -8q-13 0 -39 4 q21 -63 74.5 -104t121.5 -42q-116 -90 -261 -90q-26 0 -50 3q148 -94 322 -94q112 0 210 35.5t168 95t120.5 137t75 162t24.5 168.5q0 18 -1 27q63 45 105 109zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5 t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1307 618l23 219h-198v109q0 49 15.5 68.5t71.5 19.5h110v219h-175q-152 0 -218 -72t-66 -213v-131h-131v-219h131v-635h262v635h175zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960 q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M928 704q0 14 -9 23t-23 9q-66 0 -113 -47t-47 -113q0 -14 9 -23t23 -9t23 9t9 23q0 40 28 68t68 28q14 0 23 9t9 23zM1152 574q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM128 0h1536v128h-1536v-128zM1280 574q0 159 -112.5 271.5 t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM256 1216h384v128h-384v-128zM128 1024h1536v118v138h-828l-64 -128h-644v-128zM1792 1280v-1280q0 -53 -37.5 -90.5t-90.5 -37.5h-1536q-53 0 -90.5 37.5t-37.5 90.5v1280 q0 53 37.5 90.5t90.5 37.5h1536q53 0 90.5 -37.5t37.5 -90.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M832 1024q0 80 -56 136t-136 56t-136 -56t-56 -136q0 -42 19 -83q-41 19 -83 19q-80 0 -136 -56t-56 -136t56 -136t136 -56t136 56t56 136q0 42 -19 83q41 -19 83 -19q80 0 136 56t56 136zM1683 320q0 -17 -49 -66t-66 -49q-9 0 -28.5 16t-36.5 33t-38.5 40t-24.5 26 l-96 -96l220 -220q28 -28 28 -68q0 -42 -39 -81t-81 -39q-40 0 -68 28l-671 671q-176 -131 -365 -131q-163 0 -265.5 102.5t-102.5 265.5q0 160 95 313t248 248t313 95q163 0 265.5 -102.5t102.5 -265.5q0 -189 -131 -365l355 -355l96 96q-3 3 -26 24.5t-40 38.5t-33 36.5 t-16 28.5q0 17 49 66t66 49q13 0 23 -10q6 -6 46 -44.5t82 -79.5t86.5 -86t73 -78t28.5 -41z" /> +<glyph unicode="" horiz-adv-x="1920" d="M896 640q0 106 -75 181t-181 75t-181 -75t-75 -181t75 -181t181 -75t181 75t75 181zM1664 128q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 1152q0 52 -38 90t-90 38t-90 -38t-38 -90q0 -53 37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1280 731v-185q0 -10 -7 -19.5t-16 -10.5l-155 -24q-11 -35 -32 -76q34 -48 90 -115q7 -10 7 -20q0 -12 -7 -19q-23 -30 -82.5 -89.5t-78.5 -59.5q-11 0 -21 7l-115 90q-37 -19 -77 -31q-11 -108 -23 -155q-7 -24 -30 -24h-186q-11 0 -20 7.5t-10 17.5 l-23 153q-34 10 -75 31l-118 -89q-7 -7 -20 -7q-11 0 -21 8q-144 133 -144 160q0 9 7 19q10 14 41 53t47 61q-23 44 -35 82l-152 24q-10 1 -17 9.5t-7 19.5v185q0 10 7 19.5t16 10.5l155 24q11 35 32 76q-34 48 -90 115q-7 11 -7 20q0 12 7 20q22 30 82 89t79 59q11 0 21 -7 l115 -90q34 18 77 32q11 108 23 154q7 24 30 24h186q11 0 20 -7.5t10 -17.5l23 -153q34 -10 75 -31l118 89q8 7 20 7q11 0 21 -8q144 -133 144 -160q0 -9 -7 -19q-12 -16 -42 -54t-45 -60q23 -48 34 -82l152 -23q10 -2 17 -10.5t7 -19.5zM1920 198v-140q0 -16 -149 -31 q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20 t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31zM1920 1222v-140q0 -16 -149 -31q-12 -27 -30 -52q51 -113 51 -138q0 -4 -4 -7q-122 -71 -124 -71q-8 0 -46 47t-52 68 q-20 -2 -30 -2t-30 2q-14 -21 -52 -68t-46 -47q-2 0 -124 71q-4 3 -4 7q0 25 51 138q-18 25 -30 52q-149 15 -149 31v140q0 16 149 31q13 29 30 52q-51 113 -51 138q0 4 4 7q4 2 35 20t59 34t30 16q8 0 46 -46.5t52 -67.5q20 2 30 2t30 -2q51 71 92 112l6 2q4 0 124 -70 q4 -3 4 -7q0 -25 -51 -138q17 -23 30 -52q149 -15 149 -31z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1408 768q0 -139 -94 -257t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224 q0 139 94 257t256.5 186.5t353.5 68.5t353.5 -68.5t256.5 -186.5t94 -257zM1792 512q0 -120 -71 -224.5t-195 -176.5q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7 q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230z" /> +<glyph unicode="" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 768q0 51 -39 89.5t-89 38.5h-352q0 58 48 159.5t48 160.5q0 98 -32 145t-128 47q-26 -26 -38 -85t-30.5 -125.5t-59.5 -109.5q-22 -23 -77 -91q-4 -5 -23 -30t-31.5 -41t-34.5 -42.5 t-40 -44t-38.5 -35.5t-40 -27t-35.5 -9h-32v-640h32q13 0 31.5 -3t33 -6.5t38 -11t35 -11.5t35.5 -12.5t29 -10.5q211 -73 342 -73h121q192 0 192 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5q32 1 53.5 47t21.5 81zM1536 769 q0 -89 -49 -163q9 -33 9 -69q0 -77 -38 -144q3 -21 3 -43q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5h-36h-93q-96 0 -189.5 22.5t-216.5 65.5q-116 40 -138 40h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h274q36 24 137 155q58 75 107 128 q24 25 35.5 85.5t30.5 126.5t62 108q39 37 90 37q84 0 151 -32.5t102 -101.5t35 -186q0 -93 -48 -192h176q104 0 180 -76t76 -179z" /> +<glyph unicode="" d="M256 1088q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 512q0 35 -21.5 81t-53.5 47q15 17 25 47.5t10 55.5q0 69 -53 119q18 32 18 69t-17.5 73.5t-47.5 52.5q5 30 5 56q0 85 -49 126t-136 41h-128q-131 0 -342 -73q-5 -2 -29 -10.5 t-35.5 -12.5t-35 -11.5t-38 -11t-33 -6.5t-31.5 -3h-32v-640h32q16 0 35.5 -9t40 -27t38.5 -35.5t40 -44t34.5 -42.5t31.5 -41t23 -30q55 -68 77 -91q41 -43 59.5 -109.5t30.5 -125.5t38 -85q96 0 128 47t32 145q0 59 -48 160.5t-48 159.5h352q50 0 89 38.5t39 89.5z M1536 511q0 -103 -76 -179t-180 -76h-176q48 -99 48 -192q0 -118 -35 -186q-35 -69 -102 -101.5t-151 -32.5q-51 0 -90 37q-34 33 -54 82t-25.5 90.5t-17.5 84.5t-31 64q-48 50 -107 127q-101 131 -137 155h-274q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5 h288q22 0 138 40q128 44 223 66t200 22h112q140 0 226.5 -79t85.5 -216v-5q60 -77 60 -178q0 -22 -3 -43q38 -67 38 -144q0 -36 -9 -69q49 -74 49 -163z" /> +<glyph unicode="" horiz-adv-x="896" d="M832 1504v-1339l-449 -236q-22 -12 -40 -12q-21 0 -31.5 14.5t-10.5 35.5q0 6 2 20l86 500l-364 354q-25 27 -25 48q0 37 56 46l502 73l225 455q19 41 49 41z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1664 940q0 81 -21.5 143t-55 98.5t-81.5 59.5t-94 31t-98 8t-112 -25.5t-110.5 -64t-86.5 -72t-60 -61.5q-18 -22 -49 -22t-49 22q-24 28 -60 61.5t-86.5 72t-110.5 64t-112 25.5t-98 -8t-94 -31t-81.5 -59.5t-55 -98.5t-21.5 -143q0 -168 187 -355l581 -560l580 559 q188 188 188 356zM1792 940q0 -221 -229 -450l-623 -600q-18 -18 -44 -18t-44 18l-624 602q-10 8 -27.5 26t-55.5 65.5t-68 97.5t-53.5 121t-23.5 138q0 220 127 344t351 124q62 0 126.5 -21.5t120 -58t95.5 -68.5t76 -68q36 36 76 68t95.5 68.5t120 58t126.5 21.5 q224 0 351 -124t127 -344z" /> +<glyph unicode="" horiz-adv-x="1664" d="M640 96q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-119 0 -203.5 84.5t-84.5 203.5v704q0 119 84.5 203.5t203.5 84.5h320q13 0 22.5 -9.5t9.5 -22.5q0 -4 1 -20t0.5 -26.5t-3 -23.5t-10 -19.5t-20.5 -6.5h-320q-66 0 -113 -47t-47 -113v-704 q0 -66 47 -113t113 -47h288h11h13t11.5 -1t11.5 -3t8 -5.5t7 -9t2 -13.5zM1568 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45z" /> +<glyph unicode="" d="M237 122h231v694h-231v-694zM483 1030q-1 52 -36 86t-93 34t-94.5 -34t-36.5 -86q0 -51 35.5 -85.5t92.5 -34.5h1q59 0 95 34.5t36 85.5zM1068 122h231v398q0 154 -73 233t-193 79q-136 0 -209 -117h2v101h-231q3 -66 0 -694h231v388q0 38 7 56q15 35 45 59.5t74 24.5 q116 0 116 -157v-371zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1152" d="M480 672v448q0 14 -9 23t-23 9t-23 -9t-9 -23v-448q0 -14 9 -23t23 -9t23 9t9 23zM1152 320q0 -26 -19 -45t-45 -19h-429l-51 -483q-2 -12 -10.5 -20.5t-20.5 -8.5h-1q-27 0 -32 27l-76 485h-404q-26 0 -45 19t-19 45q0 123 78.5 221.5t177.5 98.5v512q-52 0 -90 38 t-38 90t38 90t90 38h640q52 0 90 -38t38 -90t-38 -90t-90 -38v-512q99 0 177.5 -98.5t78.5 -221.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1408 608v-320q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h704q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-704q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v320 q0 14 9 23t23 9h64q14 0 23 -9t9 -23zM1792 1472v-512q0 -26 -19 -45t-45 -19t-45 19l-176 176l-652 -652q-10 -10 -23 -10t-23 10l-114 114q-10 10 -10 23t10 23l652 652l-176 176q-19 19 -19 45t19 45t45 19h512q26 0 45 -19t19 -45z" /> +<glyph unicode="" d="M1184 640q0 -26 -19 -45l-544 -544q-19 -19 -45 -19t-45 19t-19 45v288h-448q-26 0 -45 19t-19 45v384q0 26 19 45t45 19h448v288q0 26 19 45t45 19t45 -19l544 -544q19 -19 19 -45zM1536 992v-704q0 -119 -84.5 -203.5t-203.5 -84.5h-320q-13 0 -22.5 9.5t-9.5 22.5 q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q66 0 113 47t47 113v704q0 66 -47 113t-113 47h-288h-11h-13t-11.5 1t-11.5 3t-8 5.5t-7 9t-2 13.5q0 4 -1 20t-0.5 26.5t3 23.5t10 19.5t20.5 6.5h320q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M458 653q-74 162 -74 371h-256v-96q0 -78 94.5 -162t235.5 -113zM1536 928v96h-256q0 -209 -74 -371q141 29 235.5 113t94.5 162zM1664 1056v-128q0 -71 -41.5 -143t-112 -130t-173 -97.5t-215.5 -44.5q-42 -54 -95 -95q-38 -34 -52.5 -72.5t-14.5 -89.5q0 -54 30.5 -91 t97.5 -37q75 0 133.5 -45.5t58.5 -114.5v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 69 58.5 114.5t133.5 45.5q67 0 97.5 37t30.5 91q0 51 -14.5 89.5t-52.5 72.5q-53 41 -95 95q-113 5 -215.5 44.5t-173 97.5t-112 130t-41.5 143v128q0 40 28 68t68 28h288v96 q0 66 47 113t113 47h576q66 0 113 -47t47 -113v-96h288q40 0 68 -28t28 -68z" /> +<glyph unicode="" d="M394 184q-8 -9 -20 3q-13 11 -4 19q8 9 20 -3q12 -11 4 -19zM352 245q9 -12 0 -19q-8 -6 -17 7t0 18q9 7 17 -6zM291 305q-5 -7 -13 -2q-10 5 -7 12q3 5 13 2q10 -5 7 -12zM322 271q-6 -7 -16 3q-9 11 -2 16q6 6 16 -3q9 -11 2 -16zM451 159q-4 -12 -19 -6q-17 4 -13 15 t19 7q16 -5 13 -16zM514 154q0 -11 -16 -11q-17 -2 -17 11q0 11 16 11q17 2 17 -11zM572 164q2 -10 -14 -14t-18 8t14 15q16 2 18 -9zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-224q-16 0 -24.5 1t-19.5 5t-16 14.5t-5 27.5v239q0 97 -52 142q57 6 102.5 18t94 39 t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103 q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -103t0.5 -68q0 -22 -11 -33.5t-22 -13t-33 -1.5 h-224q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1280 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 288v-320q0 -40 -28 -68t-68 -28h-1472q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h427q21 -56 70.5 -92 t110.5 -36h256q61 0 110.5 36t70.5 92h427q40 0 68 -28t28 -68zM1339 936q-17 -40 -59 -40h-256v-448q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v448h-256q-42 0 -59 40q-17 39 14 69l448 448q18 19 45 19t45 -19l448 -448q31 -30 14 -69z" /> +<glyph unicode="" d="M1407 710q0 44 -7 113.5t-18 96.5q-12 30 -17 44t-9 36.5t-4 48.5q0 23 5 68.5t5 67.5q0 37 -10 55q-4 1 -13 1q-19 0 -58 -4.5t-59 -4.5q-60 0 -176 24t-175 24q-43 0 -94.5 -11.5t-85 -23.5t-89.5 -34q-137 -54 -202 -103q-96 -73 -159.5 -189.5t-88 -236t-24.5 -248.5 q0 -40 12.5 -120t12.5 -121q0 -23 -11 -66.5t-11 -65.5t12 -36.5t34 -14.5q24 0 72.5 11t73.5 11q57 0 169.5 -15.5t169.5 -15.5q181 0 284 36q129 45 235.5 152.5t166 245.5t59.5 275zM1535 712q0 -165 -70 -327.5t-196 -288t-281 -180.5q-124 -44 -326 -44 q-57 0 -170 14.5t-169 14.5q-24 0 -72.5 -14.5t-73.5 -14.5q-73 0 -123.5 55.5t-50.5 128.5q0 24 11 68t11 67q0 40 -12.5 120.5t-12.5 121.5q0 111 18 217.5t54.5 209.5t100.5 194t150 156q78 59 232 120q194 78 316 78q60 0 175.5 -24t173.5 -24q19 0 57 5t58 5 q81 0 118 -50.5t37 -134.5q0 -23 -5 -68t-5 -68q0 -10 1 -18.5t3 -17t4 -13.5t6.5 -16t6.5 -17q16 -40 25 -118.5t9 -136.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1408 296q0 -27 -10 -70.5t-21 -68.5q-21 -50 -122 -106q-94 -51 -186 -51q-27 0 -52.5 3.5t-57.5 12.5t-47.5 14.5t-55.5 20.5t-49 18q-98 35 -175 83q-128 79 -264.5 215.5t-215.5 264.5q-48 77 -83 175q-3 9 -18 49t-20.5 55.5t-14.5 47.5t-12.5 57.5t-3.5 52.5 q0 92 51 186q56 101 106 122q25 11 68.5 21t70.5 10q14 0 21 -3q18 -6 53 -76q11 -19 30 -54t35 -63.5t31 -53.5q3 -4 17.5 -25t21.5 -35.5t7 -28.5q0 -20 -28.5 -50t-62 -55t-62 -53t-28.5 -46q0 -9 5 -22.5t8.5 -20.5t14 -24t11.5 -19q76 -137 174 -235t235 -174 q2 -1 19 -11.5t24 -14t20.5 -8.5t22.5 -5q18 0 46 28.5t53 62t55 62t50 28.5q14 0 28.5 -7t35.5 -21.5t25 -17.5q25 -15 53.5 -31t63.5 -35t54 -30q70 -35 76 -53q3 -7 3 -21z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1120 1280h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113v832q0 66 -47 113t-113 47zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832 q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1152 1280h-1024v-1242l423 406l89 85l89 -85l423 -406v1242zM1164 1408q23 0 44 -9q33 -13 52.5 -41t19.5 -62v-1289q0 -34 -19.5 -62t-52.5 -41q-19 -8 -44 -8q-48 0 -83 32l-441 424l-441 -424q-36 -33 -83 -33q-23 0 -44 9q-33 13 -52.5 41t-19.5 62v1289 q0 34 19.5 62t52.5 41q21 9 44 9h1048z" /> +<glyph unicode="" d="M1280 343q0 11 -2 16q-3 8 -38.5 29.5t-88.5 49.5l-53 29q-5 3 -19 13t-25 15t-21 5q-18 0 -47 -32.5t-57 -65.5t-44 -33q-7 0 -16.5 3.5t-15.5 6.5t-17 9.5t-14 8.5q-99 55 -170.5 126.5t-126.5 170.5q-2 3 -8.5 14t-9.5 17t-6.5 15.5t-3.5 16.5q0 13 20.5 33.5t45 38.5 t45 39.5t20.5 36.5q0 10 -5 21t-15 25t-13 19q-3 6 -15 28.5t-25 45.5t-26.5 47.5t-25 40.5t-16.5 18t-16 2q-48 0 -101 -22q-46 -21 -80 -94.5t-34 -130.5q0 -16 2.5 -34t5 -30.5t9 -33t10 -29.5t12.5 -33t11 -30q60 -164 216.5 -320.5t320.5 -216.5q6 -2 30 -11t33 -12.5 t29.5 -10t33 -9t30.5 -5t34 -2.5q57 0 130.5 34t94.5 80q22 53 22 101zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1620 1128q-67 -98 -162 -167q1 -14 1 -42q0 -130 -38 -259.5t-115.5 -248.5t-184.5 -210.5t-258 -146t-323 -54.5q-271 0 -496 145q35 -4 78 -4q225 0 401 138q-105 2 -188 64.5t-114 159.5q33 -5 61 -5q43 0 85 11q-112 23 -185.5 111.5t-73.5 205.5v4q68 -38 146 -41 q-66 44 -105 115t-39 154q0 88 44 163q121 -149 294.5 -238.5t371.5 -99.5q-8 38 -8 74q0 134 94.5 228.5t228.5 94.5q140 0 236 -102q109 21 205 78q-37 -115 -142 -178q93 10 186 50z" /> +<glyph unicode="" horiz-adv-x="768" d="M511 980h257l-30 -284h-227v-824h-341v824h-170v284h170v171q0 182 86 275.5t283 93.5h227v-284h-142q-39 0 -62.5 -6.5t-34 -23.5t-13.5 -34.5t-3 -49.5v-142z" /> +<glyph unicode="" d="M1536 640q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5 q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23 q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1664 960v-256q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45v256q0 106 -75 181t-181 75t-181 -75t-75 -181v-192h96q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h672v192q0 185 131.5 316.5t316.5 131.5 t316.5 -131.5t131.5 -316.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1760 1408q66 0 113 -47t47 -113v-1216q0 -66 -47 -113t-113 -47h-1600q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1600zM160 1280q-13 0 -22.5 -9.5t-9.5 -22.5v-224h1664v224q0 13 -9.5 22.5t-22.5 9.5h-1600zM1760 0q13 0 22.5 9.5t9.5 22.5v608h-1664v-608 q0 -13 9.5 -22.5t22.5 -9.5h1600zM256 128v128h256v-128h-256zM640 128v128h384v-128h-384z" /> +<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM896 69q2 -28 -17 -48q-18 -21 -47 -21h-135q-25 0 -43 16.5t-20 41.5q-22 229 -184.5 391.5t-391.5 184.5q-25 2 -41.5 20t-16.5 43v135q0 29 21 47q17 17 43 17h5q160 -13 306 -80.5 t259 -181.5q114 -113 181.5 -259t80.5 -306zM1408 67q2 -27 -18 -47q-18 -20 -46 -20h-143q-26 0 -44.5 17.5t-19.5 42.5q-12 215 -101 408.5t-231.5 336t-336 231.5t-408.5 102q-25 1 -42.5 19.5t-17.5 43.5v143q0 28 20 46q18 18 44 18h3q262 -13 501.5 -120t425.5 -294 q187 -186 294 -425.5t120 -501.5z" /> +<glyph unicode="" d="M1040 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1296 320q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5zM1408 160v320q0 13 -9.5 22.5t-22.5 9.5 h-1216q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h1216q13 0 22.5 9.5t9.5 22.5zM178 640h1180l-157 482q-4 13 -16 21.5t-26 8.5h-782q-14 0 -26 -8.5t-16 -21.5zM1536 480v-320q0 -66 -47 -113t-113 -47h-1216q-66 0 -113 47t-47 113v320q0 25 16 75 l197 606q17 53 63 86t101 33h782q55 0 101 -33t63 -86l197 -606q16 -50 16 -75z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1664 896q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5v-384q0 -52 -38 -90t-90 -38q-417 347 -812 380q-58 -19 -91 -66t-31 -100.5t40 -92.5q-20 -33 -23 -65.5t6 -58t33.5 -55t48 -50t61.5 -50.5q-29 -58 -111.5 -83t-168.5 -11.5t-132 55.5q-7 23 -29.5 87.5 t-32 94.5t-23 89t-15 101t3.5 98.5t22 110.5h-122q-66 0 -113 47t-47 113v192q0 66 47 113t113 47h480q435 0 896 384q52 0 90 -38t38 -90v-384zM1536 292v954q-394 -302 -768 -343v-270q377 -42 768 -341z" /> +<glyph unicode="" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM183 128h1298q-164 181 -246.5 411.5t-82.5 484.5q0 256 -320 256t-320 -256q0 -254 -82.5 -484.5t-246.5 -411.5zM1664 128q0 -52 -38 -90t-90 -38 h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" /> +<glyph unicode="" d="M1376 640l138 -135q30 -28 20 -70q-12 -41 -52 -51l-188 -48l53 -186q12 -41 -19 -70q-29 -31 -70 -19l-186 53l-48 -188q-10 -40 -51 -52q-12 -2 -19 -2q-31 0 -51 22l-135 138l-135 -138q-28 -30 -70 -20q-41 11 -51 52l-48 188l-186 -53q-41 -12 -70 19q-31 29 -19 70 l53 186l-188 48q-40 10 -52 51q-10 42 20 70l138 135l-138 135q-30 28 -20 70q12 41 52 51l188 48l-53 186q-12 41 19 70q29 31 70 19l186 -53l48 188q10 41 51 51q41 12 70 -19l135 -139l135 139q29 30 70 19q41 -10 51 -51l48 -188l186 53q41 12 70 -19q31 -29 19 -70 l-53 -186l188 -48q40 -10 52 -51q10 -42 -20 -70z" /> +<glyph unicode="" horiz-adv-x="1792" d="M256 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1664 768q0 51 -39 89.5t-89 38.5h-576q0 20 15 48.5t33 55t33 68t15 84.5q0 67 -44.5 97.5t-115.5 30.5q-24 0 -90 -139q-24 -44 -37 -65q-40 -64 -112 -145q-71 -81 -101 -106 q-69 -57 -140 -57h-32v-640h32q72 0 167 -32t193.5 -64t179.5 -32q189 0 189 167q0 26 -5 56q30 16 47.5 52.5t17.5 73.5t-18 69q53 50 53 119q0 25 -10 55.5t-25 47.5h331q52 0 90 38t38 90zM1792 769q0 -105 -75.5 -181t-180.5 -76h-169q-4 -62 -37 -119q3 -21 3 -43 q0 -101 -60 -178q1 -139 -85 -219.5t-227 -80.5q-133 0 -322 69q-164 59 -223 59h-288q-53 0 -90.5 37.5t-37.5 90.5v640q0 53 37.5 90.5t90.5 37.5h288q10 0 21.5 4.5t23.5 14t22.5 18t24 22.5t20.5 21.5t19 21.5t14 17q65 74 100 129q13 21 33 62t37 72t40.5 63t55 49.5 t69.5 17.5q125 0 206.5 -67t81.5 -189q0 -68 -22 -128h374q104 0 180 -76t76 -179z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1376 128h32v640h-32q-35 0 -67.5 12t-62.5 37t-50 46t-49 54q-2 3 -3.5 4.5t-4 4.5t-4.5 5q-72 81 -112 145q-14 22 -38 68q-1 3 -10.5 22.5t-18.5 36t-20 35.5t-21.5 30.5t-18.5 11.5q-71 0 -115.5 -30.5t-44.5 -97.5q0 -43 15 -84.5t33 -68t33 -55t15 -48.5h-576 q-50 0 -89 -38.5t-39 -89.5q0 -52 38 -90t90 -38h331q-15 -17 -25 -47.5t-10 -55.5q0 -69 53 -119q-18 -32 -18 -69t17.5 -73.5t47.5 -52.5q-4 -24 -4 -56q0 -85 48.5 -126t135.5 -41q84 0 183 32t194 64t167 32zM1664 192q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45 t45 -19t45 19t19 45zM1792 768v-640q0 -53 -37.5 -90.5t-90.5 -37.5h-288q-59 0 -223 -59q-190 -69 -317 -69q-142 0 -230 77.5t-87 217.5l1 5q-61 76 -61 178q0 22 3 43q-33 57 -37 119h-169q-105 0 -180.5 76t-75.5 181q0 103 76 179t180 76h374q-22 60 -22 128 q0 122 81.5 189t206.5 67q38 0 69.5 -17.5t55 -49.5t40.5 -63t37 -72t33 -62q35 -55 100 -129q2 -3 14 -17t19 -21.5t20.5 -21.5t24 -22.5t22.5 -18t23.5 -14t21.5 -4.5h288q53 0 90.5 -37.5t37.5 -90.5z" /> +<glyph unicode="" d="M1280 -64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 700q0 189 -167 189q-26 0 -56 -5q-16 30 -52.5 47.5t-73.5 17.5t-69 -18q-50 53 -119 53q-25 0 -55.5 -10t-47.5 -25v331q0 52 -38 90t-90 38q-51 0 -89.5 -39t-38.5 -89v-576 q-20 0 -48.5 15t-55 33t-68 33t-84.5 15q-67 0 -97.5 -44.5t-30.5 -115.5q0 -24 139 -90q44 -24 65 -37q64 -40 145 -112q81 -71 106 -101q57 -69 57 -140v-32h640v32q0 72 32 167t64 193.5t32 179.5zM1536 705q0 -133 -69 -322q-59 -164 -59 -223v-288q0 -53 -37.5 -90.5 t-90.5 -37.5h-640q-53 0 -90.5 37.5t-37.5 90.5v288q0 10 -4.5 21.5t-14 23.5t-18 22.5t-22.5 24t-21.5 20.5t-21.5 19t-17 14q-74 65 -129 100q-21 13 -62 33t-72 37t-63 40.5t-49.5 55t-17.5 69.5q0 125 67 206.5t189 81.5q68 0 128 -22v374q0 104 76 180t179 76 q105 0 181 -75.5t76 -180.5v-169q62 -4 119 -37q21 3 43 3q101 0 178 -60q139 1 219.5 -85t80.5 -227z" /> +<glyph unicode="" d="M1408 576q0 84 -32 183t-64 194t-32 167v32h-640v-32q0 -35 -12 -67.5t-37 -62.5t-46 -50t-54 -49q-9 -8 -14 -12q-81 -72 -145 -112q-22 -14 -68 -38q-3 -1 -22.5 -10.5t-36 -18.5t-35.5 -20t-30.5 -21.5t-11.5 -18.5q0 -71 30.5 -115.5t97.5 -44.5q43 0 84.5 15t68 33 t55 33t48.5 15v-576q0 -50 38.5 -89t89.5 -39q52 0 90 38t38 90v331q46 -35 103 -35q69 0 119 53q32 -18 69 -18t73.5 17.5t52.5 47.5q24 -4 56 -4q85 0 126 48.5t41 135.5zM1280 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1536 580 q0 -142 -77.5 -230t-217.5 -87l-5 1q-76 -61 -178 -61q-22 0 -43 3q-54 -30 -119 -37v-169q0 -105 -76 -180.5t-181 -75.5q-103 0 -179 76t-76 180v374q-54 -22 -128 -22q-121 0 -188.5 81.5t-67.5 206.5q0 38 17.5 69.5t49.5 55t63 40.5t72 37t62 33q55 35 129 100 q3 2 17 14t21.5 19t21.5 20.5t22.5 24t18 22.5t14 23.5t4.5 21.5v288q0 53 37.5 90.5t90.5 37.5h640q53 0 90.5 -37.5t37.5 -90.5v-288q0 -59 59 -223q69 -190 69 -317z" /> +<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-502l189 189q19 19 19 45t-19 45l-91 91q-18 18 -45 18t-45 -18l-362 -362l-91 -91q-18 -18 -18 -45t18 -45l91 -91l362 -362q18 -18 45 -18t45 18l91 91q18 18 18 45t-18 45l-189 189h502q26 0 45 19t19 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1285 640q0 27 -18 45l-91 91l-362 362q-18 18 -45 18t-45 -18l-91 -91q-18 -18 -18 -45t18 -45l189 -189h-502q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h502l-189 -189q-19 -19 -19 -45t19 -45l91 -91q18 -18 45 -18t45 18l362 362l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1284 641q0 27 -18 45l-362 362l-91 91q-18 18 -45 18t-45 -18l-91 -91l-362 -362q-18 -18 -18 -45t18 -45l91 -91q18 -18 45 -18t45 18l189 189v-502q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v502l189 -189q19 -19 45 -19t45 19l91 91q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1284 639q0 27 -18 45l-91 91q-18 18 -45 18t-45 -18l-189 -189v502q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-502l-189 189q-19 19 -45 19t-45 -19l-91 -91q-18 -18 -18 -45t18 -45l362 -362l91 -91q18 -18 45 -18t45 18l91 91l362 362q18 18 18 45zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1042 887q-2 -1 -9.5 -9.5t-13.5 -9.5q2 0 4.5 5t5 11t3.5 7q6 7 22 15q14 6 52 12q34 8 51 -11 q-2 2 9.5 13t14.5 12q3 2 15 4.5t15 7.5l2 22q-12 -1 -17.5 7t-6.5 21q0 -2 -6 -8q0 7 -4.5 8t-11.5 -1t-9 -1q-10 3 -15 7.5t-8 16.5t-4 15q-2 5 -9.5 10.5t-9.5 10.5q-1 2 -2.5 5.5t-3 6.5t-4 5.5t-5.5 2.5t-7 -5t-7.5 -10t-4.5 -5q-3 2 -6 1.5t-4.5 -1t-4.5 -3t-5 -3.5 q-3 -2 -8.5 -3t-8.5 -2q15 5 -1 11q-10 4 -16 3q9 4 7.5 12t-8.5 14h5q-1 4 -8.5 8.5t-17.5 8.5t-13 6q-8 5 -34 9.5t-33 0.5q-5 -6 -4.5 -10.5t4 -14t3.5 -12.5q1 -6 -5.5 -13t-6.5 -12q0 -7 14 -15.5t10 -21.5q-3 -8 -16 -16t-16 -12q-5 -8 -1.5 -18.5t10.5 -16.5 q2 -2 1.5 -4t-3.5 -4.5t-5.5 -4t-6.5 -3.5l-3 -2q-11 -5 -20.5 6t-13.5 26q-7 25 -16 30q-23 8 -29 -1q-5 13 -41 26q-25 9 -58 4q6 1 0 15q-7 15 -19 12q3 6 4 17.5t1 13.5q3 13 12 23q1 1 7 8.5t9.5 13.5t0.5 6q35 -4 50 11q5 5 11.5 17t10.5 17q9 6 14 5.5t14.5 -5.5 t14.5 -5q14 -1 15.5 11t-7.5 20q12 -1 3 17q-5 7 -8 9q-12 4 -27 -5q-8 -4 2 -8q-1 1 -9.5 -10.5t-16.5 -17.5t-16 5q-1 1 -5.5 13.5t-9.5 13.5q-8 0 -16 -15q3 8 -11 15t-24 8q19 12 -8 27q-7 4 -20.5 5t-19.5 -4q-5 -7 -5.5 -11.5t5 -8t10.5 -5.5t11.5 -4t8.5 -3 q14 -10 8 -14q-2 -1 -8.5 -3.5t-11.5 -4.5t-6 -4q-3 -4 0 -14t-2 -14q-5 5 -9 17.5t-7 16.5q7 -9 -25 -6l-10 1q-4 0 -16 -2t-20.5 -1t-13.5 8q-4 8 0 20q1 4 4 2q-4 3 -11 9.5t-10 8.5q-46 -15 -94 -41q6 -1 12 1q5 2 13 6.5t10 5.5q34 14 42 7l5 5q14 -16 20 -25 q-7 4 -30 1q-20 -6 -22 -12q7 -12 5 -18q-4 3 -11.5 10t-14.5 11t-15 5q-16 0 -22 -1q-146 -80 -235 -222q7 -7 12 -8q4 -1 5 -9t2.5 -11t11.5 3q9 -8 3 -19q1 1 44 -27q19 -17 21 -21q3 -11 -10 -18q-1 2 -9 9t-9 4q-3 -5 0.5 -18.5t10.5 -12.5q-7 0 -9.5 -16t-2.5 -35.5 t-1 -23.5l2 -1q-3 -12 5.5 -34.5t21.5 -19.5q-13 -3 20 -43q6 -8 8 -9q3 -2 12 -7.5t15 -10t10 -10.5q4 -5 10 -22.5t14 -23.5q-2 -6 9.5 -20t10.5 -23q-1 0 -2.5 -1t-2.5 -1q3 -7 15.5 -14t15.5 -13q1 -3 2 -10t3 -11t8 -2q2 20 -24 62q-15 25 -17 29q-3 5 -5.5 15.5 t-4.5 14.5q2 0 6 -1.5t8.5 -3.5t7.5 -4t2 -3q-3 -7 2 -17.5t12 -18.5t17 -19t12 -13q6 -6 14 -19.5t0 -13.5q9 0 20 -10t17 -20q5 -8 8 -26t5 -24q2 -7 8.5 -13.5t12.5 -9.5l16 -8t13 -7q5 -2 18.5 -10.5t21.5 -11.5q10 -4 16 -4t14.5 2.5t13.5 3.5q15 2 29 -15t21 -21 q36 -19 55 -11q-2 -1 0.5 -7.5t8 -15.5t9 -14.5t5.5 -8.5q5 -6 18 -15t18 -15q6 4 7 9q-3 -8 7 -20t18 -10q14 3 14 32q-31 -15 -49 18q0 1 -2.5 5.5t-4 8.5t-2.5 8.5t0 7.5t5 3q9 0 10 3.5t-2 12.5t-4 13q-1 8 -11 20t-12 15q-5 -9 -16 -8t-16 9q0 -1 -1.5 -5.5t-1.5 -6.5 q-13 0 -15 1q1 3 2.5 17.5t3.5 22.5q1 4 5.5 12t7.5 14.5t4 12.5t-4.5 9.5t-17.5 2.5q-19 -1 -26 -20q-1 -3 -3 -10.5t-5 -11.5t-9 -7q-7 -3 -24 -2t-24 5q-13 8 -22.5 29t-9.5 37q0 10 2.5 26.5t3 25t-5.5 24.5q3 2 9 9.5t10 10.5q2 1 4.5 1.5t4.5 0t4 1.5t3 6q-1 1 -4 3 q-3 3 -4 3q7 -3 28.5 1.5t27.5 -1.5q15 -11 22 2q0 1 -2.5 9.5t-0.5 13.5q5 -27 29 -9q3 -3 15.5 -5t17.5 -5q3 -2 7 -5.5t5.5 -4.5t5 0.5t8.5 6.5q10 -14 12 -24q11 -40 19 -44q7 -3 11 -2t4.5 9.5t0 14t-1.5 12.5l-1 8v18l-1 8q-15 3 -18.5 12t1.5 18.5t15 18.5q1 1 8 3.5 t15.5 6.5t12.5 8q21 19 15 35q7 0 11 9q-1 0 -5 3t-7.5 5t-4.5 2q9 5 2 16q5 3 7.5 11t7.5 10q9 -12 21 -2q7 8 1 16q5 7 20.5 10.5t18.5 9.5q7 -2 8 2t1 12t3 12q4 5 15 9t13 5l17 11q3 4 0 4q18 -2 31 11q10 11 -6 20q3 6 -3 9.5t-15 5.5q3 1 11.5 0.5t10.5 1.5 q15 10 -7 16q-17 5 -43 -12zM879 10q206 36 351 189q-3 3 -12.5 4.5t-12.5 3.5q-18 7 -24 8q1 7 -2.5 13t-8 9t-12.5 8t-11 7q-2 2 -7 6t-7 5.5t-7.5 4.5t-8.5 2t-10 -1l-3 -1q-3 -1 -5.5 -2.5t-5.5 -3t-4 -3t0 -2.5q-21 17 -36 22q-5 1 -11 5.5t-10.5 7t-10 1.5t-11.5 -7 q-5 -5 -6 -15t-2 -13q-7 5 0 17.5t2 18.5q-3 6 -10.5 4.5t-12 -4.5t-11.5 -8.5t-9 -6.5t-8.5 -5.5t-8.5 -7.5q-3 -4 -6 -12t-5 -11q-2 4 -11.5 6.5t-9.5 5.5q2 -10 4 -35t5 -38q7 -31 -12 -48q-27 -25 -29 -40q-4 -22 12 -26q0 -7 -8 -20.5t-7 -21.5q0 -6 2 -16z" /> +<glyph unicode="" horiz-adv-x="1664" d="M384 64q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1028 484l-682 -682q-37 -37 -90 -37q-52 0 -91 37l-106 108q-38 36 -38 90q0 53 38 91l681 681q39 -98 114.5 -173.5t173.5 -114.5zM1662 919q0 -39 -23 -106q-47 -134 -164.5 -217.5 t-258.5 -83.5q-185 0 -316.5 131.5t-131.5 316.5t131.5 316.5t316.5 131.5q58 0 121.5 -16.5t107.5 -46.5q16 -11 16 -28t-16 -28l-293 -169v-224l193 -107q5 3 79 48.5t135.5 81t70.5 35.5q15 0 23.5 -10t8.5 -25z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1024 128h640v128h-640v-128zM640 640h1024v128h-1024v-128zM1280 1152h384v128h-384v-128zM1792 320v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 832v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19 t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45zM1792 1344v-256q0 -26 -19 -45t-45 -19h-1664q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1664q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1403 1241q17 -41 -14 -70l-493 -493v-742q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-256 256q-19 19 -19 45v486l-493 493q-31 29 -14 70q17 39 59 39h1280q42 0 59 -39z" /> +<glyph unicode="" horiz-adv-x="1792" d="M640 1280h512v128h-512v-128zM1792 640v-480q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v480h672v-160q0 -26 19 -45t45 -19h320q26 0 45 19t19 45v160h672zM1024 640v-128h-256v128h256zM1792 1120v-384h-1792v384q0 66 47 113t113 47h352v160q0 40 28 68 t68 28h576q40 0 68 -28t28 -68v-160h352q66 0 113 -47t47 -113z" /> +<glyph unicode="" d="M1283 995l-355 -355l355 -355l144 144q29 31 70 14q39 -17 39 -59v-448q0 -26 -19 -45t-45 -19h-448q-42 0 -59 40q-17 39 14 69l144 144l-355 355l-355 -355l144 -144q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l144 -144 l355 355l-355 355l-144 -144q-19 -19 -45 -19q-12 0 -24 5q-40 17 -40 59v448q0 26 19 45t45 19h448q42 0 59 -40q17 -39 -14 -69l-144 -144l355 -355l355 355l-144 144q-31 30 -14 69q17 40 59 40h448q26 0 45 -19t19 -45v-448q0 -42 -39 -59q-13 -5 -25 -5q-26 0 -45 19z " /> +<glyph unicode="" horiz-adv-x="1920" d="M593 640q-162 -5 -265 -128h-134q-82 0 -138 40.5t-56 118.5q0 353 124 353q6 0 43.5 -21t97.5 -42.5t119 -21.5q67 0 133 23q-5 -37 -5 -66q0 -139 81 -256zM1664 3q0 -120 -73 -189.5t-194 -69.5h-874q-121 0 -194 69.5t-73 189.5q0 53 3.5 103.5t14 109t26.5 108.5 t43 97.5t62 81t85.5 53.5t111.5 20q10 0 43 -21.5t73 -48t107 -48t135 -21.5t135 21.5t107 48t73 48t43 21.5q61 0 111.5 -20t85.5 -53.5t62 -81t43 -97.5t26.5 -108.5t14 -109t3.5 -103.5zM640 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75 t75 -181zM1344 896q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5t271.5 -112.5t112.5 -271.5zM1920 671q0 -78 -56 -118.5t-138 -40.5h-134q-103 123 -265 128q81 117 81 256q0 29 -5 66q66 -23 133 -23q59 0 119 21.5t97.5 42.5 t43.5 21q124 0 124 -353zM1792 1280q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1456 320q0 40 -28 68l-208 208q-28 28 -68 28q-42 0 -72 -32q3 -3 19 -18.5t21.5 -21.5t15 -19t13 -25.5t3.5 -27.5q0 -40 -28 -68t-68 -28q-15 0 -27.5 3.5t-25.5 13t-19 15t-21.5 21.5t-18.5 19q-33 -31 -33 -73q0 -40 28 -68l206 -207q27 -27 68 -27q40 0 68 26 l147 146q28 28 28 67zM753 1025q0 40 -28 68l-206 207q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l208 -208q27 -27 68 -27q42 0 72 31q-3 3 -19 18.5t-21.5 21.5t-15 19t-13 25.5t-3.5 27.5q0 40 28 68t68 28q15 0 27.5 -3.5t25.5 -13t19 -15 t21.5 -21.5t18.5 -19q33 31 33 73zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-206 207q-83 83 -83 203q0 123 88 209l-88 88q-86 -88 -208 -88q-120 0 -204 84l-208 208q-84 84 -84 204t85 203l147 146q83 83 203 83q121 0 204 -85l206 -207 q83 -83 83 -203q0 -123 -88 -209l88 -88q86 88 208 88q120 0 204 -84l208 -208q84 -84 84 -204z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088q-185 0 -316.5 131.5t-131.5 316.5q0 132 71 241.5t187 163.5q-2 28 -2 43q0 212 150 362t362 150q158 0 286.5 -88t187.5 -230q70 62 166 62q106 0 181 -75t75 -181q0 -75 -41 -138q129 -30 213 -134.5t84 -239.5z " /> +<glyph unicode="" horiz-adv-x="1664" d="M1527 88q56 -89 21.5 -152.5t-140.5 -63.5h-1152q-106 0 -140.5 63.5t21.5 152.5l503 793v399h-64q-26 0 -45 19t-19 45t19 45t45 19h512q26 0 45 -19t19 -45t-19 -45t-45 -19h-64v-399zM748 813l-272 -429h712l-272 429l-20 31v37v399h-128v-399v-37z" /> +<glyph unicode="" horiz-adv-x="1792" d="M960 640q26 0 45 -19t19 -45t-19 -45t-45 -19t-45 19t-19 45t19 45t45 19zM1260 576l507 -398q28 -20 25 -56q-5 -35 -35 -51l-128 -64q-13 -7 -29 -7q-17 0 -31 8l-690 387l-110 -66q-8 -4 -12 -5q14 -49 10 -97q-7 -77 -56 -147.5t-132 -123.5q-132 -84 -277 -84 q-136 0 -222 78q-90 84 -79 207q7 76 56 147t131 124q132 84 278 84q83 0 151 -31q9 13 22 22l122 73l-122 73q-13 9 -22 22q-68 -31 -151 -31q-146 0 -278 84q-82 53 -131 124t-56 147q-5 59 15.5 113t63.5 93q85 79 222 79q145 0 277 -84q83 -52 132 -123t56 -148 q4 -48 -10 -97q4 -1 12 -5l110 -66l690 387q14 8 31 8q16 0 29 -7l128 -64q30 -16 35 -51q3 -36 -25 -56zM579 836q46 42 21 108t-106 117q-92 59 -192 59q-74 0 -113 -36q-46 -42 -21 -108t106 -117q92 -59 192 -59q74 0 113 36zM494 91q81 51 106 117t-21 108 q-39 36 -113 36q-100 0 -192 -59q-81 -51 -106 -117t21 -108q39 -36 113 -36q100 0 192 59zM672 704l96 -58v11q0 36 33 56l14 8l-79 47l-26 -26q-3 -3 -10 -11t-12 -12q-2 -2 -4 -3.5t-3 -2.5zM896 480l96 -32l736 576l-128 64l-768 -431v-113l-160 -96l9 -8q2 -2 7 -6 q4 -4 11 -12t11 -12l26 -26zM1600 64l128 64l-520 408l-177 -138q-2 -3 -13 -7z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1696 1152q40 0 68 -28t28 -68v-1216q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v288h-544q-40 0 -68 28t-28 68v672q0 40 20 88t48 76l408 408q28 28 76 48t88 20h416q40 0 68 -28t28 -68v-328q68 40 128 40h416zM1152 939l-299 -299h299v299zM512 1323l-299 -299 h299v299zM708 676l316 316v416h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h512v256q0 40 20 88t48 76zM1664 -128v1152h-384v-416q0 -40 -28 -68t-68 -28h-416v-640h896z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1404 151q0 -117 -79 -196t-196 -79q-135 0 -235 100l-777 776q-113 115 -113 271q0 159 110 270t269 111q158 0 273 -113l605 -606q10 -10 10 -22q0 -16 -30.5 -46.5t-46.5 -30.5q-13 0 -23 10l-606 607q-79 77 -181 77q-106 0 -179 -75t-73 -181q0 -105 76 -181 l776 -777q63 -63 145 -63q64 0 106 42t42 106q0 82 -63 145l-581 581q-26 24 -60 24q-29 0 -48 -19t-19 -48q0 -32 25 -59l410 -410q10 -10 10 -22q0 -16 -31 -47t-47 -31q-12 0 -22 10l-410 410q-63 61 -63 149q0 82 57 139t139 57q88 0 149 -63l581 -581q100 -98 100 -235 z" /> +<glyph unicode="" d="M384 0h768v384h-768v-384zM1280 0h128v896q0 14 -10 38.5t-20 34.5l-281 281q-10 10 -34 20t-39 10v-416q0 -40 -28 -68t-68 -28h-576q-40 0 -68 28t-28 68v416h-128v-1280h128v416q0 40 28 68t68 28h832q40 0 68 -28t28 -68v-416zM896 928v320q0 13 -9.5 22.5t-22.5 9.5 h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5zM1536 896v-928q0 -40 -28 -68t-68 -28h-1344q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h928q40 0 88 -20t76 -48l280 -280q28 -28 48 -76t20 -88z" /> +<glyph unicode="" d="M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1536 192v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 704v-128q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1536 1216v-128q0 -26 -19 -45 t-45 -19h-1408q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M384 128q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM384 640q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 224v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5 t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1152q0 -80 -56 -136t-136 -56t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z M1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M381 -84q0 -80 -54.5 -126t-135.5 -46q-106 0 -172 66l57 88q49 -45 106 -45q29 0 50.5 14.5t21.5 42.5q0 64 -105 56l-26 56q8 10 32.5 43.5t42.5 54t37 38.5v1q-16 0 -48.5 -1t-48.5 -1v-53h-106v152h333v-88l-95 -115q51 -12 81 -49t30 -88zM383 543v-159h-362 q-6 36 -6 54q0 51 23.5 93t56.5 68t66 47.5t56.5 43.5t23.5 45q0 25 -14.5 38.5t-39.5 13.5q-46 0 -81 -58l-85 59q24 51 71.5 79.5t105.5 28.5q73 0 123 -41.5t50 -112.5q0 -50 -34 -91.5t-75 -64.5t-75.5 -50.5t-35.5 -52.5h127v60h105zM1792 224v-192q0 -13 -9.5 -22.5 t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM384 1123v-99h-335v99h107q0 41 0.5 122t0.5 121v12h-2q-8 -17 -50 -54l-71 76l136 127h106v-404h108zM1792 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5 t-9.5 22.5v192q0 14 9 23t23 9h1216q13 0 22.5 -9.5t9.5 -22.5zM1792 1248v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1216q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1216q13 0 22.5 -9.5t9.5 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1760 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-1728q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h1728zM483 704q-28 35 -51 80q-48 97 -48 188q0 181 134 309q133 127 393 127q50 0 167 -19q66 -12 177 -48q10 -38 21 -118q14 -123 14 -183q0 -18 -5 -45l-12 -3l-84 6 l-14 2q-50 149 -103 205q-88 91 -210 91q-114 0 -182 -59q-67 -58 -67 -146q0 -73 66 -140t279 -129q69 -20 173 -66q58 -28 95 -52h-743zM990 448h411q7 -39 7 -92q0 -111 -41 -212q-23 -55 -71 -104q-37 -35 -109 -81q-80 -48 -153 -66q-80 -21 -203 -21q-114 0 -195 23 l-140 40q-57 16 -72 28q-8 8 -8 22v13q0 108 -2 156q-1 30 0 68l2 37v44l102 2q15 -34 30 -71t22.5 -56t12.5 -27q35 -57 80 -94q43 -36 105 -57q59 -22 132 -22q64 0 139 27q77 26 122 86q47 61 47 129q0 84 -81 157q-34 29 -137 71z" /> +<glyph unicode="" d="M48 1313q-37 2 -45 4l-3 88q13 1 40 1q60 0 112 -4q132 -7 166 -7q86 0 168 3q116 4 146 5q56 0 86 2l-1 -14l2 -64v-9q-60 -9 -124 -9q-60 0 -79 -25q-13 -14 -13 -132q0 -13 0.5 -32.5t0.5 -25.5l1 -229l14 -280q6 -124 51 -202q35 -59 96 -92q88 -47 177 -47 q104 0 191 28q56 18 99 51q48 36 65 64q36 56 53 114q21 73 21 229q0 79 -3.5 128t-11 122.5t-13.5 159.5l-4 59q-5 67 -24 88q-34 35 -77 34l-100 -2l-14 3l2 86h84l205 -10q76 -3 196 10l18 -2q6 -38 6 -51q0 -7 -4 -31q-45 -12 -84 -13q-73 -11 -79 -17q-15 -15 -15 -41 q0 -7 1.5 -27t1.5 -31q8 -19 22 -396q6 -195 -15 -304q-15 -76 -41 -122q-38 -65 -112 -123q-75 -57 -182 -89q-109 -33 -255 -33q-167 0 -284 46q-119 47 -179 122q-61 76 -83 195q-16 80 -16 237v333q0 188 -17 213q-25 36 -147 39zM1536 -96v64q0 14 -9 23t-23 9h-1472 q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h1472q14 0 23 9t9 23z" /> +<glyph unicode="" horiz-adv-x="1664" d="M512 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 160v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23 v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM512 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 160v192 q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1024 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 544v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192 q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1536 928v192q0 14 -9 23t-23 9h-320q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h320q14 0 23 9t9 23zM1664 1248v-1088q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1344q66 0 113 -47t47 -113 z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1190 955l293 293l-107 107l-293 -293zM1637 1248q0 -27 -18 -45l-1286 -1286q-18 -18 -45 -18t-45 18l-198 198q-18 18 -18 45t18 45l1286 1286q18 18 45 18t45 -18l198 -198q18 -18 18 -45zM286 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM636 1276 l196 -60l-196 -60l-60 -196l-60 196l-196 60l196 60l60 196zM1566 798l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98zM926 1438l98 -30l-98 -30l-30 -98l-30 98l-98 30l98 30l30 98z" /> +<glyph unicode="" horiz-adv-x="1792" d="M640 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM256 640h384v256h-158q-13 0 -22 -9l-195 -195q-9 -9 -9 -22v-30zM1536 128q0 52 -38 90t-90 38t-90 -38t-38 -90t38 -90t90 -38t90 38t38 90zM1792 1216v-1024q0 -15 -4 -26.5t-13.5 -18.5 t-16.5 -11.5t-23.5 -6t-22.5 -2t-25.5 0t-22.5 0.5q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-64q-3 0 -22.5 -0.5t-25.5 0t-22.5 2t-23.5 6t-16.5 11.5t-13.5 18.5t-4 26.5q0 26 19 45t45 19v320q0 8 -0.5 35t0 38 t2.5 34.5t6.5 37t14 30.5t22.5 30l198 198q19 19 50.5 32t58.5 13h160v192q0 26 19 45t45 19h1024q26 0 45 -19t19 -45z" /> +<glyph unicode="" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103q-111 0 -218 32q59 93 78 164q9 34 54 211q20 -39 73 -67.5t114 -28.5q121 0 216 68.5t147 188.5t52 270q0 114 -59.5 214t-172.5 163t-255 63q-105 0 -196 -29t-154.5 -77t-109 -110.5t-67 -129.5t-21.5 -134 q0 -104 40 -183t117 -111q30 -12 38 20q2 7 8 31t8 30q6 23 -11 43q-51 61 -51 151q0 151 104.5 259.5t273.5 108.5q151 0 235.5 -82t84.5 -213q0 -170 -68.5 -289t-175.5 -119q-61 0 -98 43.5t-23 104.5q8 35 26.5 93.5t30 103t11.5 75.5q0 50 -27 83t-77 33 q-62 0 -105 -57t-43 -142q0 -73 25 -122l-99 -418q-17 -70 -13 -177q-206 91 -333 281t-127 423q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-725q85 122 108 210q9 34 53 209q21 -39 73.5 -67t112.5 -28q181 0 295.5 147.5t114.5 373.5q0 84 -35 162.5t-96.5 139t-152.5 97t-197 36.5q-104 0 -194.5 -28.5t-153 -76.5 t-107.5 -109.5t-66.5 -128t-21.5 -132.5q0 -102 39.5 -180t116.5 -110q13 -5 23.5 0t14.5 19q10 44 15 61q6 23 -11 42q-50 62 -50 150q0 150 103.5 256.5t270.5 106.5q149 0 232.5 -81t83.5 -210q0 -168 -67.5 -286t-173.5 -118q-60 0 -97 43.5t-23 103.5q8 34 26.5 92.5 t29.5 102t11 74.5q0 49 -26.5 81.5t-75.5 32.5q-61 0 -103.5 -56.5t-42.5 -139.5q0 -72 24 -121l-98 -414q-24 -100 -7 -254h-183q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960z" /> +<glyph unicode="" d="M678 -57q0 -38 -10 -71h-380q-95 0 -171.5 56.5t-103.5 147.5q24 45 69 77.5t100 49.5t107 24t107 7q32 0 49 -2q6 -4 30.5 -21t33 -23t31 -23t32 -25.5t27.5 -25.5t26.5 -29.5t21 -30.5t17.5 -34.5t9.5 -36t4.5 -40.5zM385 294q-234 -7 -385 -85v433q103 -118 273 -118 q32 0 70 5q-21 -61 -21 -86q0 -67 63 -149zM558 805q0 -100 -43.5 -160.5t-140.5 -60.5q-51 0 -97 26t-78 67.5t-56 93.5t-35.5 104t-11.5 99q0 96 51.5 165t144.5 69q66 0 119 -41t84 -104t47 -130t16 -128zM1536 896v-736q0 -119 -84.5 -203.5t-203.5 -84.5h-468 q39 73 39 157q0 66 -22 122.5t-55.5 93t-72 71t-72 59.5t-55.5 54.5t-22 59.5q0 36 23 68t56 61.5t65.5 64.5t55.5 93t23 131t-26.5 145.5t-75.5 118.5q-6 6 -14 11t-12.5 7.5t-10 9.5t-10.5 17h135l135 64h-437q-138 0 -244.5 -38.5t-182.5 -133.5q0 126 81 213t207 87h960 q119 0 203.5 -84.5t84.5 -203.5v-96h-256v256h-128v-256h-256v-128h256v-256h128v256h256z" /> +<glyph unicode="" horiz-adv-x="1664" d="M876 71q0 21 -4.5 40.5t-9.5 36t-17.5 34.5t-21 30.5t-26.5 29.5t-27.5 25.5t-32 25.5t-31 23t-33 23t-30.5 21q-17 2 -50 2q-54 0 -106 -7t-108 -25t-98 -46t-69 -75t-27 -107q0 -68 35.5 -121.5t93 -84t120.5 -45.5t127 -15q59 0 112.5 12.5t100.5 39t74.5 73.5 t27.5 110zM756 933q0 60 -16.5 127.5t-47 130.5t-84 104t-119.5 41q-93 0 -144 -69t-51 -165q0 -47 11.5 -99t35.5 -104t56 -93.5t78 -67.5t97 -26q97 0 140.5 60.5t43.5 160.5zM625 1408h437l-135 -79h-135q71 -45 110 -126t39 -169q0 -74 -23 -131.5t-56 -92.5t-66 -64.5 t-56 -61t-23 -67.5q0 -26 16.5 -51t43 -48t58.5 -48t64 -55.5t58.5 -66t43 -85t16.5 -106.5q0 -160 -140 -282q-152 -131 -420 -131q-59 0 -119.5 10t-122 33.5t-108.5 58t-77 89t-30 121.5q0 61 37 135q32 64 96 110.5t145 71t155 36t150 13.5q-64 83 -64 149q0 12 2 23.5 t5 19.5t8 21.5t7 21.5q-40 -5 -70 -5q-149 0 -255.5 98t-106.5 246q0 140 95 250.5t234 141.5q94 20 187 20zM1664 1152v-128h-256v-256h-128v256h-256v128h256v256h128v-256h256z" /> +<glyph unicode="" horiz-adv-x="1920" d="M768 384h384v96h-128v448h-114l-148 -137l77 -80q42 37 55 57h2v-288h-128v-96zM1280 640q0 -70 -21 -142t-59.5 -134t-101.5 -101t-138 -39t-138 39t-101.5 101t-59.5 134t-21 142t21 142t59.5 134t101.5 101t138 39t138 -39t101.5 -101t59.5 -134t21 -142zM1792 384 v512q-106 0 -181 75t-75 181h-1152q0 -106 -75 -181t-181 -75v-512q106 0 181 -75t75 -181h1152q0 106 75 181t181 75zM1920 1216v-1152q0 -26 -19 -45t-45 -19h-1792q-26 0 -45 19t-19 45v1152q0 26 19 45t45 19h1792q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1024 320q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="640" d="M640 1088v-896q0 -26 -19 -45t-45 -19t-45 19l-448 448q-19 19 -19 45t19 45l448 448q19 19 45 19t45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="640" d="M576 640q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19t-19 45v896q0 26 19 45t45 19t45 -19l448 -448q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M160 0h608v1152h-640v-1120q0 -13 9.5 -22.5t22.5 -9.5zM1536 32v1120h-640v-1152h608q13 0 22.5 9.5t9.5 22.5zM1664 1248v-1216q0 -66 -47 -113t-113 -47h-1344q-66 0 -113 47t-47 113v1216q0 66 47 113t113 47h1344q66 0 113 -47t47 -113z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45zM1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1024 448q0 -26 -19 -45l-448 -448q-19 -19 -45 -19t-45 19l-448 448q-19 19 -19 45t19 45t45 19h896q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1024 832q0 -26 -19 -45t-45 -19h-896q-26 0 -45 19t-19 45t19 45l448 448q19 19 45 19t45 -19l448 -448q19 -19 19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 826v-794q0 -66 -47 -113t-113 -47h-1472q-66 0 -113 47t-47 113v794q44 -49 101 -87q362 -246 497 -345q57 -42 92.5 -65.5t94.5 -48t110 -24.5h1h1q51 0 110 24.5t94.5 48t92.5 65.5q170 123 498 345q57 39 100 87zM1792 1120q0 -79 -49 -151t-122 -123 q-376 -261 -468 -325q-10 -7 -42.5 -30.5t-54 -38t-52 -32.5t-57.5 -27t-50 -9h-1h-1q-23 0 -50 9t-57.5 27t-52 32.5t-54 38t-42.5 30.5q-91 64 -262 182.5t-205 142.5q-62 42 -117 115.5t-55 136.5q0 78 41.5 130t118.5 52h1472q65 0 112.5 -47t47.5 -113z" /> +<glyph unicode="" d="M349 911v-991h-330v991h330zM370 1217q1 -73 -50.5 -122t-135.5 -49h-2q-82 0 -132 49t-50 122q0 74 51.5 122.5t134.5 48.5t133 -48.5t51 -122.5zM1536 488v-568h-329v530q0 105 -40.5 164.5t-126.5 59.5q-63 0 -105.5 -34.5t-63.5 -85.5q-11 -30 -11 -81v-553h-329 q2 399 2 647t-1 296l-1 48h329v-144h-2q20 32 41 56t56.5 52t87 43.5t114.5 15.5q171 0 275 -113.5t104 -332.5z" /> +<glyph unicode="" d="M1536 640q0 -156 -61 -298t-164 -245t-245 -164t-298 -61q-172 0 -327 72.5t-264 204.5q-7 10 -6.5 22.5t8.5 20.5l137 138q10 9 25 9q16 -2 23 -12q73 -95 179 -147t225 -52q104 0 198.5 40.5t163.5 109.5t109.5 163.5t40.5 198.5t-40.5 198.5t-109.5 163.5 t-163.5 109.5t-198.5 40.5q-98 0 -188 -35.5t-160 -101.5l137 -138q31 -30 14 -69q-17 -40 -59 -40h-448q-26 0 -45 19t-19 45v448q0 42 40 59q39 17 69 -14l130 -129q107 101 244.5 156.5t284.5 55.5q156 0 298 -61t245 -164t164 -245t61 -298z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1771 0q0 -53 -37 -90l-107 -108q-39 -37 -91 -37q-53 0 -90 37l-363 364q-38 36 -38 90q0 53 43 96l-256 256l-126 -126q-14 -14 -34 -14t-34 14q2 -2 12.5 -12t12.5 -13t10 -11.5t10 -13.5t6 -13.5t5.5 -16.5t1.5 -18q0 -38 -28 -68q-3 -3 -16.5 -18t-19 -20.5 t-18.5 -16.5t-22 -15.5t-22 -9t-26 -4.5q-40 0 -68 28l-408 408q-28 28 -28 68q0 13 4.5 26t9 22t15.5 22t16.5 18.5t20.5 19t18 16.5q30 28 68 28q10 0 18 -1.5t16.5 -5.5t13.5 -6t13.5 -10t11.5 -10t13 -12.5t12 -12.5q-14 14 -14 34t14 34l348 348q14 14 34 14t34 -14 q-2 2 -12.5 12t-12.5 13t-10 11.5t-10 13.5t-6 13.5t-5.5 16.5t-1.5 18q0 38 28 68q3 3 16.5 18t19 20.5t18.5 16.5t22 15.5t22 9t26 4.5q40 0 68 -28l408 -408q28 -28 28 -68q0 -13 -4.5 -26t-9 -22t-15.5 -22t-16.5 -18.5t-20.5 -19t-18 -16.5q-30 -28 -68 -28 q-10 0 -18 1.5t-16.5 5.5t-13.5 6t-13.5 10t-11.5 10t-13 12.5t-12 12.5q14 -14 14 -34t-14 -34l-126 -126l256 -256q43 43 96 43q52 0 91 -37l363 -363q37 -39 37 -91z" /> +<glyph unicode="" horiz-adv-x="1792" d="M384 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM576 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1004 351l101 382q6 26 -7.5 48.5t-38.5 29.5 t-48 -6.5t-30 -39.5l-101 -382q-60 -5 -107 -43.5t-63 -98.5q-20 -77 20 -146t117 -89t146 20t89 117q16 60 -6 117t-72 91zM1664 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1024 1024q0 53 -37.5 90.5 t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1472 832q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1792 384q0 -261 -141 -483q-19 -29 -54 -29h-1402q-35 0 -54 29 q-141 221 -141 483q0 182 71 348t191 286t286 191t348 71t348 -71t286 -191t191 -286t71 -348z" /> +<glyph unicode="" horiz-adv-x="1792" d="M896 1152q-204 0 -381.5 -69.5t-282 -187.5t-104.5 -255q0 -112 71.5 -213.5t201.5 -175.5l87 -50l-27 -96q-24 -91 -70 -172q152 63 275 171l43 38l57 -6q69 -8 130 -8q204 0 381.5 69.5t282 187.5t104.5 255t-104.5 255t-282 187.5t-381.5 69.5zM1792 640 q0 -174 -120 -321.5t-326 -233t-450 -85.5q-70 0 -145 8q-198 -175 -460 -242q-49 -14 -114 -22h-5q-15 0 -27 10.5t-16 27.5v1q-3 4 -0.5 12t2 10t4.5 9.5l6 9t7 8.5t8 9q7 8 31 34.5t34.5 38t31 39.5t32.5 51t27 59t26 76q-157 89 -247.5 220t-90.5 281q0 174 120 321.5 t326 233t450 85.5t450 -85.5t326 -233t120 -321.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M704 1152q-153 0 -286 -52t-211.5 -141t-78.5 -191q0 -82 53 -158t149 -132l97 -56l-35 -84q34 20 62 39l44 31l53 -10q78 -14 153 -14q153 0 286 52t211.5 141t78.5 191t-78.5 191t-211.5 141t-286 52zM704 1280q191 0 353.5 -68.5t256.5 -186.5t94 -257t-94 -257 t-256.5 -186.5t-353.5 -68.5q-86 0 -176 16q-124 -88 -278 -128q-36 -9 -86 -16h-3q-11 0 -20.5 8t-11.5 21q-1 3 -1 6.5t0.5 6.5t2 6l2.5 5t3.5 5.5t4 5t4.5 5t4 4.5q5 6 23 25t26 29.5t22.5 29t25 38.5t20.5 44q-124 72 -195 177t-71 224q0 139 94 257t256.5 186.5 t353.5 68.5zM1526 111q10 -24 20.5 -44t25 -38.5t22.5 -29t26 -29.5t23 -25q1 -1 4 -4.5t4.5 -5t4 -5t3.5 -5.5l2.5 -5t2 -6t0.5 -6.5t-1 -6.5q-3 -14 -13 -22t-22 -7q-50 7 -86 16q-154 40 -278 128q-90 -16 -176 -16q-271 0 -472 132q58 -4 88 -4q161 0 309 45t264 129 q125 92 192 212t67 254q0 77 -23 152q129 -71 204 -178t75 -230q0 -120 -71 -224.5t-195 -176.5z" /> +<glyph unicode="" horiz-adv-x="896" d="M885 970q18 -20 7 -44l-540 -1157q-13 -25 -42 -25q-4 0 -14 2q-17 5 -25.5 19t-4.5 30l197 808l-406 -101q-4 -1 -12 -1q-18 0 -31 11q-18 15 -13 39l201 825q4 14 16 23t28 9h328q19 0 32 -12.5t13 -29.5q0 -8 -5 -18l-171 -463l396 98q8 2 12 2q19 0 34 -15z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 288v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192h-512v-192h96q40 0 68 -28t28 -68v-320 q0 -40 -28 -68t-68 -28h-320q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h96v192q0 52 38 90t90 38h512v192h-96q-40 0 -68 28t-28 68v320q0 40 28 68t68 28h320q40 0 68 -28t28 -68v-320q0 -40 -28 -68t-68 -28h-96v-192h512q52 0 90 -38t38 -90v-192h96q40 0 68 -28t28 -68 z" /> +<glyph unicode="" horiz-adv-x="1664" d="M896 708v-580q0 -104 -76 -180t-180 -76t-180 76t-76 180q0 26 19 45t45 19t45 -19t19 -45q0 -50 39 -89t89 -39t89 39t39 89v580q33 11 64 11t64 -11zM1664 681q0 -13 -9.5 -22.5t-22.5 -9.5q-11 0 -23 10q-49 46 -93 69t-102 23q-68 0 -128 -37t-103 -97 q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -28 -17q-18 0 -29 17q-4 6 -14.5 24t-17.5 28q-43 60 -102.5 97t-127.5 37t-127.5 -37t-102.5 -97q-7 -10 -17.5 -28t-14.5 -24q-11 -17 -29 -17q-17 0 -28 17q-4 6 -14.5 24t-17.5 28q-43 60 -103 97t-128 37q-58 0 -102 -23t-93 -69 q-12 -10 -23 -10q-13 0 -22.5 9.5t-9.5 22.5q0 5 1 7q45 183 172.5 319.5t298 204.5t360.5 68q140 0 274.5 -40t246.5 -113.5t194.5 -187t115.5 -251.5q1 -2 1 -7zM896 1408v-98q-42 2 -64 2t-64 -2v98q0 26 19 45t45 19t45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M768 -128h896v640h-416q-40 0 -68 28t-28 68v416h-384v-1152zM1024 1312v64q0 13 -9.5 22.5t-22.5 9.5h-704q-13 0 -22.5 -9.5t-9.5 -22.5v-64q0 -13 9.5 -22.5t22.5 -9.5h704q13 0 22.5 9.5t9.5 22.5zM1280 640h299l-299 299v-299zM1792 512v-672q0 -40 -28 -68t-68 -28 h-960q-40 0 -68 28t-28 68v160h-544q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h1088q40 0 68 -28t28 -68v-328q21 -13 36 -28l408 -408q28 -28 48 -76t20 -88z" /> +<glyph unicode="" horiz-adv-x="1024" d="M736 960q0 -13 -9.5 -22.5t-22.5 -9.5t-22.5 9.5t-9.5 22.5q0 46 -54 71t-106 25q-13 0 -22.5 9.5t-9.5 22.5t9.5 22.5t22.5 9.5q50 0 99.5 -16t87 -54t37.5 -90zM896 960q0 72 -34.5 134t-90 101.5t-123 62t-136.5 22.5t-136.5 -22.5t-123 -62t-90 -101.5t-34.5 -134 q0 -101 68 -180q10 -11 30.5 -33t30.5 -33q128 -153 141 -298h228q13 145 141 298q10 11 30.5 33t30.5 33q68 79 68 180zM1024 960q0 -155 -103 -268q-45 -49 -74.5 -87t-59.5 -95.5t-34 -107.5q47 -28 47 -82q0 -37 -25 -64q25 -27 25 -64q0 -52 -45 -81q13 -23 13 -47 q0 -46 -31.5 -71t-77.5 -25q-20 -44 -60 -70t-87 -26t-87 26t-60 70q-46 0 -77.5 25t-31.5 71q0 24 13 47q-45 29 -45 81q0 37 25 64q-25 27 -25 64q0 54 47 82q-4 50 -34 107.5t-59.5 95.5t-74.5 87q-103 113 -103 268q0 99 44.5 184.5t117 142t164 89t186.5 32.5 t186.5 -32.5t164 -89t117 -142t44.5 -184.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 352v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-1376v-192q0 -13 -9.5 -22.5t-22.5 -9.5q-12 0 -24 10l-319 320q-9 9 -9 22q0 14 9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h1376q13 0 22.5 -9.5t9.5 -22.5zM1792 896q0 -14 -9 -23l-320 -320q-9 -9 -23 -9 q-13 0 -22.5 9.5t-9.5 22.5v192h-1376q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h1376v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1280 608q0 14 -9 23t-23 9h-224v352q0 13 -9.5 22.5t-22.5 9.5h-192q-13 0 -22.5 -9.5t-9.5 -22.5v-352h-224q-13 0 -22.5 -9.5t-9.5 -22.5q0 -14 9 -23l352 -352q9 -9 23 -9t23 9l351 351q10 12 10 24zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1280 672q0 14 -9 23l-352 352q-9 9 -23 9t-23 -9l-351 -351q-10 -12 -10 -24q0 -14 9 -23t23 -9h224v-352q0 -13 9.5 -22.5t22.5 -9.5h192q13 0 22.5 9.5t9.5 22.5v352h224q13 0 22.5 9.5t9.5 22.5zM1920 384q0 -159 -112.5 -271.5t-271.5 -112.5h-1088 q-185 0 -316.5 131.5t-131.5 316.5q0 130 70 240t188 165q-2 30 -2 43q0 212 150 362t362 150q156 0 285.5 -87t188.5 -231q71 62 166 62q106 0 181 -75t75 -181q0 -76 -41 -138q130 -31 213.5 -135.5t83.5 -238.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M384 192q0 -26 -19 -45t-45 -19t-45 19t-19 45t19 45t45 19t45 -19t19 -45zM1408 131q0 -121 -73 -190t-194 -69h-874q-121 0 -194 69t-73 190q0 68 5.5 131t24 138t47.5 132.5t81 103t120 60.5q-22 -52 -22 -120v-203q-58 -20 -93 -70t-35 -111q0 -80 56 -136t136 -56 t136 56t56 136q0 61 -35.5 111t-92.5 70v203q0 62 25 93q132 -104 295 -104t295 104q25 -31 25 -93v-64q-106 0 -181 -75t-75 -181v-89q-32 -29 -32 -71q0 -40 28 -68t68 -28t68 28t28 68q0 42 -32 71v89q0 52 38 90t90 38t90 -38t38 -90v-89q-32 -29 -32 -71q0 -40 28 -68 t68 -28t68 28t28 68q0 42 -32 71v89q0 68 -34.5 127.5t-93.5 93.5q0 10 0.5 42.5t0 48t-2.5 41.5t-7 47t-13 40q68 -15 120 -60.5t81 -103t47.5 -132.5t24 -138t5.5 -131zM1088 1024q0 -159 -112.5 -271.5t-271.5 -112.5t-271.5 112.5t-112.5 271.5t112.5 271.5t271.5 112.5 t271.5 -112.5t112.5 -271.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1280 832q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 832q0 -62 -35.5 -111t-92.5 -70v-395q0 -159 -131.5 -271.5t-316.5 -112.5t-316.5 112.5t-131.5 271.5v132q-164 20 -274 128t-110 252v512q0 26 19 45t45 19q6 0 16 -2q17 30 47 48 t65 18q53 0 90.5 -37.5t37.5 -90.5t-37.5 -90.5t-90.5 -37.5q-33 0 -64 18v-402q0 -106 94 -181t226 -75t226 75t94 181v402q-31 -18 -64 -18q-53 0 -90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5q35 0 65 -18t47 -48q10 2 16 2q26 0 45 -19t19 -45v-512q0 -144 -110 -252 t-274 -128v-132q0 -106 94 -181t226 -75t226 75t94 181v395q-57 21 -92.5 70t-35.5 111q0 80 56 136t136 56t136 -56t56 -136z" /> +<glyph unicode="" horiz-adv-x="1792" d="M640 1152h512v128h-512v-128zM288 1152v-1280h-64q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h64zM1408 1152v-1280h-1024v1280h128v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h128zM1792 928v-832q0 -92 -66 -158t-158 -66h-64v1280h64q92 0 158 -66 t66 -158z" /> +<glyph unicode="" horiz-adv-x="1664" d="M848 -160q0 16 -16 16q-59 0 -101.5 42.5t-42.5 101.5q0 16 -16 16t-16 -16q0 -73 51.5 -124.5t124.5 -51.5q16 0 16 16zM1664 128q0 -52 -38 -90t-90 -38h-448q0 -106 -75 -181t-181 -75t-181 75t-75 181h-448q-52 0 -90 38t-38 90q190 161 287 397.5t97 498.5 q0 165 96 262t264 117q-8 18 -8 37q0 40 28 68t68 28t68 -28t28 -68q0 -19 -8 -37q168 -20 264 -117t96 -262q0 -262 97 -498.5t287 -397.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1664 896q0 80 -56 136t-136 56h-64v-384h64q80 0 136 56t56 136zM0 128h1792q0 -106 -75 -181t-181 -75h-1280q-106 0 -181 75t-75 181zM1856 896q0 -159 -112.5 -271.5t-271.5 -112.5h-64v-32q0 -92 -66 -158t-158 -66h-704q-92 0 -158 66t-66 158v736q0 26 19 45 t45 19h1152q159 0 271.5 -112.5t112.5 -271.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M640 1472v-640q0 -61 -35.5 -111t-92.5 -70v-779q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v779q-57 20 -92.5 70t-35.5 111v640q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45v-416q0 -26 19 -45 t45 -19t45 19t19 45v416q0 26 19 45t45 19t45 -19t19 -45zM1408 1472v-1600q0 -52 -38 -90t-90 -38h-128q-52 0 -90 38t-38 90v512h-224q-13 0 -22.5 9.5t-9.5 22.5v800q0 132 94 226t226 94h256q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1024 352v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM1024 608v-64q0 -14 -9 -23t-23 -9h-704q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h704q14 0 23 -9t9 -23zM128 0h1024v768h-416q-40 0 -68 28t-28 68v416h-512v-1280z M768 896h376q-10 29 -22 41l-313 313q-12 12 -41 22v-376zM1280 864v-896q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h640q40 0 88 -20t76 -48l312 -312q28 -28 48 -76t20 -88z" /> +<glyph unicode="" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 992v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 1248v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1536h-1152v-1536h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM1408 1472v-1664q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1664q0 26 19 45t45 19h1280q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1408" d="M384 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM384 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M1152 224v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM896 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M640 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 480v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5zM1152 736v-64q0 -13 -9.5 -22.5t-22.5 -9.5h-64q-13 0 -22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5 -9.5t9.5 -22.5z M896 -128h384v1152h-256v-32q0 -40 -28 -68t-68 -28h-448q-40 0 -68 28t-28 68v32h-256v-1152h384v224q0 13 9.5 22.5t22.5 9.5h320q13 0 22.5 -9.5t9.5 -22.5v-224zM896 1056v320q0 13 -9.5 22.5t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-96h-128v96q0 13 -9.5 22.5 t-22.5 9.5h-64q-13 0 -22.5 -9.5t-9.5 -22.5v-320q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5v96h128v-96q0 -13 9.5 -22.5t22.5 -9.5h64q13 0 22.5 9.5t9.5 22.5zM1408 1088v-1280q0 -26 -19 -45t-45 -19h-1280q-26 0 -45 19t-19 45v1280q0 26 19 45t45 19h320 v288q0 40 28 68t68 28h448q40 0 68 -28t28 -68v-288h320q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1920" d="M640 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM256 640h384v256h-158q-14 -2 -22 -9l-195 -195q-7 -12 -9 -22v-30zM1536 128q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5 t90.5 37.5t37.5 90.5zM1664 800v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM1920 1344v-1152 q0 -26 -19 -45t-45 -19h-192q0 -106 -75 -181t-181 -75t-181 75t-75 181h-384q0 -106 -75 -181t-181 -75t-181 75t-75 181h-128q-26 0 -45 19t-19 45t19 45t45 19v416q0 26 13 58t32 51l198 198q19 19 51 32t58 13h160v320q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1280 416v192q0 14 -9 23t-23 9h-224v224q0 14 -9 23t-23 9h-192q-14 0 -23 -9t-9 -23v-224h-224q-14 0 -23 -9t-9 -23v-192q0 -14 9 -23t23 -9h224v-224q0 -14 9 -23t23 -9h192q14 0 23 9t9 23v224h224q14 0 23 9t9 23zM640 1152h512v128h-512v-128zM256 1152v-1280h-32 q-92 0 -158 66t-66 158v832q0 92 66 158t158 66h32zM1440 1152v-1280h-1088v1280h160v160q0 40 28 68t68 28h576q40 0 68 -28t28 -68v-160h160zM1792 928v-832q0 -92 -66 -158t-158 -66h-32v1280h32q92 0 158 -66t66 -158z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1920 576q-1 -32 -288 -96l-352 -32l-224 -64h-64l-293 -352h69q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-96h-160h-64v32h64v416h-160l-192 -224h-96l-32 32v192h32v32h128v8l-192 24v128l192 24v8h-128v32h-32v192l32 32h96l192 -224h160v416h-64v32h64h160h96 q26 0 45 -4.5t19 -11.5t-19 -11.5t-45 -4.5h-69l293 -352h64l224 -64l352 -32q261 -58 287 -93z" /> +<glyph unicode="" horiz-adv-x="1664" d="M640 640v384h-256v-256q0 -53 37.5 -90.5t90.5 -37.5h128zM1664 192v-192h-1152v192l128 192h-128q-159 0 -271.5 112.5t-112.5 271.5v320l-64 64l32 128h480l32 128h960l32 -192l-64 -32v-800z" /> +<glyph unicode="" d="M1280 192v896q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-512v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-896q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h512v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M627 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23zM1011 160q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM979 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23 l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1075 224q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23zM1075 608q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393 q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1075 672q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23zM1075 1056q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23 t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="640" d="M627 992q0 -13 -10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="640" d="M595 576q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1075 352q0 -13 -10 -23l-50 -50q-10 -10 -23 -10t-23 10l-393 393l-393 -393q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l466 -466q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1075 800q0 -13 -10 -23l-466 -466q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l393 -393l393 393q10 10 23 10t23 -10l50 -50q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1792 544v832q0 13 -9.5 22.5t-22.5 9.5h-1600q-13 0 -22.5 -9.5t-9.5 -22.5v-832q0 -13 9.5 -22.5t22.5 -9.5h1600q13 0 22.5 9.5t9.5 22.5zM1920 1376v-1088q0 -66 -47 -113t-113 -47h-544q0 -37 16 -77.5t32 -71t16 -43.5q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19 t-19 45q0 14 16 44t32 70t16 78h-544q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h1600q66 0 113 -47t47 -113z" /> +<glyph unicode="" horiz-adv-x="1920" d="M416 256q-66 0 -113 47t-47 113v704q0 66 47 113t113 47h1088q66 0 113 -47t47 -113v-704q0 -66 -47 -113t-113 -47h-1088zM384 1120v-704q0 -13 9.5 -22.5t22.5 -9.5h1088q13 0 22.5 9.5t9.5 22.5v704q0 13 -9.5 22.5t-22.5 9.5h-1088q-13 0 -22.5 -9.5t-9.5 -22.5z M1760 192h160v-96q0 -40 -47 -68t-113 -28h-1600q-66 0 -113 28t-47 68v96h160h1600zM1040 96q16 0 16 16t-16 16h-160q-16 0 -16 -16t16 -16h160z" /> +<glyph unicode="" horiz-adv-x="1152" d="M640 128q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1024 288v960q0 13 -9.5 22.5t-22.5 9.5h-832q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h832q13 0 22.5 9.5t9.5 22.5zM1152 1248v-1088q0 -66 -47 -113t-113 -47h-832 q-66 0 -113 47t-47 113v1088q0 66 47 113t113 47h832q66 0 113 -47t47 -113z" /> +<glyph unicode="" horiz-adv-x="768" d="M464 128q0 33 -23.5 56.5t-56.5 23.5t-56.5 -23.5t-23.5 -56.5t23.5 -56.5t56.5 -23.5t56.5 23.5t23.5 56.5zM672 288v704q0 13 -9.5 22.5t-22.5 9.5h-512q-13 0 -22.5 -9.5t-9.5 -22.5v-704q0 -13 9.5 -22.5t22.5 -9.5h512q13 0 22.5 9.5t9.5 22.5zM480 1136 q0 16 -16 16h-160q-16 0 -16 -16t16 -16h160q16 0 16 16zM768 1152v-1024q0 -52 -38 -90t-90 -38h-512q-52 0 -90 38t-38 90v1024q0 52 38 90t90 38h512q52 0 90 -38t38 -90z" /> +<glyph unicode="" d="M768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103 t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M768 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z M1664 576v-384q0 -80 -56 -136t-136 -56h-384q-80 0 -136 56t-56 136v704q0 104 40.5 198.5t109.5 163.5t163.5 109.5t198.5 40.5h64q26 0 45 -19t19 -45v-128q0 -26 -19 -45t-45 -19h-64q-106 0 -181 -75t-75 -181v-32q0 -40 28 -68t68 -28h224q80 0 136 -56t56 -136z" /> +<glyph unicode="" horiz-adv-x="1664" d="M768 1216v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136zM1664 1216 v-704q0 -104 -40.5 -198.5t-109.5 -163.5t-163.5 -109.5t-198.5 -40.5h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64q106 0 181 75t75 181v32q0 40 -28 68t-68 28h-224q-80 0 -136 56t-56 136v384q0 80 56 136t136 56h384q80 0 136 -56t56 -136z" /> +<glyph unicode="" horiz-adv-x="1568" d="M496 192q0 -60 -42.5 -102t-101.5 -42q-60 0 -102 42t-42 102t42 102t102 42q59 0 101.5 -42t42.5 -102zM928 0q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM320 640q0 -66 -47 -113t-113 -47t-113 47t-47 113 t47 113t113 47t113 -47t47 -113zM1360 192q0 -46 -33 -79t-79 -33t-79 33t-33 79t33 79t79 33t79 -33t33 -79zM528 1088q0 -73 -51.5 -124.5t-124.5 -51.5t-124.5 51.5t-51.5 124.5t51.5 124.5t124.5 51.5t124.5 -51.5t51.5 -124.5zM992 1280q0 -80 -56 -136t-136 -56 t-136 56t-56 136t56 136t136 56t136 -56t56 -136zM1536 640q0 -40 -28 -68t-68 -28t-68 28t-28 68t28 68t68 28t68 -28t28 -68zM1328 1088q0 -33 -23.5 -56.5t-56.5 -23.5t-56.5 23.5t-23.5 56.5t23.5 56.5t56.5 23.5t56.5 -23.5t23.5 -56.5z" /> +<glyph unicode="" d="M1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 416q0 -166 -127 -451q-3 -7 -10.5 -24t-13.5 -30t-13 -22q-12 -17 -28 -17q-15 0 -23.5 10t-8.5 25q0 9 2.5 26.5t2.5 23.5q5 68 5 123q0 101 -17.5 181t-48.5 138.5t-80 101t-105.5 69.5t-133 42.5t-154 21.5t-175.5 6h-224v-256q0 -26 -19 -45t-45 -19t-45 19 l-512 512q-19 19 -19 45t19 45l512 512q19 19 45 19t45 -19t19 -45v-256h224q713 0 875 -403q53 -134 53 -333z" /> +<glyph unicode="" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M832 448v128q0 14 -9 23t-23 9h-192v192q0 14 -9 23t-23 9h-128q-14 0 -23 -9t-9 -23v-192h-192q-14 0 -23 -9t-9 -23v-128q0 -14 9 -23t23 -9h192v-192q0 -14 9 -23t23 -9h128q14 0 23 9t9 23v192h192q14 0 23 9t9 23zM1408 384q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5 t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1664 640q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM1920 512q0 -212 -150 -362t-362 -150q-192 0 -338 128h-220q-146 -128 -338 -128q-212 0 -362 150 t-150 362t150 362t362 150h896q212 0 362 -150t150 -362z" /> +<glyph unicode="" horiz-adv-x="1920" d="M384 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM512 624v-96q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h224q16 0 16 -16zM384 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 368v-96q0 -16 -16 -16 h-864q-16 0 -16 16v96q0 16 16 16h864q16 0 16 -16zM768 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM640 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1024 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16 h96q16 0 16 -16zM896 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1280 624v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 368v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1152 880v-96 q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1408 880v-96q0 -16 -16 -16h-96q-16 0 -16 16v96q0 16 16 16h96q16 0 16 -16zM1664 880v-352q0 -16 -16 -16h-224q-16 0 -16 16v96q0 16 16 16h112v240q0 16 16 16h96q16 0 16 -16zM1792 128v896h-1664v-896 h1664zM1920 1024v-896q0 -53 -37.5 -90.5t-90.5 -37.5h-1664q-53 0 -90.5 37.5t-37.5 90.5v896q0 53 37.5 90.5t90.5 37.5h1664q53 0 90.5 -37.5t37.5 -90.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1664 491v616q-169 -91 -306 -91q-82 0 -145 32q-100 49 -184 76.5t-178 27.5q-173 0 -403 -127v-599q245 113 433 113q55 0 103.5 -7.5t98 -26t77 -31t82.5 -39.5l28 -14q44 -22 101 -22q120 0 293 92zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9 h-64q-14 0 -23 9t-9 23v1266q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102 q-15 -9 -33 -9q-16 0 -32 8q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> +<glyph unicode="" horiz-adv-x="1792" d="M832 536v192q-181 -16 -384 -117v-185q205 96 384 110zM832 954v197q-172 -8 -384 -126v-189q215 111 384 118zM1664 491v184q-235 -116 -384 -71v224q-20 6 -39 15q-5 3 -33 17t-34.5 17t-31.5 15t-34.5 15.5t-32.5 13t-36 12.5t-35 8.5t-39.5 7.5t-39.5 4t-44 2 q-23 0 -49 -3v-222h19q102 0 192.5 -29t197.5 -82q19 -9 39 -15v-188q42 -17 91 -17q120 0 293 92zM1664 918v189q-169 -91 -306 -91q-45 0 -78 8v-196q148 -42 384 90zM320 1280q0 -35 -17.5 -64t-46.5 -46v-1266q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v1266 q-29 17 -46.5 46t-17.5 64q0 53 37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1792 1216v-763q0 -39 -35 -57q-10 -5 -17 -9q-218 -116 -369 -116q-88 0 -158 35l-28 14q-64 33 -99 48t-91 29t-114 14q-102 0 -235.5 -44t-228.5 -102q-15 -9 -33 -9q-16 0 -32 8 q-32 19 -32 56v742q0 35 31 55q35 21 78.5 42.5t114 52t152.5 49.5t155 19q112 0 209 -31t209 -86q38 -19 89 -19q122 0 310 112q22 12 31 17q31 16 62 -2q31 -20 31 -55z" /> +<glyph unicode="" horiz-adv-x="1664" d="M585 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23zM1664 96v-64q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h960q14 0 23 -9 t9 -23z" /> +<glyph unicode="" horiz-adv-x="1920" d="M617 137l-50 -50q-10 -10 -23 -10t-23 10l-466 466q-10 10 -10 23t10 23l466 466q10 10 23 10t23 -10l50 -50q10 -10 10 -23t-10 -23l-393 -393l393 -393q10 -10 10 -23t-10 -23zM1208 1204l-373 -1291q-4 -13 -15.5 -19.5t-23.5 -2.5l-62 17q-13 4 -19.5 15.5t-2.5 24.5 l373 1291q4 13 15.5 19.5t23.5 2.5l62 -17q13 -4 19.5 -15.5t2.5 -24.5zM1865 553l-466 -466q-10 -10 -23 -10t-23 10l-50 50q-10 10 -10 23t10 23l393 393l-393 393q-10 10 -10 23t10 23l50 50q10 10 23 10t23 -10l466 -466q10 -10 10 -23t-10 -23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M640 454v-70q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-69l-397 -398q-19 -19 -19 -45t19 -45zM1792 416q0 -58 -17 -133.5t-38.5 -138t-48 -125t-40.5 -90.5l-20 -40q-8 -17 -28 -17q-6 0 -9 1 q-25 8 -23 34q43 400 -106 565q-64 71 -170.5 110.5t-267.5 52.5v-251q0 -42 -39 -59q-13 -5 -25 -5q-27 0 -45 19l-512 512q-19 19 -19 45t19 45l512 512q29 31 70 14q39 -17 39 -59v-262q411 -28 599 -221q169 -173 169 -509z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1186 579l257 250l-356 52l-66 10l-30 60l-159 322v-963l59 -31l318 -168l-60 355l-12 66zM1638 841l-363 -354l86 -500q5 -33 -6 -51.5t-34 -18.5q-17 0 -40 12l-449 236l-449 -236q-23 -12 -40 -12q-23 0 -34 18.5t-6 51.5l86 500l-364 354q-32 32 -23 59.5t54 34.5 l502 73l225 455q20 41 49 41q28 0 49 -41l225 -455l502 -73q45 -7 54 -34.5t-24 -59.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1401 1187l-640 -1280q-17 -35 -57 -35q-5 0 -15 2q-22 5 -35.5 22.5t-13.5 39.5v576h-576q-22 0 -39.5 13.5t-22.5 35.5t4 42t29 30l1280 640q13 7 29 7q27 0 45 -19q15 -14 18.5 -34.5t-6.5 -39.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M557 256h595v595zM512 301l595 595h-595v-595zM1664 224v-192q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v224h-864q-14 0 -23 9t-9 23v864h-224q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h224v224q0 14 9 23t23 9h192q14 0 23 -9t9 -23 v-224h851l246 247q10 9 23 9t23 -9q9 -10 9 -23t-9 -23l-247 -246v-851h224q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M288 64q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM288 1216q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM928 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1024 1088q0 -52 -26 -96.5t-70 -69.5 q-2 -287 -226 -414q-68 -38 -203 -81q-128 -40 -169.5 -71t-41.5 -100v-26q44 -25 70 -69.5t26 -96.5q0 -80 -56 -136t-136 -56t-136 56t-56 136q0 52 26 96.5t70 69.5v820q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136q0 -52 -26 -96.5t-70 -69.5v-497 q54 26 154 57q55 17 87.5 29.5t70.5 31t59 39.5t40.5 51t28 69.5t8.5 91.5q-44 25 -70 69.5t-26 96.5q0 80 56 136t136 56t136 -56t56 -136z" /> +<glyph unicode="" horiz-adv-x="1664" d="M439 265l-256 -256q-10 -9 -23 -9q-12 0 -23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23zM608 224v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM384 448q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9t-9 23t9 23t23 9h320 q14 0 23 -9t9 -23zM1648 320q0 -120 -85 -203l-147 -146q-83 -83 -203 -83q-121 0 -204 85l-334 335q-21 21 -42 56l239 18l273 -274q27 -27 68 -27.5t68 26.5l147 146q28 28 28 67q0 40 -28 68l-274 275l18 239q35 -21 56 -42l336 -336q84 -86 84 -204zM1031 1044l-239 -18 l-273 274q-28 28 -68 28q-39 0 -68 -27l-147 -146q-28 -28 -28 -67q0 -40 28 -68l274 -274l-18 -240q-35 21 -56 42l-336 336q-84 86 -84 204q0 120 85 203l147 146q83 83 203 83q121 0 204 -85l334 -335q21 -21 42 -56zM1664 960q0 -14 -9 -23t-23 -9h-320q-14 0 -23 9 t-9 23t9 23t23 9h320q14 0 23 -9t9 -23zM1120 1504v-320q0 -14 -9 -23t-23 -9t-23 9t-9 23v320q0 14 9 23t23 9t23 -9t9 -23zM1527 1353l-256 -256q-11 -9 -23 -9t-23 9q-9 10 -9 23t9 23l256 256q10 9 23 9t23 -9q9 -10 9 -23t-9 -23z" /> +<glyph unicode="" horiz-adv-x="1024" d="M704 280v-240q0 -16 -12 -28t-28 -12h-240q-16 0 -28 12t-12 28v240q0 16 12 28t28 12h240q16 0 28 -12t12 -28zM1020 880q0 -54 -15.5 -101t-35 -76.5t-55 -59.5t-57.5 -43.5t-61 -35.5q-41 -23 -68.5 -65t-27.5 -67q0 -17 -12 -32.5t-28 -15.5h-240q-15 0 -25.5 18.5 t-10.5 37.5v45q0 83 65 156.5t143 108.5q59 27 84 56t25 76q0 42 -46.5 74t-107.5 32q-65 0 -108 -29q-35 -25 -107 -115q-13 -16 -31 -16q-12 0 -25 8l-164 125q-13 10 -15.5 25t5.5 28q160 266 464 266q80 0 161 -31t146 -83t106 -127.5t41 -158.5z" /> +<glyph unicode="" horiz-adv-x="640" d="M640 192v-128q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h64v384h-64q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h384q26 0 45 -19t19 -45v-576h64q26 0 45 -19t19 -45zM512 1344v-192q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v192 q0 26 19 45t45 19h256q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="640" d="M512 288v-224q0 -26 -19 -45t-45 -19h-256q-26 0 -45 19t-19 45v224q0 26 19 45t45 19h256q26 0 45 -19t19 -45zM542 1344l-28 -768q-1 -26 -20.5 -45t-45.5 -19h-256q-26 0 -45.5 19t-20.5 45l-28 768q-1 26 17.5 45t44.5 19h320q26 0 44.5 -19t17.5 -45z" /> +<glyph unicode="" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1534 846v-206h-514l-3 27 q-4 28 -4 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q83 65 188 65q110 0 178 -59.5t68 -158.5q0 -56 -24.5 -103t-62 -76.5t-81.5 -58.5t-82 -50.5t-65.5 -51.5t-30.5 -63h232v80 h126z" /> +<glyph unicode="" d="M897 167v-167h-248l-159 252l-24 42q-8 9 -11 21h-3l-9 -21q-10 -20 -25 -44l-155 -250h-258v167h128l197 291l-185 272h-137v168h276l139 -228q2 -4 23 -42q8 -9 11 -21h3q3 9 11 21l25 42l140 228h257v-168h-125l-184 -267l204 -296h109zM1536 -50v-206h-514l-4 27 q-3 45 -3 46q0 64 26 117t65 86.5t84 65t84 54.5t65 54t26 64q0 38 -29.5 62.5t-70.5 24.5q-51 0 -97 -39q-14 -11 -36 -38l-105 92q26 37 63 66q80 65 188 65q110 0 178 -59.5t68 -158.5q0 -66 -34.5 -118.5t-84 -86t-99.5 -62.5t-87 -63t-41 -73h232v80h126z" /> +<glyph unicode="" horiz-adv-x="1920" d="M896 128l336 384h-768l-336 -384h768zM1909 1205q15 -34 9.5 -71.5t-30.5 -65.5l-896 -1024q-38 -44 -96 -44h-768q-38 0 -69.5 20.5t-47.5 54.5q-15 34 -9.5 71.5t30.5 65.5l896 1024q38 44 96 44h768q38 0 69.5 -20.5t47.5 -54.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1664 438q0 -81 -44.5 -135t-123.5 -54q-41 0 -77.5 17.5t-59 38t-56.5 38t-71 17.5q-110 0 -110 -124q0 -39 16 -115t15 -115v-5q-22 0 -33 -1q-34 -3 -97.5 -11.5t-115.5 -13.5t-98 -5q-61 0 -103 26.5t-42 83.5q0 37 17.5 71t38 56.5t38 59t17.5 77.5q0 79 -54 123.5 t-135 44.5q-84 0 -143 -45.5t-59 -127.5q0 -43 15 -83t33.5 -64.5t33.5 -53t15 -50.5q0 -45 -46 -89q-37 -35 -117 -35q-95 0 -245 24q-9 2 -27.5 4t-27.5 4l-13 2q-1 0 -3 1q-2 0 -2 1v1024q2 -1 17.5 -3.5t34 -5t21.5 -3.5q150 -24 245 -24q80 0 117 35q46 44 46 89 q0 22 -15 50.5t-33.5 53t-33.5 64.5t-15 83q0 82 59 127.5t144 45.5q80 0 134 -44.5t54 -123.5q0 -41 -17.5 -77.5t-38 -59t-38 -56.5t-17.5 -71q0 -57 42 -83.5t103 -26.5q64 0 180 15t163 17v-2q-1 -2 -3.5 -17.5t-5 -34t-3.5 -21.5q-24 -150 -24 -245q0 -80 35 -117 q44 -46 89 -46q22 0 50.5 15t53 33.5t64.5 33.5t83 15q82 0 127.5 -59t45.5 -143z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1152 832v-128q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-217 24 -364.5 187.5t-147.5 384.5v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -185 131.5 -316.5t316.5 -131.5 t316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45zM896 1216v-512q0 -132 -94 -226t-226 -94t-226 94t-94 226v512q0 132 94 226t226 94t226 -94t94 -226z" /> +<glyph unicode="" horiz-adv-x="1408" d="M271 591l-101 -101q-42 103 -42 214v128q0 26 19 45t45 19t45 -19t19 -45v-128q0 -53 15 -113zM1385 1193l-361 -361v-128q0 -132 -94 -226t-226 -94q-55 0 -109 19l-96 -96q97 -51 205 -51q185 0 316.5 131.5t131.5 316.5v128q0 26 19 45t45 19t45 -19t19 -45v-128 q0 -221 -147.5 -384.5t-364.5 -187.5v-132h256q26 0 45 -19t19 -45t-19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h256v132q-125 13 -235 81l-254 -254q-10 -10 -23 -10t-23 10l-82 82q-10 10 -10 23t10 23l1234 1234q10 10 23 10t23 -10l82 -82q10 -10 10 -23 t-10 -23zM1005 1325l-621 -621v512q0 132 94 226t226 94q102 0 184.5 -59t116.5 -152z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1088 576v640h-448v-1137q119 63 213 137q235 184 235 360zM1280 1344v-768q0 -86 -33.5 -170.5t-83 -150t-118 -127.5t-126.5 -103t-121 -77.5t-89.5 -49.5t-42.5 -20q-12 -6 -26 -6t-26 6q-16 7 -42.5 20t-89.5 49.5t-121 77.5t-126.5 103t-118 127.5t-83 150 t-33.5 170.5v768q0 26 19 45t45 19h1152q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" /> +<glyph unicode="" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" /> +<glyph unicode="" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M813 237l454 454q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-307 -307l-307 307q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1130 939l16 175h-884l47 -534h612l-22 -228l-197 -53l-196 53l-13 140h-175l22 -278l362 -100h4v1l359 99l50 544h-644l-15 181h674zM0 1408h1408l-128 -1438l-578 -162l-574 162z" /> +<glyph unicode="" horiz-adv-x="1792" d="M275 1408h1505l-266 -1333l-804 -267l-698 267l71 356h297l-29 -147l422 -161l486 161l68 339h-1208l58 297h1209l38 191h-1208z" /> +<glyph unicode="" horiz-adv-x="1792" d="M960 1280q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1792 352v-352q0 -22 -20 -30q-8 -2 -12 -2q-13 0 -23 9l-93 93q-119 -143 -318.5 -226.5t-429.5 -83.5t-429.5 83.5t-318.5 226.5l-93 -93q-9 -9 -23 -9q-4 0 -12 2q-20 8 -20 30v352 q0 14 9 23t23 9h352q22 0 30 -20q8 -19 -7 -35l-100 -100q67 -91 189.5 -153.5t271.5 -82.5v647h-192q-26 0 -45 19t-19 45v128q0 26 19 45t45 19h192v163q-58 34 -93 92.5t-35 128.5q0 106 75 181t181 75t181 -75t75 -181q0 -70 -35 -128.5t-93 -92.5v-163h192q26 0 45 -19 t19 -45v-128q0 -26 -19 -45t-45 -19h-192v-647q149 20 271.5 82.5t189.5 153.5l-100 100q-15 16 -7 35q8 20 30 20h352q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1056 768q40 0 68 -28t28 -68v-576q0 -40 -28 -68t-68 -28h-960q-40 0 -68 28t-28 68v576q0 40 28 68t68 28h32v320q0 185 131.5 316.5t316.5 131.5t316.5 -131.5t131.5 -316.5q0 -26 -19 -45t-45 -19h-64q-26 0 -45 19t-19 45q0 106 -75 181t-181 75t-181 -75t-75 -181 v-320h736z" /> +<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM1152 640q0 159 -112.5 271.5t-271.5 112.5t-271.5 -112.5t-112.5 -271.5t112.5 -271.5t271.5 -112.5t271.5 112.5t112.5 271.5zM1280 640q0 -212 -150 -362t-362 -150t-362 150 t-150 362t150 362t362 150t362 -150t150 -362zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM896 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM1408 800v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> +<glyph unicode="" horiz-adv-x="384" d="M384 288v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 800v-192q0 -40 -28 -68t-68 -28h-192q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68zM384 1312v-192q0 -40 -28 -68t-68 -28h-192 q-40 0 -68 28t-28 68v192q0 40 28 68t68 28h192q40 0 68 -28t28 -68z" /> +<glyph unicode="" d="M512 256q0 53 -37.5 90.5t-90.5 37.5t-90.5 -37.5t-37.5 -90.5t37.5 -90.5t90.5 -37.5t90.5 37.5t37.5 90.5zM863 162q-13 232 -177 396t-396 177q-14 1 -24 -9t-10 -23v-128q0 -13 8.5 -22t21.5 -10q154 -11 264 -121t121 -264q1 -13 10 -21.5t22 -8.5h128q13 0 23 10 t9 24zM1247 161q-5 154 -56 297.5t-139.5 260t-205 205t-260 139.5t-297.5 56q-14 1 -23 -9q-10 -10 -10 -23v-128q0 -13 9 -22t22 -10q204 -7 378 -111.5t278.5 -278.5t111.5 -378q1 -13 10 -22t22 -9h128q13 0 23 10q11 9 9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M768 1408q209 0 385.5 -103t279.5 -279.5t103 -385.5t-103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103zM1152 585q32 18 32 55t-32 55l-544 320q-31 19 -64 1q-32 -19 -32 -56v-640q0 -37 32 -56 q16 -8 32 -8q17 0 32 9z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1024 1084l316 -316l-572 -572l-316 316zM813 105l618 618q19 19 19 45t-19 45l-362 362q-18 18 -45 18t-45 -18l-618 -618q-19 -19 -19 -45t19 -45l362 -362q18 -18 45 -18t45 18zM1702 742l-907 -908q-37 -37 -90.5 -37t-90.5 37l-126 126q56 56 56 136t-56 136 t-136 56t-136 -56l-125 126q-37 37 -37 90.5t37 90.5l907 906q37 37 90.5 37t90.5 -37l125 -125q-56 -56 -56 -136t56 -136t136 -56t136 56l126 -125q37 -37 37 -90.5t-37 -90.5z" /> +<glyph unicode="" d="M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h832q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5 t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1018 933q-18 -37 -58 -37h-192v-864q0 -14 -9 -23t-23 -9h-704q-21 0 -29 18q-8 20 4 35l160 192q9 11 25 11h320v640h-192q-40 0 -58 37q-17 37 9 68l320 384q18 22 49 22t49 -22l320 -384q27 -32 9 -68z" /> +<glyph unicode="" horiz-adv-x="1024" d="M32 1280h704q13 0 22.5 -9.5t9.5 -23.5v-863h192q40 0 58 -37t-9 -69l-320 -384q-18 -22 -49 -22t-49 22l-320 384q-26 31 -9 69q18 37 58 37h192v640h-320q-14 0 -25 11l-160 192q-13 14 -4 34q9 19 29 19z" /> +<glyph unicode="" d="M685 237l614 614q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-467 -467l-211 211q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l358 -358q19 -19 45 -19t45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5 t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M404 428l152 -152l-52 -52h-56v96h-96v56zM818 818q14 -13 -3 -30l-291 -291q-17 -17 -30 -3q-14 13 3 30l291 291q17 17 30 3zM544 128l544 544l-288 288l-544 -544v-288h288zM1152 736l92 92q28 28 28 68t-28 68l-152 152q-28 28 -68 28t-68 -28l-92 -92zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1280 608v480q0 26 -19 45t-45 19h-480q-42 0 -59 -39q-17 -41 14 -70l144 -144l-534 -534q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l534 534l144 -144q18 -19 45 -19q12 0 25 5q39 17 39 59zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1005 435l352 352q19 19 19 45t-19 45l-352 352q-30 31 -69 14q-40 -17 -40 -59v-160q-119 0 -216 -19.5t-162.5 -51t-114 -79t-76.5 -95.5t-44.5 -109t-21.5 -111.5t-5 -110.5q0 -181 167 -404q10 -12 25 -12q7 0 13 3q22 9 19 33q-44 354 62 473q46 52 130 75.5 t224 23.5v-160q0 -42 40 -59q12 -5 24 -5q26 0 45 19zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M640 448l256 128l-256 128v-256zM1024 1039v-542l-512 -256v542zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1145 861q18 -35 -5 -66l-320 -448q-19 -27 -52 -27t-52 27l-320 448q-23 31 -5 66q17 35 57 35h640q40 0 57 -35zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1145 419q-17 -35 -57 -35h-640q-40 0 -57 35q-18 35 5 66l320 448q19 27 52 27t52 -27l320 -448q23 -31 5 -66zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1088 640q0 -33 -27 -52l-448 -320q-31 -23 -66 -5q-35 17 -35 57v640q0 40 35 57q35 18 66 -5l448 -320q27 -19 27 -52zM1280 160v960q0 14 -9 23t-23 9h-960q-14 0 -23 -9t-9 -23v-960q0 -14 9 -23t23 -9h960q14 0 23 9t9 23zM1536 1120v-960q0 -119 -84.5 -203.5 t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M976 229l35 -159q3 -12 -3 -22.5t-17 -14.5l-5 -1q-4 -2 -10.5 -3.5t-16 -4.5t-21.5 -5.5t-25.5 -5t-30 -5t-33.5 -4.5t-36.5 -3t-38.5 -1q-234 0 -409 130.5t-238 351.5h-95q-13 0 -22.5 9.5t-9.5 22.5v113q0 13 9.5 22.5t22.5 9.5h66q-2 57 1 105h-67q-14 0 -23 9 t-9 23v114q0 14 9 23t23 9h98q67 210 243.5 338t400.5 128q102 0 194 -23q11 -3 20 -15q6 -11 3 -24l-43 -159q-3 -13 -14 -19.5t-24 -2.5l-4 1q-4 1 -11.5 2.5l-17.5 3.5t-22.5 3.5t-26 3t-29 2.5t-29.5 1q-126 0 -226 -64t-150 -176h468q16 0 25 -12q10 -12 7 -26 l-24 -114q-5 -26 -32 -26h-488q-3 -37 0 -105h459q15 0 25 -12q9 -12 6 -27l-24 -112q-2 -11 -11 -18.5t-20 -7.5h-387q48 -117 149.5 -185.5t228.5 -68.5q18 0 36 1.5t33.5 3.5t29.5 4.5t24.5 5t18.5 4.5l12 3l5 2q13 5 26 -2q12 -7 15 -21z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1020 399v-367q0 -14 -9 -23t-23 -9h-956q-14 0 -23 9t-9 23v150q0 13 9.5 22.5t22.5 9.5h97v383h-95q-14 0 -23 9.5t-9 22.5v131q0 14 9 23t23 9h95v223q0 171 123.5 282t314.5 111q185 0 335 -125q9 -8 10 -20.5t-7 -22.5l-103 -127q-9 -11 -22 -12q-13 -2 -23 7 q-5 5 -26 19t-69 32t-93 18q-85 0 -137 -47t-52 -123v-215h305q13 0 22.5 -9t9.5 -23v-131q0 -13 -9.5 -22.5t-22.5 -9.5h-305v-379h414v181q0 13 9 22.5t23 9.5h162q14 0 23 -9.5t9 -22.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" /> +<glyph unicode="" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" /> +<glyph unicode="" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1024 160v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1024 416v64q0 14 -9 23t-23 9h-704q-14 0 -23 -9t-9 -23v-64q0 -14 9 -23t23 -9h704q14 0 23 9t9 23zM1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28 t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1191 1128h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1572 -23 v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -11v-2l14 2q9 2 30 2h248v119h121zM1661 874v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162 l230 -662h70z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1191 104h177l-72 218l-12 47q-2 16 -2 20h-4l-3 -20q0 -1 -3.5 -18t-7.5 -29zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1661 -150 v-106h-288v106h75l-47 144h-243l-47 -144h75v-106h-287v106h70l230 662h162l230 -662h70zM1572 1001v-233h-584v90l369 529q12 18 21 27l11 9v3q-2 0 -6.5 -0.5t-7.5 -0.5q-12 -3 -30 -3h-232v-115h-120v229h567v-89l-369 -530q-6 -8 -21 -26l-11 -10v-3l14 3q9 1 30 1h248 v119h121z" /> +<glyph unicode="" horiz-adv-x="1792" d="M736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23zM1792 -32v-192q0 -14 -9 -23t-23 -9h-832q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832 q14 0 23 -9t9 -23zM1600 480v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1408 992v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1216 1504v-192q0 -14 -9 -23t-23 -9h-256 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1216 -32v-192q0 -14 -9 -23t-23 -9h-256q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h256q14 0 23 -9t9 -23zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192 q14 0 23 -9t9 -23zM1408 480v-192q0 -14 -9 -23t-23 -9h-448q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h448q14 0 23 -9t9 -23zM1600 992v-192q0 -14 -9 -23t-23 -9h-640q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h640q14 0 23 -9t9 -23zM1792 1504v-192q0 -14 -9 -23t-23 -9h-832 q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h832q14 0 23 -9t9 -23z" /> +<glyph unicode="" d="M1346 223q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9t9 -23 zM1486 165q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5 t82 -252.5zM1456 882v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165z" /> +<glyph unicode="" d="M1346 1247q0 63 -44 116t-103 53q-52 0 -83 -37t-31 -94t36.5 -95t104.5 -38q50 0 85 27t35 68zM736 96q0 -12 -10 -24l-319 -319q-10 -9 -23 -9q-12 0 -23 9l-320 320q-15 16 -7 35q8 20 30 20h192v1376q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1376h192q14 0 23 -9 t9 -23zM1456 -142v-114h-469v114h167v432q0 7 0.5 19t0.5 17v16h-2l-7 -12q-8 -13 -26 -31l-62 -58l-82 86l192 185h123v-654h165zM1486 1189q0 -62 -13 -121.5t-41 -114t-68 -95.5t-98.5 -65.5t-127.5 -24.5q-62 0 -108 16q-24 8 -42 15l39 113q15 -7 31 -11q37 -13 75 -13 q84 0 134.5 58.5t66.5 145.5h-2q-21 -23 -61.5 -37t-84.5 -14q-106 0 -173 71.5t-67 172.5q0 105 72 178t181 73q123 0 205 -94.5t82 -252.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M256 192q0 26 -19 45t-45 19q-27 0 -45.5 -19t-18.5 -45q0 -27 18.5 -45.5t45.5 -18.5q26 0 45 18.5t19 45.5zM416 704v-640q0 -26 -19 -45t-45 -19h-288q-26 0 -45 19t-19 45v640q0 26 19 45t45 19h288q26 0 45 -19t19 -45zM1600 704q0 -86 -55 -149q15 -44 15 -76 q3 -76 -43 -137q17 -56 0 -117q-15 -57 -54 -94q9 -112 -49 -181q-64 -76 -197 -78h-36h-76h-17q-66 0 -144 15.5t-121.5 29t-120.5 39.5q-123 43 -158 44q-26 1 -45 19.5t-19 44.5v641q0 25 18 43.5t43 20.5q24 2 76 59t101 121q68 87 101 120q18 18 31 48t17.5 48.5 t13.5 60.5q7 39 12.5 61t19.5 52t34 50q19 19 45 19q46 0 82.5 -10.5t60 -26t40 -40.5t24 -45t12 -50t5 -45t0.5 -39q0 -38 -9.5 -76t-19 -60t-27.5 -56q-3 -6 -10 -18t-11 -22t-8 -24h277q78 0 135 -57t57 -135z" /> +<glyph unicode="" horiz-adv-x="1664" d="M256 960q0 -26 -19 -45t-45 -19q-27 0 -45.5 19t-18.5 45q0 27 18.5 45.5t45.5 18.5q26 0 45 -18.5t19 -45.5zM416 448v640q0 26 -19 45t-45 19h-288q-26 0 -45 -19t-19 -45v-640q0 -26 19 -45t45 -19h288q26 0 45 19t19 45zM1545 597q55 -61 55 -149q-1 -78 -57.5 -135 t-134.5 -57h-277q4 -14 8 -24t11 -22t10 -18q18 -37 27 -57t19 -58.5t10 -76.5q0 -24 -0.5 -39t-5 -45t-12 -50t-24 -45t-40 -40.5t-60 -26t-82.5 -10.5q-26 0 -45 19q-20 20 -34 50t-19.5 52t-12.5 61q-9 42 -13.5 60.5t-17.5 48.5t-31 48q-33 33 -101 120q-49 64 -101 121 t-76 59q-25 2 -43 20.5t-18 43.5v641q0 26 19 44.5t45 19.5q35 1 158 44q77 26 120.5 39.5t121.5 29t144 15.5h17h76h36q133 -2 197 -78q58 -69 49 -181q39 -37 54 -94q17 -61 0 -117q46 -61 43 -137q0 -32 -15 -76z" /> +<glyph unicode="" d="M919 233v157q0 50 -29 50q-17 0 -33 -16v-224q16 -16 33 -16q29 0 29 49zM1103 355h66v34q0 51 -33 51t-33 -51v-34zM532 621v-70h-80v-423h-74v423h-78v70h232zM733 495v-367h-67v40q-39 -45 -76 -45q-33 0 -42 28q-6 16 -6 54v290h66v-270q0 -24 1 -26q1 -15 15 -15 q20 0 42 31v280h67zM985 384v-146q0 -52 -7 -73q-12 -42 -53 -42q-35 0 -68 41v-36h-67v493h67v-161q32 40 68 40q41 0 53 -42q7 -21 7 -74zM1236 255v-9q0 -29 -2 -43q-3 -22 -15 -40q-27 -40 -80 -40q-52 0 -81 38q-21 27 -21 86v129q0 59 20 86q29 38 80 38t78 -38 q21 -28 21 -86v-76h-133v-65q0 -51 34 -51q24 0 30 26q0 1 0.5 7t0.5 16.5v21.5h68zM785 1079v-156q0 -51 -32 -51t-32 51v156q0 52 32 52t32 -52zM1318 366q0 177 -19 260q-10 44 -43 73.5t-76 34.5q-136 15 -412 15q-275 0 -411 -15q-44 -5 -76.5 -34.5t-42.5 -73.5 q-20 -87 -20 -260q0 -176 20 -260q10 -43 42.5 -73t75.5 -35q137 -15 412 -15t412 15q43 5 75.5 35t42.5 73q20 84 20 260zM563 1017l90 296h-75l-51 -195l-53 195h-78l24 -69t23 -69q35 -103 46 -158v-201h74v201zM852 936v130q0 58 -21 87q-29 38 -78 38q-51 0 -78 -38 q-21 -29 -21 -87v-130q0 -58 21 -87q27 -38 78 -38q49 0 78 38q21 27 21 87zM1033 816h67v370h-67v-283q-22 -31 -42 -31q-15 0 -16 16q-1 2 -1 26v272h-67v-293q0 -37 6 -55q11 -27 43 -27q36 0 77 45v-40zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960 q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M971 292v-211q0 -67 -39 -67q-23 0 -45 22v301q22 22 45 22q39 0 39 -67zM1309 291v-46h-90v46q0 68 45 68t45 -68zM343 509h107v94h-312v-94h105v-569h100v569zM631 -60h89v494h-89v-378q-30 -42 -57 -42q-18 0 -21 21q-1 3 -1 35v364h-89v-391q0 -49 8 -73 q12 -37 58 -37q48 0 102 61v-54zM1060 88v197q0 73 -9 99q-17 56 -71 56q-50 0 -93 -54v217h-89v-663h89v48q45 -55 93 -55q54 0 71 55q9 27 9 100zM1398 98v13h-91q0 -51 -2 -61q-7 -36 -40 -36q-46 0 -46 69v87h179v103q0 79 -27 116q-39 51 -106 51q-68 0 -107 -51 q-28 -37 -28 -116v-173q0 -79 29 -116q39 -51 108 -51q72 0 108 53q18 27 21 54q2 9 2 58zM790 1011v210q0 69 -43 69t-43 -69v-210q0 -70 43 -70t43 70zM1509 260q0 -234 -26 -350q-14 -59 -58 -99t-102 -46q-184 -21 -555 -21t-555 21q-58 6 -102.5 46t-57.5 99 q-26 112 -26 350q0 234 26 350q14 59 58 99t103 47q183 20 554 20t555 -20q58 -7 102.5 -47t57.5 -99q26 -112 26 -350zM511 1536h102l-121 -399v-271h-100v271q-14 74 -61 212q-37 103 -65 187h106l71 -263zM881 1203v-175q0 -81 -28 -118q-37 -51 -106 -51q-67 0 -105 51 q-28 38 -28 118v175q0 80 28 117q38 51 105 51q69 0 106 -51q28 -37 28 -117zM1216 1365v-499h-91v55q-53 -62 -103 -62q-46 0 -59 37q-8 24 -8 75v394h91v-367q0 -33 1 -35q3 -22 21 -22q27 0 57 43v381h91z" /> +<glyph unicode="" horiz-adv-x="1408" d="M597 869q-10 -18 -257 -456q-27 -46 -65 -46h-239q-21 0 -31 17t0 36l253 448q1 0 0 1l-161 279q-12 22 -1 37q9 15 32 15h239q40 0 66 -45zM1403 1511q11 -16 0 -37l-528 -934v-1l336 -615q11 -20 1 -37q-10 -15 -32 -15h-239q-42 0 -66 45l-339 622q18 32 531 942 q25 45 64 45h241q22 0 31 -15z" /> +<glyph unicode="" d="M685 771q0 1 -126 222q-21 34 -52 34h-184q-18 0 -26 -11q-7 -12 1 -29l125 -216v-1l-196 -346q-9 -14 0 -28q8 -13 24 -13h185q31 0 50 36zM1309 1268q-7 12 -24 12h-187q-30 0 -49 -35l-411 -729q1 -2 262 -481q20 -35 52 -35h184q18 0 25 12q8 13 -1 28l-260 476v1 l409 723q8 16 0 28zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1280 640q0 37 -30 54l-512 320q-31 20 -65 2q-33 -18 -33 -56v-640q0 -38 33 -56q16 -8 31 -8q20 0 34 10l512 320q30 17 30 54zM1792 640q0 -96 -1 -150t-8.5 -136.5t-22.5 -147.5q-16 -73 -69 -123t-124 -58q-222 -25 -671 -25t-671 25q-71 8 -124.5 58t-69.5 123 q-14 65 -21.5 147.5t-8.5 136.5t-1 150t1 150t8.5 136.5t22.5 147.5q16 73 69 123t124 58q222 25 671 25t671 -25q71 -8 124.5 -58t69.5 -123q14 -65 21.5 -147.5t8.5 -136.5t1 -150z" /> +<glyph unicode="" horiz-adv-x="1792" d="M402 829l494 -305l-342 -285l-490 319zM1388 274v-108l-490 -293v-1l-1 1l-1 -1v1l-489 293v108l147 -96l342 284v2l1 -1l1 1v-2l343 -284zM554 1418l342 -285l-494 -304l-338 270zM1390 829l338 -271l-489 -319l-343 285zM1239 1418l489 -319l-338 -270l-494 304z" /> +<glyph unicode="" horiz-adv-x="1408" d="M928 135v-151l-707 -1v151zM1169 481v-701l-1 -35v-1h-1132l-35 1h-1v736h121v-618h928v618h120zM241 393l704 -65l-13 -150l-705 65zM309 709l683 -183l-39 -146l-683 183zM472 1058l609 -360l-77 -130l-609 360zM832 1389l398 -585l-124 -85l-399 584zM1285 1536 l121 -697l-149 -26l-121 697z" /> +<glyph unicode="" d="M1362 110v648h-135q20 -63 20 -131q0 -126 -64 -232.5t-174 -168.5t-240 -62q-197 0 -337 135.5t-140 327.5q0 68 20 131h-141v-648q0 -26 17.5 -43.5t43.5 -17.5h1069q25 0 43 17.5t18 43.5zM1078 643q0 124 -90.5 211.5t-218.5 87.5q-127 0 -217.5 -87.5t-90.5 -211.5 t90.5 -211.5t217.5 -87.5q128 0 218.5 87.5t90.5 211.5zM1362 1003v165q0 28 -20 48.5t-49 20.5h-174q-29 0 -49 -20.5t-20 -48.5v-165q0 -29 20 -49t49 -20h174q29 0 49 20t20 49zM1536 1211v-1142q0 -81 -58 -139t-139 -58h-1142q-81 0 -139 58t-58 139v1142q0 81 58 139 t139 58h1142q81 0 139 -58t58 -139z" /> +<glyph unicode="" d="M1248 1408q119 0 203.5 -84.5t84.5 -203.5v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960zM698 640q0 88 -62 150t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150zM1262 640q0 88 -62 150 t-150 62t-150 -62t-62 -150t62 -150t150 -62t150 62t62 150z" /> +<glyph unicode="" d="M768 914l201 -306h-402zM1133 384h94l-459 691l-459 -691h94l104 160h522zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M815 677q8 -63 -50.5 -101t-111.5 -6q-39 17 -53.5 58t-0.5 82t52 58q36 18 72.5 12t64 -35.5t27.5 -67.5zM926 698q-14 107 -113 164t-197 13q-63 -28 -100.5 -88.5t-34.5 -129.5q4 -91 77.5 -155t165.5 -56q91 8 152 84t50 168zM1165 1240q-20 27 -56 44.5t-58 22 t-71 12.5q-291 47 -566 -2q-43 -7 -66 -12t-55 -22t-50 -43q30 -28 76 -45.5t73.5 -22t87.5 -11.5q228 -29 448 -1q63 8 89.5 12t72.5 21.5t75 46.5zM1222 205q-8 -26 -15.5 -76.5t-14 -84t-28.5 -70t-58 -56.5q-86 -48 -189.5 -71.5t-202 -22t-201.5 18.5q-46 8 -81.5 18 t-76.5 27t-73 43.5t-52 61.5q-25 96 -57 292l6 16l18 9q223 -148 506.5 -148t507.5 148q21 -6 24 -23t-5 -45t-8 -37zM1403 1166q-26 -167 -111 -655q-5 -30 -27 -56t-43.5 -40t-54.5 -31q-252 -126 -610 -88q-248 27 -394 139q-15 12 -25.5 26.5t-17 35t-9 34t-6 39.5 t-5.5 35q-9 50 -26.5 150t-28 161.5t-23.5 147.5t-22 158q3 26 17.5 48.5t31.5 37.5t45 30t46 22.5t48 18.5q125 46 313 64q379 37 676 -50q155 -46 215 -122q16 -20 16.5 -51t-5.5 -54z" /> +<glyph unicode="" d="M848 666q0 43 -41 66t-77 1q-43 -20 -42.5 -72.5t43.5 -70.5q39 -23 81 4t36 72zM928 682q8 -66 -36 -121t-110 -61t-119 40t-56 113q-2 49 25.5 93t72.5 64q70 31 141.5 -10t81.5 -118zM1100 1073q-20 -21 -53.5 -34t-53 -16t-63.5 -8q-155 -20 -324 0q-44 6 -63 9.5 t-52.5 16t-54.5 32.5q13 19 36 31t40 15.5t47 8.5q198 35 408 1q33 -5 51 -8.5t43 -16t39 -31.5zM1142 327q0 7 5.5 26.5t3 32t-17.5 16.5q-161 -106 -365 -106t-366 106l-12 -6l-5 -12q26 -154 41 -210q47 -81 204 -108q249 -46 428 53q34 19 49 51.5t22.5 85.5t12.5 71z M1272 1020q9 53 -8 75q-43 55 -155 88q-216 63 -487 36q-132 -12 -226 -46q-38 -15 -59.5 -25t-47 -34t-29.5 -54q8 -68 19 -138t29 -171t24 -137q1 -5 5 -31t7 -36t12 -27t22 -28q105 -80 284 -100q259 -28 440 63q24 13 39.5 23t31 29t19.5 40q48 267 80 473zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M390 1408h219v-388h364v-241h-364v-394q0 -136 14 -172q13 -37 52 -60q50 -31 117 -31q117 0 232 76v-242q-102 -48 -178 -65q-77 -19 -173 -19q-105 0 -186 27q-78 25 -138 75q-58 51 -79 105q-22 54 -22 161v539h-170v217q91 30 155 84q64 55 103 132q39 78 54 196z " /> +<glyph unicode="" d="M1123 127v181q-88 -56 -174 -56q-51 0 -88 23q-29 17 -39 45q-11 30 -11 129v295h274v181h-274v291h-164q-11 -90 -40 -147t-78 -99q-48 -40 -116 -63v-163h127v-404q0 -78 17 -121q17 -42 59 -78q43 -37 104 -57q62 -20 140 -20q67 0 129 14q57 13 134 49zM1536 1120 v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="768" d="M765 237q8 -19 -5 -35l-350 -384q-10 -10 -23 -10q-14 0 -24 10l-355 384q-13 16 -5 35q9 19 29 19h224v1248q0 14 9 23t23 9h192q14 0 23 -9t9 -23v-1248h224q21 0 29 -19z" /> +<glyph unicode="" horiz-adv-x="768" d="M765 1043q-9 -19 -29 -19h-224v-1248q0 -14 -9 -23t-23 -9h-192q-14 0 -23 9t-9 23v1248h-224q-21 0 -29 19t5 35l350 384q10 10 23 10q14 0 24 -10l355 -384q13 -16 5 -35z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1792 736v-192q0 -14 -9 -23t-23 -9h-1248v-224q0 -21 -19 -29t-35 5l-384 350q-10 10 -10 23q0 14 10 24l384 354q16 14 35 6q19 -9 19 -29v-224h1248q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1728 643q0 -14 -10 -24l-384 -354q-16 -14 -35 -6q-19 9 -19 29v224h-1248q-14 0 -23 9t-9 23v192q0 14 9 23t23 9h1248v224q0 21 19 29t35 -5l384 -350q10 -10 10 -23z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1393 321q-39 -125 -123 -250q-129 -196 -257 -196q-49 0 -140 32q-86 32 -151 32q-61 0 -142 -33q-81 -34 -132 -34q-152 0 -301 259q-147 261 -147 503q0 228 113 374q112 144 284 144q72 0 177 -30q104 -30 138 -30q45 0 143 34q102 34 173 34q119 0 213 -65 q52 -36 104 -100q-79 -67 -114 -118q-65 -94 -65 -207q0 -124 69 -223t158 -126zM1017 1494q0 -61 -29 -136q-30 -75 -93 -138q-54 -54 -108 -72q-37 -11 -104 -17q3 149 78 257q74 107 250 148q1 -3 2.5 -11t2.5 -11q0 -4 0.5 -10t0.5 -10z" /> +<glyph unicode="" horiz-adv-x="1664" d="M682 530v-651l-682 94v557h682zM682 1273v-659h-682v565zM1664 530v-786l-907 125v661h907zM1664 1408v-794h-907v669z" /> +<glyph unicode="" horiz-adv-x="1408" d="M493 1053q16 0 27.5 11.5t11.5 27.5t-11.5 27.5t-27.5 11.5t-27 -11.5t-11 -27.5t11 -27.5t27 -11.5zM915 1053q16 0 27 11.5t11 27.5t-11 27.5t-27 11.5t-27.5 -11.5t-11.5 -27.5t11.5 -27.5t27.5 -11.5zM103 869q42 0 72 -30t30 -72v-430q0 -43 -29.5 -73t-72.5 -30 t-73 30t-30 73v430q0 42 30 72t73 30zM1163 850v-666q0 -46 -32 -78t-77 -32h-75v-227q0 -43 -30 -73t-73 -30t-73 30t-30 73v227h-138v-227q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73l-1 227h-74q-46 0 -78 32t-32 78v666h918zM931 1255q107 -55 171 -153.5t64 -215.5 h-925q0 117 64 215.5t172 153.5l-71 131q-7 13 5 20q13 6 20 -6l72 -132q95 42 201 42t201 -42l72 132q7 12 20 6q12 -7 5 -20zM1408 767v-430q0 -43 -30 -73t-73 -30q-42 0 -72 30t-30 73v430q0 43 30 72.5t72 29.5q43 0 73 -29.5t30 -72.5z" /> +<glyph unicode="" d="M663 1125q-11 -1 -15.5 -10.5t-8.5 -9.5q-5 -1 -5 5q0 12 19 15h10zM750 1111q-4 -1 -11.5 6.5t-17.5 4.5q24 11 32 -2q3 -6 -3 -9zM399 684q-4 1 -6 -3t-4.5 -12.5t-5.5 -13.5t-10 -13q-7 -10 -1 -12q4 -1 12.5 7t12.5 18q1 3 2 7t2 6t1.5 4.5t0.5 4v3t-1 2.5t-3 2z M1254 325q0 18 -55 42q4 15 7.5 27.5t5 26t3 21.5t0.5 22.5t-1 19.5t-3.5 22t-4 20.5t-5 25t-5.5 26.5q-10 48 -47 103t-72 75q24 -20 57 -83q87 -162 54 -278q-11 -40 -50 -42q-31 -4 -38.5 18.5t-8 83.5t-11.5 107q-9 39 -19.5 69t-19.5 45.5t-15.5 24.5t-13 15t-7.5 7 q-14 62 -31 103t-29.5 56t-23.5 33t-15 40q-4 21 6 53.5t4.5 49.5t-44.5 25q-15 3 -44.5 18t-35.5 16q-8 1 -11 26t8 51t36 27q37 3 51 -30t4 -58q-11 -19 -2 -26.5t30 -0.5q13 4 13 36v37q-5 30 -13.5 50t-21 30.5t-23.5 15t-27 7.5q-107 -8 -89 -134q0 -15 -1 -15 q-9 9 -29.5 10.5t-33 -0.5t-15.5 5q1 57 -16 90t-45 34q-27 1 -41.5 -27.5t-16.5 -59.5q-1 -15 3.5 -37t13 -37.5t15.5 -13.5q10 3 16 14q4 9 -7 8q-7 0 -15.5 14.5t-9.5 33.5q-1 22 9 37t34 14q17 0 27 -21t9.5 -39t-1.5 -22q-22 -15 -31 -29q-8 -12 -27.5 -23.5 t-20.5 -12.5q-13 -14 -15.5 -27t7.5 -18q14 -8 25 -19.5t16 -19t18.5 -13t35.5 -6.5q47 -2 102 15q2 1 23 7t34.5 10.5t29.5 13t21 17.5q9 14 20 8q5 -3 6.5 -8.5t-3 -12t-16.5 -9.5q-20 -6 -56.5 -21.5t-45.5 -19.5q-44 -19 -70 -23q-25 -5 -79 2q-10 2 -9 -2t17 -19 q25 -23 67 -22q17 1 36 7t36 14t33.5 17.5t30 17t24.5 12t17.5 2.5t8.5 -11q0 -2 -1 -4.5t-4 -5t-6 -4.5t-8.5 -5t-9 -4.5t-10 -5t-9.5 -4.5q-28 -14 -67.5 -44t-66.5 -43t-49 -1q-21 11 -63 73q-22 31 -25 22q-1 -3 -1 -10q0 -25 -15 -56.5t-29.5 -55.5t-21 -58t11.5 -63 q-23 -6 -62.5 -90t-47.5 -141q-2 -18 -1.5 -69t-5.5 -59q-8 -24 -29 -3q-32 31 -36 94q-2 28 4 56q4 19 -1 18l-4 -5q-36 -65 10 -166q5 -12 25 -28t24 -20q20 -23 104 -90.5t93 -76.5q16 -15 17.5 -38t-14 -43t-45.5 -23q8 -15 29 -44.5t28 -54t7 -70.5q46 24 7 92 q-4 8 -10.5 16t-9.5 12t-2 6q3 5 13 9.5t20 -2.5q46 -52 166 -36q133 15 177 87q23 38 34 30q12 -6 10 -52q-1 -25 -23 -92q-9 -23 -6 -37.5t24 -15.5q3 19 14.5 77t13.5 90q2 21 -6.5 73.5t-7.5 97t23 70.5q15 18 51 18q1 37 34.5 53t72.5 10.5t60 -22.5zM626 1152 q3 17 -2.5 30t-11.5 15q-9 2 -9 -7q2 -5 5 -6q10 0 7 -15q-3 -20 8 -20q3 0 3 3zM1045 955q-2 8 -6.5 11.5t-13 5t-14.5 5.5q-5 3 -9.5 8t-7 8t-5.5 6.5t-4 4t-4 -1.5q-14 -16 7 -43.5t39 -31.5q9 -1 14.5 8t3.5 20zM867 1168q0 11 -5 19.5t-11 12.5t-9 3q-14 -1 -7 -7l4 -2 q14 -4 18 -31q0 -3 8 2zM921 1401q0 2 -2.5 5t-9 7t-9.5 6q-15 15 -24 15q-9 -1 -11.5 -7.5t-1 -13t-0.5 -12.5q-1 -4 -6 -10.5t-6 -9t3 -8.5q4 -3 8 0t11 9t15 9q1 1 9 1t15 2t9 7zM1486 60q20 -12 31 -24.5t12 -24t-2.5 -22.5t-15.5 -22t-23.5 -19.5t-30 -18.5 t-31.5 -16.5t-32 -15.5t-27 -13q-38 -19 -85.5 -56t-75.5 -64q-17 -16 -68 -19.5t-89 14.5q-18 9 -29.5 23.5t-16.5 25.5t-22 19.5t-47 9.5q-44 1 -130 1q-19 0 -57 -1.5t-58 -2.5q-44 -1 -79.5 -15t-53.5 -30t-43.5 -28.5t-53.5 -11.5q-29 1 -111 31t-146 43q-19 4 -51 9.5 t-50 9t-39.5 9.5t-33.5 14.5t-17 19.5q-10 23 7 66.5t18 54.5q1 16 -4 40t-10 42.5t-4.5 36.5t10.5 27q14 12 57 14t60 12q30 18 42 35t12 51q21 -73 -32 -106q-32 -20 -83 -15q-34 3 -43 -10q-13 -15 5 -57q2 -6 8 -18t8.5 -18t4.5 -17t1 -22q0 -15 -17 -49t-14 -48 q3 -17 37 -26q20 -6 84.5 -18.5t99.5 -20.5q24 -6 74 -22t82.5 -23t55.5 -4q43 6 64.5 28t23 48t-7.5 58.5t-19 52t-20 36.5q-121 190 -169 242q-68 74 -113 40q-11 -9 -15 15q-3 16 -2 38q1 29 10 52t24 47t22 42q8 21 26.5 72t29.5 78t30 61t39 54q110 143 124 195 q-12 112 -16 310q-2 90 24 151.5t106 104.5q39 21 104 21q53 1 106 -13.5t89 -41.5q57 -42 91.5 -121.5t29.5 -147.5q-5 -95 30 -214q34 -113 133 -218q55 -59 99.5 -163t59.5 -191q8 -49 5 -84.5t-12 -55.5t-20 -22q-10 -2 -23.5 -19t-27 -35.5t-40.5 -33.5t-61 -14 q-18 1 -31.5 5t-22.5 13.5t-13.5 15.5t-11.5 20.5t-9 19.5q-22 37 -41 30t-28 -49t7 -97q20 -70 1 -195q-10 -65 18 -100.5t73 -33t85 35.5q59 49 89.5 66.5t103.5 42.5q53 18 77 36.5t18.5 34.5t-25 28.5t-51.5 23.5q-33 11 -49.5 48t-15 72.5t15.5 47.5q1 -31 8 -56.5 t14.5 -40.5t20.5 -28.5t21 -19t21.5 -13t16.5 -9.5z" /> +<glyph unicode="" d="M1024 36q-42 241 -140 498h-2l-2 -1q-16 -6 -43 -16.5t-101 -49t-137 -82t-131 -114.5t-103 -148l-15 11q184 -150 418 -150q132 0 256 52zM839 643q-21 49 -53 111q-311 -93 -673 -93q-1 -7 -1 -21q0 -124 44 -236.5t124 -201.5q50 89 123.5 166.5t142.5 124.5t130.5 81 t99.5 48l37 13q4 1 13 3.5t13 4.5zM732 855q-120 213 -244 378q-138 -65 -234 -186t-128 -272q302 0 606 80zM1416 536q-210 60 -409 29q87 -239 128 -469q111 75 185 189.5t96 250.5zM611 1277q-1 0 -2 -1q1 1 2 1zM1201 1132q-185 164 -433 164q-76 0 -155 -19 q131 -170 246 -382q69 26 130 60.5t96.5 61.5t65.5 57t37.5 40.5zM1424 647q-3 232 -149 410l-1 -1q-9 -12 -19 -24.5t-43.5 -44.5t-71 -60.5t-100 -65t-131.5 -64.5q25 -53 44 -95q2 -6 6.5 -17.5t7.5 -16.5q36 5 74.5 7t73.5 2t69 -1.5t64 -4t56.5 -5.5t48 -6.5t36.5 -6 t25 -4.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1173 473q0 50 -19.5 91.5t-48.5 68.5t-73 49t-82.5 34t-87.5 23l-104 24q-30 7 -44 10.5t-35 11.5t-30 16t-16.5 21t-7.5 30q0 77 144 77q43 0 77 -12t54 -28.5t38 -33.5t40 -29t48 -12q47 0 75.5 32t28.5 77q0 55 -56 99.5t-142 67.5t-182 23q-68 0 -132 -15.5 t-119.5 -47t-89 -87t-33.5 -128.5q0 -61 19 -106.5t56 -75.5t80 -48.5t103 -32.5l146 -36q90 -22 112 -36q32 -20 32 -60q0 -39 -40 -64.5t-105 -25.5q-51 0 -91.5 16t-65 38.5t-45.5 45t-46 38.5t-54 16q-50 0 -75.5 -30t-25.5 -75q0 -92 122 -157.5t291 -65.5 q73 0 140 18.5t122.5 53.5t88.5 93.5t33 131.5zM1536 256q0 -159 -112.5 -271.5t-271.5 -112.5q-130 0 -234 80q-77 -16 -150 -16q-143 0 -273.5 55.5t-225 150t-150 225t-55.5 273.5q0 73 16 150q-80 104 -80 234q0 159 112.5 271.5t271.5 112.5q130 0 234 -80 q77 16 150 16q143 0 273.5 -55.5t225 -150t150 -225t55.5 -273.5q0 -73 -16 -150q80 -104 80 -234z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1483 512l-587 -587q-52 -53 -127.5 -53t-128.5 53l-587 587q-53 53 -53 128t53 128l587 587q53 53 128 53t128 -53l265 -265l-398 -399l-188 188q-42 42 -99 42q-59 0 -100 -41l-120 -121q-42 -40 -42 -99q0 -58 42 -100l406 -408q30 -28 67 -37l6 -4h28q60 0 99 41 l619 619l2 -3q53 -53 53 -128t-53 -128zM1406 1138l120 -120q14 -15 14 -36t-14 -36l-730 -730q-17 -15 -37 -15v0q-4 0 -6 1q-18 2 -30 14l-407 408q-14 15 -14 36t14 35l121 120q13 15 35 15t36 -15l252 -252l574 575q15 15 36 15t36 -15z" /> +<glyph unicode="" d="M704 192v1024q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-1024q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1376 576v640q0 14 -9 23t-23 9h-480q-14 0 -23 -9t-9 -23v-640q0 -14 9 -23t23 -9h480q14 0 23 9t9 23zM1536 1344v-1408q0 -26 -19 -45t-45 -19h-1408 q-26 0 -45 19t-19 45v1408q0 26 19 45t45 19h1408q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1280 480q0 -40 -28 -68t-68 -28q-51 0 -80 43l-227 341h-45v-132l247 -411q9 -15 9 -33q0 -26 -19 -45t-45 -19h-192v-272q0 -46 -33 -79t-79 -33h-160q-46 0 -79 33t-33 79v272h-192q-26 0 -45 19t-19 45q0 18 9 33l247 411v132h-45l-227 -341q-29 -43 -80 -43 q-40 0 -68 28t-28 68q0 29 16 53l256 384q73 107 176 107h384q103 0 176 -107l256 -384q16 -24 16 -53zM864 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> +<glyph unicode="" horiz-adv-x="1024" d="M1024 832v-416q0 -40 -28 -68t-68 -28t-68 28t-28 68v352h-64v-912q0 -46 -33 -79t-79 -33t-79 33t-33 79v464h-64v-464q0 -46 -33 -79t-79 -33t-79 33t-33 79v912h-64v-352q0 -40 -28 -68t-68 -28t-68 28t-28 68v416q0 80 56 136t136 56h640q80 0 136 -56t56 -136z M736 1280q0 -93 -65.5 -158.5t-158.5 -65.5t-158.5 65.5t-65.5 158.5t65.5 158.5t158.5 65.5t158.5 -65.5t65.5 -158.5z" /> +<glyph unicode="" d="M773 234l350 473q16 22 24.5 59t-6 85t-61.5 79q-40 26 -83 25.5t-73.5 -17.5t-54.5 -45q-36 -40 -96 -40q-59 0 -95 40q-24 28 -54.5 45t-73.5 17.5t-84 -25.5q-46 -31 -60.5 -79t-6 -85t24.5 -59zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103 t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1472 640q0 117 -45.5 223.5t-123 184t-184 123t-223.5 45.5t-223.5 -45.5t-184 -123t-123 -184t-45.5 -223.5t45.5 -223.5t123 -184t184 -123t223.5 -45.5t223.5 45.5t184 123t123 184t45.5 223.5zM1748 363q-4 -15 -20 -20l-292 -96v-306q0 -16 -13 -26q-15 -10 -29 -4 l-292 94l-180 -248q-10 -13 -26 -13t-26 13l-180 248l-292 -94q-14 -6 -29 4q-13 10 -13 26v306l-292 96q-16 5 -20 20q-5 17 4 29l180 248l-180 248q-9 13 -4 29q4 15 20 20l292 96v306q0 16 13 26q15 10 29 4l292 -94l180 248q9 12 26 12t26 -12l180 -248l292 94 q14 6 29 -4q13 -10 13 -26v-306l292 -96q16 -5 20 -20q5 -16 -4 -29l-180 -248l180 -248q9 -12 4 -29z" /> +<glyph unicode="" d="M1262 233q-54 -9 -110 -9q-182 0 -337 90t-245 245t-90 337q0 192 104 357q-201 -60 -328.5 -229t-127.5 -384q0 -130 51 -248.5t136.5 -204t204 -136.5t248.5 -51q144 0 273.5 61.5t220.5 171.5zM1465 318q-94 -203 -283.5 -324.5t-413.5 -121.5q-156 0 -298 61 t-245 164t-164 245t-61 298q0 153 57.5 292.5t156 241.5t235.5 164.5t290 68.5q44 2 61 -39q18 -41 -15 -72q-86 -78 -131.5 -181.5t-45.5 -218.5q0 -148 73 -273t198 -198t273 -73q118 0 228 51q41 18 72 -13q14 -14 17.5 -34t-4.5 -38z" /> +<glyph unicode="" horiz-adv-x="1792" d="M1088 704q0 26 -19 45t-45 19h-256q-26 0 -45 -19t-19 -45t19 -45t45 -19h256q26 0 45 19t19 45zM1664 896v-960q0 -26 -19 -45t-45 -19h-1408q-26 0 -45 19t-19 45v960q0 26 19 45t45 19h1408q26 0 45 -19t19 -45zM1728 1344v-256q0 -26 -19 -45t-45 -19h-1536 q-26 0 -45 19t-19 45v256q0 26 19 45t45 19h1536q26 0 45 -19t19 -45z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" /> +<glyph unicode="" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" /> +<glyph unicode="" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" /> +<glyph unicode="" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" /> +<glyph unicode="" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " /> +<glyph unicode="" d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" /> +<glyph unicode="" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" /> +<glyph unicode="" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" /> +<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +<glyph unicode="" horiz-adv-x="1792" /> +</font> +</defs></svg>
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf Binary files differnew file mode 100644 index 0000000000..e89738de5e --- /dev/null +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.ttf diff --git a/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff Binary files differnew file mode 100644 index 0000000000..8c1748aab7 --- /dev/null +++ b/WebContent/VAADIN/themes/base/fonts/fontawesome-webfont.woff diff --git a/WebContent/VAADIN/themes/base/fonts/fonts.scss b/WebContent/VAADIN/themes/base/fonts/fonts.scss new file mode 100644 index 0000000000..2a882ab53d --- /dev/null +++ b/WebContent/VAADIN/themes/base/fonts/fonts.scss @@ -0,0 +1,25 @@ +@mixin fonts { + @include fonticons; +} + +@mixin fonticons { + @include font(FontAwesome, fontawesome-webfont); +} + +@mixin font($font-family, $file-name) { + @font-face { + font-family: '#{$font-family}'; + src: url('#{$file-name}.eot'); + src: url('#{$file-name}.eot?#iefix') format('embedded-opentype'), url('#{$file-name}.woff') format('woff'), url('#{$file-name}.ttf') format('truetype'), url('#{$file-name}.svg') format('svg'); + font-weight: normal; + font-style: normal; + } + .#{$font-family} { + font-family: '#{$font-family}'; + font-style: normal; + font-weight: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + } +} diff --git a/WebContent/VAADIN/themes/base/tabsheet/tabsheet.scss b/WebContent/VAADIN/themes/base/tabsheet/tabsheet.scss index 1a799814c1..14def56ab5 100644 --- a/WebContent/VAADIN/themes/base/tabsheet/tabsheet.scss +++ b/WebContent/VAADIN/themes/base/tabsheet/tabsheet.scss @@ -106,6 +106,12 @@ .#{$primaryStyleName}-tabitem-selected .v-caption { cursor: default; } +.#{$primaryStyleName}-tabitem-focus .v-captiontext { + text-decoration: underline; +} +.#{$primaryStyleName}-tabitem-selected.#{$primaryStyleName}-tabitem-focus .v-captiontext { + text-decoration: inherit; +} .#{$primaryStyleName}-content { border: 1px solid #aaa; /* Vertical borders are not supported, use v-tabsheet-tabcontainer and v-tabsheet-deco to present these borders */ diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js index b2995dd0bd..bab759b812 100644 --- a/WebContent/VAADIN/vaadinBootstrap.js +++ b/WebContent/VAADIN/vaadinBootstrap.js @@ -120,6 +120,8 @@ url += '&theme=' + encodeURIComponent(theme); } + url += "&v-appId=" + appId; + var extraParams = getConfig('extraParams') if (extraParams !== undefined) { url += extraParams; diff --git a/WebContent/license.html b/WebContent/license.html index 5e9bfe4dc5..0f9a573041 100644 --- a/WebContent/license.html +++ b/WebContent/license.html @@ -130,7 +130,11 @@ <td>jQuery^</td> <td><a href="licenses/the-mit-license.txt">The MIT License</a></td> </tr> - + <!-- Used by font icons --> + <tr> + <td>FontAwesome</td> + <td><a href="licenses/OFL.txt">SIL OFL 1.1</a></td> + </tr> </tbody> </table> diff --git a/WebContent/licenses/OFL.txt b/WebContent/licenses/OFL.txt new file mode 100644 index 0000000000..f1a20ac1a8 --- /dev/null +++ b/WebContent/licenses/OFL.txt @@ -0,0 +1,97 @@ +Copyright (c) <dates>, <Copyright Holder> (<URL|email>),
+with Reserved Font Name <Reserved Font Name>.
+Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>),
+with Reserved Font Name <additional Reserved Font Name>.
+Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>).
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index c7e7558e6a..6e4b77845b 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -585,11 +585,12 @@ </p> <ul> - <li>Apache Tomcat 5-7</li> + <li>Apache Tomcat 5-8</li> <li>Apache TomEE 1</li> <li>Oracle WebLogic Server 10.3-12</li> <li>IBM WebSphere Application Server 7-8</li> <li>JBoss Application Server 4-7</li> + <li>Wildfly 8</li> <li>Jetty 5-9</li> <li>Glassfish 2-4</li> </ul> diff --git a/WebContent/statictestfiles/EmbedSizeHostPage.html b/WebContent/statictestfiles/EmbedSizeHostPage.html index 2576a200db..3ef6c5d0cd 100644 --- a/WebContent/statictestfiles/EmbedSizeHostPage.html +++ b/WebContent/statictestfiles/EmbedSizeHostPage.html @@ -37,7 +37,6 @@ setTimeout('if (typeof com_vaadin_DefaultWidgetSet == "undefined") {alert("Faile </script> <div style="width: 80%; border: 1px solid black"> <h1>Test page for resize events with embedded applications</h1> -<div id="runcomvaadintestsintegrationEmbedSizeTest-225840176" class="v-app v-theme-reindeer v-app-EmbedSizeTest" ><div class="v-app-loading"></div></div> +<div id="runcomvaadintestsintegrationEmbedSizeTest-225840176" class="v-app v-theme-reindeer v-app-EmbedSizeTest" ><div class="v-app-loading"></div></div></div> <noscript>You have to enable javascript in your browser to use an application built with Vaadin.</noscript></body> -</div> </html> diff --git a/WebContent/statictestfiles/vaadinsessions.jsp b/WebContent/statictestfiles/vaadinsessions.jsp new file mode 100644 index 0000000000..b22787a203 --- /dev/null +++ b/WebContent/statictestfiles/vaadinsessions.jsp @@ -0,0 +1,54 @@ +<!DOCTYPE> +<%@page import="com.vaadin.ui.UI"%> +<%@page import="com.vaadin.server.VaadinSession"%> +<HTML> +<HEAD> +<TITLE>JSP integration</TITLE> +<style> +table { + background: #fff; +} + +td { + border: 1px solid black; + padding: .5em; +} +</style> +</HEAD> +<BODY> + <table> + <tr> + <th align="left" colspan=4>Available UIs:</th> + </tr> + <tr> + <th>Service Name</th> + <th>CSRF token</th> + <th>UI id</th> + <th>UI type</th> + <th>Main content</th> + </tr> + <% + HttpSession httpSession = request.getSession(false); + for (VaadinSession vs : VaadinSession.getAllSessions(httpSession)) { + try { + vs.lock(); + for (UI ui : vs.getUIs()) { + out.append("<tr class='uirow'>"); + out.append("<td>" + vs.getService().getServiceName() + + "</td>"); + out.append("<td>" + vs.getCsrfToken() + "</td>"); + out.append("<td>" + ui.getUIId() + "</td>"); + out.append("<td>" + ui.getClass().getName() + "</td>"); + out.append("<td>" + ui.getContent().getClass().getName() + "</td>"); + out.append("</tr>"); + + } + } finally { + vs.unlock(); + } + + } + %> + </table> +</BODY> +</HTML>
\ No newline at end of file diff --git a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java index 5c3810099a..fb7b672b21 100644 --- a/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java +++ b/buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java @@ -37,7 +37,6 @@ public class FetchReleaseNotesTickets { URLConnection connection = url.openConnection(); InputStream urlStream = connection.getInputStream(); - @SuppressWarnings("unchecked") List<String> tickets = IOUtils.readLines(urlStream); for (String ticket : tickets) { diff --git a/client-compiler/ivy.xml b/client-compiler/ivy.xml index f66a2e0255..f0fa5a49b0 100644 --- a/client-compiler/ivy.xml +++ b/client-compiler/ivy.xml @@ -31,33 +31,56 @@ <dependency org="commons-collections" name="commons-collections" rev="3.1" conf="build,ide -> default" /> <dependency org="commons-logging" name="commons-logging" - rev="1.1.1" conf="build,ide -> default" /> + rev="1.1.3" conf="build,ide -> default" /> <dependency org="ant" name="ant" rev="1.6.5" conf="build,ide -> default" /> <dependency org="net.sourceforge.cssparser" name="cssparser" - rev="0.9.5" conf="build,ide -> default" /> + rev="0.9.11" conf="build,ide -> default" /> <dependency org="ant" name="ant" rev="1.6.5" conf="build,ide -> default" /> <dependency org="ant" name="ant-launcher" rev="1.6.5" conf="build,ide -> default" /> - <dependency org="org.mortbay.jetty" name="jetty" rev="6.1.11" - conf="build,ide -> default" /> - <dependency org="org.mortbay.jetty" name="jetty-util" - rev="6.1.11" conf="build,ide -> default" /> + + <dependency org="org.eclipse.jetty" name="jetty-server" + rev="8.1.12.v20130726" conf="build,ide -> default"> + <exclude org="org.eclipse.jetty.orbit"></exclude> + </dependency> + <dependency org="org.eclipse.jetty" name="jetty-util" + rev="8.1.12.v20130726" conf="build,ide -> default" /> + <dependency org="org.jdesktop" name="swing-worker" rev="1.1" conf="build,ide -> default" /> <dependency org="commons-codec" name="commons-codec" - rev="1.3" conf="build,ide -> default" /> - <dependency org="commons-io" name="commons-io" rev="2.2" + rev="1.8" conf="build,ide -> default" /> + <dependency org="commons-io" name="commons-io" rev="2.4" conf="build,ide -> default" /> - <dependency org="commons-lang" name="commons-lang" - rev="2.6" conf="build,ide -> default" /> + <dependency org="org.apache.commons" name="commons-lang3" + rev="3.1" conf="build,ide -> default" /> <dependency org="org.apache.james" name="apache-mime4j" rev="0.6" conf="build,ide -> default" /> + <dependency org="org.apache.httpcomponents" name="httpclient" + rev="4.3.1" conf="build,ide -> default" /> + <dependency org="org.apache.httpcomponents" name="httpcore" + rev="4.3" conf="build,ide -> default" /> + <dependency org="org.apache.httpcomponents" name="httpmime" + rev="4.3.1" conf="build,ide -> default" /> + + <dependency org="net.sourceforge.nekohtml" name="nekohtml" + rev="1.9.19" conf="build,ide -> default" /> + <dependency org="xalan" name="serializer" rev="2.7.1" + conf="build,ide -> default" /> + <dependency org="xerces" name="xercesImpl" rev="2.11.0" + conf="build,ide -> default" /> + <dependency org="xml-apis" name="xml-apis" rev="1.4.01" + conf="build,ide -> default" /> + + <dependency org="com.ibm.icu" name="icu4j" rev="50.1.1" + conf="build,ide -> default" /> + <dependency org="com.vaadin" name="vaadin-client-compiler-deps" - rev="1.0.2" conf="build,ide -> default" /> + rev="1.1.0" conf="build,ide -> default" /> </dependencies> diff --git a/client-compiler/src/com/vaadin/sass/linker/SassLinker.java b/client-compiler/src/com/vaadin/sass/linker/SassLinker.java index 05d9e311a6..3183f4bfe7 100644 --- a/client-compiler/src/com/vaadin/sass/linker/SassLinker.java +++ b/client-compiler/src/com/vaadin/sass/linker/SassLinker.java @@ -132,7 +132,7 @@ public class SassLinker extends AbstractLinker { if (!fileInfo.isMixin()) { scss.compile(); InputStream is = new ByteArrayInputStream(scss - .toString().getBytes()); + .printState().getBytes()); toReturn.add(this.emitInputStream(logger, is, fileInfo.getOriginalCssPath())); diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java index f8aa586064..1c06cea3fa 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -19,6 +19,8 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -74,6 +76,7 @@ public class ConnectorBundleLoaderFactory extends Generator { private final SourceWriter target; private final String baseName; private final int splitSize; + private final List<String> methodNames; // Seems to be undercounted by about 15% private int approximateChars = 0; @@ -84,6 +87,8 @@ public class ConnectorBundleLoaderFactory extends Generator { this.target = target; this.baseName = baseName; this.splitSize = splitSize; + methodNames = new ArrayList<String>(); + methodNames.add(baseName); } @Override @@ -169,17 +174,34 @@ public class ConnectorBundleLoaderFactory extends Generator { } public void splitIfNeeded() { + splitIfNeeded(false, null); + } + + public void splitIfNeeded(boolean isNative, String params) { if (approximateChars > splitSize) { String newMethod = baseName + wrapCount++; - println("%s();", newMethod); - outdent(); - println("}"); - println("private void %s() {", newMethod); + String args = params == null ? "" : params; + if (isNative) { + outdent(); + println("}-*/;"); + println("private native void %s(%s) /*-{", newMethod, args); + } else { + println("%s();", newMethod); + outdent(); + println("}"); + println("private void %s(%s) {", newMethod, args); + } + methodNames.add(newMethod); indent(); approximateChars = 0; } } + + public List<String> getMethodNames() { + return Collections.unmodifiableList(methodNames); + } + } @Override @@ -227,6 +249,8 @@ public class ConnectorBundleLoaderFactory extends Generator { w.indent(); for (ConnectorBundle bundle : bundles) { + detectBadProperties(bundle, logger); + String name = bundle.getName(); boolean isEager = name .equals(ConnectorBundleLoader.EAGER_BUNDLE_NAME); @@ -275,12 +299,34 @@ public class ConnectorBundleLoaderFactory extends Generator { w.println("private void load() {"); w.indent(); - printBundleData(logger, w, bundle); + String loadNativeJsBundle = "loadJsBundle"; + printBundleData(logger, w, bundle, loadNativeJsBundle); // Close load method w.outdent(); w.println("}"); + // Separate method for loading native JS stuff (e.g. callbacks) + String loadNativeJsMethodName = "loadNativeJs"; + w.println("private native void %s(%s store) /*-{", + loadNativeJsMethodName, TypeDataStore.class.getName()); + w.indent(); + List<String> jsMethodNames = printJsBundleData(logger, w, bundle, + loadNativeJsMethodName); + + w.outdent(); + w.println("}-*/;"); + + // Call all generated native method inside one Java method to avoid + // refercences inside native methods to each other + w.println("private void %s(%s store) {", loadNativeJsBundle, + TypeDataStore.class.getName()); + w.indent(); + printLoadJsBundleData(w, loadNativeJsBundle, jsMethodNames); + w.outdent(); + w.println("}"); + + // onFailure method declaration starts w.println("public void onFailure(Throwable reason) {"); w.indent(); @@ -315,27 +361,153 @@ public class ConnectorBundleLoaderFactory extends Generator { w.commit(logger); } + private void printLoadJsBundleData(SourceWriter w, String methodName, + List<String> methods) { + SplittingSourceWriter writer = new SplittingSourceWriter(w, methodName, + 30000); + + for (String method : methods) { + writer.println("%s(store);", method); + writer.splitIfNeeded(); + } + } + + private void detectBadProperties(ConnectorBundle bundle, TreeLogger logger) + throws UnableToCompleteException { + Map<JClassType, Set<String>> definedProperties = new HashMap<JClassType, Set<String>>(); + + for (Property property : bundle.getNeedsProperty()) { + JClassType beanType = property.getBeanType(); + Set<String> usedPropertyNames = definedProperties.get(beanType); + if (usedPropertyNames == null) { + usedPropertyNames = new HashSet<String>(); + definedProperties.put(beanType, usedPropertyNames); + } + + String name = property.getName(); + if (!usedPropertyNames.add(name)) { + logger.log(Type.ERROR, beanType.getQualifiedSourceName() + + " has multiple properties with the name " + name + + ". This can happen if there are multiple " + + "setters with identical names ignoring case."); + throw new UnableToCompleteException(); + } + if (!property.hasAccessorMethods()) { + logger.log(Type.ERROR, beanType.getQualifiedSourceName() + + " has the property '" + name + + "' without getter defined."); + throw new UnableToCompleteException(); + } + } + } + + private List<String> printJsBundleData(TreeLogger logger, SourceWriter w, + ConnectorBundle bundle, String methodName) { + SplittingSourceWriter writer = new SplittingSourceWriter(w, methodName, + 30000); + Set<Property> needsProperty = bundle.getNeedsProperty(); + for (Property property : needsProperty) { + writer.println("var data = {"); + writer.indent(); + + writer.println("setter: function(bean, value) {"); + writer.indent(); + property.writeSetterBody(logger, writer, "bean", "value"); + writer.outdent(); + writer.println("},"); + + writer.println("getter: function(bean) {"); + writer.indent(); + property.writeGetterBody(logger, writer, "bean"); + writer.outdent(); + writer.println("}"); + + writer.outdent(); + writer.println("};"); + + // Method declaration + writer.print( + "store.@%s::setPropertyData(Ljava/lang/Class;Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)", + TypeDataStore.class.getName()); + writer.println("(@%s::class, '%s', data);", property.getBeanType() + .getQualifiedSourceName(), property.getName()); + writer.println(); + writer.splitIfNeeded(true, + String.format("%s store", TypeDataStore.class.getName())); + } + return writer.getMethodNames(); + } + private void printBundleData(TreeLogger logger, SourceWriter sourceWriter, - ConnectorBundle bundle) throws UnableToCompleteException { + ConnectorBundle bundle, String loadNativeJsMethodName) + throws UnableToCompleteException { // Split into new load method when reaching approximately 30000 bytes SplittingSourceWriter w = new SplittingSourceWriter(sourceWriter, "load", 30000); + writeSuperClasses(w, bundle); writeIdentifiers(w, bundle); writeGwtConstructors(w, bundle); writeReturnTypes(w, bundle); writeInvokers(w, bundle); writeParamTypes(w, bundle); writeProxys(w, bundle); - wirteDelayedInfo(w, bundle); - writeProperites(logger, w, bundle); - writePropertyTypes(w, bundle); - writeSetters(logger, w, bundle); - writeGetters(logger, w, bundle); + writeDelayedInfo(w, bundle); + + w.println("%s(store);", loadNativeJsMethodName); + + // Must use Java code to generate Type data (because of Type[]), doing + // this after the JS property data has been initialized + writePropertyTypes(logger, w, bundle); writeSerializers(logger, w, bundle); writeDelegateToWidget(logger, w, bundle); } + private void writeSuperClasses(SplittingSourceWriter w, + ConnectorBundle bundle) { + List<JClassType> needsSuperclass = new ArrayList<JClassType>( + bundle.getNeedsSuperclass()); + // Emit in hierarchy order to ensure superclass is defined when + // referenced + Collections.sort(needsSuperclass, new Comparator<JClassType>() { + + @Override + public int compare(JClassType type1, JClassType type2) { + int depthDiff = getDepth(type1) - getDepth(type2); + if (depthDiff != 0) { + return depthDiff; + } else { + // Just something to get a stable compare + return type1.getName().compareTo(type2.getName()); + } + } + + private int getDepth(JClassType type) { + int depth = 0; + while (type != null) { + depth++; + type = type.getSuperclass(); + } + return depth; + } + }); + + for (JClassType jClassType : needsSuperclass) { + JClassType superclass = jClassType.getSuperclass(); + while (superclass != null && !superclass.isPublic()) { + superclass = superclass.getSuperclass(); + } + String classLiteralString; + if (superclass == null) { + classLiteralString = "null"; + } else { + classLiteralString = getClassLiteralString(superclass); + } + w.println("store.setSuperClass(%s, %s);", + getClassLiteralString(jClassType), classLiteralString); + } + } + private void writeDelegateToWidget(TreeLogger logger, SplittingSourceWriter w, ConnectorBundle bundle) { Set<Property> needsDelegateToWidget = bundle.getNeedsDelegateToWidget(); @@ -378,64 +550,9 @@ public class ConnectorBundleLoaderFactory extends Generator { } } - private void writeGetters(TreeLogger logger, SplittingSourceWriter w, + private void writePropertyTypes(TreeLogger logger, SplittingSourceWriter w, ConnectorBundle bundle) { - Set<Property> properties = bundle.getNeedsSetter(); - for (Property property : properties) { - w.print("store.setGetter("); - writeClassLiteral(w, property.getBeanType()); - w.print(", \""); - w.print(escape(property.getName())); - w.println("\", new Invoker() {"); - w.indent(); - - w.println("public Object invoke(Object bean, Object[] params) {"); - w.indent(); - - property.writeGetterBody(logger, w, "bean"); - w.println(); - - w.outdent(); - w.println("}"); - - w.outdent(); - w.println("});"); - - w.splitIfNeeded(); - } - } - - private void writeSetters(TreeLogger logger, SplittingSourceWriter w, - ConnectorBundle bundle) { - Set<Property> properties = bundle.getNeedsSetter(); - for (Property property : properties) { - w.print("store.setSetter("); - writeClassLiteral(w, property.getBeanType()); - w.print(", \""); - w.print(escape(property.getName())); - w.println("\", new Invoker() {"); - w.indent(); - - w.println("public Object invoke(Object bean, Object[] params) {"); - w.indent(); - - property.writeSetterBody(logger, w, "bean", "params[0]"); - - w.println("return null;"); - - w.outdent(); - w.println("}"); - - w.outdent(); - w.println("});"); - - w.splitIfNeeded(); - } - } - - private void writePropertyTypes(SplittingSourceWriter w, - ConnectorBundle bundle) { - Set<Property> properties = bundle.getNeedsType(); + Set<Property> properties = bundle.getNeedsProperty(); for (Property property : properties) { w.print("store.setPropertyType("); writeClassLiteral(w, property.getBeanType()); @@ -449,40 +566,7 @@ public class ConnectorBundleLoaderFactory extends Generator { } } - private void writeProperites(TreeLogger logger, SplittingSourceWriter w, - ConnectorBundle bundle) throws UnableToCompleteException { - Set<JClassType> needsPropertyListing = bundle.getNeedsPropertyListing(); - for (JClassType type : needsPropertyListing) { - w.print("store.setProperties("); - writeClassLiteral(w, type); - w.print(", new String[] {"); - - Set<String> usedPropertyNames = new HashSet<String>(); - Collection<Property> properties = bundle.getProperties(type); - for (Property property : properties) { - String name = property.getName(); - if (!usedPropertyNames.add(name)) { - logger.log( - Type.ERROR, - type.getQualifiedSourceName() - + " has multiple properties with the name " - + name - + ". This can happen if there are multiple setters with identical names exect casing."); - throw new UnableToCompleteException(); - } - - w.print("\""); - w.print(name); - w.print("\", "); - } - - w.println("});"); - - w.splitIfNeeded(); - } - } - - private void wirteDelayedInfo(SplittingSourceWriter w, + private void writeDelayedInfo(SplittingSourceWriter w, ConnectorBundle bundle) { Map<JClassType, Set<JMethod>> needsDelayedInfo = bundle .getNeedsDelayedInfo(); diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java index 4d6a7ff6d7..0064a24aef 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java @@ -59,7 +59,7 @@ public class ConnectorBundle { private final Set<JType> needsSerializeSupport = new HashSet<JType>(); private final Map<JType, GeneratedSerializer> serializers = new HashMap<JType, GeneratedSerializer>(); - private final Set<JClassType> needsPropertyList = new HashSet<JClassType>(); + private final Set<JClassType> needsSuperClass = new HashSet<JClassType>(); private final Set<JClassType> needsGwtConstructor = new HashSet<JClassType>(); private final Set<JClassType> visitedTypes = new HashSet<JClassType>(); private final Set<JClassType> needsProxySupport = new HashSet<JClassType>(); @@ -70,9 +70,7 @@ public class ConnectorBundle { private final Map<JClassType, Set<JMethod>> needsParamTypes = new HashMap<JClassType, Set<JMethod>>(); private final Map<JClassType, Set<JMethod>> needsDelayedInfo = new HashMap<JClassType, Set<JMethod>>(); - private final Set<Property> needsSetter = new HashSet<Property>(); - private final Set<Property> needsType = new HashSet<Property>(); - private final Set<Property> needsGetter = new HashSet<Property>(); + private final Set<Property> needsProperty = new HashSet<Property>(); private final Set<Property> needsDelegateToWidget = new HashSet<Property>(); private ConnectorBundle(String name, ConnectorBundle previousBundle, @@ -246,16 +244,18 @@ public class ConnectorBundle { logger.log(Type.INFO, "Will serialize " + type + " as a bean"); - setNeedsPropertyList(typeAsClass); + JClassType needsSuperClass = typeAsClass; + while (needsSuperClass != null) { + if (needsSuperClass.isPublic()) { + setNeedsSuperclass(needsSuperClass); + } + needsSuperClass = needsSuperClass.getSuperclass(); + } for (Property property : getProperties(typeAsClass)) { setNeedsGwtConstructor(property.getBeanType()); - setNeedsSetter(property); - // Getters needed for reading previous value that should be - // passed to sub encoder - setNeedsGetter(property); - setNeedsType(property); + setNeedsProperty(property); JType propertyType = property.getPropertyType(); setNeedsSerialize(propertyType); @@ -304,80 +304,42 @@ public class ConnectorBundle { return Collections.unmodifiableMap(serializers); } - private void setNeedsGetter(Property property) { - if (!isNeedsGetter(property)) { - needsGetter.add(property); - } - } - - private boolean isNeedsGetter(Property property) { - if (needsGetter.contains(property)) { - return true; - } else { - return previousBundle != null - && previousBundle.isNeedsGetter(property); - } - } - - public Set<Property> getNeedsGetter() { - return Collections.unmodifiableSet(needsGetter); - } - - private void setNeedsType(Property property) { - if (!isNeedsType(property)) { - needsType.add(property); - } - } - - public Set<Property> getNeedsType() { - return Collections.unmodifiableSet(needsType); - } - - private boolean isNeedsType(Property property) { - if (needsType.contains(property)) { - return true; - } else { - return previousBundle != null - && previousBundle.isNeedsType(property); - } - } - - public void setNeedsSetter(Property property) { - if (!isNeedsSetter(property)) { - needsSetter.add(property); + private void setNeedsSuperclass(JClassType typeAsClass) { + if (!isNeedsSuperClass(typeAsClass)) { + needsSuperClass.add(typeAsClass); } } - private boolean isNeedsSetter(Property property) { - if (needsSetter.contains(property)) { + private boolean isNeedsSuperClass(JClassType typeAsClass) { + if (needsSuperClass.contains(typeAsClass)) { return true; } else { return previousBundle != null - && previousBundle.isNeedsSetter(property); + && previousBundle.isNeedsSuperClass(typeAsClass); } } - public Set<Property> getNeedsSetter() { - return Collections.unmodifiableSet(needsSetter); + public Set<JClassType> getNeedsSuperclass() { + return Collections.unmodifiableSet(needsSuperClass); } - private void setNeedsPropertyList(JClassType type) { - if (!isNeedsPropertyList(type)) { - needsPropertyList.add(type); + private void setNeedsProperty(Property property) { + if (!isNeedsProperty(property)) { + needsProperty.add(property); } } - private boolean isNeedsPropertyList(JClassType type) { - if (needsPropertyList.contains(type)) { + private boolean isNeedsProperty(Property property) { + if (needsProperty.contains(property)) { return true; } else { return previousBundle != null - && previousBundle.isNeedsPropertyList(type); + && previousBundle.isNeedsProperty(property); } } - public Set<JClassType> getNeedsPropertyListing() { - return Collections.unmodifiableSet(needsPropertyList); + public Set<Property> getNeedsProperty() { + return Collections.unmodifiableSet(needsProperty); } public Collection<Property> getProperties(JClassType type) { @@ -623,4 +585,4 @@ public class ConnectorBundle { return Collections.unmodifiableSet(needsDelegateToWidget); } -}
\ No newline at end of file +} diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java index 86b8260885..e9ff4587fb 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java @@ -38,18 +38,25 @@ public class FieldProperty extends Property { } @Override + public boolean hasAccessorMethods() { + return true; + } + + @Override public void writeSetterBody(TreeLogger logger, SourceWriter w, String beanVariable, String valueVariable) { - w.print("((%s) %s).%s = (%s)%s;", getBeanType() - .getQualifiedSourceName(), beanVariable, getName(), - getUnboxedPropertyTypeName(), valueVariable); + w.println("%s.@%s::%s = %s;", beanVariable, getBeanType() + .getQualifiedSourceName(), getName(), unboxValue(valueVariable)); } @Override public void writeGetterBody(TreeLogger logger, SourceWriter w, String beanVariable) { - w.print("return ((%s) %s).%s;", getBeanType().getQualifiedSourceName(), - beanVariable, getName()); + String value = String.format("%s.@%s::%s", beanVariable, getBeanType() + .getQualifiedSourceName(), getName()); + w.print("return "); + w.print(boxValue(value)); + w.println(";"); } public static Collection<FieldProperty> findProperties(JClassType type) { @@ -57,7 +64,7 @@ public class FieldProperty extends Property { List<JField> fields = getPublicFields(type); for (JField field : fields) { - properties.add(new FieldProperty(type, field)); + properties.add(new FieldProperty(field.getEnclosingType(), field)); } return properties; diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/MethodProperty.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/MethodProperty.java index 3c317e033e..1d9deef265 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/MethodProperty.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/MethodProperty.java @@ -19,7 +19,9 @@ package com.vaadin.server.widgetsetutils.metadata; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.typeinfo.JClassType; @@ -31,18 +33,29 @@ public class MethodProperty extends Property { private final JMethod setter; - private MethodProperty(JClassType beanType, JMethod setter) { + private final String getter; + + private MethodProperty(JClassType beanType, JMethod setter, String getter) { super(getTransportFieldName(setter), beanType, setter .getParameterTypes()[0]); this.setter = setter; + this.getter = getter; + } + + @Override + public boolean hasAccessorMethods() { + return getter != null; } public static Collection<MethodProperty> findProperties(JClassType type) { Collection<MethodProperty> properties = new ArrayList<MethodProperty>(); - List<JMethod> setters = getSetters(type); + Set<String> getters = new HashSet<String>(); + List<JMethod> setters = getSetters(type, getters); for (JMethod setter : setters) { - properties.add(new MethodProperty(type, setter)); + String getter = findGetter(type, setter); + properties.add(new MethodProperty(setter.getEnclosingType(), + setter, getters.contains(getter) ? getter : null)); } return properties; @@ -53,9 +66,12 @@ public class MethodProperty extends Property { * * @param beanType * The type to check + * @param getters + * Set that will be filled with names of getters. * @return A list of setter methods from the class and its parents */ - private static List<JMethod> getSetters(JClassType beanType) { + private static List<JMethod> getSetters(JClassType beanType, + Set<String> getters) { List<JMethod> setterMethods = new ArrayList<JMethod>(); while (beanType != null @@ -63,13 +79,19 @@ public class MethodProperty extends Property { Object.class.getName())) { for (JMethod method : beanType.getMethods()) { // Process all setters that have corresponding fields - if (!method.isPublic() || method.isStatic() - || !method.getName().startsWith("set") - || method.getParameterTypes().length != 1) { - // Not setter, skip to next method + if (!method.isPublic() || method.isStatic()) { + // Not getter/setter, skip to next method continue; } - setterMethods.add(method); + String methodName = method.getName(); + if (methodName.startsWith("set") + && method.getParameterTypes().length == 1) { + setterMethods.add(method); + } else if (method.getParameterTypes().length == 0 + && methodName.startsWith("is") + || methodName.startsWith("get")) { + getters.add(methodName); + } } beanType = beanType.getSuperclass(); } @@ -78,34 +100,26 @@ public class MethodProperty extends Property { } @Override - public void writeSetterBody(TreeLogger logger, SourceWriter w, - String beanVariable, String valueVariable) { - w.print("(("); - w.print(getBeanType().getQualifiedSourceName()); - w.print(") "); - w.print(beanVariable); - w.print(")."); - w.print(setter.getName()); - w.print("(("); - w.print(getUnboxedPropertyTypeName()); - w.print(") "); - w.print(valueVariable); - w.println(");"); + public void writeGetterBody(TreeLogger logger, SourceWriter w, + String beanVariable) { + String value = String.format("%s.@%s::%s()()", beanVariable, + getBeanType().getQualifiedSourceName(), getter); + w.print("return "); + w.print(boxValue(value)); + w.println(";"); } @Override - public void writeGetterBody(TreeLogger logger, SourceWriter w, - String beanVariable) { - w.print("return (("); - w.print(getBeanType().getQualifiedSourceName()); - w.print(") "); - w.print(beanVariable); - w.print(")."); - w.print(findGetter(getBeanType(), setter)); - w.print("();"); + public void writeSetterBody(TreeLogger logger, SourceWriter w, + String beanVariable, String valueVariable) { + w.println("%s.@%s::%s(%s)(%s);", beanVariable, getBeanType() + .getQualifiedSourceName(), setter.getName(), setter + .getParameterTypes()[0].getJNISignature(), + unboxValue(valueVariable)); + } - private String findGetter(JClassType beanType, JMethod setterMethod) { + private static String findGetter(JClassType beanType, JMethod setterMethod) { JType setterParameterType = setterMethod.getParameterTypes()[0]; String fieldName = setterMethod.getName().substring(3); if (setterParameterType.getQualifiedSourceName().equals( diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/Property.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/Property.java index 02aad7bdf2..381af23b42 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/Property.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/Property.java @@ -53,6 +53,28 @@ public abstract class Property { } } + public String boxValue(String codeSnippet) { + JPrimitiveType primitive = propertyType.isPrimitive(); + if (primitive == null) { + return codeSnippet; + } else { + return String.format("@%s::valueOf(%s)(%s)", + primitive.getQualifiedBoxedSourceName(), + propertyType.getJNISignature(), codeSnippet); + } + } + + public String unboxValue(String codeSnippet) { + JPrimitiveType primitive = propertyType.isPrimitive(); + if (primitive == null) { + return codeSnippet; + } else { + return String.format("%s.@%s::%sValue()()", codeSnippet, + primitive.getQualifiedBoxedSourceName(), + primitive.getSimpleSourceName()); + } + } + public JClassType getBeanType() { return beanType; } @@ -63,6 +85,8 @@ public abstract class Property { public abstract void writeGetterBody(TreeLogger logger, SourceWriter w, String beanVariable); + public abstract boolean hasAccessorMethods(); + @Override public boolean equals(Object obj) { if (this == obj) { diff --git a/client/src/com/vaadin/DefaultWidgetSet.gwt.xml b/client/src/com/vaadin/DefaultWidgetSet.gwt.xml index 3aba1f6fee..2719493853 100755 --- a/client/src/com/vaadin/DefaultWidgetSet.gwt.xml +++ b/client/src/com/vaadin/DefaultWidgetSet.gwt.xml @@ -10,4 +10,8 @@ <entry-point class="com.vaadin.client.ApplicationConfiguration" /> + <!-- Since 7.2. Compile all permutations (browser support) into one Javascript + file. Speeds up compilation and does not make the Javascript significantly + larger. --> + <collapse-all-properties /> </module> diff --git a/client/src/com/vaadin/Vaadin.gwt.xml b/client/src/com/vaadin/Vaadin.gwt.xml index a1dca07a1c..d4eb454e86 100644 --- a/client/src/com/vaadin/Vaadin.gwt.xml +++ b/client/src/com/vaadin/Vaadin.gwt.xml @@ -59,6 +59,7 @@ <!-- Use the new cross site linker to get a nocache.js without document.write --> <add-linker name="xsiframe" /> + <extend-property name="user.agent" values="opera" /> <!-- Remove IE6/IE7 permutation as they are not supported --> <set-property name="user.agent" value="ie8,ie9,ie10,gecko1_8,safari,opera" /> diff --git a/client/src/com/vaadin/client/ApplicationConfiguration.java b/client/src/com/vaadin/client/ApplicationConfiguration.java index 7a70080c7e..1a5b0d836f 100644 --- a/client/src/com/vaadin/client/ApplicationConfiguration.java +++ b/client/src/com/vaadin/client/ApplicationConfiguration.java @@ -41,6 +41,7 @@ import com.vaadin.client.debug.internal.LogSection; import com.vaadin.client.debug.internal.NetworkSection; import com.vaadin.client.debug.internal.ProfilerSection; import com.vaadin.client.debug.internal.Section; +import com.vaadin.client.debug.internal.TestBenchSection; import com.vaadin.client.debug.internal.VDebugWindow; import com.vaadin.client.metadata.BundleLoadCallback; import com.vaadin.client.metadata.ConnectorBundleLoader; @@ -511,6 +512,30 @@ public class ApplicationConfiguration implements EntryPoint { } } + /** + * Returns all tags for given class. Tags are used in + * {@link ApplicationConfiguration} to keep track of different classes and + * their hierarchy + * + * @since 7.2 + * @param classname + * name of class which tags we want + * @return Integer array of tags pointing to this classname + */ + public Integer[] getTagsForServerSideClassName(String classname) { + List<Integer> tags = new ArrayList<Integer>(); + + for (Map.Entry<Integer, String> entry : tagToServerSideClassName + .entrySet()) { + if (classname.equals(entry.getValue())) { + tags.add(entry.getKey()); + } + } + + Integer[] out = new Integer[tags.size()]; + return tags.toArray(out); + } + public Integer getParentTag(int tag) { return componentInheritanceMap.get(tag); } @@ -595,6 +620,7 @@ public class ApplicationConfiguration implements EntryPoint { window.addSection((Section) GWT.create(InfoSection.class)); window.addSection((Section) GWT.create(HierarchySection.class)); window.addSection((Section) GWT.create(NetworkSection.class)); + window.addSection((Section) GWT.create(TestBenchSection.class)); if (Profiler.isEnabled()) { window.addSection((Section) GWT.create(ProfilerSection.class)); } @@ -760,5 +786,4 @@ public class ApplicationConfiguration implements EntryPoint { private static final Logger getLogger() { return Logger.getLogger(ApplicationConfiguration.class.getName()); } - } diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index a87fa3e342..3d00141aae 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -1,4 +1,4 @@ -/* +/* * Copyright 2000-2013 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -50,6 +50,7 @@ import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.http.client.URL; import com.google.gwt.json.client.JSONArray; +import com.google.gwt.json.client.JSONNumber; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; import com.google.gwt.regexp.shared.MatchResult; @@ -64,15 +65,18 @@ import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConfiguration.ErrorMessage; +import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; import com.vaadin.client.ResourceLoader.ResourceLoadEvent; import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.client.communication.Heartbeat; import com.vaadin.client.communication.JavaScriptMethodInvocation; import com.vaadin.client.communication.JsonDecoder; import com.vaadin.client.communication.JsonEncoder; import com.vaadin.client.communication.PushConnection; import com.vaadin.client.communication.RpcManager; import com.vaadin.client.communication.StateChangeEvent; +import com.vaadin.client.componentlocator.ComponentLocator; import com.vaadin.client.extensions.AbstractExtensionConnector; import com.vaadin.client.metadata.ConnectorBundleLoader; import com.vaadin.client.metadata.Method; @@ -82,6 +86,9 @@ import com.vaadin.client.metadata.Type; import com.vaadin.client.metadata.TypeData; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.AbstractConnector; +import com.vaadin.client.ui.FontIcon; +import com.vaadin.client.ui.Icon; +import com.vaadin.client.ui.ImageIcon; import com.vaadin.client.ui.VContextMenu; import com.vaadin.client.ui.VNotification; import com.vaadin.client.ui.VNotification.HideEvent; @@ -91,6 +98,7 @@ import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.client.ui.window.WindowConnector; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.ApplicationConstants; +import com.vaadin.shared.JsonConstants; import com.vaadin.shared.Version; import com.vaadin.shared.communication.LegacyChangeVariablesInvocation; import com.vaadin.shared.communication.MethodInvocation; @@ -137,10 +145,6 @@ public class ApplicationConnection { public static final String ERROR_CLASSNAME_EXT = "-error"; - public static final char VAR_BURST_SEPARATOR = '\u001d'; - - public static final char VAR_ESCAPE_CHARACTER = '\u001b'; - /** * A string that, if found in a non-JSON response to a UIDL request, will * cause the browser to refresh the page. If followed by a colon, optional @@ -271,8 +275,6 @@ public class ApplicationConnection { /** Event bus for communication events */ private EventBus eventBus = GWT.create(SimpleEventBus.class); - private int lastResponseId = -1; - /** * The communication handler methods are called at certain points during * communication with the server. This allows for making add-ons that keep @@ -366,7 +368,7 @@ public class ApplicationConnection { * * To listen for the event add a {@link ApplicationStoppedHandler} by * invoking - * {@link ApplicationConnection#addHandler(ApplicationStoppedEvent.Type, ApplicationStoppedHandler)} + * {@link ApplicationConnection#addHandler(ApplicationConnection.ApplicationStoppedEvent.Type, ApplicationStoppedHandler)} * to the {@link ApplicationConnection} * * @since 7.1.8 @@ -431,6 +433,8 @@ public class ApplicationConnection { private VLoadingIndicator loadingIndicator; + private Heartbeat heartbeat = GWT.create(Heartbeat.class); + public static class MultiStepDuration extends Duration { private int previousStep = elapsedMillis(); @@ -493,7 +497,7 @@ public class ApplicationConnection { getLoadingIndicator().show(); - scheduleHeartbeat(); + heartbeat.init(this); Window.addWindowClosingHandler(new ClosingHandler() { @Override @@ -540,44 +544,57 @@ public class ApplicationConnection { // initial UIDL provided in DOM, continue as if returned by request handleJSONText(jsonText, -1); + + // Tooltip can't be created earlier because the necessary fields are + // not setup to add it in the correct place in the DOM + getVTooltip().showAssistive(new TooltipInfo(" ")); } } private native void initializeTestbenchHooks( ComponentLocator componentLocator, String TTAppId) /*-{ - var ap = this; - var client = {}; - client.isActive = $entry(function() { - return ap.@com.vaadin.client.ApplicationConnection::hasActiveRequest()() - || ap.@com.vaadin.client.ApplicationConnection::isExecutingDeferredCommands()(); - }); - var vi = ap.@com.vaadin.client.ApplicationConnection::getVersionInfo()(); - if (vi) { - client.getVersionInfo = function() { - return vi; - } - } + var ap = this; + var client = {}; + client.isActive = $entry(function() { + return ap.@com.vaadin.client.ApplicationConnection::hasActiveRequest()() + || ap.@com.vaadin.client.ApplicationConnection::isExecutingDeferredCommands()(); + }); + var vi = ap.@com.vaadin.client.ApplicationConnection::getVersionInfo()(); + if (vi) { + client.getVersionInfo = function() { + return vi; + } + } - client.getProfilingData = $entry(function() { - var pd = [ - ap.@com.vaadin.client.ApplicationConnection::lastProcessingTime, + client.getProfilingData = $entry(function() { + var pd = [ + ap.@com.vaadin.client.ApplicationConnection::lastProcessingTime, ap.@com.vaadin.client.ApplicationConnection::totalProcessingTime - ]; - pd = pd.concat(ap.@com.vaadin.client.ApplicationConnection::serverTimingInfo); - pd[pd.length] = ap.@com.vaadin.client.ApplicationConnection::bootstrapTime; - return pd; - }); + ]; + pd = pd.concat(ap.@com.vaadin.client.ApplicationConnection::serverTimingInfo); + pd[pd.length] = ap.@com.vaadin.client.ApplicationConnection::bootstrapTime; + return pd; + }); - client.getElementByPath = $entry(function(id) { - return componentLocator.@com.vaadin.client.ComponentLocator::getElementByPath(Ljava/lang/String;)(id); - }); - client.getPathForElement = $entry(function(element) { - return componentLocator.@com.vaadin.client.ComponentLocator::getPathForElement(Lcom/google/gwt/user/client/Element;)(element); - }); - client.initializing = false; + client.getElementByPath = $entry(function(id) { + return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getElementByPath(Ljava/lang/String;)(id); + }); + client.getElementByPathStartingAt = $entry(function(id, element) { + return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getElementByPathStartingAt(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)(id, element); + }); + client.getElementsByPath = $entry(function(id) { + return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getElementsByPath(Ljava/lang/String;)(id); + }); + client.getElementsByPathStartingAt = $entry(function(id, element) { + return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getElementsByPathStartingAt(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)(id, element); + }); + client.getPathForElement = $entry(function(element) { + return componentLocator.@com.vaadin.client.componentlocator.ComponentLocator::getPathForElement(Lcom/google/gwt/user/client/Element;)(element); + }); + client.initializing = false; - $wnd.vaadin.clients[TTAppId] = client; + $wnd.vaadin.clients[TTAppId] = client; }-*/; private static native final int calculateBootstrapTime() @@ -721,7 +738,7 @@ public class ApplicationConnection { }-*/; protected void repaintAll() { - makeUidlRequest("", getRepaintAllParameters()); + makeUidlRequest(new JSONArray(), getRepaintAllParameters()); } /** @@ -752,20 +769,25 @@ public class ApplicationConnection { /** * Makes an UIDL request to the server. * - * @param requestData - * Data that is passed to the server. + * @param reqInvocations + * Data containing RPC invocations and all related information. * @param extraParams * Parameters that are added as GET parameters to the url. * Contains key=value pairs joined by & characters or is empty if * no parameters should be added. Should not start with any * special character. */ - protected void makeUidlRequest(final String requestData, + protected void makeUidlRequest(final JSONArray reqInvocations, final String extraParams) { startRequest(); - // Security: double cookie submission pattern - final String payload = getCsrfToken() + VAR_BURST_SEPARATOR - + requestData; + + JSONObject payload = new JSONObject(); + payload.put(ApplicationConstants.CSRF_TOKEN, new JSONString( + getCsrfToken())); + payload.put(ApplicationConstants.RPC_INVOCATIONS, reqInvocations); + payload.put(ApplicationConstants.SERVER_SYNC_ID, new JSONNumber( + lastSeenServerSyncId)); + VConsole.log("Making UIDL Request with params: " + payload); String uri = translateVaadinUri(ApplicationConstants.APP_PROTOCOL_PREFIX + ApplicationConstants.UIDL_PATH + '/'); @@ -789,7 +811,7 @@ public class ApplicationConnection { * @param payload * The contents of the request to send */ - protected void doUidlRequest(final String uri, final String payload) { + protected void doUidlRequest(final String uri, final JSONObject payload) { RequestCallback requestCallback = new RequestCallback() { @Override public void onError(Request request, Throwable exception) { @@ -956,14 +978,14 @@ public class ApplicationConnection { * @throws RequestException * if the request could not be sent */ - protected void doAjaxRequest(String uri, String payload, + protected void doAjaxRequest(String uri, JSONObject payload, RequestCallback requestCallback) throws RequestException { RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri); // TODO enable timeout // rb.setTimeoutMillis(timeoutMillis); // TODO this should be configurable - rb.setHeader("Content-Type", "text/plain;charset=utf-8"); - rb.setRequestData(payload); + rb.setHeader("Content-Type", JsonConstants.JSON_CONTENT_TYPE); + rb.setRequestData(payload.toString()); rb.setCallback(requestCallback); final Request request = rb.send(); @@ -1028,6 +1050,29 @@ public class ApplicationConnection { */ private ValueMap serverTimingInfo; + /** + * Holds the last seen response id given by the server. + * <p> + * The server generates a strictly increasing id for each response to each + * request from the client. This ID is then replayed back to the server on + * each request. This helps the server in knowing in what state the client + * is, and compare it to its own state. In short, it helps with concurrent + * changes between the client and server. + * <p> + * Initial value, i.e. no responses received from the server, is + * {@link #UNDEFINED_SYNC_ID} ({@value #UNDEFINED_SYNC_ID}). This happens + * between the bootstrap HTML being loaded and the first UI being rendered; + */ + private int lastSeenServerSyncId = UNDEFINED_SYNC_ID; + + /** + * The value of an undefined sync id. + * <p> + * This must be <code>-1</code>, because of the contract in + * {@link #getLastResponseId()} + */ + private static final int UNDEFINED_SYNC_ID = -1; + static final int MAX_CSS_WAITS = 100; protected void handleWhenCSSLoaded(final String jsonText, @@ -1308,7 +1353,13 @@ public class ApplicationConnection { * @return and id identifying the response */ public int getLastResponseId() { - return lastResponseId; + /* + * The discrepancy between field name and getter name is simply historic + * - API can't be changed, but the field was repurposed in a more + * general, yet compatible, use. "Response id" was deemed unsuitable a + * name, so it was called "server sync id" instead. + */ + return lastSeenServerSyncId; } protected void handleUIDLMessage(final Date start, final String jsonText, @@ -1335,6 +1386,17 @@ public class ApplicationConnection { VConsole.log("Handling message from server"); eventBus.fireEvent(new ResponseHandlingStartedEvent(this)); + if (json.containsKey(ApplicationConstants.SERVER_SYNC_ID)) { + int syncId = json.getInt(ApplicationConstants.SERVER_SYNC_ID); + + assert (lastSeenServerSyncId == UNDEFINED_SYNC_ID || syncId == lastSeenServerSyncId + 1) : "Newly retrieved server sync id was not exactly one larger than the previous one (new: " + + syncId + ", last seen: " + lastSeenServerSyncId + ")"; + + lastSeenServerSyncId = syncId; + } else { + VConsole.error("Server response didn't contain an id."); + } + // Handle redirect if (json.containsKey("redirect")) { String url = json.getValueMap("redirect").getString("url"); @@ -1343,8 +1405,6 @@ public class ApplicationConnection { return; } - lastResponseId++; - final MultiStepDuration handleUIDLDuration = new MultiStepDuration(); // Get security key @@ -2532,15 +2592,13 @@ public class ApplicationConnection { */ private void buildAndSendVariableBurst( LinkedHashMap<String, MethodInvocation> pendingInvocations) { - final StringBuffer req = new StringBuffer(); - while (!pendingInvocations.isEmpty()) { + JSONArray reqJson = new JSONArray(); + if (!pendingInvocations.isEmpty()) { if (ApplicationConfiguration.isDebugMode()) { Util.logVariableBurst(this, pendingInvocations.values()); } - JSONArray reqJson = new JSONArray(); - for (MethodInvocation invocation : pendingInvocations.values()) { JSONArray invocationJson = new JSONArray(); invocationJson.set(0, @@ -2579,9 +2637,6 @@ public class ApplicationConnection { reqJson.set(reqJson.size(), invocationJson); } - // escape burst separators (if any) - req.append(escapeBurstContents(reqJson.toString())); - pendingInvocations.clear(); // Keep tag string short lastInvocationTag = 0; @@ -2605,7 +2660,7 @@ public class ApplicationConnection { getConfiguration().setWidgetsetVersionSent(); } - makeUidlRequest(req.toString(), extraParams); + makeUidlRequest(reqJson, extraParams); } private boolean isJavascriptRpc(MethodInvocation invocation) { @@ -2849,35 +2904,6 @@ public class ApplicationConnection { } /** - * Encode burst separator characters in a String for transport over the - * network. This protects from separator injection attacks. - * - * @param value - * to encode - * @return encoded value - */ - protected String escapeBurstContents(String value) { - final StringBuilder result = new StringBuilder(); - for (int i = 0; i < value.length(); ++i) { - char character = value.charAt(i); - switch (character) { - case VAR_ESCAPE_CHARACTER: - // fall-through - escape character is duplicated - case VAR_BURST_SEPARATOR: - result.append(VAR_ESCAPE_CHARACTER); - // encode as letters for easier reading - result.append(((char) (character + 0x30))); - break; - default: - // the char is not a special one - add it to the result as is - result.append(character); - break; - } - } - return result.toString(); - } - - /** * Does absolutely nothing. Replaced by {@link LayoutManager}. * * @param container @@ -3009,6 +3035,26 @@ public class ApplicationConnection { } /** + * Gets an {@link Icon} instance corresponding to a URI. + * + * @since 7.2 + * @param uri + * @return Icon object + */ + public Icon getIcon(String uri) { + Icon icon; + if (uri == null) { + return null; + } else if (FontIcon.isFontIconUri(uri)) { + icon = GWT.create(FontIcon.class); + } else { + icon = GWT.create(ImageIcon.class); + } + icon.setUri(translateVaadinUri(uri)); + return icon; + } + + /** * Translates custom protocols in UIDL URI's to be recognizable by browser. * All uri's from UIDL should be routed via this method before giving them * to browser due URI's in UIDL may contain custom protocols like theme://. @@ -3304,20 +3350,11 @@ public class ApplicationConnection { * interval elapses if the interval is a positive number. Otherwise, does * nothing. * - * @see #sendHeartbeat() - * @see ApplicationConfiguration#getHeartbeatInterval() + * @deprecated as of 7.2, use {@link Heartbeat#schedule()} instead */ + @Deprecated protected void scheduleHeartbeat() { - final int interval = getConfiguration().getHeartbeatInterval(); - if (interval > 0) { - VConsole.log("Scheduling heartbeat in " + interval + " seconds"); - new Timer() { - @Override - public void run() { - sendHeartbeat(); - } - }.schedule(interval * 1000); - } + heartbeat.schedule(); } /** @@ -3326,51 +3363,12 @@ public class ApplicationConnection { * Heartbeat requests are used to inform the server that the client-side is * still alive. If the client page is closed or the connection lost, the * server will eventually close the inactive UI. - * <p> - * <b>TODO</b>: Improved error handling, like in doUidlRequest(). * - * @see #scheduleHeartbeat() + * @deprecated as of 7.2, use {@link Heartbeat#send()} instead */ + @Deprecated protected void sendHeartbeat() { - final String uri = addGetParameters( - translateVaadinUri(ApplicationConstants.APP_PROTOCOL_PREFIX - + ApplicationConstants.HEARTBEAT_PATH + '/'), - UIConstants.UI_ID_PARAMETER + "=" - + getConfiguration().getUIId()); - - final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri); - - final RequestCallback callback = new RequestCallback() { - - @Override - public void onResponseReceived(Request request, Response response) { - int status = response.getStatusCode(); - if (status == Response.SC_OK) { - // TODO Permit retry in some error situations - VConsole.log("Heartbeat response OK"); - scheduleHeartbeat(); - } else if (status == Response.SC_GONE) { - showSessionExpiredError(null); - } else { - VConsole.error("Failed sending heartbeat to server. Error code: " - + status); - } - } - - @Override - public void onError(Request request, Throwable exception) { - VConsole.error("Exception sending heartbeat: " + exception); - } - }; - - rb.setCallback(callback); - - try { - VConsole.log("Sending heartbeat request..."); - rb.send(); - } catch (RequestException re) { - callback.onError(null, re); - } + heartbeat.send(); } /** diff --git a/client/src/com/vaadin/client/ComponentLocator.java b/client/src/com/vaadin/client/ComponentLocator.java index af934470c2..f30528c0c0 100644 --- a/client/src/com/vaadin/client/ComponentLocator.java +++ b/client/src/com/vaadin/client/ComponentLocator.java @@ -15,706 +15,22 @@ */ package com.vaadin.client; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.Element; -import com.google.gwt.user.client.ui.HasWidgets; -import com.google.gwt.user.client.ui.RootPanel; -import com.google.gwt.user.client.ui.Widget; -import com.vaadin.client.ui.SubPartAware; -import com.vaadin.client.ui.VCssLayout; -import com.vaadin.client.ui.VGridLayout; -import com.vaadin.client.ui.VOverlay; -import com.vaadin.client.ui.VTabsheetPanel; -import com.vaadin.client.ui.VUI; -import com.vaadin.client.ui.VWindow; -import com.vaadin.client.ui.orderedlayout.Slot; -import com.vaadin.client.ui.orderedlayout.VAbstractOrderedLayout; -import com.vaadin.client.ui.window.WindowConnector; -import com.vaadin.shared.AbstractComponentState; -import com.vaadin.shared.Connector; -import com.vaadin.shared.communication.SharedState; - /** * ComponentLocator provides methods for generating a String locator for a given * DOM element and for locating a DOM element using a String locator. + * + * @since 5.4 + * @deprecated Moved to com.vaadin.client.componentlocator.ComponentLocator */ -public class ComponentLocator { - - /** - * Separator used in the String locator between a parent and a child widget. - */ - private static final String PARENTCHILD_SEPARATOR = "/"; - - /** - * Separator used in the String locator between the part identifying the - * containing widget and the part identifying the target element within the - * widget. - */ - private static final String SUBPART_SEPARATOR = "#"; - - /** - * String that identifies the root panel when appearing first in the String - * locator. - */ - private static final String ROOT_ID = "Root"; - - /** - * Reference to ApplicationConnection instance. - */ - private ApplicationConnection client; - +public class ComponentLocator extends + com.vaadin.client.componentlocator.ComponentLocator { /** * Construct a ComponentLocator for the given ApplicationConnection. - * + * * @param client * ApplicationConnection instance for the application. */ public ComponentLocator(ApplicationConnection client) { - this.client = client; - } - - /** - * Generates a String locator which uniquely identifies the target element. - * The {@link #getElementByPath(String)} method can be used for the inverse - * operation, i.e. locating an element based on the return value from this - * method. - * <p> - * Note that getElementByPath(getPathForElement(element)) == element is not - * always true as {@link #getPathForElement(Element)} can return a path to - * another element if the widget determines an action on the other element - * will give the same result as the action on the target element. - * </p> - * - * @since 5.4 - * @param targetElement - * The element to generate a path for. - * @return A String locator that identifies the target element or null if a - * String locator could not be created. - */ - public String getPathForElement(Element targetElement) { - String pid = null; - - targetElement = getElement(targetElement); - - Element e = targetElement; - - while (true) { - pid = ConnectorMap.get(client).getConnectorId(e); - if (pid != null) { - break; - } - - e = DOM.getParent(e); - if (e == null) { - break; - } - } - - Widget w = null; - if (pid != null) { - // If we found a Paintable then we use that as reference. We should - // find the Paintable for all but very special cases (like - // overlays). - w = ((ComponentConnector) ConnectorMap.get(client) - .getConnector(pid)).getWidget(); - - /* - * Still if the Paintable contains a widget that implements - * SubPartAware, we want to use that as a reference - */ - Widget targetParent = findParentWidget(targetElement, w); - while (targetParent != w && targetParent != null) { - if (targetParent instanceof SubPartAware) { - /* - * The targetParent widget is a child of the Paintable and - * the first parent (of the targetElement) that implements - * SubPartAware - */ - w = targetParent; - break; - } - targetParent = targetParent.getParent(); - } - } - if (w == null) { - // Check if the element is part of a widget that is attached - // directly to the root panel - RootPanel rootPanel = RootPanel.get(); - int rootWidgetCount = rootPanel.getWidgetCount(); - for (int i = 0; i < rootWidgetCount; i++) { - Widget rootWidget = rootPanel.getWidget(i); - if (rootWidget.getElement().isOrHasChild(targetElement)) { - // The target element is contained by this root widget - w = findParentWidget(targetElement, rootWidget); - break; - } - } - if (w != null) { - // We found a widget but we should still see if we find a - // SubPartAware implementor (we cannot find the Paintable as - // there is no link from VOverlay to its paintable/owner). - Widget subPartAwareWidget = findSubPartAwareParentWidget(w); - if (subPartAwareWidget != null) { - w = subPartAwareWidget; - } - } - } - - if (w == null) { - // Containing widget not found - return null; - } - - // Determine the path for the target widget - String path = getPathForWidget(w); - if (path == null) { - /* - * No path could be determined for the target widget. Cannot create - * a locator string. - */ - return null; - } - - // The parent check is a work around for Firefox 15 which fails to - // compare elements properly (#9534) - if (w.getElement() == targetElement) { - /* - * We are done if the target element is the root of the target - * widget. - */ - return path; - } else if (w instanceof SubPartAware) { - /* - * If the widget can provide an identifier for the targetElement we - * let it do that - */ - String elementLocator = ((SubPartAware) w) - .getSubPartName(targetElement); - if (elementLocator != null) { - return path + SUBPART_SEPARATOR + elementLocator; - } - } - /* - * If everything else fails we use the DOM path to identify the target - * element - */ - String domPath = getDOMPathForElement(targetElement, w.getElement()); - if (domPath == null) { - return path; - } else { - return path + domPath; - } - } - - /** - * Returns the element passed to the method. Or in case of Firefox 15, - * returns the real element that is in the DOM instead of the element passed - * to the method (which is the same element but not ==). - * - * @param targetElement - * the element to return - * @return the element passed to the method - */ - private Element getElement(Element targetElement) { - if (targetElement == null) { - return null; - } - - if (!BrowserInfo.get().isFirefox()) { - return targetElement; - } - - if (BrowserInfo.get().getBrowserMajorVersion() != 15) { - return targetElement; - } - - // Firefox 15, you make me sad - if (targetElement.getNextSibling() != null) { - return (Element) targetElement.getNextSibling() - .getPreviousSibling(); - } - if (targetElement.getPreviousSibling() != null) { - return (Element) targetElement.getPreviousSibling() - .getNextSibling(); - } - // No siblings so this is the only child - return (Element) targetElement.getParentNode().getChild(0); - } - - /** - * Finds the first widget in the hierarchy (moving upwards) that implements - * SubPartAware. Returns the SubPartAware implementor or null if none is - * found. - * - * @param w - * The widget to start from. This is returned if it implements - * SubPartAware. - * @return The first widget (upwards in hierarchy) that implements - * SubPartAware or null - */ - private Widget findSubPartAwareParentWidget(Widget w) { - - while (w != null) { - if (w instanceof SubPartAware) { - return w; - } - w = w.getParent(); - } - return null; - } - - /** - * Returns the first widget found when going from {@code targetElement} - * upwards in the DOM hierarchy, assuming that {@code ancestorWidget} is a - * parent of {@code targetElement}. - * - * @param targetElement - * @param ancestorWidget - * @return The widget whose root element is a parent of - * {@code targetElement}. - */ - private Widget findParentWidget(Element targetElement, Widget ancestorWidget) { - /* - * As we cannot resolve Widgets from the element we start from the - * widget and move downwards to the correct child widget, as long as we - * find one. - */ - if (ancestorWidget instanceof HasWidgets) { - for (Widget w : ((HasWidgets) ancestorWidget)) { - if (w.getElement().isOrHasChild(targetElement)) { - return findParentWidget(targetElement, w); - } - } - } - - // No children found, this is it - return ancestorWidget; - } - - /** - * Locates an element based on a DOM path and a base element. - * - * @param baseElement - * The base element which the path is relative to - * @param path - * String locator (consisting of domChild[x] parts) that - * identifies the element - * @return The element identified by path, relative to baseElement or null - * if the element could not be found. - */ - private Element getElementByDOMPath(Element baseElement, String path) { - String parts[] = path.split(PARENTCHILD_SEPARATOR); - Element element = baseElement; - - for (String part : parts) { - if (part.startsWith("domChild[")) { - String childIndexString = part.substring("domChild[".length(), - part.length() - 1); - - if (Util.findWidget(baseElement, null) instanceof VAbstractOrderedLayout) { - if (element.hasChildNodes()) { - Element e = element.getFirstChildElement().cast(); - String cn = e.getClassName(); - if (cn != null - && (cn.equals("v-expand") || cn - .contains("v-has-caption"))) { - element = e; - } - } - } - - try { - int childIndex = Integer.parseInt(childIndexString); - element = DOM.getChild(element, childIndex); - } catch (Exception e) { - return null; - } - - if (element == null) { - return null; - } - - } - } - - return element; + super(client); } - - /** - * Generates a String locator using domChild[x] parts for the element - * relative to the baseElement. - * - * @param element - * The target element - * @param baseElement - * The starting point for the locator. The generated path is - * relative to this element. - * @return A String locator that can be used to locate the target element - * using {@link #getElementByDOMPath(Element, String)} or null if - * the locator String cannot be created. - */ - private String getDOMPathForElement(Element element, Element baseElement) { - Element e = element; - String path = ""; - while (true) { - int childIndex = -1; - Element siblingIterator = e; - while (siblingIterator != null) { - childIndex++; - siblingIterator = siblingIterator.getPreviousSiblingElement() - .cast(); - } - - path = PARENTCHILD_SEPARATOR + "domChild[" + childIndex + "]" - + path; - - JavaScriptObject parent = e.getParentElement(); - if (parent == null) { - return null; - } - // The parent check is a work around for Firefox 15 which fails to - // compare elements properly (#9534) - if (parent == baseElement) { - break; - } - - e = parent.cast(); - } - - return path; - } - - /** - * Locates an element using a String locator (path) which identifies a DOM - * element. The {@link #getPathForElement(Element)} method can be used for - * the inverse operation, i.e. generating a string expression for a DOM - * element. - * - * @since 5.4 - * @param path - * The String locater which identifies the target element. - * @return The DOM element identified by {@code path} or null if the element - * could not be located. - */ - public Element getElementByPath(String path) { - /* - * Path is of type "targetWidgetPath#componentPart" or - * "targetWidgetPath". - */ - String parts[] = path.split(SUBPART_SEPARATOR, 2); - String widgetPath = parts[0]; - Widget w = getWidgetFromPath(widgetPath); - if (w == null || !Util.isAttachedAndDisplayed(w)) { - return null; - } - - if (parts.length == 1) { - int pos = widgetPath.indexOf("domChild"); - if (pos == -1) { - return w.getElement(); - } - - // Contains dom reference to a sub element of the widget - String subPath = widgetPath.substring(pos); - return getElementByDOMPath(w.getElement(), subPath); - } else if (parts.length == 2) { - if (w instanceof SubPartAware) { - return ((SubPartAware) w).getSubPartElement(parts[1]); - } - } - - return null; - } - - /** - * Creates a locator String for the given widget. The path can be used to - * locate the widget using {@link #getWidgetFromPath(String)}. - * - * Returns null if no path can be determined for the widget or if the widget - * is null. - * - * @param w - * The target widget - * @return A String locator for the widget - */ - private String getPathForWidget(Widget w) { - if (w == null) { - return null; - } - String elementId = w.getElement().getId(); - if (elementId != null && !elementId.isEmpty() - && !elementId.startsWith("gwt-uid-")) { - // Use PID_S+id if the user has set an id but do not use it for auto - // generated id:s as these might not be consistent - return "PID_S" + elementId; - } else if (w instanceof VUI) { - return ""; - } else if (w instanceof VWindow) { - Connector windowConnector = ConnectorMap.get(client) - .getConnector(w); - List<WindowConnector> subWindowList = client.getUIConnector() - .getSubWindows(); - int indexOfSubWindow = subWindowList.indexOf(windowConnector); - return PARENTCHILD_SEPARATOR + "VWindow[" + indexOfSubWindow + "]"; - } else if (w instanceof RootPanel) { - return ROOT_ID; - } - - Widget parent = w.getParent(); - - String basePath = getPathForWidget(parent); - if (basePath == null) { - return null; - } - String simpleName = Util.getSimpleName(w); - - /* - * Check if the parent implements Iterable. At least VPopupView does not - * implement HasWdgets so we cannot check for that. - */ - if (!(parent instanceof Iterable<?>)) { - // Parent does not implement Iterable so we cannot find out which - // child this is - return null; - } - - Iterator<?> i = ((Iterable<?>) parent).iterator(); - int pos = 0; - while (i.hasNext()) { - Object child = i.next(); - if (child == w) { - return basePath + PARENTCHILD_SEPARATOR + simpleName + "[" - + pos + "]"; - } - String simpleName2 = Util.getSimpleName(child); - if (simpleName.equals(simpleName2)) { - pos++; - } - } - - return null; - } - - /** - * Locates the widget based on a String locator. - * - * @param path - * The String locator that identifies the widget. - * @return The Widget identified by the String locator or null if the widget - * could not be identified. - */ - private Widget getWidgetFromPath(String path) { - Widget w = null; - String parts[] = path.split(PARENTCHILD_SEPARATOR); - - for (int i = 0; i < parts.length; i++) { - String part = parts[i]; - - if (part.equals(ROOT_ID)) { - w = RootPanel.get(); - } else if (part.equals("")) { - w = client.getUIConnector().getWidget(); - } else if (w == null) { - String id = part; - // Must be old static pid (PID_S*) - ServerConnector connector = ConnectorMap.get(client) - .getConnector(id); - if (connector == null) { - // Lookup by component id - // TODO Optimize this - connector = findConnectorById(client.getUIConnector(), - id.substring(5)); - } - - if (connector instanceof ComponentConnector) { - w = ((ComponentConnector) connector).getWidget(); - } else { - // Not found - return null; - } - } else if (part.startsWith("domChild[")) { - // The target widget has been found and the rest identifies the - // element - break; - } else if (w instanceof Iterable) { - // W identifies a widget that contains other widgets, as it - // should. Try to locate the child - Iterable<?> parent = (Iterable<?>) w; - - // Part is of type "VVerticalLayout[0]", split this into - // VVerticalLayout and 0 - String[] split = part.split("\\[", 2); - String widgetClassName = split[0]; - String indexString = split[1].substring(0, - split[1].length() - 1); - int widgetPosition = Integer.parseInt(indexString); - - // AbsolutePanel in GridLayout has been removed -> skip it - if (w instanceof VGridLayout - && "AbsolutePanel".equals(widgetClassName)) { - continue; - } - - // FlowPane in CSSLayout has been removed -> skip it - if (w instanceof VCssLayout - && "VCssLayout$FlowPane".equals(widgetClassName)) { - continue; - } - - // ChildComponentContainer and VOrderedLayout$Slot have been - // replaced with Slot - if (w instanceof VAbstractOrderedLayout - && ("ChildComponentContainer".equals(widgetClassName) || "VOrderedLayout$Slot" - .equals(widgetClassName))) { - widgetClassName = "Slot"; - } - - if (w instanceof VTabsheetPanel && widgetPosition != 0) { - // TabSheetPanel now only contains 1 connector => the index - // is always 0 which indicates the widget in the active tab - widgetPosition = 0; - } - if (w instanceof VOverlay - && "VCalendarPanel".equals(widgetClassName)) { - // Vaadin 7.1 adds a wrapper for datefield popups - parent = (Iterable<?>) ((Iterable) parent).iterator() - .next(); - } - /* - * The new grid and ordered layotus do not contain - * ChildComponentContainer widgets. This is instead simulated by - * constructing a path step that would find the desired widget - * from the layout and injecting it as the next search step - * (which would originally have found the widget inside the - * ChildComponentContainer) - */ - if ((w instanceof VGridLayout) - && "ChildComponentContainer".equals(widgetClassName) - && i + 1 < parts.length) { - - HasWidgets layout = (HasWidgets) w; - - String nextPart = parts[i + 1]; - String[] nextSplit = nextPart.split("\\[", 2); - String nextWidgetClassName = nextSplit[0]; - - // Find the n:th child and count the number of children with - // the same type before it - int nextIndex = 0; - for (Widget child : layout) { - boolean matchingType = nextWidgetClassName.equals(Util - .getSimpleName(child)); - if (matchingType && widgetPosition == 0) { - // This is the n:th child that we looked for - break; - } else if (widgetPosition < 0) { - // Error if we're past the desired position without - // a match - return null; - } else if (matchingType) { - // If this was another child of the expected type, - // increase the count for the next step - nextIndex++; - } - - // Don't count captions - if (!(child instanceof VCaption)) { - widgetPosition--; - } - } - - // Advance to the next step, this time checking for the - // actual child widget - parts[i + 1] = nextWidgetClassName + '[' + nextIndex + ']'; - continue; - } - - // Locate the child - Iterator<? extends Widget> iterator; - - /* - * VWindow and VContextMenu workarounds for backwards - * compatibility - */ - if (widgetClassName.equals("VWindow")) { - List<WindowConnector> windows = client.getUIConnector() - .getSubWindows(); - List<VWindow> windowWidgets = new ArrayList<VWindow>( - windows.size()); - for (WindowConnector wc : windows) { - windowWidgets.add(wc.getWidget()); - } - iterator = windowWidgets.iterator(); - } else if (widgetClassName.equals("VContextMenu")) { - return client.getContextMenu(); - } else { - iterator = (Iterator<? extends Widget>) parent.iterator(); - } - - boolean ok = false; - - // Find the widgetPosition:th child of type "widgetClassName" - while (iterator.hasNext()) { - - Widget child = iterator.next(); - String simpleName2 = Util.getSimpleName(child); - - if (!widgetClassName.equals(simpleName2) - && child instanceof Slot) { - /* - * Support legacy tests without any selector for the - * Slot widget (i.e. /VVerticalLayout[0]/VButton[0]) by - * directly checking the stuff inside the slot - */ - child = ((Slot) child).getWidget(); - simpleName2 = Util.getSimpleName(child); - } - - if (widgetClassName.equals(simpleName2)) { - if (widgetPosition == 0) { - w = child; - ok = true; - break; - } - widgetPosition--; - - } - } - - if (!ok) { - // Did not find the child - return null; - } - } else { - // W identifies something that is not a "HasWidgets". This - // should not happen as all widget containers should implement - // HasWidgets. - return null; - } - } - - return w; - } - - private ServerConnector findConnectorById(ServerConnector root, String id) { - SharedState state = root.getState(); - if (state instanceof AbstractComponentState - && id.equals(((AbstractComponentState) state).id)) { - return root; - } - for (ServerConnector child : root.getChildren()) { - ServerConnector found = findConnectorById(child, id); - if (found != null) { - return found; - } - } - - return null; - } - } diff --git a/client/src/com/vaadin/client/ConnectorMap.java b/client/src/com/vaadin/client/ConnectorMap.java index 810f12824a..c2f1eda21d 100644 --- a/client/src/com/vaadin/client/ConnectorMap.java +++ b/client/src/com/vaadin/client/ConnectorMap.java @@ -116,7 +116,7 @@ public class ConnectorMap { * no connector was found */ public ComponentConnector getConnector(Widget widget) { - return getConnector(widget.getElement()); + return widget == null ? null : getConnector(widget.getElement()); } public void registerConnector(String id, ServerConnector connector) { diff --git a/client/src/com/vaadin/client/LayoutManager.java b/client/src/com/vaadin/client/LayoutManager.java index 1ced003146..4fb656b16d 100644 --- a/client/src/com/vaadin/client/LayoutManager.java +++ b/client/src/com/vaadin/client/LayoutManager.java @@ -1029,6 +1029,98 @@ public class LayoutManager { } /** + * Gets the top border of the given element, provided that it has been + * measured. These elements are guaranteed to be measured: + * <ul> + * <li>ManagedLayotus and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * A negative number is returned if the element has not been measured. If 0 + * is returned, it might indicate that the element is not attached to the + * DOM. + * + * @param element + * the element to get the measured size for + * @return the measured top border of the element in pixels. + */ + public int getBorderTop(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return getMeasuredSize(element, nullSize).getBorderTop(); + } + + /** + * Gets the left border of the given element, provided that it has been + * measured. These elements are guaranteed to be measured: + * <ul> + * <li>ManagedLayotus and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * A negative number is returned if the element has not been measured. If 0 + * is returned, it might indicate that the element is not attached to the + * DOM. + * + * @param element + * the element to get the measured size for + * @return the measured left border of the element in pixels. + */ + public int getBorderLeft(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return getMeasuredSize(element, nullSize).getBorderLeft(); + } + + /** + * Gets the bottom border of the given element, provided that it has been + * measured. These elements are guaranteed to be measured: + * <ul> + * <li>ManagedLayotus and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * A negative number is returned if the element has not been measured. If 0 + * is returned, it might indicate that the element is not attached to the + * DOM. + * + * @param element + * the element to get the measured size for + * @return the measured bottom border of the element in pixels. + */ + public int getBorderBottom(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return getMeasuredSize(element, nullSize).getBorderBottom(); + } + + /** + * Gets the right border of the given element, provided that it has been + * measured. These elements are guaranteed to be measured: + * <ul> + * <li>ManagedLayotus and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * A negative number is returned if the element has not been measured. If 0 + * is returned, it might indicate that the element is not attached to the + * DOM. + * + * @param element + * the element to get the measured size for + * @return the measured right border of the element in pixels. + */ + public int getBorderRight(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return getMeasuredSize(element, nullSize).getBorderRight(); + } + + /** * Gets the padding width (left padding + right padding) of the given * element, provided that it has been measured. These elements are * guaranteed to be measured: @@ -1449,10 +1541,15 @@ public class LayoutManager { /** * Informs this LayoutManager that the size of a component might have - * changed. If there is no upcoming layout phase, a new layout phase is - * scheduled. This method should be used whenever a size might have changed - * from outside of Vaadin's normal update phase, e.g. when an icon has been - * loaded or when the user resizes some part of the UI using the mouse. + * changed. This method should be used whenever the size of an individual + * component might have changed from outside of Vaadin's normal update + * phase, e.g. when an icon has been loaded or when the user resizes some + * part of the UI using the mouse. + * <p> + * To set an entire component hierarchy to be measured, use + * {@link #setNeedsMeasureRecursively(ComponentConnector)} instead. + * <p> + * If there is no upcoming layout phase, a new layout phase is scheduled. * * @param component * the component whose size might have changed. @@ -1466,6 +1563,33 @@ public class LayoutManager { } } + /** + * Informs this LayoutManager that some sizes in a component hierarchy might + * have changed. This method should be used whenever the size of any child + * component might have changed from outside of Vaadin's normal update + * phase, e.g. when a CSS class name related to sizing has been changed. + * <p> + * To set a single component to be measured, use + * {@link #setNeedsMeasure(ComponentConnector)} instead. + * <p> + * If there is no upcoming layout phase, a new layout phase is scheduled. + * + * @since 7.2 + * @param component + * the component at the root of the component hierarchy to + * measure + */ + public void setNeedsMeasureRecursively(ComponentConnector component) { + setNeedsMeasure(component); + + if (component instanceof HasComponentsConnector) { + HasComponentsConnector hasComponents = (HasComponentsConnector) component; + for (ComponentConnector child : hasComponents.getChildComponents()) { + setNeedsMeasureRecursively(child); + } + } + } + public void setEverythingNeedsMeasure() { everythingNeedsMeasure = true; } diff --git a/client/src/com/vaadin/client/Profiler.java b/client/src/com/vaadin/client/Profiler.java index 083f2559b1..cfce59b08b 100644 --- a/client/src/com/vaadin/client/Profiler.java +++ b/client/src/com/vaadin/client/Profiler.java @@ -297,10 +297,6 @@ public class Profiler { if (isEnabled()) { double now = Duration.currentTimeMillis(); - StringBuilder stringBuilder = new StringBuilder( - "Time since window.performance.timing events"); - SimpleTree tree = new SimpleTree(stringBuilder.toString()); - String[] keys = new String[] { "navigationStart", "unloadEventStart", "unloadEventEnd", "redirectStart", "redirectEnd", "fetchStart", "domainLookupStart", diff --git a/client/src/com/vaadin/client/SimpleTree.java b/client/src/com/vaadin/client/SimpleTree.java index 7370496cb8..edfa23fb13 100644 --- a/client/src/com/vaadin/client/SimpleTree.java +++ b/client/src/com/vaadin/client/SimpleTree.java @@ -116,6 +116,14 @@ public class SimpleTree extends ComplexPanel implements HasDoubleClickHandlers { } } + public boolean isOpen() { + return "-".equals(handle.getInnerHTML()); + } + + public String getCaption() { + return text.getInnerText(); + } + public SimpleTree(String caption) { this(); setText(caption); diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index aae3dd5458..7cf8338171 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -855,6 +855,7 @@ public class Util { * @param class1 * the Widget type to seek for */ + @SuppressWarnings("unchecked") public static <T> T findWidget(Element element, Class<? extends Widget> class1) { if (element != null) { diff --git a/client/src/com/vaadin/client/VCaption.java b/client/src/com/vaadin/client/VCaption.java index d0338de4a1..e11082cf47 100644 --- a/client/src/com/vaadin/client/VCaption.java +++ b/client/src/com/vaadin/client/VCaption.java @@ -24,6 +24,7 @@ import com.google.gwt.user.client.ui.HTML; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.Icon; +import com.vaadin.client.ui.ImageIcon; import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.AbstractFieldState; @@ -42,6 +43,8 @@ public class VCaption extends HTML { private Icon icon; + private String iconAltText = ""; + private Element captionText; private final ApplicationConnection client; @@ -104,6 +107,7 @@ public class VCaption extends HTML { if (null != owner) { AriaHelper.bindCaption(owner.getWidget(), getElement()); } + } @Override @@ -112,6 +116,8 @@ public class VCaption extends HTML { if (null != owner) { AriaHelper.bindCaption(owner.getWidget(), null); + AriaHelper.handleInputInvalid(owner.getWidget(), false); + AriaHelper.handleInputRequired(owner.getWidget(), false); } } @@ -155,25 +161,27 @@ public class VCaption extends HTML { showRequired = ((AbstractFieldConnector) owner).isRequired(); } + if (icon != null) { + getElement().removeChild(icon.getElement()); + icon = null; + } if (hasIcon) { - if (icon == null) { - icon = new Icon(client); + String uri = owner.getState().resources.get( + ComponentConstants.ICON_RESOURCE).getURL(); + + icon = client.getIcon(uri); + + if (icon instanceof ImageIcon) { + // onload will set appropriate size later icon.setWidth("0"); icon.setHeight("0"); - - DOM.insertChild(getElement(), icon.getElement(), - getInsertPosition(InsertPosition.ICON)); } - // Icon forces the caption to be above the component - placedAfterComponent = false; - icon.setUri(owner.getState().resources.get( - ComponentConstants.ICON_RESOURCE).getURL()); + DOM.insertChild(getElement(), icon.getElement(), + getInsertPosition(InsertPosition.ICON)); - } else if (icon != null) { - // Remove existing - DOM.removeChild(getElement(), icon.getElement()); - icon = null; + // Icon forces the caption to be above the component + placedAfterComponent = false; } if (owner.getState().caption != null) { @@ -300,6 +308,14 @@ public class VCaption extends HTML { @Deprecated public boolean updateCaptionWithoutOwner(String caption, boolean disabled, boolean hasDescription, boolean hasError, String iconURL) { + return updateCaptionWithoutOwner(caption, disabled, hasDescription, + hasError, iconURL, ""); + } + + @Deprecated + public boolean updateCaptionWithoutOwner(String caption, boolean disabled, + boolean hasDescription, boolean hasError, String iconURL, + String iconAltText) { boolean wasPlacedAfterComponent = placedAfterComponent; // Caption is placed after component unless there is some part which @@ -320,24 +336,24 @@ public class VCaption extends HTML { } boolean hasIcon = iconURL != null; + if (icon != null) { + getElement().removeChild(icon.getElement()); + icon = null; + } if (hasIcon) { - if (icon == null) { - icon = new Icon(client); + icon = client.getIcon(iconURL); + if (icon instanceof ImageIcon) { + // onload sets appropriate size later icon.setWidth("0"); icon.setHeight("0"); - - DOM.insertChild(getElement(), icon.getElement(), - getInsertPosition(InsertPosition.ICON)); } + icon.setAlternateText(iconAltText); + DOM.insertChild(getElement(), icon.getElement(), + getInsertPosition(InsertPosition.ICON)); + // Icon forces the caption to be above the component placedAfterComponent = false; - icon.setUri(iconURL); - - } else if (icon != null) { - // Remove existing - DOM.removeChild(getElement(), icon.getElement()); - icon = null; } if (caption != null) { diff --git a/client/src/com/vaadin/client/VErrorMessage.java b/client/src/com/vaadin/client/VErrorMessage.java index 2e42b98a05..a384b451dd 100644 --- a/client/src/com/vaadin/client/VErrorMessage.java +++ b/client/src/com/vaadin/client/VErrorMessage.java @@ -31,9 +31,6 @@ public class VErrorMessage extends FlowPanel { public VErrorMessage() { super(); setStyleName(CLASSNAME); - - // Needed for binding with WAI-ARIA attributes - getElement().setId(DOM.createUniqueId()); } /** diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java index 6191821988..e5c2ba117a 100644 --- a/client/src/com/vaadin/client/VTooltip.java +++ b/client/src/com/vaadin/client/VTooltip.java @@ -15,7 +15,8 @@ */ package com.vaadin.client; -import com.google.gwt.aria.client.Id; +import com.google.gwt.aria.client.LiveValue; +import com.google.gwt.aria.client.RelevantValue; import com.google.gwt.aria.client.Roles; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; @@ -36,12 +37,12 @@ import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; -import com.vaadin.client.ui.VOverlay; +import com.vaadin.client.ui.VWindowOverlay; /** * TODO open for extension */ -public class VTooltip extends VOverlay { +public class VTooltip extends VWindowOverlay { private static final String CLASSNAME = "v-tooltip"; private static final int MARGIN = 4; public static final int TOOLTIP_EVENTS = Event.ONKEYDOWN @@ -57,7 +58,6 @@ public class VTooltip extends VOverlay { private boolean justClosed = false; private String uniqueId = DOM.createUniqueId(); - private Element layoutElement; private int maxWidth; // Delays for the tooltip, configurable on the server side @@ -80,17 +80,28 @@ public class VTooltip extends VOverlay { setWidget(layout); layout.add(em); DOM.setElementProperty(description, "className", CLASSNAME + "-text"); - - layoutElement = layout.getElement(); - DOM.appendChild(layoutElement, description); + DOM.appendChild(layout.getElement(), description); setSinkShadowEvents(true); - // Used to bind the tooltip to the owner for assistive devices - layoutElement.setId(uniqueId); + // When a tooltip is shown, the content of the tooltip changes. With a + // tooltip being a live-area, this change is notified to a assistive + // device. + Roles.getTooltipRole().set(getElement()); + Roles.getTooltipRole().setAriaLiveProperty(getElement(), + LiveValue.ASSERTIVE); + Roles.getTooltipRole().setAriaRelevantProperty(getElement(), + RelevantValue.ADDITIONS); + } - description.setId(DOM.createUniqueId()); - Roles.getTooltipRole().set(layoutElement); - Roles.getTooltipRole().setAriaHiddenState(layoutElement, true); + /** + * Show the tooltip with the provided info for assistive devices. + * + * @param info + * with the content of the tooltip + */ + public void showAssistive(TooltipInfo info) { + updatePosition(null, true); + show(info); } /** @@ -229,10 +240,11 @@ public class VTooltip extends VOverlay { @Override public void hide() { - super.hide(); - Roles.getTooltipRole().setAriaHiddenState(layoutElement, true); - Roles.getTooltipRole().removeAriaDescribedbyProperty( - tooltipEventHandler.currentElement); + em.updateMessage(""); + description.setInnerHTML(""); + + updatePosition(null, true); + setPopupPosition(tooltipEventMouseX, tooltipEventMouseY); } private int tooltipEventMouseX; @@ -287,9 +299,9 @@ public class VTooltip extends VOverlay { private com.google.gwt.dom.client.Element currentElement = null; /** - * Current element focused + * Marker for handling of tooltip through focus */ - private boolean currentIsFocused; + private boolean handledByFocus; /** * Current tooltip active @@ -392,6 +404,7 @@ public class VTooltip extends VOverlay { */ @Override public void onBlur(BlurEvent be) { + handledByFocus = false; handleHideEvent(); } @@ -401,7 +414,7 @@ public class VTooltip extends VOverlay { .getEventTarget()); // We can ignore move event if it's handled by move or over already - if (currentElement == element && currentIsFocused == isFocused) { + if (currentElement == element && handledByFocus == true) { return; } @@ -409,27 +422,20 @@ public class VTooltip extends VOverlay { if (!connectorAndTooltipFound) { if (isShowing()) { handleHideEvent(); - Roles.getButtonRole() - .removeAriaDescribedbyProperty(element); } else { currentTooltipInfo = null; } } else { updatePosition(event, isFocused); - if (isShowing()) { + if (isShowing() && !isFocused) { replaceCurrentTooltip(); - Roles.getTooltipRole().removeAriaDescribedbyProperty( - currentElement); } else { showTooltip(); } - - Roles.getTooltipRole().setAriaDescribedbyProperty(element, - Id.of(uniqueId)); } - currentIsFocused = isFocused; + handledByFocus = isFocused; currentElement = element; } } @@ -464,9 +470,11 @@ public class VTooltip extends VOverlay { @Override public void setPopupPositionAndShow(PositionCallback callback) { - super.setPopupPositionAndShow(callback); - - Roles.getTooltipRole().setAriaHiddenState(layoutElement, false); + if (isAttached()) { + callback.setPosition(getOffsetWidth(), getOffsetHeight()); + } else { + super.setPopupPositionAndShow(callback); + } } /** diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java index f9bff8199e..f9ef537830 100644 --- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java +++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.Scheduler; +import com.google.gwt.json.client.JSONObject; import com.google.gwt.user.client.Command; import com.vaadin.client.ApplicationConfiguration; import com.vaadin.client.ApplicationConnection; @@ -110,7 +111,7 @@ public class AtmospherePushConnection implements PushConnection { private JavaScriptObject socket; - private ArrayList<String> messageQueue = new ArrayList<String>(); + private ArrayList<JSONObject> messageQueue = new ArrayList<JSONObject>(); private State state = State.CONNECT_PENDING; @@ -191,14 +192,8 @@ public class AtmospherePushConnection implements PushConnection { } } - /* - * (non-Javadoc) - * - * @see - * com.vaadin.client.communication.PushConenction#push(java.lang.String) - */ @Override - public void push(String message) { + public void push(JSONObject message) { switch (state) { case CONNECT_PENDING: assert isActive(); @@ -210,12 +205,13 @@ public class AtmospherePushConnection implements PushConnection { VConsole.log("Sending push message: " + message); if (transport.equals("websocket")) { - FragmentedMessage fragmented = new FragmentedMessage(message); + FragmentedMessage fragmented = new FragmentedMessage( + message.toString()); while (fragmented.hasNextFragment()) { doPush(socket, fragmented.getNextFragment()); } } else { - doPush(socket, message); + doPush(socket, message.toString()); } break; case DISCONNECT_PENDING: @@ -254,7 +250,7 @@ public class AtmospherePushConnection implements PushConnection { switch (state) { case CONNECT_PENDING: state = State.CONNECTED; - for (String message : messageQueue) { + for (JSONObject message : messageQueue) { push(message); } messageQueue.clear(); diff --git a/client/src/com/vaadin/client/communication/Date_Serializer.java b/client/src/com/vaadin/client/communication/Date_Serializer.java new file mode 100644 index 0000000000..c6eb7af188 --- /dev/null +++ b/client/src/com/vaadin/client/communication/Date_Serializer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.communication; + +import java.util.Date; + +import com.google.gwt.json.client.JSONNumber; +import com.google.gwt.json.client.JSONValue; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.metadata.Type; + +/** + * Client side serializer/deserializer for java.util.Date + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class Date_Serializer implements JSONSerializer<Date> { + + @Override + public Date deserialize(Type type, JSONValue jsonValue, + ApplicationConnection connection) { + return new Date((long) ((JSONNumber) jsonValue).doubleValue()); + } + + @Override + public JSONValue serialize(Date value, ApplicationConnection connection) { + return new JSONNumber(value.getTime()); + } + +} diff --git a/client/src/com/vaadin/client/communication/Heartbeat.java b/client/src/com/vaadin/client/communication/Heartbeat.java new file mode 100644 index 0000000000..4b80827127 --- /dev/null +++ b/client/src/com/vaadin/client/communication/Heartbeat.java @@ -0,0 +1,171 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.communication; + +import java.util.logging.Logger; + +import com.google.gwt.http.client.Request; +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestCallback; +import com.google.gwt.http.client.RequestException; +import com.google.gwt.http.client.Response; +import com.google.gwt.user.client.Timer; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; +import com.vaadin.shared.ApplicationConstants; +import com.vaadin.shared.ui.ui.UIConstants; + +/** + * Handles sending of heartbeats to the server and reacting to the response + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class Heartbeat { + + private int interval = -1; + private Timer timer = new Timer() { + @Override + public void run() { + send(); + } + }; + + private ApplicationConnection connection; + + private static Logger getLogger() { + return Logger.getLogger(Heartbeat.class.getName()); + } + + /** + * Initializes the heartbeat for the given application connection + * + * @param connection + * the connection + */ + public void init(ApplicationConnection connection) { + this.connection = connection; + interval = connection.getConfiguration().getHeartbeatInterval(); + setInterval(interval); + schedule(); + + connection.addHandler( + ApplicationConnection.ApplicationStoppedEvent.TYPE, + new ApplicationConnection.ApplicationStoppedHandler() { + + @Override + public void onApplicationStopped( + ApplicationStoppedEvent event) { + setInterval(-1); + schedule(); + } + }); + + } + + /** + * Sends a heartbeat to the server + */ + public void send() { + final String uri = ApplicationConnection.addGetParameters( + getConnection().translateVaadinUri( + ApplicationConstants.APP_PROTOCOL_PREFIX + + ApplicationConstants.HEARTBEAT_PATH + '/'), + UIConstants.UI_ID_PARAMETER + "=" + + getConnection().getConfiguration().getUIId()); + + final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri); + + final RequestCallback callback = new RequestCallback() { + + @Override + public void onResponseReceived(Request request, Response response) { + int status = response.getStatusCode(); + if (status == Response.SC_OK) { + // TODO Permit retry in some error situations + getLogger().fine("Heartbeat response OK"); + schedule(); + } else if (status == Response.SC_GONE) { + // FIXME This should really do something else like send an + // event + getConnection().showSessionExpiredError(null); + } else { + getLogger().warning( + "Failed sending heartbeat to server. Error code: " + + status); + } + } + + @Override + public void onError(Request request, Throwable exception) { + getLogger().severe("Exception sending heartbeat: " + exception); + } + }; + + rb.setCallback(callback); + + try { + getLogger().fine("Sending heartbeat request..."); + rb.send(); + } catch (RequestException re) { + callback.onError(null, re); + } + + } + + /** + * @return the interval at which heartbeat requests are sent + */ + public int getInterval() { + return interval; + } + + /** + * sets the interval at which heartbeat requests are sent + * + * @param interval + * the new interval + */ + public void setInterval(int interval) { + this.interval = interval; + } + + /** + * Updates the schedule of the heartbeat to match the set interval. A + * negative interval disables the heartbeat. + */ + public void schedule() { + if (getInterval() > 0) { + getLogger() + .fine("Scheduling heartbeat in " + interval + " seconds"); + timer.schedule(interval * 1000); + } else { + if (timer != null) { + getLogger().fine("Disabling heartbeat"); + timer.cancel(); + } + } + + } + + /** + * @return the application connection + */ + protected ApplicationConnection getConnection() { + return connection; + } + +} diff --git a/client/src/com/vaadin/client/communication/JSONSerializer.java b/client/src/com/vaadin/client/communication/JSONSerializer.java index e5829ece24..a4e78e503c 100644 --- a/client/src/com/vaadin/client/communication/JSONSerializer.java +++ b/client/src/com/vaadin/client/communication/JSONSerializer.java @@ -23,14 +23,17 @@ import com.vaadin.client.metadata.Type; /** * Implementors of this interface knows how to serialize an Object of a given * type to JSON and how to deserialize the JSON back into an object. - * + * <p> * The {@link #serialize(Object, ApplicationConnection)} and * {@link #deserialize(Type, JSONValue, ApplicationConnection)} methods must be * symmetric so they can be chained and produce the original result (or an equal * result). - * + * <p> * Each {@link JSONSerializer} implementation can handle an object of a single * type - see {@link Type#findSerializer()}. + * <p> + * This is the client side interface, see + * com.vaadin.server.communication.JSONSerializer for the server side interface. * * @since 7.0 */ diff --git a/client/src/com/vaadin/client/communication/PushConnection.java b/client/src/com/vaadin/client/communication/PushConnection.java index a7eba224be..ba79af9d2c 100644 --- a/client/src/com/vaadin/client/communication/PushConnection.java +++ b/client/src/com/vaadin/client/communication/PushConnection.java @@ -16,6 +16,7 @@ package com.vaadin.client.communication; +import com.google.gwt.json.client.JSONObject; import com.google.gwt.user.client.Command; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler; @@ -53,14 +54,14 @@ public interface PushConnection { * replay those messages in the original order when the connection has been * established. * - * @param message - * the message to push + * @param payload + * the payload to push * @throws IllegalStateException * if this connection is not active * * @see #isActive() */ - public void push(String message); + public void push(JSONObject payload); /** * Checks whether this push connection is in a state where it can push diff --git a/client/src/com/vaadin/client/componentlocator/ComponentLocator.java b/client/src/com/vaadin/client/componentlocator/ComponentLocator.java new file mode 100644 index 0000000000..d2a89c00d5 --- /dev/null +++ b/client/src/com/vaadin/client/componentlocator/ComponentLocator.java @@ -0,0 +1,220 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.componentlocator; + +import java.util.Arrays; +import java.util.List; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.user.client.Element; +import com.vaadin.client.ApplicationConnection; + +/** + * ComponentLocator provides methods for generating a String locator for a given + * DOM element and for locating a DOM element using a String locator. + * <p> + * The main use for this class is locating components for automated testing + * purposes. + * + * @since 7.2, moved from {@link com.vaadin.client.ComponentLocator} + */ +public class ComponentLocator { + + private final List<LocatorStrategy> locatorStrategies; + + /** + * Reference to ApplicationConnection instance. + */ + + private final ApplicationConnection client; + + /** + * Construct a ComponentLocator for the given ApplicationConnection. + * + * @param client + * ApplicationConnection instance for the application. + */ + public ComponentLocator(ApplicationConnection client) { + this.client = client; + locatorStrategies = Arrays.asList(new VaadinFinderLocatorStrategy( + client), new LegacyLocatorStrategy(client)); + } + + /** + * Generates a String locator which uniquely identifies the target element. + * The {@link #getElementByPath(String)} method can be used for the inverse + * operation, i.e. locating an element based on the return value from this + * method. + * <p> + * Note that getElementByPath(getPathForElement(element)) == element is not + * always true as #getPathForElement(Element) can return a path to another + * element if the widget determines an action on the other element will give + * the same result as the action on the target element. + * </p> + * + * @since 5.4 + * @param targetElement + * The element to generate a path for. + * @return A String locator that identifies the target element or null if a + * String locator could not be created. + */ + public String getPathForElement(Element targetElement) { + for (LocatorStrategy strategy : locatorStrategies) { + String path = strategy.getPathForElement(targetElement); + if (null != path) { + return path; + } + } + return null; + } + + /** + * Locates an element using a String locator (path) which identifies a DOM + * element. The {@link #getPathForElement(Element)} method can be used for + * the inverse operation, i.e. generating a string expression for a DOM + * element. + * + * @since 5.4 + * @param path + * The String locator which identifies the target element. + * @return The DOM element identified by {@code path} or null if the element + * could not be located. + */ + public Element getElementByPath(String path) { + for (LocatorStrategy strategy : locatorStrategies) { + if (strategy.validatePath(path)) { + Element element = strategy.getElementByPath(path); + if (null != element) { + return element; + } + } + } + return null; + } + + /** + * Locates elements using a String locator (path) which identifies DOM + * elements. + * + * @since 7.2 + * @param path + * The String locator which identifies target elements. + * @return The JavaScriptArray of DOM elements identified by {@code path} or + * empty array if elements could not be located. + */ + public JsArray<Element> getElementsByPath(String path) { + JsArray<Element> jsElements = JavaScriptObject.createArray().cast(); + for (LocatorStrategy strategy : locatorStrategies) { + if (strategy.validatePath(path)) { + List<Element> elements = strategy.getElementsByPath(path); + if (elements.size() > 0) { + for (Element e : elements) { + jsElements.push(e); + } + return jsElements; + } + } + } + return jsElements; + } + + /** + * Locates elements using a String locator (path) which identifies DOM + * elements. The path starts from the specified root element. + * + * @see #getElementByPath(String) + * + * @since 7.2 + * @param path + * The path of elements to be found + * @param root + * The root element where the path is anchored + * @return The JavaScriptArray of DOM elements identified by {@code path} or + * empty array if elements could not be located. + */ + public JsArray<Element> getElementsByPathStartingAt(String path, + Element root) { + JsArray<Element> jsElements = JavaScriptObject.createArray().cast(); + for (LocatorStrategy strategy : locatorStrategies) { + if (strategy.validatePath(path)) { + List<Element> elements = strategy.getElementsByPathStartingAt( + path, root); + if (elements.size() > 0) { + for (Element e : elements) { + jsElements.push(e); + } + return jsElements; + } + } + } + return jsElements; + } + + /** + * Locates an element using a String locator (path) which identifies a DOM + * element. The path starts from the specified root element. + * + * @see #getElementByPath(String) + * + * @param path + * The path of the element to be found + * @param root + * The root element where the path is anchored + * @return The DOM element identified by {@code path} or null if the element + * could not be located. + */ + public Element getElementByPathStartingAt(String path, Element root) { + for (LocatorStrategy strategy : locatorStrategies) { + if (strategy.validatePath(path)) { + Element element = strategy.getElementByPathStartingAt(path, + root); + if (null != element) { + return element; + } + } + } + return null; + } + + /** + * Returns the {@link ApplicationConnection} used by this locator. + * <p> + * This method is primarily for internal use by the framework. + * + * @return the application connection + */ + public ApplicationConnection getClient() { + return client; + } + + /** + * Check if a given selector is valid for LegacyLocatorStrategy. + * + * @param path + * Vaadin selector path + * @return true if passes path validation with LegacyLocatorStrategy + */ + public boolean isValidForLegacyLocator(String path) { + for (LocatorStrategy ls : locatorStrategies) { + if (ls instanceof LegacyLocatorStrategy) { + return ls.validatePath(path); + } + } + return false; + } + +} diff --git a/client/src/com/vaadin/client/componentlocator/LegacyLocatorStrategy.java b/client/src/com/vaadin/client/componentlocator/LegacyLocatorStrategy.java new file mode 100644 index 0000000000..2e9d0a16d0 --- /dev/null +++ b/client/src/com/vaadin/client/componentlocator/LegacyLocatorStrategy.java @@ -0,0 +1,719 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.componentlocator; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.regexp.shared.RegExp; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ComponentConnector; +import com.vaadin.client.ConnectorMap; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.Util; +import com.vaadin.client.VCaption; +import com.vaadin.client.ui.SubPartAware; +import com.vaadin.client.ui.VCssLayout; +import com.vaadin.client.ui.VGridLayout; +import com.vaadin.client.ui.VOverlay; +import com.vaadin.client.ui.VTabsheetPanel; +import com.vaadin.client.ui.VUI; +import com.vaadin.client.ui.VWindow; +import com.vaadin.client.ui.orderedlayout.Slot; +import com.vaadin.client.ui.orderedlayout.VAbstractOrderedLayout; +import com.vaadin.client.ui.window.WindowConnector; +import com.vaadin.shared.AbstractComponentState; +import com.vaadin.shared.Connector; +import com.vaadin.shared.communication.SharedState; + +/** + * The LegacyLocatorStrategy class handles the legacy locator syntax that was + * introduced in version 5.4 of the framework. The legacy locator strategy is + * always used if no other strategy claims responsibility for a locator string. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class LegacyLocatorStrategy implements LocatorStrategy { + + /** + * Separator used in the String locator between a parent and a child widget. + */ + static final String PARENTCHILD_SEPARATOR = "/"; + /** + * Separator used in the String locator between the part identifying the + * containing widget and the part identifying the target element within the + * widget. + */ + static final String SUBPART_SEPARATOR = "#"; + /** + * String that identifies the root panel when appearing first in the String + * locator. + */ + static final String ROOT_ID = "Root"; + + private final ApplicationConnection client; + + private static final RegExp validSyntax = RegExp + .compile("^((\\w+::)?((PID_S)?\\w[-$_a-zA-Z0-9.' ]*)?)?(/[-$_a-zA-Z0-9]+\\[\\d+\\])*/?(#.*)?$"); + + public LegacyLocatorStrategy(ApplicationConnection clientConnection) { + client = clientConnection; + } + + @Override + public boolean validatePath(String path) { + return validSyntax.test(path); + } + + @Override + public String getPathForElement(Element targetElement) { + ComponentConnector connector = Util + .findPaintable(client, targetElement); + + Widget w = null; + if (connector != null) { + // If we found a Paintable then we use that as reference. We should + // find the Paintable for all but very special cases (like + // overlays). + w = connector.getWidget(); + + /* + * Still if the Paintable contains a widget that implements + * SubPartAware, we want to use that as a reference + */ + Widget targetParent = findParentWidget(targetElement, w); + while (targetParent != w && targetParent != null) { + if (targetParent instanceof SubPartAware) { + /* + * The targetParent widget is a child of the Paintable and + * the first parent (of the targetElement) that implements + * SubPartAware + */ + w = targetParent; + break; + } + targetParent = targetParent.getParent(); + } + } + if (w == null) { + // Check if the element is part of a widget that is attached + // directly to the root panel + RootPanel rootPanel = RootPanel.get(); + int rootWidgetCount = rootPanel.getWidgetCount(); + for (int i = 0; i < rootWidgetCount; i++) { + Widget rootWidget = rootPanel.getWidget(i); + if (rootWidget.getElement().isOrHasChild(targetElement)) { + // The target element is contained by this root widget + w = findParentWidget(targetElement, rootWidget); + break; + } + } + if (w != null) { + // We found a widget but we should still see if we find a + // SubPartAware implementor (we cannot find the Paintable as + // there is no link from VOverlay to its paintable/owner). + Widget subPartAwareWidget = findSubPartAwareParentWidget(w); + if (subPartAwareWidget != null) { + w = subPartAwareWidget; + } + } + } + + if (w == null) { + // Containing widget not found + return null; + } + + // Determine the path for the target widget + String path = getPathForWidget(w); + if (path == null) { + /* + * No path could be determined for the target widget. Cannot create + * a locator string. + */ + return null; + } + + // The parent check is a work around for Firefox 15 which fails to + // compare elements properly (#9534) + if (w.getElement() == targetElement) { + /* + * We are done if the target element is the root of the target + * widget. + */ + return path; + } else if (w instanceof SubPartAware) { + /* + * If the widget can provide an identifier for the targetElement we + * let it do that + */ + String elementLocator = ((SubPartAware) w) + .getSubPartName(targetElement); + if (elementLocator != null) { + return path + LegacyLocatorStrategy.SUBPART_SEPARATOR + + elementLocator; + } + } + /* + * If everything else fails we use the DOM path to identify the target + * element + */ + String domPath = getDOMPathForElement(targetElement, w.getElement()); + if (domPath == null) { + return path; + } else { + return path + domPath; + } + } + + /** + * {@inheritDoc} + */ + @Override + public Element getElementByPath(String path) { + return getElementByPathStartingAt(path, null); + } + + /** + * {@inheritDoc} + */ + @Override + public Element getElementByPathStartingAt(String path, Element baseElement) { + /* + * Path is of type "targetWidgetPath#componentPart" or + * "targetWidgetPath". + */ + String parts[] = path.split(LegacyLocatorStrategy.SUBPART_SEPARATOR, 2); + String widgetPath = parts[0]; + + // Note that this only works if baseElement can be mapped to a + // widget to which the path is relative. Otherwise, the current + // implementation simply interprets the path as if baseElement was + // null. + Widget baseWidget = Util.findWidget(baseElement, null); + + Widget w = getWidgetFromPath(widgetPath, baseWidget); + if (w == null || !Util.isAttachedAndDisplayed(w)) { + return null; + } + if (parts.length == 1) { + int pos = widgetPath.indexOf("domChild"); + if (pos == -1) { + return w.getElement(); + } + + // Contains dom reference to a sub element of the widget + String subPath = widgetPath.substring(pos); + return getElementByDOMPath(w.getElement(), subPath); + } else if (parts.length == 2) { + if (w instanceof SubPartAware) { + return ((SubPartAware) w).getSubPartElement(parts[1]); + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Element> getElementsByPath(String path) { + // This type of search is not supported in LegacyLocator + List<Element> array = new ArrayList<Element>(); + Element e = getElementByPath(path); + if (e != null) { + array.add(e); + } + return array; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Element> getElementsByPathStartingAt(String path, Element root) { + // This type of search is not supported in LegacyLocator + List<Element> array = new ArrayList<Element>(); + Element e = getElementByPathStartingAt(path, root); + if (e != null) { + array.add(e); + } + return array; + } + + /** + * Finds the first widget in the hierarchy (moving upwards) that implements + * SubPartAware. Returns the SubPartAware implementor or null if none is + * found. + * + * @param w + * The widget to start from. This is returned if it implements + * SubPartAware. + * @return The first widget (upwards in hierarchy) that implements + * SubPartAware or null + */ + Widget findSubPartAwareParentWidget(Widget w) { + + while (w != null) { + if (w instanceof SubPartAware) { + return w; + } + w = w.getParent(); + } + return null; + } + + /** + * Returns the first widget found when going from {@code targetElement} + * upwards in the DOM hierarchy, assuming that {@code ancestorWidget} is a + * parent of {@code targetElement}. + * + * @param targetElement + * @param ancestorWidget + * @return The widget whose root element is a parent of + * {@code targetElement}. + */ + private Widget findParentWidget(Element targetElement, Widget ancestorWidget) { + /* + * As we cannot resolve Widgets from the element we start from the + * widget and move downwards to the correct child widget, as long as we + * find one. + */ + if (ancestorWidget instanceof HasWidgets) { + for (Widget w : ((HasWidgets) ancestorWidget)) { + if (w.getElement().isOrHasChild(targetElement)) { + return findParentWidget(targetElement, w); + } + } + } + + // No children found, this is it + return ancestorWidget; + } + + /** + * Locates an element based on a DOM path and a base element. + * + * @param baseElement + * The base element which the path is relative to + * @param path + * String locator (consisting of domChild[x] parts) that + * identifies the element + * @return The element identified by path, relative to baseElement or null + * if the element could not be found. + */ + private Element getElementByDOMPath(Element baseElement, String path) { + String parts[] = path.split(PARENTCHILD_SEPARATOR); + Element element = baseElement; + + for (int i = 0, l = parts.length; i < l; ++i) { + String part = parts[i]; + if (part.startsWith("domChild[")) { + String childIndexString = part.substring("domChild[".length(), + part.length() - 1); + + if (Util.findWidget(baseElement, null) instanceof VAbstractOrderedLayout) { + if (element.hasChildNodes()) { + Element e = element.getFirstChildElement().cast(); + String cn = e.getClassName(); + if (cn != null + && (cn.equals("v-expand") || cn + .contains("v-has-caption"))) { + element = e; + } + } + } + + try { + int childIndex = Integer.parseInt(childIndexString); + element = DOM.getChild(element, childIndex); + } catch (Exception e) { + return null; + } + + if (element == null) { + return null; + } + + } else { + + path = parts[i]; + for (int j = i + 1; j < l; ++j) { + path += PARENTCHILD_SEPARATOR + parts[j]; + } + + return getElementByPathStartingAt(path, element); + } + } + + return element; + } + + /** + * Generates a String locator using domChild[x] parts for the element + * relative to the baseElement. + * + * @param element + * The target element + * @param baseElement + * The starting point for the locator. The generated path is + * relative to this element. + * @return A String locator that can be used to locate the target element + * using + * {@link #getElementByDOMPath(com.google.gwt.user.client.Element, String)} + * or null if the locator String cannot be created. + */ + private String getDOMPathForElement(Element element, Element baseElement) { + Element e = element; + String path = ""; + while (true) { + int childIndex = -1; + Element siblingIterator = e; + while (siblingIterator != null) { + childIndex++; + siblingIterator = siblingIterator.getPreviousSiblingElement() + .cast(); + } + + path = PARENTCHILD_SEPARATOR + "domChild[" + childIndex + "]" + + path; + + JavaScriptObject parent = e.getParentElement(); + if (parent == null) { + return null; + } + // The parent check is a work around for Firefox 15 which fails to + // compare elements properly (#9534) + if (parent == baseElement) { + break; + } + + e = parent.cast(); + } + + return path; + } + + /** + * Creates a locator String for the given widget. The path can be used to + * locate the widget using {@link #getWidgetFromPath(String, Widget)}. + * <p/> + * Returns null if no path can be determined for the widget or if the widget + * is null. + * + * @param w + * The target widget + * @return A String locator for the widget + */ + private String getPathForWidget(Widget w) { + if (w == null) { + return null; + } + String elementId = w.getElement().getId(); + if (elementId != null && !elementId.isEmpty() + && !elementId.startsWith("gwt-uid-")) { + // Use PID_S+id if the user has set an id but do not use it for auto + // generated id:s as these might not be consistent + return "PID_S" + elementId; + } else if (w instanceof VUI) { + return ""; + } else if (w instanceof VWindow) { + Connector windowConnector = ConnectorMap.get(client) + .getConnector(w); + List<WindowConnector> subWindowList = client.getUIConnector() + .getSubWindows(); + int indexOfSubWindow = subWindowList.indexOf(windowConnector); + return PARENTCHILD_SEPARATOR + "VWindow[" + indexOfSubWindow + "]"; + } else if (w instanceof RootPanel) { + return ROOT_ID; + } + + Widget parent = w.getParent(); + + String basePath = getPathForWidget(parent); + if (basePath == null) { + return null; + } + String simpleName = Util.getSimpleName(w); + + /* + * Check if the parent implements Iterable. At least VPopupView does not + * implement HasWdgets so we cannot check for that. + */ + if (!(parent instanceof Iterable<?>)) { + // Parent does not implement Iterable so we cannot find out which + // child this is + return null; + } + + Iterator<?> i = ((Iterable<?>) parent).iterator(); + int pos = 0; + while (i.hasNext()) { + Object child = i.next(); + if (child == w) { + return basePath + PARENTCHILD_SEPARATOR + simpleName + "[" + + pos + "]"; + } + String simpleName2 = Util.getSimpleName(child); + if (simpleName.equals(simpleName2)) { + pos++; + } + } + + return null; + } + + /** + * Locates the widget based on a String locator. + * + * @param path + * The String locator that identifies the widget. + * @param baseWidget + * the widget to which the path is relative, null if relative to + * root + * @return The Widget identified by the String locator or null if the widget + * could not be identified. + */ + @SuppressWarnings("unchecked") + private Widget getWidgetFromPath(String path, Widget baseWidget) { + Widget w = baseWidget; + String parts[] = path.split(PARENTCHILD_SEPARATOR); + + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + + if (part.equals(ROOT_ID)) { + w = RootPanel.get(); + } else if (part.equals("")) { + if (w == null) { + w = client.getUIConnector().getWidget(); + } + } else if (w == null) { + String id = part; + // Must be old static pid (PID_S*) + ServerConnector connector = ConnectorMap.get(client) + .getConnector(id); + if (connector == null) { + // Lookup by component id + // TODO Optimize this + connector = findConnectorById(client.getUIConnector(), + id.substring(5)); + } + + if (connector instanceof ComponentConnector) { + w = ((ComponentConnector) connector).getWidget(); + } else { + // Not found + return null; + } + } else if (part.startsWith("domChild[")) { + // The target widget has been found and the rest identifies the + // element + break; + } else if (w instanceof Iterable) { + // W identifies a widget that contains other widgets, as it + // should. Try to locate the child + Iterable<?> parent = (Iterable<?>) w; + + // Part is of type "VVerticalLayout[0]", split this into + // VVerticalLayout and 0 + String[] split = part.split("\\[", 2); + String widgetClassName = split[0]; + String indexString = split[1].substring(0, + split[1].length() - 1); + + int widgetPosition; + try { + widgetPosition = Integer.parseInt(indexString); + } catch (NumberFormatException e) { + // We've probably been fed a new-style Vaadin locator with a + // string-form predicate, that doesn't match anything in the + // search space. + return null; + } + + // AbsolutePanel in GridLayout has been removed -> skip it + if (w instanceof VGridLayout + && "AbsolutePanel".equals(widgetClassName)) { + continue; + } + + // FlowPane in CSSLayout has been removed -> skip it + if (w instanceof VCssLayout + && "VCssLayout$FlowPane".equals(widgetClassName)) { + continue; + } + + // ChildComponentContainer and VOrderedLayout$Slot have been + // replaced with Slot + if (w instanceof VAbstractOrderedLayout + && ("ChildComponentContainer".equals(widgetClassName) || "VOrderedLayout$Slot" + .equals(widgetClassName))) { + widgetClassName = "Slot"; + } + + if (w instanceof VTabsheetPanel && widgetPosition != 0) { + // TabSheetPanel now only contains 1 connector => the index + // is always 0 which indicates the widget in the active tab + widgetPosition = 0; + } + if (w instanceof VOverlay + && "VCalendarPanel".equals(widgetClassName)) { + // Vaadin 7.1 adds a wrapper for datefield popups + parent = (Iterable<?>) ((Iterable<?>) parent).iterator() + .next(); + } + /* + * The new grid and ordered layouts do not contain + * ChildComponentContainer widgets. This is instead simulated by + * constructing a path step that would find the desired widget + * from the layout and injecting it as the next search step + * (which would originally have found the widget inside the + * ChildComponentContainer) + */ + if ((w instanceof VGridLayout) + && "ChildComponentContainer".equals(widgetClassName) + && i + 1 < parts.length) { + + HasWidgets layout = (HasWidgets) w; + + String nextPart = parts[i + 1]; + String[] nextSplit = nextPart.split("\\[", 2); + String nextWidgetClassName = nextSplit[0]; + + // Find the n:th child and count the number of children with + // the same type before it + int nextIndex = 0; + for (Widget child : layout) { + boolean matchingType = nextWidgetClassName.equals(Util + .getSimpleName(child)); + if (matchingType && widgetPosition == 0) { + // This is the n:th child that we looked for + break; + } else if (widgetPosition < 0) { + // Error if we're past the desired position without + // a match + return null; + } else if (matchingType) { + // If this was another child of the expected type, + // increase the count for the next step + nextIndex++; + } + + // Don't count captions + if (!(child instanceof VCaption)) { + widgetPosition--; + } + } + + // Advance to the next step, this time checking for the + // actual child widget + parts[i + 1] = nextWidgetClassName + '[' + nextIndex + ']'; + continue; + } + + // Locate the child + Iterator<? extends Widget> iterator; + + /* + * VWindow and VContextMenu workarounds for backwards + * compatibility + */ + if (widgetClassName.equals("VWindow")) { + List<WindowConnector> windows = client.getUIConnector() + .getSubWindows(); + List<VWindow> windowWidgets = new ArrayList<VWindow>( + windows.size()); + for (WindowConnector wc : windows) { + windowWidgets.add(wc.getWidget()); + } + iterator = windowWidgets.iterator(); + } else if (widgetClassName.equals("VContextMenu")) { + return client.getContextMenu(); + } else { + iterator = (Iterator<? extends Widget>) parent.iterator(); + } + + boolean ok = false; + + // Find the widgetPosition:th child of type "widgetClassName" + while (iterator.hasNext()) { + + Widget child = iterator.next(); + String simpleName2 = Util.getSimpleName(child); + + if (!widgetClassName.equals(simpleName2) + && child instanceof Slot) { + /* + * Support legacy tests without any selector for the + * Slot widget (i.e. /VVerticalLayout[0]/VButton[0]) by + * directly checking the stuff inside the slot + */ + child = ((Slot) child).getWidget(); + simpleName2 = Util.getSimpleName(child); + } + + if (widgetClassName.equals(simpleName2)) { + if (widgetPosition == 0) { + w = child; + ok = true; + break; + } + widgetPosition--; + + } + } + + if (!ok) { + // Did not find the child + return null; + } + } else { + // W identifies something that is not a "HasWidgets". This + // should not happen as all widget containers should implement + // HasWidgets. + return null; + } + } + + return w; + } + + private ServerConnector findConnectorById(ServerConnector root, String id) { + SharedState state = root.getState(); + if (state instanceof AbstractComponentState + && id.equals(((AbstractComponentState) state).id)) { + return root; + } + for (ServerConnector child : root.getChildren()) { + ServerConnector found = findConnectorById(child, id); + if (found != null) { + return found; + } + } + + return null; + } + +} diff --git a/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java b/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java new file mode 100644 index 0000000000..e892f43d76 --- /dev/null +++ b/client/src/com/vaadin/client/componentlocator/LocatorStrategy.java @@ -0,0 +1,122 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.componentlocator; + +import java.util.List; + +import com.google.gwt.user.client.Element; + +/** + * This interface should be implemented by all locator strategies. A locator + * strategy is responsible for generating and decoding a string that identifies + * an element in the DOM. A strategy can implement its own syntax for the + * locator string, which may be completely different from any other strategy's + * syntax. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface LocatorStrategy { + + /** + * Test the given input path for formatting errors. If a given path can not + * be validated, the locator strategy will not be attempted. + * + * @param path + * a locator path expression + * @return true, if the implementing class can process the given path, + * otherwise false + */ + boolean validatePath(String path); + + /** + * Generates a String locator which uniquely identifies the target element. + * The {@link #getElementByPath(String)} method can be used for the inverse + * operation, i.e. locating an element based on the return value from this + * method. + * <p> + * Note that getElementByPath(getPathForElement(element)) == element is not + * always true as #getPathForElement(Element) can return a path to another + * element if the widget determines an action on the other element will give + * the same result as the action on the target element. + * </p> + * + * @param targetElement + * The element to generate a path for. + * @return A String locator that identifies the target element or null if a + * String locator could not be created. + */ + String getPathForElement(Element targetElement); + + /** + * Locates an element using a String locator (path) which identifies a DOM + * element. The {@link #getPathForElement(Element)} method can be used for + * the inverse operation, i.e. generating a string expression for a DOM + * element. + * + * @param path + * The String locator which identifies the target element. + * @return The DOM element identified by {@code path} or null if the element + * could not be located. + */ + Element getElementByPath(String path); + + /** + * Locates an element using a String locator (path) which identifies a DOM + * element. The path starts from the specified root element. + * + * @see #getElementByPath(String) + * + * @param path + * The String locator which identifies the target element. + * @param root + * The element that is at the root of the path. + * @return The DOM element identified by {@code path} or null if the element + * could not be located. + */ + Element getElementByPathStartingAt(String path, Element root); + + /** + * Locates all elements that match a String locator (path) which identifies + * DOM elements. + * + * This functionality is limited in {@link LegacyLocatorStrategy}. + * + * @param path + * The String locator which identifies target elements. + * @return List that contains all matched elements. Empty list if none + * found. + */ + List<Element> getElementsByPath(String path); + + /** + * Locates all elements that match a String locator (path) which identifies + * DOM elements. The path starts from the specified root element. + * + * This functionality is limited in {@link LegacyLocatorStrategy}. + * + * @see #getElementsByPath(String) + * + * @param path + * The String locator which identifies target elements. + * @param root + * The element that is at the root of the path. + * @return List that contains all matched elements. Empty list if none + * found. + */ + + List<Element> getElementsByPathStartingAt(String path, Element root); +} diff --git a/client/src/com/vaadin/client/componentlocator/LocatorUtil.java b/client/src/com/vaadin/client/componentlocator/LocatorUtil.java new file mode 100644 index 0000000000..04624920a9 --- /dev/null +++ b/client/src/com/vaadin/client/componentlocator/LocatorUtil.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.componentlocator; + +/** + * Common String manipulator utilities used in VaadinFinderLocatorStrategy and + * SelectorPredicates. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class LocatorUtil { + + /** + * Find first occurrence of character that's not inside quotes starting from + * specified index. + * + * @param str + * Full string for searching + * @param find + * Character we want to find + * @param startingAt + * Index where we start + * @return Index of character. -1 if character not found + */ + protected static int indexOfIgnoringQuoted(String str, char find, + int startingAt) { + boolean quote = false; + String quoteChars = "'\""; + char currentQuote = '"'; + for (int i = startingAt; i < str.length(); ++i) { + char cur = str.charAt(i); + if (quote) { + if (cur == currentQuote) { + quote = !quote; + } + continue; + } else if (cur == find) { + return i; + } else { + if (quoteChars.indexOf(cur) >= 0) { + currentQuote = cur; + quote = !quote; + } + } + } + return -1; + } + + /** + * Find first occurrence of character that's not inside quotes starting from + * the beginning of string. + * + * @param str + * Full string for searching + * @param find + * Character we want to find + * @return Index of character. -1 if character not found + */ + protected static int indexOfIgnoringQuoted(String str, char find) { + return indexOfIgnoringQuoted(str, find, 0); + } +} diff --git a/client/src/com/vaadin/client/componentlocator/SelectorPredicate.java b/client/src/com/vaadin/client/componentlocator/SelectorPredicate.java new file mode 100644 index 0000000000..32b33005ed --- /dev/null +++ b/client/src/com/vaadin/client/componentlocator/SelectorPredicate.java @@ -0,0 +1,228 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.componentlocator; + +import java.util.ArrayList; +import java.util.List; + +/** + * SelectorPredicates are statements about the state of different components + * that VaadinFinderLocatorStrategy is finding. SelectorPredicates also provide + * useful information of said components to debug window by giving means to + * provide better variable naming. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class SelectorPredicate { + private String name = ""; + private String value = ""; + private boolean wildcard = false; + private int index = -1; + + public static List<SelectorPredicate> extractPostFilterPredicates( + String path) { + if (path.startsWith("(")) { + return extractPredicates(path.substring(path.lastIndexOf(')'))); + } + return new ArrayList<SelectorPredicate>(); + } + + /** + * Generate a list of predicates from a single predicate string + * + * @param str + * a comma separated string of predicates + * @return a List of Predicate objects + */ + public static List<SelectorPredicate> extractPredicates(String path) { + List<SelectorPredicate> predicates = new ArrayList<SelectorPredicate>(); + + String predicateStr = extractPredicateString(path); + if (null == predicateStr || predicateStr.length() == 0) { + return predicates; + } + + // Extract input strings + List<String> input = readPredicatesFromString(predicateStr); + + // Process each predicate into proper predicate descriptor + for (String s : input) { + SelectorPredicate p = new SelectorPredicate(); + s = s.trim(); + + try { + // If we can parse out the predicate as a pure index argument, + // stop processing here. + p.index = Integer.parseInt(s); + predicates.add(p); + + continue; + } catch (Exception e) { + p.index = -1; + } + + int idx = LocatorUtil.indexOfIgnoringQuoted(s, '='); + if (idx < 0) { + continue; + } + p.name = s.substring(0, idx); + p.value = s.substring(idx + 1); + + if (p.value.equals("?")) { + p.wildcard = true; + p.value = null; + } else { + // Only unquote predicate value once we're sure it's a proper + // value... + + p.value = unquote(p.value); + } + + predicates.add(p); + } + // Move any (and all) index predicates to last place in the list. + for (int i = 0, l = predicates.size(); i < l - 1; ++i) { + if (predicates.get(i).index > -1) { + predicates.add(predicates.remove(i)); + --i; + --l; + } + } + + return predicates; + } + + /** + * Splits the predicate string to list of predicate strings. + * + * @param predicateStr + * Comma separated predicate strings + * @return List of predicate strings + */ + private static List<String> readPredicatesFromString(String predicateStr) { + List<String> predicates = new ArrayList<String>(); + int prevIdx = 0; + int idx = LocatorUtil.indexOfIgnoringQuoted(predicateStr, ',', prevIdx); + + while (idx > -1) { + predicates.add(predicateStr.substring(prevIdx, idx)); + prevIdx = idx + 1; + idx = LocatorUtil.indexOfIgnoringQuoted(predicateStr, ',', prevIdx); + } + predicates.add(predicateStr.substring(prevIdx)); + + return predicates; + } + + /** + * Returns the predicate string, i.e. the string between the brackets in a + * path fragment. Examples: <code> + * VTextField[0] => 0 + * VTextField[caption='foo'] => caption='foo' + * </code> + * + * @param pathFragment + * The path fragment from which to extract the predicate string. + * @return The predicate string for the path fragment or empty string if not + * found. + */ + private static String extractPredicateString(String pathFragment) { + int ixOpenBracket = LocatorUtil + .indexOfIgnoringQuoted(pathFragment, '['); + if (ixOpenBracket >= 0) { + int ixCloseBracket = LocatorUtil.indexOfIgnoringQuoted( + pathFragment, ']', ixOpenBracket); + return pathFragment.substring(ixOpenBracket + 1, ixCloseBracket); + } + return ""; + } + + /** + * Removes the surrounding quotes from a string if it is quoted. + * + * @param str + * the possibly quoted string + * @return an unquoted version of str + */ + private static String unquote(String str) { + if ((str.startsWith("\"") && str.endsWith("\"")) + || (str.startsWith("'") && str.endsWith("'"))) { + return str.substring(1, str.length() - 1); + } + return str; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value + * the value to set + */ + public void setValue(String value) { + this.value = value; + } + + /** + * @return the index + */ + public int getIndex() { + return index; + } + + /** + * @param index + * the index to set + */ + public void setIndex(int index) { + this.index = index; + } + + /** + * @return the wildcard + */ + public boolean isWildcard() { + return wildcard; + } + + /** + * @param wildcard + * the wildcard to set + */ + public void setWildcard(boolean wildcard) { + this.wildcard = wildcard; + } +} diff --git a/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java b/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java new file mode 100644 index 0000000000..49090b66db --- /dev/null +++ b/client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java @@ -0,0 +1,748 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.componentlocator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ComponentConnector; +import com.vaadin.client.HasComponentsConnector; +import com.vaadin.client.Util; +import com.vaadin.client.metadata.Property; +import com.vaadin.client.metadata.TypeDataStore; +import com.vaadin.client.ui.AbstractConnector; +import com.vaadin.client.ui.SubPartAware; +import com.vaadin.client.ui.VNotification; + +/** + * The VaadinFinder locator strategy implements an XPath-like syntax for + * locating elements in Vaadin applications. This is used in the new + * VaadinFinder API in TestBench 4. + * + * Examples of the supported syntax: + * <ul> + * <li>Find the third text field in the DOM: {@code //VTextField[2]}</li> + * <li>Find the second button inside the first vertical layout: + * {@code //VVerticalLayout/VButton[1]}</li> + * <li>Find the first column on the third row of the "Accounts" table: + * {@code //VScrollTable[caption="Accounts"]#row[2]/col[0]}</li> + * </ul> + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class VaadinFinderLocatorStrategy implements LocatorStrategy { + + public static final String SUBPART_SEPARATOR = "#"; + + private final ApplicationConnection client; + + /** + * Internal descriptor for connector/element/widget name combinations + */ + private static final class ConnectorPath { + private String name; + private ComponentConnector connector; + } + + public VaadinFinderLocatorStrategy(ApplicationConnection clientConnection) { + client = clientConnection; + } + + /** + * {@inheritDoc} + */ + @Override + public String getPathForElement(Element targetElement) { + if (targetElement == null) { + return ""; + } + + List<ConnectorPath> hierarchy = getConnectorHierarchyForElement(targetElement); + List<String> path = new ArrayList<String>(); + + // Assemble longname path components back-to-forth with useful + // predicates - first try ID, then caption. + for (int i = 0; i < hierarchy.size(); ++i) { + ConnectorPath cp = hierarchy.get(i); + String pathFragment = cp.name; + String identifier = getPropertyValue(cp.connector, "id"); + + if (identifier != null) { + pathFragment += "[id=\"" + identifier + "\"]"; + } else { + identifier = getPropertyValue(cp.connector, "caption"); + if (identifier != null) { + pathFragment += "[caption=\"" + identifier + "\"]"; + } + } + path.add(pathFragment); + } + + if (path.size() == 0) { + // If we didn't find a single element, return null.. + return null; + } + + return getBestSelector(generateQueries(path), targetElement); + } + + /** + * Search different queries for the best one. Use the fact that the lowest + * possible index is with the last selector. Last selector is the full + * search path containing the complete Component hierarchy. + * + * @param selectors + * List of selectors + * @param target + * Target element + * @return Best selector string formatted with a post filter + */ + private String getBestSelector(List<String> selectors, Element target) { + // The last selector gives us smallest list index for target element. + String bestSelector = selectors.get(selectors.size() - 1); + int min = getElementsByPath(bestSelector).indexOf(target); + if (selectors.size() > 1 + && min == getElementsByPath(selectors.get(0)).indexOf(target)) { + // The first selector has same index as last. It's much shorter. + bestSelector = selectors.get(0); + } else if (selectors.size() > 2) { + // See if we get minimum from second last. If not then we already + // have the best one.. Second last one contains almost full + // component hierarchy. + if (getElementsByPath(selectors.get(selectors.size() - 2)).indexOf( + target) == min) { + for (int i = 1; i < selectors.size() - 2; ++i) { + // Loop through the remaining selectors and look for one + // with the same index + if (getElementsByPath(selectors.get(i)).indexOf(target) == min) { + bestSelector = selectors.get(i); + break; + } + } + + } + } + return "(" + bestSelector + ")[" + min + "]"; + + } + + /** + * Function to generate all possible search paths for given component list. + * Function strips out all the com.vaadin.ui. prefixes from elements as this + * functionality makes generating a query later on easier. + * + * @param components + * List of components + * @return List of Vaadin selectors + */ + private List<String> generateQueries(List<String> components) { + // Prepare to loop through all the elements. + List<String> paths = new ArrayList<String>(); + int compIdx = 0; + String basePath = components.get(compIdx).replace("com.vaadin.ui.", ""); + // Add a basic search for the first element (eg. //Button) + paths.add((components.size() == 1 ? "/" : "//") + basePath); + while (++compIdx < components.size()) { + // Loop through the remaining components + for (int i = components.size() - 1; i >= compIdx; --i) { + boolean recursive = false; + if (i > compIdx) { + recursive = true; + } + paths.add((i == components.size() - 1 ? "/" : "//") + + components.get(i).replace("com.vaadin.ui.", "") + + (recursive ? "//" : "/") + basePath); + } + // Add the element at index compIdx to the basePath so it is + // included in all the following searches. + basePath = components.get(compIdx).replace("com.vaadin.ui.", "") + + "/" + basePath; + } + + return paths; + } + + /** + * Helper method to get the string-form value of a named property of a + * component connector + * + * @since 7.2 + * @param c + * any ComponentConnector instance + * @param propertyName + * property name to test for + * @return a string, if the property is found, or null, if the property does + * not exist on the object (or some other error is encountered). + */ + private String getPropertyValue(ComponentConnector c, String propertyName) { + Property prop = AbstractConnector.getStateType(c).getProperty( + propertyName); + try { + return prop.getValue(c.getState()).toString(); + } catch (Exception e) { + return null; + } + } + + /** + * Generate a list representing the top-to-bottom connector hierarchy for + * any given element. ConnectorPath element provides long- and short names, + * as well as connector and widget root element references. + * + * @since 7.2 + * @param elem + * any Element that is part of a widget hierarchy + * @return a list of ConnectorPath objects, in descending order towards the + * common root container. + */ + private List<ConnectorPath> getConnectorHierarchyForElement(Element elem) { + Element e = elem; + ComponentConnector c = Util.findPaintable(client, e); + List<ConnectorPath> connectorHierarchy = new ArrayList<ConnectorPath>(); + + while (c != null) { + + for (String id : getIDsForConnector(c)) { + ConnectorPath cp = new ConnectorPath(); + cp.name = getFullClassName(id); + cp.connector = c; + + // We want to make an exception for the UI object, since it's + // our default search context (and can't be found inside itself) + if (!cp.name.equals("com.vaadin.ui.UI")) { + connectorHierarchy.add(cp); + } + } + + e = (Element) e.getParentElement(); + if (e != null) { + c = Util.findPaintable(client, e); + e = c != null ? c.getWidget().getElement() : null; + } + + } + + return connectorHierarchy; + } + + private boolean isNotificationExpression(String path) { + String[] starts = { "//", "/" }; + + String[] frags = { "com.vaadin.ui.Notification.class", + "com.vaadin.ui.Notification", "VNotification.class", + "VNotification", "Notification.class", "Notification" }; + + String[] ends = { "/", "[" }; + + for (String s : starts) { + for (String f : frags) { + if (path.equals(s + f)) { + return true; + } + + for (String e : ends) { + if (path.startsWith(s + f + e)) { + return true; + } + } + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public List<Element> getElementsByPath(String path) { + List<SelectorPredicate> postFilters = SelectorPredicate + .extractPostFilterPredicates(path); + if (postFilters.size() > 0) { + path = path.substring(1, path.lastIndexOf(')')); + } + + List<Element> elements = new ArrayList<Element>(); + if (isNotificationExpression(path)) { + + for (VNotification n : findNotificationsByPath(path)) { + elements.add(n.getElement()); + } + + } else { + + elements.addAll(eliminateDuplicates(getElementsByPathStartingAtConnector( + path, client.getUIConnector()))); + } + + for (SelectorPredicate p : postFilters) { + // Post filtering supports only indexes and follows instruction + // blindly. Index that is outside of our list results into an empty + // list and multiple indexes are likely to ruin a search completely + if (p.getIndex() >= 0) { + if (p.getIndex() >= elements.size()) { + elements.clear(); + } else { + Element e = elements.get(p.getIndex()); + elements.clear(); + elements.add(e); + } + } + } + + return elements; + } + + /** + * {@inheritDoc} + */ + @Override + public Element getElementByPath(String path) { + List<Element> elements = getElementsByPath(path); + if (elements.isEmpty()) { + return null; + } + return elements.get(0); + } + + /** + * {@inheritDoc} + */ + @Override + public Element getElementByPathStartingAt(String path, Element root) { + List<Element> elements = getElementsByPathStartingAt(path, root); + if (elements.isEmpty()) { + return null; + } + return elements.get(0); + + } + + /** + * {@inheritDoc} + */ + @Override + public List<Element> getElementsByPathStartingAt(String path, Element root) { + List<SelectorPredicate> postFilters = SelectorPredicate + .extractPostFilterPredicates(path); + if (postFilters.size() > 0) { + path = path.substring(1, path.lastIndexOf(')')); + } + + List<Element> elements = getElementsByPathStartingAtConnector(path, + Util.findPaintable(client, root)); + + for (SelectorPredicate p : postFilters) { + // Post filtering supports only indexes and follows instruction + // blindly. Index that is outside of our list results into an empty + // list and multiple indexes are likely to ruin a search completely + if (p.getIndex() >= 0) { + if (p.getIndex() >= elements.size()) { + elements.clear(); + } else { + Element e = elements.get(p.getIndex()); + elements.clear(); + elements.add(e); + } + } + } + + return elements; + } + + /** + * Special case for finding notifications as they have no connectors and are + * directly attached to {@link RootPanel}. + * + * @param path + * The path of the notification, should be + * {@code "//VNotification"} optionally followed by an index in + * brackets. + * @return the notification element or null if not found. + */ + private List<VNotification> findNotificationsByPath(String path) { + + List<VNotification> notifications = new ArrayList<VNotification>(); + for (Widget w : RootPanel.get()) { + if (w instanceof VNotification) { + notifications.add((VNotification) w); + } + } + + List<SelectorPredicate> predicates = SelectorPredicate + .extractPredicates(path); + for (SelectorPredicate p : predicates) { + + if (p.getIndex() > -1) { + VNotification n = notifications.get(p.getIndex()); + notifications.clear(); + if (n != null) { + notifications.add(n); + } + } + + } + + return eliminateDuplicates(notifications); + } + + /** + * Finds a list of elements by the specified path, starting traversal of the + * connector hierarchy from the specified root. + * + * @param path + * the locator path + * @param root + * the root connector + * @return the list of elements identified by path or empty list if not + * found. + */ + private List<Element> getElementsByPathStartingAtConnector(String path, + ComponentConnector root) { + String[] pathComponents = path.split(SUBPART_SEPARATOR); + List<ComponentConnector> connectors; + if (pathComponents[0].length() > 0) { + connectors = findConnectorsByPath(pathComponents[0], + Arrays.asList(root)); + } else { + connectors = Arrays.asList(root); + } + + List<Element> output = new ArrayList<Element>(); + if (null != connectors && !connectors.isEmpty()) { + if (pathComponents.length > 1) { + // We have subparts + for (ComponentConnector connector : connectors) { + if (connector.getWidget() instanceof SubPartAware) { + output.add(((SubPartAware) connector.getWidget()) + .getSubPartElement(pathComponents[1])); + } + } + } else { + for (ComponentConnector connector : connectors) { + output.add(connector.getWidget().getElement()); + } + } + } + return eliminateDuplicates(output); + } + + /** + * Recursively finds connectors for the elements identified by the provided + * path by traversing the connector hierarchy starting from {@code parents} + * connectors. + * + * @param path + * The path identifying elements. + * @param parents + * The list of connectors to start traversing from. + * @return The list of connectors identified by {@code path} or empty list + * if no such connectors could be found. + */ + private List<ComponentConnector> findConnectorsByPath(String path, + List<ComponentConnector> parents) { + boolean findRecursively = path.startsWith("//"); + // Strip away the one or two slashes from the beginning of the path + path = path.substring(findRecursively ? 2 : 1); + + String[] fragments = splitFirstFragmentFromTheRest(path); + + List<ComponentConnector> connectors = new ArrayList<ComponentConnector>(); + for (ComponentConnector parent : parents) { + connectors.addAll(filterMatches( + collectPotentialMatches(parent, fragments[0], + findRecursively), SelectorPredicate + .extractPredicates(fragments[0]))); + } + + if (!connectors.isEmpty() && fragments.length > 1) { + return (findConnectorsByPath(fragments[1], connectors)); + } + return eliminateDuplicates(connectors); + } + + /** + * Go through a list of potentially matching components, modifying that list + * until all elements that remain in that list match the complete list of + * predicates. + * + * @param potentialMatches + * a list of component connectors. Will be changed. + * @param predicates + * an immutable list of predicates + * @return filtered list of component connectors. + */ + private List<ComponentConnector> filterMatches( + List<ComponentConnector> potentialMatches, + List<SelectorPredicate> predicates) { + + for (SelectorPredicate p : predicates) { + + if (p.getIndex() > -1) { + try { + ComponentConnector v = potentialMatches.get(p.getIndex()); + potentialMatches.clear(); + potentialMatches.add(v); + } catch (IndexOutOfBoundsException e) { + potentialMatches.clear(); + } + + continue; + } + + for (int i = 0, l = potentialMatches.size(); i < l; ++i) { + + String propData = getPropertyValue(potentialMatches.get(i), + p.getName()); + + if ((p.isWildcard() && propData == null) + || (!p.isWildcard() && !p.getValue().equals(propData))) { + potentialMatches.remove(i); + --l; + --i; + } + } + + } + + return eliminateDuplicates(potentialMatches); + } + + /** + * Collects all connectors that match the widget class name of the path + * fragment. If the {@code collectRecursively} parameter is true, a + * depth-first search of the connector hierarchy is performed. + * + * Searching depth-first ensure that we can return the matches in correct + * order for selecting based on index predicates. + * + * @param parent + * The {@link ComponentConnector} to start the search from. + * @param pathFragment + * The path fragment identifying which type of widget to search + * for. + * @param collectRecursively + * If true, all matches from all levels below {@code parent} will + * be collected. If false only direct children will be collected. + * @return A list of {@link ComponentConnector}s matching the widget type + * specified in the {@code pathFragment}. + */ + private List<ComponentConnector> collectPotentialMatches( + ComponentConnector parent, String pathFragment, + boolean collectRecursively) { + ArrayList<ComponentConnector> potentialMatches = new ArrayList<ComponentConnector>(); + if (parent instanceof HasComponentsConnector) { + List<ComponentConnector> children = ((HasComponentsConnector) parent) + .getChildComponents(); + for (ComponentConnector child : children) { + String widgetName = getWidgetName(pathFragment); + if (connectorMatchesPathFragment(child, widgetName)) { + potentialMatches.add(child); + } + if (collectRecursively) { + potentialMatches.addAll(collectPotentialMatches(child, + pathFragment, collectRecursively)); + } + } + } + return eliminateDuplicates(potentialMatches); + } + + private List<String> getIDsForConnector(ComponentConnector connector) { + Class<?> connectorClass = connector.getClass(); + List<String> ids = new ArrayList<String>(); + + TypeDataStore.get().findIdentifiersFor(connectorClass).addAllTo(ids); + + return ids; + } + + /** + * Determines whether a connector matches a path fragment. This is done by + * comparing the path fragment to the name of the widget type of the + * connector. + * + * @param connector + * The connector to compare. + * @param widgetName + * The name of the widget class. + * @return true if the widget type of the connector equals the widget type + * identified by the path fragment. + */ + private boolean connectorMatchesPathFragment(ComponentConnector connector, + String widgetName) { + + List<String> ids = getIDsForConnector(connector); + + Integer[] widgetTags = client.getConfiguration() + .getTagsForServerSideClassName(getFullClassName(widgetName)); + if (widgetTags.length == 0) { + widgetTags = client.getConfiguration() + .getTagsForServerSideClassName( + getFullClassName("com.vaadin.ui." + widgetName)); + } + + for (int i = 0, l = ids.size(); i < l; ++i) { + + // Fuzz the connector name, so that the client can provide (for + // example: /Button, /Button.class, /com.vaadin.ui.Button, + // /com.vaadin.ui.Button.class, etc) + + String name = ids.get(i); + final String simpleName = getSimpleClassName(name); + final String fullName = getFullClassName(name); + + if (widgetTags.length > 0) { + Integer[] foundTags = client.getConfiguration() + .getTagsForServerSideClassName(fullName); + for (int tag : foundTags) { + if (tagsMatch(widgetTags, tag)) { + return true; + } + } + } + + // Fallback if something failed before. + if (widgetName.equals(fullName + ".class") + || widgetName.equals(fullName) + || widgetName.equals(simpleName + ".class") + || widgetName.equals(simpleName) || widgetName.equals(name)) { + return true; + } + } + + // If the server-side class name didn't match, fall back to testing for + // the explicit widget name + String widget = Util.getSimpleName(connector.getWidget()); + return widgetName.equals(widget) + || widgetName.equals(widget + ".class"); + + } + + /** + * Extracts the name of the widget class from a path fragment + * + * @param pathFragment + * the path fragment + * @return the name of the widget class. + */ + private String getWidgetName(String pathFragment) { + String widgetName = pathFragment; + int ixBracket = pathFragment.indexOf('['); + if (ixBracket >= 0) { + widgetName = pathFragment.substring(0, ixBracket); + } + return widgetName; + } + + /** + * Splits off the first path fragment from a path and returns an array of + * two elements, where the first element is the first path fragment and the + * second element is the rest of the path (all remaining path fragments + * untouched). + * + * @param path + * The path to split. + * @return An array of two elements: The first path fragment and the rest of + * the path. + */ + private String[] splitFirstFragmentFromTheRest(String path) { + int ixOfSlash = LocatorUtil.indexOfIgnoringQuoted(path, '/'); + if (ixOfSlash > 0) { + return new String[] { path.substring(0, ixOfSlash), + path.substring(ixOfSlash) }; + } + return new String[] { path }; + } + + private String getSimpleClassName(String s) { + String[] parts = s.split("\\."); + if (s.endsWith(".class")) { + return parts[parts.length - 2]; + } + return parts.length > 0 ? parts[parts.length - 1] : s; + } + + private String getFullClassName(String s) { + if (s.endsWith(".class")) { + return s.substring(0, s.lastIndexOf(".class")); + } + return s; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.client.componentlocator.LocatorStrategy#validatePath(java. + * lang.String) + */ + @Override + public boolean validatePath(String path) { + // This syntax is so difficult to regexp properly, that we'll just try + // to find something with it regardless of the correctness of the + // syntax... + return true; + } + + /** + * Go through a list, removing all duplicate elements from it. This method + * is used to avoid accumulation of duplicate entries in result lists + * resulting from low-context recursion. + * + * Preserves first entry in list, removes others. Preserves list order. + * + * @return list passed as parameter, after modification + */ + private final <T> List<T> eliminateDuplicates(List<T> list) { + + int l = list.size(); + for (int j = 0; j < l; ++j) { + T ref = list.get(j); + + for (int i = j + 1; i < l; ++i) { + if (list.get(i) == ref) { + list.remove(i); + --i; + --l; + } + } + } + + return list; + } + + private boolean tagsMatch(Integer[] targets, Integer tag) { + for (int i = 0; i < targets.length; ++i) { + if (targets[i].equals(tag)) { + return true; + } + } + + try { + return tagsMatch(targets, + client.getConfiguration().getParentTag(tag)); + } catch (Exception e) { + return false; + } + } +} diff --git a/client/src/com/vaadin/client/debug/internal/AnalyzeLayoutsPanel.java b/client/src/com/vaadin/client/debug/internal/AnalyzeLayoutsPanel.java new file mode 100644 index 0000000000..7561bc2c03 --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/AnalyzeLayoutsPanel.java @@ -0,0 +1,267 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.debug.internal; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.google.gwt.core.client.JsArray; +import com.google.gwt.dom.client.Style.TextDecoration; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.event.dom.client.MouseOverEvent; +import com.google.gwt.event.dom.client.MouseOverHandler; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.VerticalPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.ApplicationConfiguration; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ComponentConnector; +import com.vaadin.client.ComputedStyle; +import com.vaadin.client.ConnectorMap; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.SimpleTree; +import com.vaadin.client.Util; +import com.vaadin.client.ValueMap; + +/** + * Analyze layouts view panel of the debug window. + * + * @since 7.1.4 + */ +public class AnalyzeLayoutsPanel extends FlowPanel { + + private List<SelectConnectorListener> listeners = new ArrayList<SelectConnectorListener>(); + + public void update() { + clear(); + add(new Label("Analyzing layouts...")); + List<ApplicationConnection> runningApplications = ApplicationConfiguration + .getRunningApplications(); + for (ApplicationConnection applicationConnection : runningApplications) { + applicationConnection.analyzeLayouts(); + } + } + + public void meta(ApplicationConnection ac, ValueMap meta) { + clear(); + JsArray<ValueMap> valueMapArray = meta + .getJSValueMapArray("invalidLayouts"); + int size = valueMapArray.length(); + + if (size > 0) { + SimpleTree root = new SimpleTree("Layouts analyzed, " + size + + " top level problems"); + for (int i = 0; i < size; i++) { + printLayoutError(ac, valueMapArray.get(i), root); + } + root.open(false); + add(root); + } else { + add(new Label("Layouts analyzed, no top level problems")); + } + + Set<ComponentConnector> zeroHeightComponents = new HashSet<ComponentConnector>(); + Set<ComponentConnector> zeroWidthComponents = new HashSet<ComponentConnector>(); + findZeroSizeComponents(zeroHeightComponents, zeroWidthComponents, + ac.getUIConnector()); + if (zeroHeightComponents.size() > 0 || zeroWidthComponents.size() > 0) { + add(new HTML("<h4> Client side notifications</h4>" + + " <em>The following relative sized components were " + + "rendered to a zero size container on the client side." + + " Note that these are not necessarily invalid " + + "states, but reported here as they might be.</em>")); + if (zeroHeightComponents.size() > 0) { + add(new HTML("<p><strong>Vertically zero size:</strong></p>")); + printClientSideDetectedIssues(zeroHeightComponents, ac); + } + if (zeroWidthComponents.size() > 0) { + add(new HTML("<p><strong>Horizontally zero size:</strong></p>")); + printClientSideDetectedIssues(zeroWidthComponents, ac); + } + } + + } + + private void printClientSideDetectedIssues( + Set<ComponentConnector> zeroSized, ApplicationConnection ac) { + + // keep track of already highlighted parents + HashSet<String> parents = new HashSet<String>(); + + for (final ComponentConnector connector : zeroSized) { + final ServerConnector parent = connector.getParent(); + final String parentId = parent.getConnectorId(); + + final Label errorDetails = new Label(Util.getSimpleName(connector) + + "[" + connector.getConnectorId() + "]" + " inside " + + Util.getSimpleName(parent)); + + if (parent instanceof ComponentConnector) { + final ComponentConnector parentConnector = (ComponentConnector) parent; + if (!parents.contains(parentId)) { + parents.add(parentId); + Highlight.show(parentConnector, "yellow"); + } + + errorDetails.addMouseOverHandler(new MouseOverHandler() { + @Override + public void onMouseOver(MouseOverEvent event) { + Highlight.hideAll(); + Highlight.show(parentConnector, "yellow"); + Highlight.show(connector); + errorDetails.getElement().getStyle() + .setTextDecoration(TextDecoration.UNDERLINE); + } + }); + errorDetails.addMouseOutHandler(new MouseOutHandler() { + @Override + public void onMouseOut(MouseOutEvent event) { + Highlight.hideAll(); + errorDetails.getElement().getStyle() + .setTextDecoration(TextDecoration.NONE); + } + }); + errorDetails.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + fireSelectEvent(connector); + } + }); + + } + + Highlight.show(connector); + add(errorDetails); + + } + } + + private void printLayoutError(ApplicationConnection ac, ValueMap valueMap, + SimpleTree root) { + final String pid = valueMap.getString("id"); + + // find connector + final ComponentConnector connector = (ComponentConnector) ConnectorMap + .get(ac).getConnector(pid); + + if (connector == null) { + root.add(new SimpleTree("[" + pid + "] NOT FOUND")); + return; + } + + Highlight.show(connector); + + final SimpleTree errorNode = new SimpleTree( + Util.getSimpleName(connector) + " id: " + pid); + errorNode.addDomHandler(new MouseOverHandler() { + @Override + public void onMouseOver(MouseOverEvent event) { + Highlight.showOnly(connector); + ((Widget) event.getSource()).getElement().getStyle() + .setTextDecoration(TextDecoration.UNDERLINE); + } + }, MouseOverEvent.getType()); + errorNode.addDomHandler(new MouseOutHandler() { + @Override + public void onMouseOut(MouseOutEvent event) { + Highlight.hideAll(); + ((Widget) event.getSource()).getElement().getStyle() + .setTextDecoration(TextDecoration.NONE); + } + }, MouseOutEvent.getType()); + + errorNode.addDomHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + if (event.getNativeEvent().getEventTarget().cast() == errorNode + .getElement().getChild(1).cast()) { + fireSelectEvent(connector); + } + } + }, ClickEvent.getType()); + + VerticalPanel errorDetails = new VerticalPanel(); + + if (valueMap.containsKey("heightMsg")) { + errorDetails.add(new Label("Height problem: " + + valueMap.getString("heightMsg"))); + } + if (valueMap.containsKey("widthMsg")) { + errorDetails.add(new Label("Width problem: " + + valueMap.getString("widthMsg"))); + } + if (errorDetails.getWidgetCount() > 0) { + errorNode.add(errorDetails); + } + if (valueMap.containsKey("subErrors")) { + HTML l = new HTML( + "<em>Expand this node to show problems that may be dependent on this problem.</em>"); + errorDetails.add(l); + JsArray<ValueMap> suberrors = valueMap + .getJSValueMapArray("subErrors"); + for (int i = 0; i < suberrors.length(); i++) { + ValueMap value = suberrors.get(i); + printLayoutError(ac, value, errorNode); + } + + } + root.add(errorNode); + } + + private void findZeroSizeComponents( + Set<ComponentConnector> zeroHeightComponents, + Set<ComponentConnector> zeroWidthComponents, + ComponentConnector connector) { + Widget widget = connector.getWidget(); + ComputedStyle computedStyle = new ComputedStyle(widget.getElement()); + if (computedStyle.getIntProperty("height") == 0) { + zeroHeightComponents.add(connector); + } + if (computedStyle.getIntProperty("width") == 0) { + zeroWidthComponents.add(connector); + } + List<ServerConnector> children = connector.getChildren(); + for (ServerConnector serverConnector : children) { + if (serverConnector instanceof ComponentConnector) { + findZeroSizeComponents(zeroHeightComponents, + zeroWidthComponents, + (ComponentConnector) serverConnector); + } + } + } + + public void addListener(SelectConnectorListener listener) { + listeners.add(listener); + } + + public void removeListener(SelectConnectorListener listener) { + listeners.remove(listener); + } + + private void fireSelectEvent(ServerConnector connector) { + for (SelectConnectorListener listener : listeners) { + listener.select(connector, null); + } + } + +} diff --git a/client/src/com/vaadin/client/debug/internal/ConnectorInfoPanel.java b/client/src/com/vaadin/client/debug/internal/ConnectorInfoPanel.java new file mode 100644 index 0000000000..fc7b55497e --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/ConnectorInfoPanel.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.debug.internal; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.vaadin.client.ComponentConnector; +import com.vaadin.client.JsArrayObject; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.Util; +import com.vaadin.client.VConsole; +import com.vaadin.client.metadata.NoDataException; +import com.vaadin.client.metadata.Property; +import com.vaadin.client.ui.AbstractConnector; +import com.vaadin.shared.AbstractComponentState; +import com.vaadin.shared.communication.SharedState; + +/** + * Connector information view panel of the debug window. + * + * @since 7.1.4 + */ +public class ConnectorInfoPanel extends FlowPanel { + + /** + * Update the panel to show information about a connector. + * + * @param connector + */ + public void update(ServerConnector connector) { + SharedState state = connector.getState(); + + Set<String> ignoreProperties = new HashSet<String>(); + ignoreProperties.add("id"); + + String html = getRowHTML("Id", connector.getConnectorId()); + html += getRowHTML("Connector", Util.getSimpleName(connector)); + + if (connector instanceof ComponentConnector) { + ComponentConnector component = (ComponentConnector) connector; + + ignoreProperties.addAll(Arrays.asList("caption", "description", + "width", "height")); + + AbstractComponentState componentState = component.getState(); + + html += getRowHTML("Widget", + Util.getSimpleName(component.getWidget())); + html += getRowHTML("Caption", componentState.caption); + html += getRowHTML("Description", componentState.description); + html += getRowHTML("Width", componentState.width + " (actual: " + + component.getWidget().getOffsetWidth() + "px)"); + html += getRowHTML("Height", componentState.height + " (actual: " + + component.getWidget().getOffsetHeight() + "px)"); + } + + try { + JsArrayObject<Property> properties = AbstractConnector + .getStateType(connector).getPropertiesAsArray(); + for (int i = 0; i < properties.size(); i++) { + Property property = properties.get(i); + String name = property.getName(); + if (!ignoreProperties.contains(name)) { + html += getRowHTML(property.getDisplayName(), + property.getValue(state)); + } + } + } catch (NoDataException e) { + html += "<div>Could not read state, error has been logged to the console</div>"; + VConsole.error(e); + } + + clear(); + add(new HTML(html)); + } + + private String getRowHTML(String caption, Object value) { + return "<div class=\"" + VDebugWindow.STYLENAME + + "-row\"><span class=\"caption\">" + caption + + "</span><span class=\"value\">" + + Util.escapeHTML(String.valueOf(value)) + "</span></div>"; + } + + /** + * Clear the contents of the panel. + */ + public void clearContents() { + clear(); + } +} diff --git a/client/src/com/vaadin/client/debug/internal/HierarchyPanel.java b/client/src/com/vaadin/client/debug/internal/HierarchyPanel.java new file mode 100644 index 0000000000..755f076b7a --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/HierarchyPanel.java @@ -0,0 +1,178 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.debug.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.DoubleClickEvent; +import com.google.gwt.event.dom.client.DoubleClickHandler; +import com.google.gwt.event.dom.client.HasDoubleClickHandlers; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HasWidgets; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.SimplePanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.ApplicationConfiguration; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.FastStringSet; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.SimpleTree; +import com.vaadin.client.Util; + +/** + * Hierarchy view panel of the debug window. This class can be used in various + * debug window sections to show the current connector hierarchy. + * + * @since 7.1.4 + */ +public class HierarchyPanel extends FlowPanel { + + // TODO separate click listeners for simple selection and doubleclick + private List<SelectConnectorListener> listeners = new ArrayList<SelectConnectorListener>(); + + public void update() { + // Try to keep track of currently open nodes and reopen them + FastStringSet openNodes = FastStringSet.create(); + Iterator<Widget> it = iterator(); + while (it.hasNext()) { + collectOpenNodes(it.next(), openNodes); + } + + clear(); + + SimplePanel trees = new SimplePanel(); + + for (ApplicationConnection application : ApplicationConfiguration + .getRunningApplications()) { + ServerConnector uiConnector = application.getUIConnector(); + Widget connectorTree = buildConnectorTree(uiConnector, openNodes); + + trees.add(connectorTree); + } + + add(trees); + } + + /** + * Adds the captions of all open (non-leaf) nodes in the hierarchy tree + * recursively. + * + * @param widget + * the widget in which to search for open nodes (if SimpleTree) + * @param openNodes + * the set in which open nodes should be added + */ + private void collectOpenNodes(Widget widget, FastStringSet openNodes) { + if (widget instanceof SimpleTree) { + SimpleTree tree = (SimpleTree) widget; + if (tree.isOpen()) { + openNodes.add(tree.getCaption()); + } else { + // no need to look inside closed nodes + return; + } + } + if (widget instanceof HasWidgets) { + Iterator<Widget> it = ((HasWidgets) widget).iterator(); + while (it.hasNext()) { + collectOpenNodes(it.next(), openNodes); + } + } + } + + private Widget buildConnectorTree(final ServerConnector connector, + FastStringSet openNodes) { + String connectorString = Util.getConnectorString(connector); + + List<ServerConnector> children = connector.getChildren(); + + Widget widget; + if (children == null || children.isEmpty()) { + // Leaf node, just add a label + Label label = new Label(connectorString); + label.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + Highlight.showOnly(connector); + showServerDebugInfo(connector); + } + }); + widget = label; + } else { + SimpleTree tree = new SimpleTree(connectorString) { + @Override + protected void select(ClickEvent event) { + super.select(event); + Highlight.showOnly(connector); + showServerDebugInfo(connector); + } + }; + for (ServerConnector child : children) { + tree.add(buildConnectorTree(child, openNodes)); + } + if (openNodes.contains(connectorString)) { + tree.open(false); + } + widget = tree; + } + + if (widget instanceof HasDoubleClickHandlers) { + HasDoubleClickHandlers has = (HasDoubleClickHandlers) widget; + has.addDoubleClickHandler(new DoubleClickHandler() { + @Override + public void onDoubleClick(DoubleClickEvent event) { + fireSelectEvent(connector); + } + }); + } + + return widget; + } + + public void addListener(SelectConnectorListener listener) { + listeners.add(listener); + } + + public void removeListener(SelectConnectorListener listener) { + listeners.remove(listener); + } + + private void fireSelectEvent(ServerConnector connector) { + for (SelectConnectorListener listener : listeners) { + listener.select(connector, null); + } + } + + /** + * Outputs debug information on the server - usually in the console of an + * IDE, with a clickable reference to the relevant code location. + * + * @since 7.1 + * @param connector + * show debug info for this connector + */ + static void showServerDebugInfo(ServerConnector connector) { + if (connector != null) { + connector.getConnection().getUIConnector() + .showServerDebugInfo(connector); + } + } + +} diff --git a/client/src/com/vaadin/client/debug/internal/HierarchySection.java b/client/src/com/vaadin/client/debug/internal/HierarchySection.java index 90c9086d7d..616bf70c38 100644 --- a/client/src/com/vaadin/client/debug/internal/HierarchySection.java +++ b/client/src/com/vaadin/client/debug/internal/HierarchySection.java @@ -15,23 +15,9 @@ */ package com.vaadin.client.debug.internal; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.google.gwt.core.client.JsArray; -import com.google.gwt.dom.client.Style.TextDecoration; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.event.dom.client.DoubleClickEvent; -import com.google.gwt.event.dom.client.DoubleClickHandler; -import com.google.gwt.event.dom.client.HasDoubleClickHandlers; import com.google.gwt.event.dom.client.KeyCodes; -import com.google.gwt.event.dom.client.MouseOutEvent; -import com.google.gwt.event.dom.client.MouseOutHandler; -import com.google.gwt.event.dom.client.MouseOverEvent; -import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; @@ -40,28 +26,15 @@ import com.google.gwt.user.client.Event.NativePreviewHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConfiguration; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ComponentConnector; -import com.vaadin.client.ComputedStyle; -import com.vaadin.client.ConnectorMap; -import com.vaadin.client.JsArrayObject; import com.vaadin.client.ServerConnector; -import com.vaadin.client.SimpleTree; import com.vaadin.client.Util; -import com.vaadin.client.VConsole; import com.vaadin.client.ValueMap; -import com.vaadin.client.metadata.NoDataException; -import com.vaadin.client.metadata.Property; -import com.vaadin.client.ui.AbstractConnector; -import com.vaadin.client.ui.UnknownComponentConnector; -import com.vaadin.shared.AbstractComponentState; -import com.vaadin.shared.communication.SharedState; /** * Provides functionality for examining the UI component hierarchy. @@ -73,7 +46,15 @@ public class HierarchySection implements Section { private final DebugButton tabButton = new DebugButton(Icon.HIERARCHY, "Examine component hierarchy"); - private final FlowPanel content = new FlowPanel(); + private final SimplePanel content = new SimplePanel(); + + // TODO highlighting logic is split between these, should be refactored + private final FlowPanel helpPanel = new FlowPanel(); + private final ConnectorInfoPanel infoPanel = new ConnectorInfoPanel(); + private final HierarchyPanel hierarchyPanel = new HierarchyPanel(); + private final OptimizedWidgetsetPanel widgetsetPanel = new OptimizedWidgetsetPanel(); + private final AnalyzeLayoutsPanel analyzeLayoutsPanel = new AnalyzeLayoutsPanel(); + private final FlowPanel controls = new FlowPanel(); private final Button find = new DebugButton(Icon.HIGHLIGHT, @@ -125,79 +106,40 @@ public class HierarchySection implements Section { } }); + hierarchyPanel.addListener(new SelectConnectorListener() { + @Override + public void select(ServerConnector connector, Element element) { + printState(connector, true); + } + }); + + analyzeLayoutsPanel.addListener(new SelectConnectorListener() { + @Override + public void select(ServerConnector connector, Element element) { + printState(connector, true); + } + }); + content.setStylePrimaryName(VDebugWindow.STYLENAME + "-hierarchy"); + initializeHelpPanel(); + content.setWidget(helpPanel); + } + + private void initializeHelpPanel() { HTML info = new HTML(showHierarchy.getHTML() + " " + showHierarchy.getTitle() + "<br/>" + find.getHTML() + " " + find.getTitle() + "<br/>" + analyze.getHTML() + " " + analyze.getTitle() + "<br/>" + generateWS.getHTML() + " " + generateWS.getTitle() + "<br/>"); info.setStyleName(VDebugWindow.STYLENAME + "-info"); - content.add(info); + helpPanel.add(info); } private void showHierarchy() { Highlight.hideAll(); - content.clear(); - - // TODO Clearing and rebuilding the contents is not optimal for UX as - // any previous expansions are lost. - SimplePanel trees = new SimplePanel(); - - for (ApplicationConnection application : ApplicationConfiguration - .getRunningApplications()) { - ServerConnector uiConnector = application.getUIConnector(); - Widget connectorTree = buildConnectorTree(uiConnector); - - trees.add(connectorTree); - } - - content.add(trees); - } - - private Widget buildConnectorTree(final ServerConnector connector) { - String connectorString = Util.getConnectorString(connector); - - List<ServerConnector> children = connector.getChildren(); - - Widget widget; - if (children == null || children.isEmpty()) { - // Leaf node, just add a label - Label label = new Label(connectorString); - label.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - Highlight.showOnly(connector); - Highlight.showServerDebugInfo(connector); - } - }); - widget = label; - } else { - SimpleTree tree = new SimpleTree(connectorString) { - @Override - protected void select(ClickEvent event) { - super.select(event); - Highlight.showOnly(connector); - Highlight.showServerDebugInfo(connector); - } - }; - for (ServerConnector child : children) { - tree.add(buildConnectorTree(child)); - } - widget = tree; - } - - if (widget instanceof HasDoubleClickHandlers) { - HasDoubleClickHandlers has = (HasDoubleClickHandlers) widget; - has.addDoubleClickHandler(new DoubleClickHandler() { - @Override - public void onDoubleClick(DoubleClickEvent event) { - printState(connector, true); - } - }); - } - - return widget; + hierarchyPanel.update(); + content.setWidget(hierarchyPanel); } @Override @@ -226,302 +168,19 @@ public class HierarchySection implements Section { } private void generateWidgetset() { - - content.clear(); - HTML h = new HTML("Getting used connectors"); - content.add(h); - - String s = ""; - for (ApplicationConnection ac : ApplicationConfiguration - .getRunningApplications()) { - ApplicationConfiguration conf = ac.getConfiguration(); - s += "<h1>Used connectors for " + conf.getServiceUrl() + "</h1>"; - - for (String connectorName : getUsedConnectorNames(conf)) { - s += connectorName + "<br/>"; - } - - s += "<h2>To make an optimized widgetset based on these connectors, do:</h2>"; - s += "<h3>1. Add to your widgetset.gwt.xml file:</h2>"; - s += "<textarea rows=\"3\" style=\"width:90%\">"; - s += "<generate-with class=\"OptimizedConnectorBundleLoaderFactory\">\n"; - s += " <when-type-assignable class=\"com.vaadin.client.metadata.ConnectorBundleLoader\" />\n"; - s += "</generate-with>"; - s += "</textarea>"; - - s += "<h3>2. Add the following java file to your project:</h2>"; - s += "<textarea rows=\"5\" style=\"width:90%\">"; - s += generateOptimizedWidgetSet(getUsedConnectorNames(conf)); - s += "</textarea>"; - s += "<h3>3. Recompile widgetset</h2>"; - - } - - h.setHTML(s); - } - - private Set<String> getUsedConnectorNames( - ApplicationConfiguration configuration) { - int tag = 0; - Set<String> usedConnectors = new HashSet<String>(); - while (true) { - String serverSideClass = configuration - .getServerSideClassNameForTag(tag); - if (serverSideClass == null) { - break; - } - Class<? extends ServerConnector> connectorClass = configuration - .getConnectorClassByEncodedTag(tag); - if (connectorClass == null) { - break; - } - - if (connectorClass != UnknownComponentConnector.class) { - usedConnectors.add(connectorClass.getName()); - } - tag++; - if (tag > 10000) { - // Sanity check - VConsole.error("Search for used connector classes was forcefully terminated"); - break; - } - } - return usedConnectors; - } - - public String generateOptimizedWidgetSet(Set<String> usedConnectors) { - String s = "import java.util.HashSet;\n"; - s += "import java.util.Set;\n"; - - s += "import com.google.gwt.core.ext.typeinfo.JClassType;\n"; - s += "import com.vaadin.client.ui.ui.UIConnector;\n"; - s += "import com.vaadin.server.widgetsetutils.ConnectorBundleLoaderFactory;\n"; - s += "import com.vaadin.shared.ui.Connect.LoadStyle;\n\n"; - - s += "public class OptimizedConnectorBundleLoaderFactory extends\n"; - s += " ConnectorBundleLoaderFactory {\n"; - s += " private Set<String> eagerConnectors = new HashSet<String>();\n"; - s += " {\n"; - for (String c : usedConnectors) { - s += " eagerConnectors.add(" + c - + ".class.getName());\n"; - } - s += " }\n"; - s += "\n"; - s += " @Override\n"; - s += " protected LoadStyle getLoadStyle(JClassType connectorType) {\n"; - s += " if (eagerConnectors.contains(connectorType.getQualifiedBinaryName())) {\n"; - s += " return LoadStyle.EAGER;\n"; - s += " } else {\n"; - s += " // Loads all other connectors immediately after the initial view has\n"; - s += " // been rendered\n"; - s += " return LoadStyle.DEFERRED;\n"; - s += " }\n"; - s += " }\n"; - s += "}\n"; - - return s; + widgetsetPanel.update(); + content.setWidget(widgetsetPanel); } private void analyzeLayouts() { - content.clear(); - content.add(new Label("Analyzing layouts...")); - List<ApplicationConnection> runningApplications = ApplicationConfiguration - .getRunningApplications(); - for (ApplicationConnection applicationConnection : runningApplications) { - applicationConnection.analyzeLayouts(); - } + analyzeLayoutsPanel.update(); + content.setWidget(analyzeLayoutsPanel); } @Override public void meta(ApplicationConnection ac, ValueMap meta) { - content.clear(); - JsArray<ValueMap> valueMapArray = meta - .getJSValueMapArray("invalidLayouts"); - int size = valueMapArray.length(); - - if (size > 0) { - SimpleTree root = new SimpleTree("Layouts analyzed, " + size - + " top level problems"); - for (int i = 0; i < size; i++) { - printLayoutError(ac, valueMapArray.get(i), root); - } - root.open(false); - content.add(root); - } else { - content.add(new Label("Layouts analyzed, no top level problems")); - } - - Set<ComponentConnector> zeroHeightComponents = new HashSet<ComponentConnector>(); - Set<ComponentConnector> zeroWidthComponents = new HashSet<ComponentConnector>(); - findZeroSizeComponents(zeroHeightComponents, zeroWidthComponents, - ac.getUIConnector()); - if (zeroHeightComponents.size() > 0 || zeroWidthComponents.size() > 0) { - content.add(new HTML("<h4> Client side notifications</h4>" - + " <em>The following relative sized components were " - + "rendered to a zero size container on the client side." - + " Note that these are not necessarily invalid " - + "states, but reported here as they might be.</em>")); - if (zeroHeightComponents.size() > 0) { - content.add(new HTML( - "<p><strong>Vertically zero size:</strong></p>")); - printClientSideDetectedIssues(zeroHeightComponents, ac); - } - if (zeroWidthComponents.size() > 0) { - content.add(new HTML( - "<p><strong>Horizontally zero size:</strong></p>")); - printClientSideDetectedIssues(zeroWidthComponents, ac); - } - } - - } - - private void printClientSideDetectedIssues( - Set<ComponentConnector> zeroSized, ApplicationConnection ac) { - - // keep track of already highlighted parents - HashSet<String> parents = new HashSet<String>(); - - for (final ComponentConnector connector : zeroSized) { - final ServerConnector parent = connector.getParent(); - final String parentId = parent.getConnectorId(); - - final Label errorDetails = new Label(Util.getSimpleName(connector) - + "[" + connector.getConnectorId() + "]" + " inside " - + Util.getSimpleName(parent)); - - if (parent instanceof ComponentConnector) { - final ComponentConnector parentConnector = (ComponentConnector) parent; - if (!parents.contains(parentId)) { - parents.add(parentId); - Highlight.show(parentConnector, "yellow"); - } - - errorDetails.addMouseOverHandler(new MouseOverHandler() { - @Override - public void onMouseOver(MouseOverEvent event) { - Highlight.hideAll(); - Highlight.show(parentConnector, "yellow"); - Highlight.show(connector); - errorDetails.getElement().getStyle() - .setTextDecoration(TextDecoration.UNDERLINE); - } - }); - errorDetails.addMouseOutHandler(new MouseOutHandler() { - @Override - public void onMouseOut(MouseOutEvent event) { - Highlight.hideAll(); - errorDetails.getElement().getStyle() - .setTextDecoration(TextDecoration.NONE); - } - }); - errorDetails.addClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - printState(connector, true); - } - }); - - } - - Highlight.show(connector); - content.add(errorDetails); - - } - } - - private void printLayoutError(ApplicationConnection ac, ValueMap valueMap, - SimpleTree root) { - final String pid = valueMap.getString("id"); - - // find connector - final ComponentConnector connector = (ComponentConnector) ConnectorMap - .get(ac).getConnector(pid); - - if (connector == null) { - root.add(new SimpleTree("[" + pid + "] NOT FOUND")); - return; - } - - Highlight.show(connector); - - final SimpleTree errorNode = new SimpleTree( - Util.getSimpleName(connector) + " id: " + pid); - errorNode.addDomHandler(new MouseOverHandler() { - @Override - public void onMouseOver(MouseOverEvent event) { - Highlight.showOnly(connector); - ((Widget) event.getSource()).getElement().getStyle() - .setTextDecoration(TextDecoration.UNDERLINE); - } - }, MouseOverEvent.getType()); - errorNode.addDomHandler(new MouseOutHandler() { - @Override - public void onMouseOut(MouseOutEvent event) { - Highlight.hideAll(); - ((Widget) event.getSource()).getElement().getStyle() - .setTextDecoration(TextDecoration.NONE); - } - }, MouseOutEvent.getType()); - - errorNode.addDomHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - if (event.getNativeEvent().getEventTarget().cast() == errorNode - .getElement().getChild(1).cast()) { - printState(connector, true); - } - } - }, ClickEvent.getType()); - - VerticalPanel errorDetails = new VerticalPanel(); - - if (valueMap.containsKey("heightMsg")) { - errorDetails.add(new Label("Height problem: " - + valueMap.getString("heightMsg"))); - } - if (valueMap.containsKey("widthMsg")) { - errorDetails.add(new Label("Width problem: " - + valueMap.getString("widthMsg"))); - } - if (errorDetails.getWidgetCount() > 0) { - errorNode.add(errorDetails); - } - if (valueMap.containsKey("subErrors")) { - HTML l = new HTML( - "<em>Expand this node to show problems that may be dependent on this problem.</em>"); - errorDetails.add(l); - JsArray<ValueMap> suberrors = valueMap - .getJSValueMapArray("subErrors"); - for (int i = 0; i < suberrors.length(); i++) { - ValueMap value = suberrors.get(i); - printLayoutError(ac, value, errorNode); - } - - } - root.add(errorNode); - } - - private void findZeroSizeComponents( - Set<ComponentConnector> zeroHeightComponents, - Set<ComponentConnector> zeroWidthComponents, - ComponentConnector connector) { - Widget widget = connector.getWidget(); - ComputedStyle computedStyle = new ComputedStyle(widget.getElement()); - if (computedStyle.getIntProperty("height") == 0) { - zeroHeightComponents.add(connector); - } - if (computedStyle.getIntProperty("width") == 0) { - zeroWidthComponents.add(connector); - } - List<ServerConnector> children = connector.getChildren(); - for (ServerConnector serverConnector : children) { - if (serverConnector instanceof ComponentConnector) { - findZeroSizeComponents(zeroHeightComponents, - zeroWidthComponents, - (ComponentConnector) serverConnector); - } - } + // show the results of analyzeLayouts + analyzeLayoutsPanel.meta(ac, meta); } @Override @@ -561,60 +220,11 @@ public class HierarchySection implements Section { private void printState(ServerConnector connector, boolean serverDebug) { Highlight.showOnly(connector); if (serverDebug) { - Highlight.showServerDebugInfo(connector); + HierarchyPanel.showServerDebugInfo(connector); } - SharedState state = connector.getState(); - - Set<String> ignoreProperties = new HashSet<String>(); - ignoreProperties.add("id"); - - String html = getRowHTML("Id", connector.getConnectorId()); - html += getRowHTML("Connector", Util.getSimpleName(connector)); - - if (connector instanceof ComponentConnector) { - ComponentConnector component = (ComponentConnector) connector; - - ignoreProperties.addAll(Arrays.asList("caption", "description", - "width", "height")); - - AbstractComponentState componentState = component.getState(); - - html += getRowHTML("Widget", - Util.getSimpleName(component.getWidget())); - html += getRowHTML("Caption", componentState.caption); - html += getRowHTML("Description", componentState.description); - html += getRowHTML("Width", componentState.width + " (actual: " - + component.getWidget().getOffsetWidth() + "px)"); - html += getRowHTML("Height", componentState.height + " (actual: " - + component.getWidget().getOffsetHeight() + "px)"); - } - - try { - JsArrayObject<Property> properties = AbstractConnector - .getStateType(connector).getPropertiesAsArray(); - for (int i = 0; i < properties.size(); i++) { - Property property = properties.get(i); - String name = property.getName(); - if (!ignoreProperties.contains(name)) { - html += getRowHTML(property.getDisplayName(), - property.getValue(state)); - } - } - } catch (NoDataException e) { - html += "<div>Could not read state, error has been logged to the console</div>"; - VConsole.error(e); - } - - content.clear(); - content.add(new HTML(html)); - } - - private String getRowHTML(String caption, Object value) { - return "<div class=\"" + VDebugWindow.STYLENAME - + "-row\"><span class=\"caption\">" + caption - + "</span><span class=\"value\">" - + Util.escapeHTML(String.valueOf(value)) + "</span></div>"; + infoPanel.update(connector); + content.setWidget(infoPanel); } private final NativePreviewHandler highlightModeHandler = new NativePreviewHandler() { @@ -634,7 +244,7 @@ public class HierarchySection implements Section { .getNativeEvent().getClientX(), event.getNativeEvent() .getClientY()); if (VDebugWindow.get().getElement().isOrHasChild(eventTarget)) { - content.clear(); + infoPanel.clear(); return; } @@ -654,7 +264,7 @@ public class HierarchySection implements Section { return; } } - content.clear(); + infoPanel.clear(); } if (event.getTypeInt() == Event.ONCLICK) { Highlight.hideAll(); diff --git a/client/src/com/vaadin/client/debug/internal/Highlight.java b/client/src/com/vaadin/client/debug/internal/Highlight.java index 3c1af445a9..5ee3a25e2c 100644 --- a/client/src/com/vaadin/client/debug/internal/Highlight.java +++ b/client/src/com/vaadin/client/debug/internal/Highlight.java @@ -144,20 +144,55 @@ public class Highlight { */ static Element show(Widget widget, String color) { if (widget != null) { + show(widget.getElement(), color); + } + return null; + } + + /** + * Highlights the given {@link Element}. + * <p> + * Pass the returned {@link Element} to {@link #hide(Element)} to remove + * this particular highlight. + * </p> + * + * @param element + * Element to highlight + * @return Highlight element + */ + static Element show(Element element) { + return show(element, DEFAULT_COLOR); + } + + /** + * Highlight the given {@link Element} using the given color. + * <p> + * Pass the returned highlight {@link Element} to {@link #hide(Element)} to + * remove this particular highlight. + * </p> + * + * @param element + * Element to highlight + * @param color + * Color of highlight + * @return Highlight element + */ + static Element show(Element element, String color) { + if (element != null) { if (highlights == null) { highlights = new HashSet<Element>(); } Element highlight = DOM.createDiv(); Style style = highlight.getStyle(); - style.setTop(widget.getAbsoluteTop(), Unit.PX); - style.setLeft(widget.getAbsoluteLeft(), Unit.PX); - int width = widget.getOffsetWidth(); + style.setTop(element.getAbsoluteTop(), Unit.PX); + style.setLeft(element.getAbsoluteLeft(), Unit.PX); + int width = element.getOffsetWidth(); if (width < MIN_WIDTH) { width = MIN_WIDTH; } style.setWidth(width, Unit.PX); - int height = widget.getOffsetHeight(); + int height = element.getOffsetHeight(); if (height < MIN_HEIGHT) { height = MIN_HEIGHT; } @@ -207,19 +242,4 @@ public class Highlight { } } - /** - * Outputs debug information on the server - usually in the console of an - * IDE, with a clickable reference to the relevant code location. - * - * @since 7.1 - * @param connector - * show debug info for this connector - */ - static void showServerDebugInfo(ServerConnector connector) { - if (connector != null) { - connector.getConnection().getUIConnector() - .showServerDebugInfo(connector); - } - } - } diff --git a/client/src/com/vaadin/client/debug/internal/Icon.java b/client/src/com/vaadin/client/debug/internal/Icon.java index cc2ef3b348..70bac11175 100644 --- a/client/src/com/vaadin/client/debug/internal/Icon.java +++ b/client/src/com/vaadin/client/debug/internal/Icon.java @@ -32,6 +32,8 @@ public enum Icon { LOG(""), // OPTIMIZE(""), // HIERARCHY(""), // + // TODO create more appropriate icon + SELECTOR("≣"), // MENU(""), // NETWORK(""), // ANALYZE(""), // @@ -42,7 +44,9 @@ public enum Icon { // BAN_CIRCLE(""), // MAXIMIZE(""), // RESET(""), // - PERSIST(""); // + PERSIST(""), // + TESTBENCH(""), // + ; private String id; diff --git a/client/src/com/vaadin/client/debug/internal/OptimizedWidgetsetPanel.java b/client/src/com/vaadin/client/debug/internal/OptimizedWidgetsetPanel.java new file mode 100644 index 0000000000..a8d8aad888 --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/OptimizedWidgetsetPanel.java @@ -0,0 +1,137 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.debug.internal; + +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.vaadin.client.ApplicationConfiguration; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.VConsole; +import com.vaadin.client.ui.UnknownComponentConnector; + +/** + * Optimized widgetset view panel of the debug window. + * + * @since 7.1.4 + */ +public class OptimizedWidgetsetPanel extends FlowPanel { + + /** + * Update the panel contents based on the connectors that have been used so + * far on this execution of the application. + */ + public void update() { + clear(); + HTML h = new HTML("Getting used connectors"); + add(h); + + String s = ""; + for (ApplicationConnection ac : ApplicationConfiguration + .getRunningApplications()) { + ApplicationConfiguration conf = ac.getConfiguration(); + s += "<h1>Used connectors for " + conf.getServiceUrl() + "</h1>"; + + for (String connectorName : getUsedConnectorNames(conf)) { + s += connectorName + "<br/>"; + } + + s += "<h2>To make an optimized widgetset based on these connectors, do:</h2>"; + s += "<h3>1. Add to your widgetset.gwt.xml file:</h2>"; + s += "<textarea rows=\"3\" style=\"width:90%\">"; + s += "<generate-with class=\"OptimizedConnectorBundleLoaderFactory\">\n"; + s += " <when-type-assignable class=\"com.vaadin.client.metadata.ConnectorBundleLoader\" />\n"; + s += "</generate-with>"; + s += "</textarea>"; + + s += "<h3>2. Add the following java file to your project:</h2>"; + s += "<textarea rows=\"5\" style=\"width:90%\">"; + s += generateOptimizedWidgetSet(getUsedConnectorNames(conf)); + s += "</textarea>"; + s += "<h3>3. Recompile widgetset</h2>"; + + } + + h.setHTML(s); + } + + private Set<String> getUsedConnectorNames( + ApplicationConfiguration configuration) { + int tag = 0; + Set<String> usedConnectors = new HashSet<String>(); + while (true) { + String serverSideClass = configuration + .getServerSideClassNameForTag(tag); + if (serverSideClass == null) { + break; + } + Class<? extends ServerConnector> connectorClass = configuration + .getConnectorClassByEncodedTag(tag); + if (connectorClass == null) { + break; + } + + if (connectorClass != UnknownComponentConnector.class) { + usedConnectors.add(connectorClass.getName()); + } + tag++; + if (tag > 10000) { + // Sanity check + VConsole.error("Search for used connector classes was forcefully terminated"); + break; + } + } + return usedConnectors; + } + + public String generateOptimizedWidgetSet(Set<String> usedConnectors) { + String s = "import java.util.HashSet;\n"; + s += "import java.util.Set;\n"; + + s += "import com.google.gwt.core.ext.typeinfo.JClassType;\n"; + s += "import com.vaadin.client.ui.ui.UIConnector;\n"; + s += "import com.vaadin.server.widgetsetutils.ConnectorBundleLoaderFactory;\n"; + s += "import com.vaadin.shared.ui.Connect.LoadStyle;\n\n"; + + s += "public class OptimizedConnectorBundleLoaderFactory extends\n"; + s += " ConnectorBundleLoaderFactory {\n"; + s += " private Set<String> eagerConnectors = new HashSet<String>();\n"; + s += " {\n"; + for (String c : usedConnectors) { + s += " eagerConnectors.add(" + c + + ".class.getName());\n"; + } + s += " }\n"; + s += "\n"; + s += " @Override\n"; + s += " protected LoadStyle getLoadStyle(JClassType connectorType) {\n"; + s += " if (eagerConnectors.contains(connectorType.getQualifiedBinaryName())) {\n"; + s += " return LoadStyle.EAGER;\n"; + s += " } else {\n"; + s += " // Loads all other connectors immediately after the initial view has\n"; + s += " // been rendered\n"; + s += " return LoadStyle.DEFERRED;\n"; + s += " }\n"; + s += " }\n"; + s += "}\n"; + + return s; + } + +} diff --git a/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java b/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java new file mode 100644 index 0000000000..409f9d14ce --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.debug.internal; + +import com.google.gwt.user.client.Element; +import com.vaadin.client.ServerConnector; + +/** + * Listener for the selection of a connector in the debug window. + * + * @since 7.1.4 + */ +public interface SelectConnectorListener { + /** + * Listener method called when a connector has been selected. If a specific + * element of the connector was selected, it is also given. + * + * @param connector + * selected connector + * @param element + * selected element of the connector or null if unknown + */ + public void select(ServerConnector connector, Element element); +}
\ No newline at end of file diff --git a/client/src/com/vaadin/client/debug/internal/SelectorPath.java b/client/src/com/vaadin/client/debug/internal/SelectorPath.java new file mode 100644 index 0000000000..e7fb0801db --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/SelectorPath.java @@ -0,0 +1,246 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.client.debug.internal; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.google.gwt.user.client.Element; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.componentlocator.ComponentLocator; +import com.vaadin.client.componentlocator.SelectorPredicate; + +/** + * A single segment of a selector path pointing to an Element. + * <p> + * This class should be considered internal to the framework and may change at + * any time. + * <p> + * + * @since 7.1.x + */ +public class SelectorPath { + private final String path; + private final Element element; + private final ComponentLocator locator; + private static Map<String, Integer> counter = new HashMap<String, Integer>(); + private static Map<String, String> legacyNames = new HashMap<String, String>(); + + static { + legacyNames.put("FilterSelect", "ComboBox"); + legacyNames.put("ScrollTable", "Table"); + } + + protected SelectorPath(ServerConnector c, Element e) { + element = e; + locator = new ComponentLocator(c.getConnection()); + path = locator.getPathForElement(e); + } + + public String getPath() { + return path; + } + + public Element getElement() { + return element; + } + + public ComponentLocator getLocator() { + return locator; + } + + /** + * Generate ElementQuery code for Java. Fallback to By.vaadin(path) if + * dealing with LegacyLocator + * + * @return String containing Java code for finding the element described by + * path + */ + public String getElementQuery() { + if (path.isEmpty() || locator.isValidForLegacyLocator(path)) { + return getLegacyLocatorQuery(); + } + + String[] fragments; + String tmpPath = path; + List<SelectorPredicate> postFilters = SelectorPredicate + .extractPostFilterPredicates(path); + if (postFilters.size() > 0) { + tmpPath = tmpPath.substring(1, tmpPath.lastIndexOf(')')); + } + + // Generate an ElementQuery + fragments = tmpPath.split("/"); + String elementQueryString = ""; + int index = 0; + for (SelectorPredicate p : postFilters) { + if (p.getIndex() > 0) { + index = p.getIndex(); + } + } + + for (int i = 1; i < fragments.length; ++i) { + if (fragments[i].isEmpty()) { + // Recursive searches cause empty fragments + continue; + } + + // if i == 1 or previous fragment was empty, search is recursive + boolean recursive = (i > 1 ? fragments[i - 1].isEmpty() : false); + + // if elementQueryString is not empty, join the next query with . + String queryFragment = (!elementQueryString.isEmpty() ? "." : ""); + // if search is not recursive, add another $ in front of fragment + queryFragment += (!recursive ? "$" : "") + + generateFragment(fragments[i]); + + elementQueryString += queryFragment; + } + + if (index == 0) { + elementQueryString += ".first()"; + } else { + elementQueryString += ".get(" + index + ");"; + } + + // Return full Java variable assignment and eQuery + return generateJavaVariable(fragments[fragments.length - 1]) + + elementQueryString; + } + + /** + * Generates a recursive ElementQuery for given path fragment + * + * @return ElementQuery java code as a String + */ + private String generateFragment(String fragment) { + // Get Element.class -name + String elementClass = getComponentName(fragment) + "Element.class"; + + String queryFragment = "$(" + elementClass + ")"; + + for (SelectorPredicate p : SelectorPredicate + .extractPredicates(fragment)) { + // Add in predicates like .caption and .id + queryFragment += "." + p.getName() + "(\"" + p.getValue() + "\")"; + } + return queryFragment; + } + + /** + * @since + * @param frags + * @param i + * @return + */ + protected String getComponentName(String fragment) { + return fragment.split("\\[")[0]; + } + + /** + * Generates a legacy locator for SelectorPath. + * + * @return String containing Java code for element search and assignment + */ + private String getLegacyLocatorQuery() { + String name; + if (!path.isEmpty()) { + String[] frags = path.split("/"); + name = getComponentName(frags[frags.length - 1]).substring(1); + } else { + name = "root"; + } + + if (legacyNames.containsKey(name)) { + name = legacyNames.get(name); + } + + name = getNameWithCount(name); + + // Use direct path and elementX naming style. + return "WebElement " + name.substring(0, 1).toLowerCase() + + name.substring(1) + " = getDriver().findElement(By.vaadin(\"" + + path + "\"));"; + } + + /** + * Get variable name with counter for given component name. + * + * @param name + * Component name + * @return name followed by count + */ + protected String getNameWithCount(String name) { + if (!counter.containsKey(name)) { + counter.put(name, 0); + } + counter.put(name, counter.get(name) + 1); + name += counter.get(name); + return name; + } + + /** + * Generate Java variable assignment from given selector fragment + * + * @param pathFragment + * Selector fragment + * @return piece of java code + */ + private String generateJavaVariable(String pathFragment) { + // Get element type and predicates from fragment + List<SelectorPredicate> predicates = SelectorPredicate + .extractPredicates(pathFragment); + String elementType = pathFragment.split("\\[")[0]; + String name = getNameFromPredicates(predicates, elementType); + + if (name.equals(elementType)) { + name = getNameWithCount(name); + } + + // Replace unusable characters + name = name.replaceAll("\\W", ""); + + // Lowercase the first character of name + return elementType + "Element " + name.substring(0, 1).toLowerCase() + + name.substring(1) + " = "; + } + + /** + * Get variable name based on predicates. Fallback to elementType + * + * @param predicates + * Predicates related to element + * @param elementType + * Element type + * @return name for Variable + */ + private String getNameFromPredicates(List<SelectorPredicate> predicates, + String elementType) { + String name = elementType; + for (SelectorPredicate p : predicates) { + if ("caption".equals(p.getName())) { + // Caption + elementType is a suitable name + name = p.getValue() + elementType; + } else if ("id".equals(p.getName())) { + // Just id. This is unique, use it. + return p.getValue(); + } + } + return name; + } +}
\ No newline at end of file diff --git a/client/src/com/vaadin/client/debug/internal/TestBenchSection.java b/client/src/com/vaadin/client/debug/internal/TestBenchSection.java new file mode 100644 index 0000000000..b3b2d3ad86 --- /dev/null +++ b/client/src/com/vaadin/client/debug/internal/TestBenchSection.java @@ -0,0 +1,281 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.debug.internal; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.MouseOutEvent; +import com.google.gwt.event.dom.client.MouseOutHandler; +import com.google.gwt.event.dom.client.MouseOverEvent; +import com.google.gwt.event.dom.client.MouseOverHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Event.NativePreviewEvent; +import com.google.gwt.user.client.Event.NativePreviewHandler; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.ApplicationConfiguration; +import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ComponentConnector; +import com.vaadin.client.ServerConnector; +import com.vaadin.client.Util; +import com.vaadin.client.ValueMap; + +/** + * Provides functionality for picking selectors for Vaadin TestBench. + * + * @since 7.1.x + * @author Vaadin Ltd + */ +public class TestBenchSection implements Section { + + /** + * Selector widget showing a selector in a program-usable form. + */ + private static class SelectorWidget extends HTML implements + MouseOverHandler, MouseOutHandler { + private final SelectorPath path; + + public SelectorWidget(final SelectorPath path) { + this.path = path; + + String html = "<div class=\"" + VDebugWindow.STYLENAME + + "-selector\"><span class=\"tb-selector\">" + + Util.escapeHTML(path.getElementQuery()) + "</span></div>"; + setHTML(html); + + addMouseOverHandler(this); + addMouseOutHandler(this); + } + + @Override + public void onMouseOver(MouseOverEvent event) { + Highlight.hideAll(); + + Element element = path.getElement(); + if (null != element) { + Highlight.show(element); + } + } + + @Override + public void onMouseOut(MouseOutEvent event) { + Highlight.hideAll(); + } + } + + private final DebugButton tabButton = new DebugButton(Icon.TESTBENCH, + "Pick Vaadin TestBench selectors"); + + private final FlowPanel content = new FlowPanel(); + + private final FlowPanel selectorPanel = new FlowPanel(); + // map from full path to SelectorWidget to enable reuse of old selectors + private Map<SelectorPath, SelectorWidget> selectorWidgets = new HashMap<SelectorPath, SelectorWidget>(); + + private final FlowPanel controls = new FlowPanel(); + + private final Button find = new DebugButton(Icon.HIGHLIGHT, + "Pick an element and generate a query for it"); + + private final Button clear = new DebugButton(Icon.CLEAR, + "Clear current elements"); + + private HandlerRegistration highlightModeRegistration = null; + + public TestBenchSection() { + + controls.add(find); + find.setStylePrimaryName(VDebugWindow.STYLENAME_BUTTON); + find.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + toggleFind(); + } + }); + + controls.add(clear); + clear.setStylePrimaryName(VDebugWindow.STYLENAME_BUTTON); + clear.addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + clearResults(); + } + }); + + content.setStylePrimaryName(VDebugWindow.STYLENAME + "-testbench"); + content.add(selectorPanel); + } + + @Override + public DebugButton getTabButton() { + return tabButton; + } + + @Override + public Widget getControls() { + return controls; + } + + @Override + public Widget getContent() { + return content; + } + + @Override + public void show() { + + } + + @Override + public void hide() { + stopFind(); + } + + @Override + public void meta(ApplicationConnection ac, ValueMap meta) { + // NOP + } + + @Override + public void uidl(ApplicationConnection ac, ValueMap uidl) { + // NOP + } + + private boolean isFindMode() { + return (highlightModeRegistration != null); + } + + private void toggleFind() { + if (isFindMode()) { + stopFind(); + } else { + startFind(); + } + } + + private void startFind() { + Highlight.hideAll(); + if (!isFindMode()) { + highlightModeRegistration = Event + .addNativePreviewHandler(highlightModeHandler); + find.addStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); + } + } + + private void stopFind() { + if (isFindMode()) { + highlightModeRegistration.removeHandler(); + highlightModeRegistration = null; + find.removeStyleDependentName(VDebugWindow.STYLENAME_ACTIVE); + } + Highlight.hideAll(); + } + + private void pickSelector(ServerConnector connector, Element element) { + + SelectorPath p = new SelectorPath(connector, Util + .findPaintable(connector.getConnection(), element).getWidget() + .getElement()); + SelectorWidget w = new SelectorWidget(p); + + content.add(w); + } + + private final NativePreviewHandler highlightModeHandler = new NativePreviewHandler() { + + @Override + public void onPreviewNativeEvent(NativePreviewEvent event) { + + if (event.getTypeInt() == Event.ONKEYDOWN + && event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ESCAPE) { + stopFind(); + Highlight.hideAll(); + return; + } + if (event.getTypeInt() == Event.ONMOUSEMOVE + || event.getTypeInt() == Event.ONCLICK) { + Element eventTarget = Util.getElementFromPoint(event + .getNativeEvent().getClientX(), event.getNativeEvent() + .getClientY()); + if (VDebugWindow.get().getElement().isOrHasChild(eventTarget)) { + if (isFindMode() && event.getTypeInt() == Event.ONCLICK) { + stopFind(); + event.cancel(); + } + return; + } + + // make sure that not finding the highlight element only + Highlight.hideAll(); + + eventTarget = Util.getElementFromPoint(event.getNativeEvent() + .getClientX(), event.getNativeEvent().getClientY()); + ComponentConnector connector = findConnector(eventTarget); + + if (event.getTypeInt() == Event.ONMOUSEMOVE) { + if (connector != null) { + Highlight.showOnly(connector); + event.cancel(); + event.consume(); + event.getNativeEvent().stopPropagation(); + return; + } + } else if (event.getTypeInt() == Event.ONCLICK) { + event.cancel(); + event.consume(); + event.getNativeEvent().stopPropagation(); + if (connector != null) { + Highlight.showOnly(connector); + pickSelector(connector, eventTarget); + return; + } + } + } + event.cancel(); + } + + }; + + private ComponentConnector findConnector(Element element) { + for (ApplicationConnection a : ApplicationConfiguration + .getRunningApplications()) { + ComponentConnector connector = Util.getConnectorForElement(a, a + .getUIConnector().getWidget(), element); + if (connector == null) { + connector = Util.getConnectorForElement(a, RootPanel.get(), + element); + } + if (connector != null) { + return connector; + } + } + return null; + } + + private void clearResults() { + content.clear(); + } + +} diff --git a/client/src/com/vaadin/client/metadata/ConnectorBundleLoader.java b/client/src/com/vaadin/client/metadata/ConnectorBundleLoader.java index f1a9fa1ee7..8148010b54 100644 --- a/client/src/com/vaadin/client/metadata/ConnectorBundleLoader.java +++ b/client/src/com/vaadin/client/metadata/ConnectorBundleLoader.java @@ -15,11 +15,10 @@ */ package com.vaadin.client.metadata; -import java.util.HashMap; import java.util.List; -import java.util.Map; import com.google.gwt.core.shared.GWT; +import com.vaadin.client.FastStringMap; import com.vaadin.client.metadata.AsyncBundleLoader.State; public abstract class ConnectorBundleLoader { @@ -28,8 +27,9 @@ public abstract class ConnectorBundleLoader { private static ConnectorBundleLoader impl; - private Map<String, AsyncBundleLoader> asyncBlockLoaders = new HashMap<String, AsyncBundleLoader>(); - private Map<String, String> identifierToBundle = new HashMap<String, String>(); + private FastStringMap<AsyncBundleLoader> asyncBlockLoaders = FastStringMap + .create(); + private FastStringMap<String> identifierToBundle = FastStringMap.create(); private final TypeDataStore datStore = new TypeDataStore(); diff --git a/client/src/com/vaadin/client/metadata/Method.java b/client/src/com/vaadin/client/metadata/Method.java index aea2fd7f85..390574cdf8 100644 --- a/client/src/com/vaadin/client/metadata/Method.java +++ b/client/src/com/vaadin/client/metadata/Method.java @@ -19,13 +19,10 @@ public class Method { private final Type type; private final String name; - private String signature; public Method(Type type, String name) { this.type = type; this.name = name; - // Cache derived signature value - signature = type.getSignature() + "." + name; } public Type getType() { @@ -53,7 +50,20 @@ public class Method { * @return the unique signature of this method */ public String getSignature() { - return signature; + return type.getSignature() + "." + name; + } + + /** + * Gets the string that is internally used when looking up generated support + * code for this method. This is the same as {@link #getSignature()}, but + * without any type parameters. + * + * @return the string to use for looking up generated support code + * + * @since 7.2 + */ + public String getLookupKey() { + return type.getBaseTypeName() + "." + name; } @Override diff --git a/client/src/com/vaadin/client/metadata/Property.java b/client/src/com/vaadin/client/metadata/Property.java index 2e0ea49c88..72ed7fec41 100644 --- a/client/src/com/vaadin/client/metadata/Property.java +++ b/client/src/com/vaadin/client/metadata/Property.java @@ -20,21 +20,18 @@ import com.vaadin.shared.annotations.DelegateToWidget; public class Property { private final Type bean; private final String name; - private final String signature; public Property(Type bean, String name) { this.bean = bean; this.name = name; - // Cache derived signature value - signature = bean.getSignature() + "." + name; } public Object getValue(Object bean) throws NoDataException { - return TypeDataStore.getGetter(this).invoke(bean); + return TypeDataStore.getValue(this, bean); } public void setValue(Object bean, Object value) throws NoDataException { - TypeDataStore.getSetter(this).invoke(bean, value); + TypeDataStore.setValue(this, bean, value); } public String getDelegateToWidgetMethodName() { @@ -50,6 +47,10 @@ public class Property { return TypeDataStore.getType(this); } + public Type getBeanType() { + return bean; + } + /** * The unique signature used to identify this property. The structure of the * returned string may change without notice and should not be used for any @@ -59,7 +60,20 @@ public class Property { * @return the unique signature of this property */ public String getSignature() { - return signature; + return bean.getSignature() + "." + name; + } + + /** + * Gets the string that is internally used when looking up generated support + * code for this method. This is the same as {@link #getSignature()}, but + * without any type parameters. + * + * @return the string to use for looking up generated support code + * + * @since 7.2 + */ + public String getLookupKey() { + return bean.getBaseTypeName() + "." + name; } @Override diff --git a/client/src/com/vaadin/client/metadata/TypeDataStore.java b/client/src/com/vaadin/client/metadata/TypeDataStore.java index aa37d75dc8..d5fbc94823 100644 --- a/client/src/com/vaadin/client/metadata/TypeDataStore.java +++ b/client/src/com/vaadin/client/metadata/TypeDataStore.java @@ -34,8 +34,6 @@ public class TypeDataStore { .create(); private final FastStringMap<ProxyHandler> proxyHandlers = FastStringMap .create(); - private final FastStringMap<JsArrayObject<Property>> properties = FastStringMap - .create(); private final FastStringMap<JsArrayString> delegateToWidgetProperties = FastStringMap .create(); @@ -46,12 +44,11 @@ public class TypeDataStore { private final FastStringMap<Invoker> invokers = FastStringMap.create(); private final FastStringMap<Type[]> paramTypes = FastStringMap.create(); - private final FastStringMap<Type> propertyTypes = FastStringMap.create(); - private final FastStringMap<Invoker> setters = FastStringMap.create(); - private final FastStringMap<Invoker> getters = FastStringMap.create(); private final FastStringMap<String> delegateToWidget = FastStringMap .create(); + private final JavaScriptObject jsTypeData = JavaScriptObject.createObject(); + public static TypeDataStore get() { return ConnectorBundleLoader.get().getTypeDataStore(); } @@ -69,12 +66,28 @@ public class TypeDataStore { return class1; } + // this is a very inefficient implementation for getting all the identifiers + // for a class + public FastStringSet findIdentifiersFor(Class<?> type) { + FastStringSet result = FastStringSet.create(); + + JsArrayString keys = identifiers.getKeys(); + for (int i = 0; i < keys.length(); i++) { + String key = keys.get(i); + if (identifiers.get(key) == type) { + result.add(key); + } + } + + return result; + } + public static Type getType(Class<?> clazz) { return new Type(clazz); } public static Type getReturnType(Method method) throws NoDataException { - Type type = get().returnTypes.get(method.getSignature()); + Type type = get().returnTypes.get(method.getLookupKey()); if (type == null) { throw new NoDataException("There is no return type for " + method.getSignature()); @@ -83,7 +96,7 @@ public class TypeDataStore { } public static Invoker getInvoker(Method method) throws NoDataException { - Invoker invoker = get().invokers.get(method.getSignature()); + Invoker invoker = get().invokers.get(method.getLookupKey()); if (invoker == null) { throw new NoDataException("There is no invoker for " + method.getSignature()); @@ -93,7 +106,7 @@ public class TypeDataStore { public static Invoker getConstructor(Type type) throws NoDataException { Invoker invoker = get().invokers.get(new Method(type, CONSTRUCTOR_NAME) - .getSignature()); + .getLookupKey()); if (invoker == null) { throw new NoDataException("There is no constructor for " + type.getSignature()); @@ -101,45 +114,37 @@ public class TypeDataStore { return invoker; } - public static Invoker getGetter(Property property) throws NoDataException { - Invoker getter = get().getters.get(property.getSignature()); - if (getter == null) { - throw new NoDataException("There is no getter for " - + property.getSignature()); - } - - return getter; - } - - public void setGetter(Class<?> clazz, String propertyName, Invoker invoker) { - getters.put(new Property(getType(clazz), propertyName).getSignature(), - invoker); + public static Object getValue(Property property, Object target) + throws NoDataException { + return getJsPropertyValue(get().jsTypeData, property.getBeanType() + .getBaseTypeName(), property.getName(), target); } public static String getDelegateToWidget(Property property) { - return get().delegateToWidget.get(property.getSignature()); + return get().delegateToWidget.get(property.getLookupKey()); } public static JsArrayString getDelegateToWidgetProperites(Type type) { - return get().delegateToWidgetProperties.get(type.getSignature()); + return get().delegateToWidgetProperties.get(type.getBaseTypeName()); } public void setDelegateToWidget(Class<?> clazz, String propertyName, String delegateValue) { Type type = getType(clazz); - delegateToWidget.put(new Property(type, propertyName).getSignature(), + delegateToWidget.put(new Property(type, propertyName).getLookupKey(), delegateValue); JsArrayString typeProperties = delegateToWidgetProperties.get(type - .getSignature()); + .getBaseTypeName()); if (typeProperties == null) { typeProperties = JavaScriptObject.createArray().cast(); - delegateToWidgetProperties.put(type.getSignature(), typeProperties); + delegateToWidgetProperties.put(type.getBaseTypeName(), + typeProperties); } typeProperties.push(propertyName); } public void setReturnType(Class<?> type, String methodName, Type returnType) { - returnTypes.put(new Method(getType(type), methodName).getSignature(), + returnTypes.put(new Method(getType(type), methodName).getLookupKey(), returnType); } @@ -148,12 +153,12 @@ public class TypeDataStore { } public void setInvoker(Class<?> type, String methodName, Invoker invoker) { - invokers.put(new Method(getType(type), methodName).getSignature(), + invokers.put(new Method(getType(type), methodName).getLookupKey(), invoker); } public static Type[] getParamTypes(Method method) throws NoDataException { - Type[] types = get().paramTypes.get(method.getSignature()); + Type[] types = get().paramTypes.get(method.getLookupKey()); if (types == null) { throw new NoDataException("There are no parameter type data for " + method.getSignature()); @@ -164,7 +169,7 @@ public class TypeDataStore { public void setParamTypes(Class<?> type, String methodName, Type[] paramTypes) { this.paramTypes.put( - new Method(getType(type), methodName).getSignature(), + new Method(getType(type), methodName).getLookupKey(), paramTypes); } @@ -174,8 +179,8 @@ public class TypeDataStore { public static ProxyHandler getProxyHandler(Type type) throws NoDataException { - ProxyHandler proxyHandler = get().proxyHandlers - .get(type.getSignature()); + ProxyHandler proxyHandler = get().proxyHandlers.get(type + .getBaseTypeName()); if (proxyHandler == null) { throw new NoDataException("No proxy handler for " + type.getSignature()); @@ -184,24 +189,24 @@ public class TypeDataStore { } public void setProxyHandler(Class<?> type, ProxyHandler proxyHandler) { - proxyHandlers.put(getType(type).getSignature(), proxyHandler); + proxyHandlers.put(getType(type).getBaseTypeName(), proxyHandler); } public static boolean isDelayed(Method method) { - return get().delayedMethods.contains(method.getSignature()); + return get().delayedMethods.contains(method.getLookupKey()); } public void setDelayed(Class<?> type, String methodName) { - delayedMethods.add(getType(type).getMethod(methodName).getSignature()); + delayedMethods.add(getType(type).getMethod(methodName).getLookupKey()); } public static boolean isLastOnly(Method method) { - return get().lastOnlyMethods.contains(method.getSignature()); + return get().lastOnlyMethods.contains(method.getLookupKey()); } public void setLastOnly(Class<?> clazz, String methodName) { lastOnlyMethods - .add(getType(clazz).getMethod(methodName).getSignature()); + .add(getType(clazz).getMethod(methodName).getLookupKey()); } /** @@ -227,60 +232,40 @@ public class TypeDataStore { public static JsArrayObject<Property> getPropertiesAsArray(Type type) throws NoDataException { - JsArrayObject<Property> properties = get().properties.get(type - .getSignature()); - if (properties == null) { - throw new NoDataException("No property list for " - + type.getSignature()); - } - return properties; - } + JsArrayString names = getJsPropertyNames(get().jsTypeData, + type.getBaseTypeName()); - public void setProperties(Class<?> clazz, String[] propertyNames) { + // Create Property instances for each property name JsArrayObject<Property> properties = JavaScriptObject.createArray() .cast(); - Type type = getType(clazz); - for (String name : propertyNames) { - properties.add(new Property(type, name)); + for (int i = 0; i < names.length(); i++) { + properties.add(new Property(type, names.get(i))); } - this.properties.put(type.getSignature(), properties); - } - public static Type getType(Property property) throws NoDataException { - Type type = get().propertyTypes.get(property.getSignature()); - if (type == null) { - throw new NoDataException("No return type for " - + property.getSignature()); - } - return type; + return properties; } - public void setPropertyType(Class<?> clazz, String propertName, Type type) { - propertyTypes.put( - new Property(getType(clazz), propertName).getSignature(), type); + public static Type getType(Property property) throws NoDataException { + return getJsPropertyType(get().jsTypeData, property.getBeanType() + .getBaseTypeName(), property.getName()); } - public static Invoker getSetter(Property property) throws NoDataException { - Invoker setter = get().setters.get(property.getSignature()); - if (setter == null) { - throw new NoDataException("No setter for " - + property.getSignature()); - } - return setter; + public void setPropertyType(Class<?> clazz, String propertyName, Type type) { + setJsPropertyType(jsTypeData, clazz.getName(), propertyName, type); } - public void setSetter(Class<?> clazz, String propertyName, Invoker setter) { - setters.put(new Property(getType(clazz), propertyName).getSignature(), - setter); + public static void setValue(Property property, Object target, Object value) { + setJsPropertyValue(get().jsTypeData, property.getBeanType() + .getBaseTypeName(), property.getName(), target, value); } public void setSerializerFactory(Class<?> clazz, Invoker factory) { - serializerFactories.put(getType(clazz).getSignature(), factory); + serializerFactories.put(getType(clazz).getBaseTypeName(), factory); } public static JSONSerializer<?> findSerializer(Type type) { Invoker factoryCreator = get().serializerFactories.get(type - .getSignature()); + .getBaseTypeName()); if (factoryCreator == null) { return null; } @@ -288,6 +273,99 @@ public class TypeDataStore { } public static boolean hasProperties(Type type) { - return get().properties.containsKey(type.getSignature()); + return hasJsProperties(get().jsTypeData, type.getBaseTypeName()); } + + public void setSuperClass(Class<?> baseClass, Class<?> superClass) { + String superClassName = superClass == null ? null : superClass + .getName(); + setSuperClass(jsTypeData, baseClass.getName(), superClassName); + } + + public void setPropertyData(Class<?> type, String propertyName, + JavaScriptObject propertyData) { + setPropertyData(jsTypeData, type.getName(), propertyName, propertyData); + } + + private static native void setPropertyData(JavaScriptObject typeData, + String className, String propertyName, JavaScriptObject propertyData) + /*-{ + typeData[className][propertyName] = propertyData; + }-*/; + + /* + * This method sets up prototypes chain for <code>baseClassName</code>. + * Precondition is : <code>superClassName</code> had to be handled before + * its child <code>baseClassName</code>. + * + * It makes all properties defined in the <code>superClassName</code> + * available for <code>baseClassName</code> as well. + */ + private static native void setSuperClass(JavaScriptObject typeData, + String baseClassName, String superClassName) + /*-{ + var parentType = typeData[superClassName]; + if (parentType !== undefined ){ + var ctor = function () {}; + ctor.prototype = parentType; + typeData[baseClassName] = new ctor; + } + else { + typeData[baseClassName] = {}; + } + }-*/; + + private static native boolean hasGetter(JavaScriptObject typeData, + String beanName, String propertyName) + /*-{ + return typeData[beanName][propertyName].getter !== undefined; + }-*/; + + private static native boolean hasSetter(JavaScriptObject typeData, + String beanName, String propertyName) + /*-{ + return typeData[beanName][propertyName].setter !== undefined; + }-*/; + + private static native Object getJsPropertyValue(JavaScriptObject typeData, + String beanName, String propertyName, Object beanInstance) + /*-{ + return typeData[beanName][propertyName].getter(beanInstance); + }-*/; + + private static native void setJsPropertyValue(JavaScriptObject typeData, + String beanName, String propertyName, Object beanInstance, + Object value) + /*-{ + typeData[beanName][propertyName].setter(beanInstance, value); + }-*/; + + private static native Type getJsPropertyType(JavaScriptObject typeData, + String beanName, String propertyName) + /*-{ + return typeData[beanName][propertyName].type; + }-*/; + + private static native void setJsPropertyType(JavaScriptObject typeData, + String beanName, String propertyName, Type type) + /*-{ + typeData[beanName][propertyName].type = type; + }-*/; + + private static native JsArrayString getJsPropertyNames( + JavaScriptObject typeData, String beanName) + /*-{ + var names = []; + for(var name in typeData[beanName]) { + names.push(name); + } + return names; + }-*/; + + private static native boolean hasJsProperties(JavaScriptObject typeData, + String beanName) + /*-{ + return typeData[beanName] !== undefined ; + }-*/; + } diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java index 8fdaf0a5be..5933441e0a 100644 --- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java @@ -462,15 +462,24 @@ public abstract class AbstractComponentConnector extends AbstractConnector } /** - * Gets the icon set for this component. + * Gets the URI of the icon set for this component. * - * @return the URL of the icon, or <code>null</code> if no icon has been + * @return the URI of the icon, or <code>null</code> if no icon has been * defined. */ - protected String getIcon() { + protected String getIconUri() { return getResourceUrl(ComponentConstants.ICON_RESOURCE); } + /** + * Gets the icon set for this component. + * + * @return the icon, or <code>null</code> if no icon has been defined. + */ + protected Icon getIcon() { + return getConnection().getIcon(getIconUri()); + } + /* * (non-Javadoc) * diff --git a/client/src/com/vaadin/client/ui/Action.java b/client/src/com/vaadin/client/ui/Action.java index e1b85dcb82..60d3e9aabf 100644 --- a/client/src/com/vaadin/client/ui/Action.java +++ b/client/src/com/vaadin/client/ui/Action.java @@ -17,7 +17,6 @@ package com.vaadin.client.ui; import com.google.gwt.user.client.Command; -import com.vaadin.client.Util; /** * @@ -43,9 +42,11 @@ public abstract class Action implements Command { public String getHTML() { final StringBuffer sb = new StringBuffer(); sb.append("<div>"); - if (getIconUrl() != null) { - sb.append("<img src=\"" + Util.escapeAttribute(getIconUrl()) - + "\" alt=\"icon\" />"); + // Could store the icon in a field instead, but it doesn't really matter + // right now because Actions are recreated every time they are needed + Icon icon = owner.getClient().getIcon(getIconUrl()); + if (icon != null) { + sb.append(icon.getElement().getString()); } sb.append(getCaption()); sb.append("</div>"); @@ -78,5 +79,4 @@ public abstract class Action implements Command { return "Action [owner=" + owner + ", iconUrl=" + iconUrl + ", caption=" + caption + "]"; } - } diff --git a/client/src/com/vaadin/client/ui/FontIcon.java b/client/src/com/vaadin/client/ui/FontIcon.java new file mode 100644 index 0000000000..04640fab06 --- /dev/null +++ b/client/src/com/vaadin/client/ui/FontIcon.java @@ -0,0 +1,149 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui; + +import com.google.gwt.http.client.URL; +import com.google.gwt.user.client.DOM; +import com.vaadin.shared.ApplicationConstants; + +/** + * A font-based icon implementation. + * <p> + * The icon represents a specific character (identified by codepoint, + * {@link #getCodepoint()}, {@link #setCodepoint(int)}) within a specific font + * (identified by font-family, {@link #getFontFamily()}, + * {@link #setFontFamily(String)}). + * </p> + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class FontIcon extends Icon { + + private int codepoint; + private String fontFamily; + + public FontIcon() { + setElement(DOM.createSpan()); + setStyleName(CLASSNAME); + } + + @Override + public void setUri(String uri) { + String[] parts = uri.substring( + ApplicationConstants.FONTICON_PROTOCOL_PREFIX.length()).split( + "/"); + setFontFamily(URL.decode(parts[0])); + setCodepoint(Integer.parseInt(parts[1], 16)); + } + + /** + * Not implemeted for {@link FontIcon} yet. + * + * @see com.vaadin.client.ui.Icon#setAlternateText(java.lang.String) + */ + @Override + public void setAlternateText(String alternateText) { + // TODO this is mostly for WAI-ARIA and should be implemented in an + // appropriate way. + + } + + /** + * Sets the font-family from which this icon comes. Use + * {@link #setCodepoint(int)} to specify a particular icon (character) + * within the font. + * + * @param fontFamily + * font-family name + */ + protected void setFontFamily(String fontFamily) { + if (this.fontFamily != null) { + removeStyleName(getFontStylename()); + } + this.fontFamily = fontFamily; + if (fontFamily != null) { + addStyleName(getFontStylename()); + } + } + + /** + * Gets the font-family from which this icon comes. Use + * {@link #getCodepoint()} to find out which particular icon (character) + * within the font this is. + * + * @return font-family name + */ + public String getFontFamily() { + return fontFamily; + } + + /** + * Sets the codepoint indicating which particular icon (character) within + * the font-family this is. + * + * @param codepoint + */ + protected void setCodepoint(int codepoint) { + this.codepoint = codepoint; + getElement().setInnerText(new String(Character.toChars(codepoint))); + } + + /** + * Gets the codepoint indicating which particular icon (character) within + * the font-family this is. + * + * @return + */ + public int getCodepoint() { + return codepoint; + } + + /** + * Get the font-family based stylename used to apply the font-family. + * + * @since 7.2 + * @return stylename used to apply font-family + */ + protected String getFontStylename() { + if (fontFamily == null) { + return null; + } + return fontFamily.replace(' ', '-'); + } + + /** + * Checks whether or not the given uri is a font icon uri. Does not check + * whether or not the font icon is available and can be rendered. + * + * @since 7.2 + * @param uri + * @return true if it's a fonticon uri + */ + public static boolean isFontIconUri(String uri) { + return uri != null + && uri.startsWith(ApplicationConstants.FONTICON_PROTOCOL_PREFIX); + } + + @Override + public String getUri() { + if (fontFamily == null) { + return null; + } + return ApplicationConstants.FONTICON_PROTOCOL_PREFIX + fontFamily + "/" + + codepoint; + } +} diff --git a/client/src/com/vaadin/client/ui/Icon.java b/client/src/com/vaadin/client/ui/Icon.java index 9d5829c079..219692161e 100644 --- a/client/src/com/vaadin/client/ui/Icon.java +++ b/client/src/com/vaadin/client/ui/Icon.java @@ -13,45 +13,40 @@ * License for the specific language governing permissions and limitations under * the License. */ - package com.vaadin.client.ui; -import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.UIObject; import com.vaadin.client.ApplicationConnection; -public class Icon extends UIObject { - public static final String CLASSNAME = "v-icon"; - private final ApplicationConnection client; - private String myUri; - - public Icon(ApplicationConnection client) { - setElement(DOM.createImg()); - DOM.setElementProperty(getElement(), "alt", ""); - setStyleName(CLASSNAME); - this.client = client; - } +/** + * An abstract representation of an icon. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public abstract class Icon extends UIObject { - public Icon(ApplicationConnection client, String uidlUri) { - this(client); - setUri(uidlUri); - } + public static final String CLASSNAME = "v-icon"; - public void setUri(String uidlUri) { - if (!uidlUri.equals(myUri)) { - /* - * Start sinking onload events, widgets responsibility to react. We - * must do this BEFORE we set src as IE fires the event immediately - * if the image is found in cache (#2592). - */ - sinkEvents(Event.ONLOAD); + /** + * Sets the URI for the icon. The URI should be run trough + * {@link ApplicationConnection#translateVaadinUri(String)} before setting. + * <p> + * This might be a URL referencing a image (e.g {@link ImageIcon}) or a + * custom URI (e.g {@link FontIcon}). + * </p> + * + * @param uri + * the URI for this icon + */ + public abstract void setUri(String uri); - String uri = client.translateVaadinUri(uidlUri); - DOM.setElementProperty(getElement(), "src", uri); - myUri = uidlUri; - } - } + /** + * Gets the current URI for this icon. + * + * @return URI in use + */ + public abstract String getUri(); /** * Sets the alternate text for the icon. @@ -59,9 +54,6 @@ public class Icon extends UIObject { * @param alternateText * with the alternate text. */ - public void setAlternateText(String alternateText) { - getElement().setAttribute("alt", - alternateText == null ? "" : alternateText); - } + public abstract void setAlternateText(String alternateText); } diff --git a/client/src/com/vaadin/client/ui/ImageIcon.java b/client/src/com/vaadin/client/ui/ImageIcon.java new file mode 100644 index 0000000000..787b0175aa --- /dev/null +++ b/client/src/com/vaadin/client/ui/ImageIcon.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.client.ui; + +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; +import com.vaadin.client.BrowserInfo; + +/** + * A image based implementation of {@link Icon}. + * <p> + * The image is loaded from the given URL ( {@link #setUri(String)}) and + * displayed in full. + * </p> + * + * @author Vaadin Ltd + */ +public class ImageIcon extends Icon { + public static final String CLASSNAME = "v-icon"; + + public ImageIcon() { + setElement(DOM.createImg()); + setStyleName(CLASSNAME); + } + + @Override + public void setUri(final String imageUrl) { + /* + * Start sinking onload events, widgets responsibility to react. We must + * do this BEFORE we set src as IE fires the event immediately if the + * image is found in cache (#2592). + */ + sinkEvents(Event.ONLOAD); + + if (BrowserInfo.get().isIE()) { + // apply src later for IE, to ensure onload is fired + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + DOM.setElementProperty(getElement(), "src", imageUrl); + } + }); + } + + DOM.setElementProperty(getElement(), "src", imageUrl); + + } + + @Override + public void setAlternateText(String alternateText) { + getElement().setAttribute("alt", + alternateText == null ? "" : alternateText); + } + + @Override + public String getUri() { + return DOM.getElementProperty(getElement(), "src"); + } + +} diff --git a/client/src/com/vaadin/client/ui/SubPartAware.java b/client/src/com/vaadin/client/ui/SubPartAware.java index a7d72fab01..36959e7b1f 100644 --- a/client/src/com/vaadin/client/ui/SubPartAware.java +++ b/client/src/com/vaadin/client/ui/SubPartAware.java @@ -17,7 +17,7 @@ package com.vaadin.client.ui; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.Widget; -import com.vaadin.client.ComponentLocator; +import com.vaadin.client.componentlocator.ComponentLocator; /** * Interface implemented by {@link Widget}s which can provide identifiers for at @@ -59,4 +59,4 @@ public interface SubPartAware { */ String getSubPartName(Element subElement); -}
\ No newline at end of file +} diff --git a/client/src/com/vaadin/client/ui/VAccordion.java b/client/src/com/vaadin/client/ui/VAccordion.java index f87186fe37..ddfe9dbc2c 100644 --- a/client/src/com/vaadin/client/ui/VAccordion.java +++ b/client/src/com/vaadin/client/ui/VAccordion.java @@ -463,7 +463,6 @@ public class VAccordion extends VTabsheetBase { } @Override - @SuppressWarnings("unchecked") public Iterator<Widget> getWidgetIterator() { return widgets.iterator(); } diff --git a/client/src/com/vaadin/client/ui/VCalendarPanel.java b/client/src/com/vaadin/client/ui/VCalendarPanel.java index e584a21563..5fbd3ec15c 100644 --- a/client/src/com/vaadin/client/ui/VCalendarPanel.java +++ b/client/src/com/vaadin/client/ui/VCalendarPanel.java @@ -170,8 +170,6 @@ public class VCalendarPanel extends FocusableFlexTable implements private Resolution resolution = Resolution.YEAR; - private int focusedRow; - private Timer mouseTimer; private Date value; @@ -256,7 +254,6 @@ public class VCalendarPanel extends FocusableFlexTable implements if (curday.getDate().equals(date)) { curday.addStyleDependentName(CN_FOCUSED); focusedDay = curday; - focusedRow = i; return; } } @@ -741,7 +738,6 @@ public class VCalendarPanel extends FocusableFlexTable implements } if (curr.equals(focusedDate)) { focusedDay = day; - focusedRow = weekOfMonth; if (hasFocus) { day.addStyleDependentName(CN_FOCUSED); } @@ -1792,10 +1788,8 @@ public class VCalendarPanel extends FocusableFlexTable implements * Updates the valus to correspond to the values in value */ public void updateTimes() { - boolean selected = true; if (value == null) { value = new Date(); - selected = false; } if (getDateTimeService().isTwelveHourClock()) { int h = value.getHours(); @@ -1830,10 +1824,6 @@ public class VCalendarPanel extends FocusableFlexTable implements } - private int getMilliseconds() { - return DateTimeService.getMilliseconds(value); - } - private DateTimeService getDateTimeService() { if (dateTimeService == null) { dateTimeService = new DateTimeService(); @@ -2031,7 +2021,6 @@ public class VCalendarPanel extends FocusableFlexTable implements private static final String SUBPART_HOUR_SELECT = "h"; private static final String SUBPART_MINUTE_SELECT = "m"; private static final String SUBPART_SECS_SELECT = "s"; - private static final String SUBPART_MSECS_SELECT = "ms"; private static final String SUBPART_AMPM_SELECT = "ampm"; private static final String SUBPART_DAY = "day"; private static final String SUBPART_MONTH_YEAR_HEADER = "header"; diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index 63c8d3dbf9..9bace9141c 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -1786,6 +1786,11 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, if (client.hasEventListeners(this, EventId.FOCUS)) { client.updateVariable(paintableId, EventId.FOCUS, "", true); } + + ComponentConnector connector = ConnectorMap.get(client).getConnector( + this); + client.getVTooltip().showAssistive( + connector.getTooltipInfo(getElement())); } /** diff --git a/client/src/com/vaadin/client/ui/VFormLayout.java b/client/src/com/vaadin/client/ui/VFormLayout.java index 6c2661d1d8..56870e5e41 100644 --- a/client/src/com/vaadin/client/ui/VFormLayout.java +++ b/client/src/com/vaadin/client/ui/VFormLayout.java @@ -260,21 +260,17 @@ public class VFormLayout extends SimplePanel { boolean isEmpty = true; + if (icon != null) { + getElement().removeChild(icon.getElement()); + icon = null; + } if (state.resources.containsKey(ComponentConstants.ICON_RESOURCE)) { - if (icon == null) { - icon = new Icon(owner.getConnection()); + icon = owner.getConnection().getIcon( + state.resources.get(ComponentConstants.ICON_RESOURCE) + .getURL()); + DOM.insertChild(getElement(), icon.getElement(), 0); - DOM.insertChild(getElement(), icon.getElement(), 0); - } - icon.setUri(state.resources.get( - ComponentConstants.ICON_RESOURCE).getURL()); isEmpty = false; - } else { - if (icon != null) { - DOM.removeChild(getElement(), icon.getElement()); - icon = null; - } - } if (state.caption != null) { diff --git a/client/src/com/vaadin/client/ui/VLabel.java b/client/src/com/vaadin/client/ui/VLabel.java index 8acd653778..35f47d540a 100644 --- a/client/src/com/vaadin/client/ui/VLabel.java +++ b/client/src/com/vaadin/client/ui/VLabel.java @@ -18,7 +18,6 @@ package com.vaadin.client.ui; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.HTML; -import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.Util; import com.vaadin.client.VTooltip; @@ -28,8 +27,6 @@ public class VLabel extends HTML { public static final String CLASSNAME = "v-label"; private static final String CLASSNAME_UNDEFINED_WIDTH = "v-label-undef-w"; - private ApplicationConnection connection; - public VLabel() { super(); setStyleName(CLASSNAME); @@ -71,9 +68,4 @@ public class VLabel extends HTML { super.setText(text); } } - - /** For internal use only. May be removed or replaced in the future. */ - public void setConnection(ApplicationConnection client) { - connection = client; - } } diff --git a/client/src/com/vaadin/client/ui/VLink.java b/client/src/com/vaadin/client/ui/VLink.java index fa4ee36bcf..064a012873 100644 --- a/client/src/com/vaadin/client/ui/VLink.java +++ b/client/src/com/vaadin/client/ui/VLink.java @@ -23,7 +23,6 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.HTML; -import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Util; import com.vaadin.shared.ui.BorderStyle; @@ -70,9 +69,6 @@ public class VLink extends HTML implements ClickHandler { /** For internal use only. May be removed or replaced in the future. */ public Icon icon; - /** For internal use only. May be removed or replaced in the future. */ - public ApplicationConnection client; - public VLink() { super(); getElement().appendChild(anchor); diff --git a/client/src/com/vaadin/client/ui/VMenuBar.java b/client/src/com/vaadin/client/ui/VMenuBar.java index 0aa26e4999..b6aee92779 100644 --- a/client/src/com/vaadin/client/ui/VMenuBar.java +++ b/client/src/com/vaadin/client/ui/VMenuBar.java @@ -226,11 +226,9 @@ public class VMenuBar extends SimpleFocusablePanel implements itemHTML.append("<span class=\"" + getStylePrimaryName() + "-menuitem-caption\">"); - if (item.hasAttribute("icon")) { - itemHTML.append("<img src=\"" - + Util.escapeAttribute(client.translateVaadinUri(item - .getStringAttribute("icon"))) + "\" class=\"" - + Icon.CLASSNAME + "\" alt=\"\" />"); + Icon icon = client.getIcon(item.getStringAttribute("icon")); + if (icon != null) { + itemHTML.append(icon.getElement().getString()); } String itemText = item.getStringAttribute("text"); if (!htmlContentAllowed) { diff --git a/client/src/com/vaadin/client/ui/VNativeButton.java b/client/src/com/vaadin/client/ui/VNativeButton.java index 67fa6f2ee3..d38e4c3374 100644 --- a/client/src/com/vaadin/client/ui/VNativeButton.java +++ b/client/src/com/vaadin/client/ui/VNativeButton.java @@ -33,8 +33,6 @@ public class VNativeButton extends Button implements ClickHandler { public static final String CLASSNAME = "v-nativebutton"; - protected String width = null; - /** For internal use only. May be removed or replaced in the future. */ public String paintableId; @@ -123,12 +121,6 @@ public class VNativeButton extends Button implements ClickHandler { } } - @Override - public void setWidth(String width) { - this.width = width; - super.setWidth(width); - } - /* * (non-Javadoc) * diff --git a/client/src/com/vaadin/client/ui/VNotification.java b/client/src/com/vaadin/client/ui/VNotification.java index 7019394e3b..4748df4e62 100644 --- a/client/src/com/vaadin/client/ui/VNotification.java +++ b/client/src/com/vaadin/client/ui/VNotification.java @@ -21,19 +21,25 @@ import java.util.Date; import java.util.EventObject; import java.util.Iterator; +import com.google.gwt.aria.client.Roles; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; import com.vaadin.client.UIDL; import com.vaadin.client.Util; +import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.shared.Position; +import com.vaadin.shared.ui.ui.NotificationConfigurationBean; +import com.vaadin.shared.ui.ui.NotificationConfigurationBean.Role; import com.vaadin.shared.ui.ui.UIConstants; public class VNotification extends VOverlay { @@ -46,6 +52,12 @@ public class VNotification extends VOverlay { public static final Position BOTTOM_LEFT = Position.BOTTOM_LEFT; public static final Position BOTTOM_RIGHT = Position.BOTTOM_RIGHT; + /** + * Position that is only accessible for assistive devices, invisible for + * visual users. + */ + public static final Position ASSISTIVE = Position.ASSISTIVE; + public static final int DELAY_FOREVER = -1; public static final int DELAY_NONE = 0; @@ -149,15 +161,67 @@ public class VNotification extends VOverlay { } public void show(Widget widget, Position position, String style) { - setWidget(widget); + NotificationConfigurationBean styleSetup = getUiState(style); + setWaiAriaRole(styleSetup); + + FlowPanel panel = new FlowPanel(); + if (styleSetup.hasAssistivePrefix()) { + panel.add(new Label(styleSetup.getAssistivePrefix())); + AriaHelper.setVisibleForAssistiveDevicesOnly(panel.getElement(), + true); + } + + panel.add(widget); + + if (styleSetup.hasAssistivePostfix()) { + panel.add(new Label(styleSetup.getAssistivePostfix())); + AriaHelper.setVisibleForAssistiveDevicesOnly(panel.getElement(), + true); + } + setWidget(panel); show(position, style); } public void show(String html, Position position, String style) { - setWidget(new HTML(html)); + NotificationConfigurationBean styleSetup = getUiState(style); + String assistiveDeviceOnlyStyle = AriaHelper.ASSISTIVE_DEVICE_ONLY_STYLE; + + setWaiAriaRole(styleSetup); + + String type = ""; + String usage = ""; + + if (styleSetup != null && styleSetup.hasAssistivePrefix()) { + type = "<span class='" + assistiveDeviceOnlyStyle + "'>" + + styleSetup.getAssistivePrefix() + "</span>"; + } + + if (styleSetup != null && styleSetup.hasAssistivePostfix()) { + usage = "<span class='" + assistiveDeviceOnlyStyle + "'>" + + styleSetup.getAssistivePostfix() + "</span>"; + } + + setWidget(new HTML(type + html + usage)); show(position, style); } + private NotificationConfigurationBean getUiState(String style) { + NotificationConfigurationBean styleSetup = getApplicationConnection() + .getUIConnector().getState().notificationConfiguration.setup + .get(style); + return styleSetup; + } + + private void setWaiAriaRole(NotificationConfigurationBean styleSetup) { + Roles.getAlertRole().set(getElement()); + + if (styleSetup != null && styleSetup.getAssistiveRole() != null) { + if (Role.STATUS == styleSetup.getAssistiveRole()) { + Roles.getStatusRole().set(getElement()); + } + } + } + public void show(Position position, String style) { setOpacity(getElement(), startOpacity); if (style != null) { @@ -257,6 +321,10 @@ public class VNotification extends VOverlay { DOM.setStyleAttribute(el, "top", ""); DOM.setStyleAttribute(el, "bottom", "0px"); break; + case ASSISTIVE: + DOM.setStyleAttribute(el, "top", "-2000px"); + DOM.setStyleAttribute(el, "left", "-2000px"); + break; default: case MIDDLE_CENTER: center(); @@ -374,10 +442,9 @@ public class VNotification extends VOverlay { .hasAttribute(UIConstants.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED); String html = ""; if (notification.hasAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_ICON)) { - final String parsedUri = client - .translateVaadinUri(notification - .getStringAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_ICON)); - html += "<img src=\"" + Util.escapeAttribute(parsedUri) + "\" />"; + String iconUri = notification + .getStringAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_ICON); + html += client.getIcon(iconUri).getElement().getString(); } if (notification .hasAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_CAPTION)) { @@ -417,6 +484,8 @@ public class VNotification extends VOverlay { public static VNotification createNotification(int delayMsec, Widget owner) { final VNotification notification = GWT.create(VNotification.class); + notification.setWaiAriaRole(null); + notification.delayMsec = delayMsec; if (BrowserInfo.get().isTouchDevice()) { new Timer() { diff --git a/client/src/com/vaadin/client/ui/VOptionGroup.java b/client/src/com/vaadin/client/ui/VOptionGroup.java index fe4ef214cb..3e4b357be3 100644 --- a/client/src/com/vaadin/client/ui/VOptionGroup.java +++ b/client/src/com/vaadin/client/ui/VOptionGroup.java @@ -139,12 +139,10 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler, itemHtml = Util.escapeHTML(itemHtml); } - String icon = opUidl.getStringAttribute("icon"); - if (icon != null && icon.length() != 0) { - String iconUrl = client.translateVaadinUri(icon); - itemHtml = "<img src=\"" + Util.escapeAttribute(iconUrl) - + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />" - + itemHtml; + String iconUrl = opUidl.getStringAttribute("icon"); + if (iconUrl != null && iconUrl.length() != 0) { + Icon icon = client.getIcon(iconUrl); + itemHtml = icon.getElement().getString() + itemHtml; } String key = opUidl.getStringAttribute("key"); @@ -161,7 +159,7 @@ public class VOptionGroup extends VOptionGroupBase implements FocusHandler, op = new RadioButton(paintableId); op.setStyleName("v-radiobutton"); } - if (icon != null && icon.length() != 0) { + if (iconUrl != null && iconUrl.length() != 0) { Util.sinkOnloadForImages(op.getElement()); op.addHandler(iconLoadHandler, LoadEvent.getType()); } diff --git a/client/src/com/vaadin/client/ui/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java index e2c9001fed..545af2ce83 100644 --- a/client/src/com/vaadin/client/ui/VOverlay.java +++ b/client/src/com/vaadin/client/ui/VOverlay.java @@ -172,7 +172,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> { * * See default theme 'shadow.css' for implementation example. */ - private static final String SHADOW_HTML = "<div class=\"top-left\"></div><div class=\"top\"></div><div class=\"top-right\"></div><div class=\"left\"></div><div class=\"center\"></div><div class=\"right\"></div><div class=\"bottom-left\"></div><div class=\"bottom\"></div><div class=\"bottom-right\"></div>"; + private static final String SHADOW_HTML = "<div aria-hidden=\"true\" class=\"top-left\"></div><div class=\"top\"></div><div class=\"top-right\"></div><div class=\"left\"></div><div class=\"center\"></div><div class=\"right\"></div><div class=\"bottom-left\"></div><div class=\"bottom\"></div><div class=\"bottom-right\"></div>"; /** * Matches {@link PopupPanel}.ANIMATION_DURATION diff --git a/client/src/com/vaadin/client/ui/VPanel.java b/client/src/com/vaadin/client/ui/VPanel.java index 6b02f079d1..32d99e7ca9 100644 --- a/client/src/com/vaadin/client/ui/VPanel.java +++ b/client/src/com/vaadin/client/ui/VPanel.java @@ -152,17 +152,12 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, /** For internal use only. May be removed or replaced in the future. */ public void setIconUri(String iconUri, ApplicationConnection client) { - if (iconUri == null) { - if (icon != null) { - DOM.removeChild(captionNode, icon.getElement()); - icon = null; - } - } else { - if (icon == null) { - icon = new Icon(client); - DOM.insertChild(captionNode, icon.getElement(), 0); - } - icon.setUri(iconUri); + if (icon != null) { + captionNode.removeChild(icon.getElement()); + } + icon = client.getIcon(iconUri); + if (icon != null) { + DOM.insertChild(captionNode, icon.getElement(), 0); } } @@ -170,7 +165,6 @@ public class VPanel extends SimplePanel implements ShortcutActionHandlerOwner, public void onBrowserEvent(Event event) { super.onBrowserEvent(event); - final Element target = DOM.eventGetTarget(event); final int type = DOM.eventGetType(event); if (type == Event.ONKEYDOWN && shortcutHandler != null) { shortcutHandler.handleKeyboardEvent(event); diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index e800e7fe79..59d1131ff5 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -61,6 +61,8 @@ import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.regexp.shared.MatchResult; +import com.google.gwt.regexp.shared.RegExp; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; @@ -71,7 +73,6 @@ import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.PopupPanel; -import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; @@ -80,6 +81,7 @@ import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorMap; import com.vaadin.client.Focusable; import com.vaadin.client.MouseEventDetailsBuilder; +import com.vaadin.client.StyleConstants; import com.vaadin.client.TooltipInfo; import com.vaadin.client.UIDL; import com.vaadin.client.Util; @@ -123,7 +125,7 @@ import com.vaadin.shared.ui.table.TableConstants; */ public class VScrollTable extends FlowPanel implements HasWidgets, ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable, - ActionOwner { + ActionOwner, SubPartAware { public static final String STYLENAME = "v-table"; @@ -2314,7 +2316,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private int reqFirstRow = 0; private int reqRows = 0; - private boolean isRunning = false; + private boolean isRequestHandlerRunning = false; public void triggerRowFetch(int first, int rows) { setReqFirstRow(first); @@ -2332,12 +2334,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, deferRowFetch(250); } - public boolean isRunning() { - return isRunning; + public boolean isRequestHandlerRunning() { + return isRequestHandlerRunning; } public void deferRowFetch(int msec) { - isRunning = true; + isRequestHandlerRunning = true; if (reqRows > 0 && reqFirstRow < totalRows) { schedule(msec); @@ -2479,7 +2481,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, unSyncedselectionsBeforeRowFetch = new HashSet<Object>( selectedRowKeys); } - isRunning = false; + isRequestHandlerRunning = false; } } @@ -2487,7 +2489,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, * Sends request to refresh content at this position. */ public void refreshContent() { - isRunning = true; + isRequestHandlerRunning = true; int first = (int) (firstRowInViewPort - pageLength * cache_rate); int reqRows = (int) (2 * pageLength * cache_rate + pageLength); if (first < 0) { @@ -2811,13 +2813,27 @@ public class VScrollTable extends FlowPanel implements HasWidgets, DOM.setInnerHTML(floatingCopyOfHeaderCell, DOM.getInnerHTML(td)); floatingCopyOfHeaderCell = DOM .getChild(floatingCopyOfHeaderCell, 2); - DOM.setElementProperty(floatingCopyOfHeaderCell, "className", - VScrollTable.this.getStylePrimaryName() + "-header-drag"); + // #12714 the shown "ghost element" should be inside + // v-overlay-container, and it should contain the same styles as the + // table to enable theming (except v-table & v-widget). + String stylePrimaryName = VScrollTable.this.getStylePrimaryName(); + StringBuilder sb = new StringBuilder(); + for (String s : VScrollTable.this.getStyleName().split(" ")) { + if (!s.equals(StyleConstants.UI_WIDGET)) { + sb.append(s); + if (s.equals(stylePrimaryName)) { + sb.append("-header-drag "); + } else { + sb.append(" "); + } + } + } + floatingCopyOfHeaderCell.setClassName(sb.toString().trim()); // otherwise might wrap or be cut if narrow column DOM.setStyleAttribute(floatingCopyOfHeaderCell, "width", "auto"); updateFloatingCopysPosition(DOM.getAbsoluteLeft(td), DOM.getAbsoluteTop(td)); - DOM.appendChild(RootPanel.get().getElement(), + DOM.appendChild(VOverlay.getOverlayContainer(client), floatingCopyOfHeaderCell); } @@ -2832,8 +2848,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } private void hideFloatingCopy() { - DOM.removeChild(RootPanel.get().getElement(), - floatingCopyOfHeaderCell); + floatingCopyOfHeaderCell.removeFromParent(); floatingCopyOfHeaderCell = null; } @@ -5083,6 +5098,20 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } } + public int indexOf(Widget row) { + int relIx = -1; + for (int ix = 0; ix < renderedRows.size(); ix++) { + if (renderedRows.get(ix) == row) { + relIx = ix; + break; + } + } + if (relIx >= 0) { + return firstRendered + relIx; + } + return -1; + } + public class VScrollTableRow extends Panel implements ActionOwner { private static final int TOUCHSCROLL_TIMEOUT = 100; @@ -6064,7 +6093,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private Element getEventTargetTdOrTr(Event event) { final Element eventTarget = event.getEventTarget().cast(); Widget widget = Util.findWidget(eventTarget, null); - final Element thisTrElement = getElement(); if (widget != this) { /* @@ -6896,10 +6924,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets, String s = uidl.hasAttribute("caption") ? uidl .getStringAttribute("caption") : ""; if (uidl.hasAttribute("icon")) { - s = "<img src=\"" - + Util.escapeAttribute(client.translateVaadinUri(uidl - .getStringAttribute("icon"))) - + "\" alt=\"icon\" class=\"v-icon\">" + s; + Icon icon = client.getIcon(uidl.getStringAttribute("icon")); + icon.setAlternateText("icon"); + s = icon.getElement().getString() + s; } return s; } @@ -7140,7 +7167,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private void deEmphasis() { UIObject.setStyleName(getElement(), - VScrollTable.this.getStylePrimaryName() + "-drag", false); + getStylePrimaryName() + "-drag", false); if (lastEmphasized == null) { return; } @@ -7166,7 +7193,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private void emphasis(TableDDDetails details) { deEmphasis(); UIObject.setStyleName(getElement(), - VScrollTable.this.getStylePrimaryName() + "-drag", true); + getStylePrimaryName() + "-drag", true); // iterate old and new emphasized row for (Widget w : scrollBody.renderedRows) { VScrollTableRow row = (VScrollTableRow) w; @@ -7798,4 +7825,101 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return this; } + private static final String SUBPART_HEADER = "header"; + private static final String SUBPART_FOOTER = "footer"; + private static final String SUBPART_ROW = "row"; + private static final String SUBPART_COL = "col"; + /** + * Matches header[ix] - used for extracting the index of the targeted header + * cell + */ + private static final RegExp SUBPART_HEADER_REGEXP = RegExp + .compile(SUBPART_HEADER + "\\[(\\d+)\\]"); + /** + * Matches footer[ix] - used for extracting the index of the targeted footer + * cell + */ + private static final RegExp SUBPART_FOOTER_REGEXP = RegExp + .compile(SUBPART_FOOTER + "\\[(\\d+)\\]"); + /** Matches row[ix] - used for extracting the index of the targeted row */ + private static final RegExp SUBPART_ROW_REGEXP = RegExp.compile(SUBPART_ROW + + "\\[(\\d+)]"); + /** Matches col[ix] - used for extracting the index of the targeted column */ + private static final RegExp SUBPART_ROW_COL_REGEXP = RegExp + .compile(SUBPART_ROW + "\\[(\\d+)\\]/" + SUBPART_COL + + "\\[(\\d+)\\]"); + + @Override + public Element getSubPartElement(String subPart) { + if (SUBPART_ROW_COL_REGEXP.test(subPart)) { + MatchResult result = SUBPART_ROW_COL_REGEXP.exec(subPart); + int rowIx = Integer.valueOf(result.getGroup(1)); + int colIx = Integer.valueOf(result.getGroup(2)); + VScrollTableRow row = scrollBody.getRowByRowIndex(rowIx); + if (row != null) { + Element rowElement = row.getElement(); + if (colIx < rowElement.getChildCount()) { + return rowElement.getChild(colIx).getFirstChild().cast(); + } + } + + } else if (SUBPART_ROW_REGEXP.test(subPart)) { + MatchResult result = SUBPART_ROW_REGEXP.exec(subPart); + int rowIx = Integer.valueOf(result.getGroup(1)); + VScrollTableRow row = scrollBody.getRowByRowIndex(rowIx); + if (row != null) { + return row.getElement(); + } + + } else if (SUBPART_HEADER_REGEXP.test(subPart)) { + MatchResult result = SUBPART_HEADER_REGEXP.exec(subPart); + int headerIx = Integer.valueOf(result.getGroup(1)); + HeaderCell headerCell = tHead.getHeaderCell(headerIx); + if (headerCell != null) { + return headerCell.getElement(); + } + + } else if (SUBPART_FOOTER_REGEXP.test(subPart)) { + MatchResult result = SUBPART_FOOTER_REGEXP.exec(subPart); + int footerIx = Integer.valueOf(result.getGroup(1)); + FooterCell footerCell = tFoot.getFooterCell(footerIx); + if (footerCell != null) { + return footerCell.getElement(); + } + } + // Nothing found. + return null; + } + + @Override + public String getSubPartName(Element subElement) { + Widget widget = Util.findWidget(subElement, null); + if (widget instanceof HeaderCell) { + return SUBPART_HEADER + "[" + tHead.visibleCells.indexOf(widget) + + "]"; + } else if (widget instanceof FooterCell) { + return SUBPART_FOOTER + "[" + tFoot.visibleCells.indexOf(widget) + + "]"; + } else if (widget instanceof VScrollTableRow) { + // a cell in a row + VScrollTableRow row = (VScrollTableRow) widget; + int rowIx = scrollBody.indexOf(row); + if (rowIx >= 0) { + int colIx = -1; + for (int ix = 0; ix < row.getElement().getChildCount(); ix++) { + if (row.getElement().getChild(ix).isOrHasChild(subElement)) { + colIx = ix; + break; + } + } + if (colIx >= 0) { + return SUBPART_ROW + "[" + rowIx + "]/" + SUBPART_COL + "[" + + colIx + "]"; + } + return SUBPART_ROW + "[" + rowIx + "]"; + } + } + // Nothing found. + return null; + } } diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index a3d96983e8..82eb9e7694 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -19,6 +19,10 @@ package com.vaadin.client.ui; import java.util.Iterator; import java.util.List; +import com.google.gwt.aria.client.Id; +import com.google.gwt.aria.client.LiveValue; +import com.google.gwt.aria.client.Roles; +import com.google.gwt.aria.client.SelectedValue; import com.google.gwt.core.client.Scheduler; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Style; @@ -55,6 +59,7 @@ import com.vaadin.client.TooltipInfo; import com.vaadin.client.UIDL; import com.vaadin.client.Util; import com.vaadin.client.VCaption; +import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.EventId; import com.vaadin.shared.ui.ComponentStateUtil; @@ -94,12 +99,18 @@ public class VTabsheet extends VTabsheetBase implements Focusable, + "-selected"; private static final String TD_SELECTED_FIRST_CLASSNAME = TD_SELECTED_CLASSNAME + "-first"; + private static final String TD_FOCUS_CLASSNAME = TD_CLASSNAME + + "-focus"; + private static final String TD_FOCUS_FIRST_CLASSNAME = TD_FOCUS_CLASSNAME + + "-first"; private static final String TD_DISABLED_CLASSNAME = TD_CLASSNAME + "-disabled"; private static final String DIV_CLASSNAME = CLASSNAME + "-tabitem"; private static final String DIV_SELECTED_CLASSNAME = DIV_CLASSNAME + "-selected"; + private static final String DIV_FOCUS_CLASSNAME = DIV_CLASSNAME + + "-focus"; private TabCaption tabCaption; Element td = getElement(); @@ -112,11 +123,17 @@ public class VTabsheet extends VTabsheetBase implements Focusable, private String styleName; + private String id; + private Tab(TabBar tabBar) { super(DOM.createTD()); this.tabBar = tabBar; setStyleName(td, TD_CLASSNAME); + Roles.getTabRole().set(getElement()); + Roles.getTabRole().setAriaSelectedState(getElement(), + SelectedValue.FALSE); + div = DOM.createDiv(); setTabulatorIndex(-1); setStyleName(div, DIV_CLASSNAME); @@ -127,6 +144,9 @@ public class VTabsheet extends VTabsheetBase implements Focusable, .getApplicationConnection()); add(tabCaption); + Roles.getTabRole().setAriaLabelledbyProperty(getElement(), + Id.of(tabCaption.getElement())); + addFocusHandler(getTabsheet()); addBlurHandler(getTabsheet()); addKeyDownHandler(getTabsheet()); @@ -138,6 +158,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, public void setHiddenOnServer(boolean hiddenOnServer) { this.hiddenOnServer = hiddenOnServer; + Roles.getTabRole().setAriaHiddenState(getElement(), hiddenOnServer); } @Override @@ -152,6 +173,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable, public void setEnabledOnServer(boolean enabled) { enabledOnServer = enabled; + Roles.getTabRole().setAriaDisabledState(getElement(), !enabled); + setStyleName(td, TD_DISABLED_CLASSNAME, !enabled); if (!enabled) { focusImpl.setTabIndex(td, -1); @@ -175,10 +198,18 @@ public class VTabsheet extends VTabsheetBase implements Focusable, * true if the Tab is the first visible Tab */ public void setStyleNames(boolean selected, boolean first) { + setStyleNames(selected, first, false); + } + + public void setStyleNames(boolean selected, boolean first, + boolean keyboardFocus) { setStyleName(td, TD_FIRST_CLASSNAME, first); setStyleName(td, TD_SELECTED_CLASSNAME, selected); setStyleName(td, TD_SELECTED_FIRST_CLASSNAME, selected && first); setStyleName(div, DIV_SELECTED_CLASSNAME, selected); + setStyleName(td, TD_FOCUS_CLASSNAME, keyboardFocus); + setStyleName(td, TD_FOCUS_FIRST_CLASSNAME, keyboardFocus && first); + setStyleName(div, DIV_FOCUS_CLASSNAME, keyboardFocus); } public void setTabulatorIndex(int tabIndex) { @@ -204,10 +235,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable, String newStyleName = tabUidl .getStringAttribute(TabsheetConstants.TAB_STYLE_NAME); // Find the nth td element - if (newStyleName != null && newStyleName.length() != 0) { + if (newStyleName != null && !newStyleName.isEmpty()) { if (!newStyleName.equals(styleName)) { // If we have a new style name - if (styleName != null && styleName.length() != 0) { + if (styleName != null && !styleName.isEmpty()) { // Remove old style name if present td.removeClassName(TD_CLASSNAME + "-" + styleName); } @@ -221,6 +252,15 @@ public class VTabsheet extends VTabsheetBase implements Focusable, td.removeClassName(TD_CLASSNAME + "-" + styleName); styleName = null; } + + String newId = tabUidl.getStringAttribute("id"); + if (newId != null && !newId.isEmpty()) { + td.setId(newId); + id = newId; + } else if (id != null) { + td.removeAttribute("id"); + id = null; + } } public void recalculateCaptionWidth() { @@ -250,15 +290,21 @@ public class VTabsheet extends VTabsheetBase implements Focusable, focusImpl.blur(td); } - public boolean isSelectable() { - VTabsheet ts = getTabsheet(); - if (ts.client == null || ts.disabled || ts.waitingForResponse) { - return false; - } - if (!isEnabledOnServer() || isHiddenOnServer()) { - return false; - } - return true; + public boolean hasTooltip() { + return tabCaption.getTooltipInfo() != null; + } + + public TooltipInfo getTooltipInfo() { + return tabCaption.getTooltipInfo(); + } + + public void setAssistiveDescription(String descriptionId) { + Roles.getTablistRole().setAriaDescribedbyProperty(getElement(), + Id.of(descriptionId)); + } + + public void removeAssistiveDescription() { + Roles.getTablistRole().removeAriaDescribedbyProperty(getElement()); } } @@ -267,12 +313,12 @@ public class VTabsheet extends VTabsheetBase implements Focusable, private boolean closable = false; private Element closeButton; private Tab tab; - private ApplicationConnection client; TabCaption(Tab tab, ApplicationConnection client) { super(client); - this.client = client; this.tab = tab; + + AriaHelper.ensureHasId(getElement()); } public boolean updateCaption(UIDL uidl) { @@ -292,7 +338,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable, uidl.hasAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_DISABLED), uidl.hasAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_DESCRIPTION), uidl.hasAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_ERROR_MESSAGE), - uidl.getStringAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_ICON)); + uidl.getStringAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_ICON), + uidl.getStringAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_ICON_ALT)); setClosable(uidl.hasAttribute("closable")); @@ -330,6 +377,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable, closeButton.setInnerHTML("×"); closeButton .setClassName(VTabsheet.CLASSNAME + "-caption-close"); + + Roles.getTabRole().setAriaHiddenState(closeButton, true); + Roles.getTabRole().setAriaDisabledState(closeButton, true); + getElement().appendChild(closeButton); } else if (!closable && closeButton != null) { getElement().removeChild(closeButton); @@ -376,6 +427,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable, this.tabsheet = tabsheet; Element el = DOM.createTable(); + Roles.getPresentationRole().set(el); + Element tbody = DOM.createTBody(); DOM.appendChild(el, tbody); DOM.appendChild(tbody, tr); @@ -432,7 +485,12 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } int index = getWidgetIndex(caption.getParent()); - getTabsheet().onTabSelected(index); + + navigateTab(getTabsheet().focusedTabIndex, index); + getTabsheet().focusedTabIndex = index; + getTabsheet().focusedTab = getTab(index); + getTabsheet().focus(); + getTabsheet().loadTabSheet(index); } public VTabsheet getTabsheet() { @@ -450,13 +508,18 @@ public class VTabsheet extends VTabsheetBase implements Focusable, final Tab newSelected = getTab(index); final Tab oldSelected = selected; - newSelected.setStyleNames(true, isFirstVisibleTab(index)); + newSelected.setStyleNames(true, isFirstVisibleTab(index), true); newSelected.setTabulatorIndex(getTabsheet().tabulatorIndex); + Roles.getTabRole().setAriaSelectedState(newSelected.getElement(), + SelectedValue.TRUE); if (oldSelected != null && oldSelected != newSelected) { oldSelected.setStyleNames(false, isFirstVisibleTab(getWidgetIndex(oldSelected))); oldSelected.setTabulatorIndex(-1); + + Roles.getTabRole().setAriaSelectedState( + oldSelected.getElement(), SelectedValue.FALSE); } // Update the field holding the currently selected tab @@ -467,6 +530,23 @@ public class VTabsheet extends VTabsheetBase implements Focusable, getTab(tabsheet.activeTabIndex).recalculateCaptionWidth(); } + public void navigateTab(int fromIndex, int toIndex) { + Tab newNavigated = getTab(toIndex); + if (newNavigated == null) { + throw new IllegalArgumentException( + "Tab at provided index toIndex was not found"); + } + + Tab oldNavigated = getTab(fromIndex); + newNavigated.setStyleNames(newNavigated.equals(selected), + isFirstVisibleTab(toIndex), true); + + if (oldNavigated != null && fromIndex != toIndex) { + oldNavigated.setStyleNames(oldNavigated.equals(selected), + isFirstVisibleTab(fromIndex), false); + } + } + public void removeTab(int i) { Tab tab = getTab(i); if (tab == null) { @@ -596,15 +676,34 @@ public class VTabsheet extends VTabsheetBase implements Focusable, private String currentStyle; - private void onTabSelected(final int tabIndex) { - if (activeTabIndex != tabIndex) { + /** + * @return Whether the tab could be selected or not. + */ + private boolean canSelectTab(final int tabIndex) { + Tab tab = tb.getTab(tabIndex); + if (client == null || disabled || waitingForResponse) { + return false; + } + if (!tab.isEnabledOnServer() || tab.isHiddenOnServer()) { + return false; + } + + // Note that we return true when tabIndex == activeTabIndex; the active + // tab could be selected, it's just a no-op. + return true; + } + + /** + * Load the content of a tab of the provided index. + * + * @param index + * of the tab to load + */ + public void loadTabSheet(int tabIndex) { + if (activeTabIndex != tabIndex && canSelectTab(tabIndex)) { tb.selectTab(tabIndex); - // If this TabSheet already has focus, set the new selected tab - // as focused. - if (focusedTab != null) { - focusedTab = tb.getTab(tabIndex); - } + activeTabIndex = tabIndex; addStyleDependentName("loading"); // Hide the current contents so a loading indicator can be shown @@ -660,22 +759,30 @@ public class VTabsheet extends VTabsheetBase implements Focusable, DOM.setStyleAttribute(getElement(), "overflow", "hidden"); tabs = DOM.createDiv(); DOM.setElementProperty(tabs, "className", TABS_CLASSNAME); + Roles.getTablistRole().set(tabs); + Roles.getTablistRole().setAriaLiveProperty(tabs, LiveValue.OFF); scroller = DOM.createDiv(); + Roles.getTablistRole().setAriaHiddenState(scroller, true); DOM.setElementProperty(scroller, "className", SCROLLER_CLASSNAME); scrollerPrev = DOM.createButton(); + scrollerPrev.setTabIndex(-1); DOM.setElementProperty(scrollerPrev, "className", SCROLLER_CLASSNAME + "Prev"); + Roles.getTablistRole().setAriaHiddenState(scrollerPrev, true); DOM.sinkEvents(scrollerPrev, Event.ONCLICK); scrollerNext = DOM.createButton(); + scrollerNext.setTabIndex(-1); DOM.setElementProperty(scrollerNext, "className", SCROLLER_CLASSNAME + "Next"); + Roles.getTablistRole().setAriaHiddenState(scrollerNext, true); DOM.sinkEvents(scrollerNext, Event.ONCLICK); DOM.appendChild(getElement(), tabs); // Tabs tp.setStyleName(CLASSNAME + "-tabsheetpanel"); contentNode = DOM.createDiv(); + Roles.getTabpanelRole().set(contentNode); deco = DOM.createDiv(); @@ -1081,7 +1188,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable, @Override public void onBlur(BlurEvent event) { + getApplicationConnection().getVTooltip().hideTooltip(); + if (focusedTab != null && focusedTab == event.getSource()) { + focusedTab.removeAssistiveDescription(); focusedTab = null; if (client.hasEventListeners(this, EventId.BLUR)) { client.updateVariable(id, EventId.BLUR, "", true); @@ -1096,6 +1206,13 @@ public class VTabsheet extends VTabsheetBase implements Focusable, if (client.hasEventListeners(this, EventId.FOCUS)) { client.updateVariable(id, EventId.FOCUS, "", true); } + + if (focusedTab.hasTooltip()) { + focusedTab.setAssistiveDescription(getApplicationConnection() + .getVTooltip().getUniqueId()); + getApplicationConnection().getVTooltip().showAssistive( + focusedTab.getTooltipInfo()); + } } } @@ -1116,13 +1233,17 @@ public class VTabsheet extends VTabsheetBase implements Focusable, if (!event.isAnyModifierKeyDown()) { if (keycode == getPreviousTabKey()) { selectPreviousTab(); + event.stopPropagation(); } else if (keycode == getNextTabKey()) { selectNextTab(); + event.stopPropagation(); } else if (keycode == getCloseTabKey()) { Tab tab = tb.getTab(activeTabIndex); if (tab.isClosable()) { tab.onClose(); } + } else if (keycode == getSelectTabKey()) { + loadTabSheet(focusedTabIndex); } } } @@ -1136,6 +1257,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable, return KeyCodes.KEY_LEFT; } + protected int getSelectTabKey() { + return 32; // Space key + } + /** * @return The key code of the keyboard shortcut that selects the next tab * in a focused tabsheet. @@ -1153,48 +1278,62 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } private void selectPreviousTab() { - int newTabIndex = activeTabIndex; - Tab newTab; + int newTabIndex = focusedTabIndex; // Find the previous visible and enabled tab if any. do { newTabIndex--; - newTab = tb.getTab(newTabIndex); - } while (newTabIndex >= 0 && !newTab.isSelectable()); + } while (newTabIndex >= 0 && !canSelectTab(newTabIndex)); if (newTabIndex >= 0) { + tb.navigateTab(focusedTabIndex, newTabIndex); + focusedTabIndex = newTabIndex; + + // If this TabSheet already has focus, set the new selected tab + // as focused. + if (focusedTab != null) { + focusedTab = tb.getTab(focusedTabIndex); + focusedTab.focus(); + } + if (isScrolledTabs()) { - // Scroll until the new active tab is visible - while (!newTab.isVisible()) { + // Scroll until the new focused tab is visible + while (!tb.getTab(focusedTabIndex).isVisible()) { scrollerIndex = tb.scrollLeft(scrollerIndex); } updateTabScroller(); } - onTabSelected(newTabIndex); - activeTabIndex = newTabIndex; } } private void selectNextTab() { - int newTabIndex = activeTabIndex; - Tab newTab; + int newTabIndex = focusedTabIndex; // Find the next visible and enabled tab if any. do { newTabIndex++; - newTab = tb.getTab(newTabIndex); - } while (newTabIndex < getTabCount() && !newTab.isSelectable()); + } while (newTabIndex < getTabCount() && !canSelectTab(newTabIndex)); if (newTabIndex < getTabCount()) { + + tb.navigateTab(focusedTabIndex, newTabIndex); + focusedTabIndex = newTabIndex; + + // If this TabSheet already has focus, set the new selected tab + // as focused. + if (focusedTab != null) { + focusedTab = tb.getTab(focusedTabIndex); + focusedTab.focus(); + } + if (isClippedTabs()) { // Scroll until the new active tab is completely visible int newScrollerIndex = scrollerIndex; - while (isClipped(newTab) && newScrollerIndex != -1) { + while (isClipped(tb.getTab(focusedTabIndex)) + && newScrollerIndex != -1) { newScrollerIndex = tb.scrollRight(newScrollerIndex); } scrollerIndex = newScrollerIndex; updateTabScroller(); } - onTabSelected(newTabIndex); - activeTabIndex = newTabIndex; } } } diff --git a/client/src/com/vaadin/client/ui/VTabsheetBase.java b/client/src/com/vaadin/client/ui/VTabsheetBase.java index 0923248115..bcd8811c7d 100644 --- a/client/src/com/vaadin/client/ui/VTabsheetBase.java +++ b/client/src/com/vaadin/client/ui/VTabsheetBase.java @@ -42,6 +42,8 @@ public abstract class VTabsheetBase extends ComplexPanel { /** For internal use only. May be removed or replaced in the future. */ public int activeTabIndex = 0; /** For internal use only. May be removed or replaced in the future. */ + public int focusedTabIndex = 0; + /** For internal use only. May be removed or replaced in the future. */ public boolean disabled; /** For internal use only. May be removed or replaced in the future. */ public boolean readonly; diff --git a/client/src/com/vaadin/client/ui/VTree.java b/client/src/com/vaadin/client/ui/VTree.java index 51c00ca310..86c724a3e0 100644 --- a/client/src/com/vaadin/client/ui/VTree.java +++ b/client/src/com/vaadin/client/ui/VTree.java @@ -70,6 +70,7 @@ import com.vaadin.client.ui.dd.VDragEvent; import com.vaadin.client.ui.dd.VDropHandler; import com.vaadin.client.ui.dd.VHasDropHandler; import com.vaadin.client.ui.dd.VTransferable; +import com.vaadin.client.ui.tree.TreeConnector; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.MouseEventDetails.MouseButton; import com.vaadin.shared.ui.MultiSelectMode; @@ -162,6 +163,9 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, /** For internal use only. May be removed or replaced in the future. */ public String[] bodyActionKeys; + /** For internal use only. May be removed or replaced in the future. */ + public TreeConnector connector; + public VLazyExecutor iconLoaded = new VLazyExecutor(50, new ScheduledCommand() { @@ -1120,23 +1124,15 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, } public void setIcon(String iconUrl, String altText) { - if (iconUrl != null) { - // Add icon if not present - if (icon == null) { - icon = new Icon(client); - Roles.getImgRole().set(icon.getElement()); - DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv), - icon.getElement(), nodeCaptionSpan); - } - icon.setUri(iconUrl); - icon.getElement().setAttribute("alt", altText); - } else { - // Remove icon if present - if (icon != null) { - DOM.removeChild(DOM.getFirstChild(nodeCaptionDiv), - icon.getElement()); - icon = null; - } + if (icon != null) { + DOM.getFirstChild(nodeCaptionDiv) + .removeChild(icon.getElement()); + } + icon = client.getIcon(iconUrl); + if (icon != null) { + DOM.insertBefore(DOM.getFirstChild(nodeCaptionDiv), + icon.getElement(), nodeCaptionSpan); + icon.setAlternateText(altText); } } @@ -1729,6 +1725,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, } } } + showTooltipForKeyboardNavigation(node); return true; } @@ -1754,6 +1751,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, } } } + showTooltipForKeyboardNavigation(node); return true; } @@ -1774,6 +1772,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, focusAndSelectNode(focusedNode.getParentNode()); } } + showTooltipForKeyboardNavigation(focusedNode); return true; } @@ -1792,6 +1791,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, focusAndSelectNode(focusedNode.getChildren().get(0)); } } + showTooltipForKeyboardNavigation(focusedNode); return true; } @@ -1820,6 +1820,7 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, selectNode(node, true); } sendSelectionToServer(); + showTooltipForKeyboardNavigation(node); return true; } @@ -1836,12 +1837,20 @@ public class VTree extends FocusElementPanel implements VHasDropHandler, selectNode(node, true); } sendSelectionToServer(); + showTooltipForKeyboardNavigation(node); return true; } return false; } + private void showTooltipForKeyboardNavigation(TreeNode node) { + if (connector != null) { + getClient().getVTooltip().showAssistive( + connector.getTooltipInfo(node.nodeCaptionSpan)); + } + } + private void focusAndSelectNode(TreeNode node) { /* * Keyboard navigation doesn't work reliably if the tree is in diff --git a/client/src/com/vaadin/client/ui/VUI.java b/client/src/com/vaadin/client/ui/VUI.java index ba3495743d..590263a5ed 100644 --- a/client/src/com/vaadin/client/ui/VUI.java +++ b/client/src/com/vaadin/client/ui/VUI.java @@ -18,6 +18,7 @@ package com.vaadin.client.ui; import java.util.ArrayList; +import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.HasScrollHandlers; @@ -43,6 +44,7 @@ import com.vaadin.client.ConnectorMap; import com.vaadin.client.Focusable; import com.vaadin.client.LayoutManager; import com.vaadin.client.Profiler; +import com.vaadin.client.Util; import com.vaadin.client.VConsole; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler; @@ -162,6 +164,8 @@ public class VUI extends SimplePanel implements ResizeHandler, }); + private Element storedFocus; + public VUI() { super(); // Allow focusing the view by using the focus() method, the view @@ -494,4 +498,36 @@ public class VUI extends SimplePanel implements ResizeHandler, FocusUtil.setTabIndex(this, index); } + /** + * Allows to store the currently focused Element. + * + * Current use case is to store the focus when a Window is opened. Does + * currently handle only a single value. Needs to be extended for #12158 + * + * @param focusedElement + */ + public void storeFocus() { + storedFocus = Util.getFocusedElement(); + } + + /** + * Restores the previously stored focus Element. + * + * Current use case is to restore the focus when a Window is closed. Does + * currently handle only a single value. Needs to be extended for #12158 + * + * @return the lastFocusElementBeforeDialogOpened + */ + public void focusStoredElement() { + if (storedFocus != null) { + storedFocus.focus(); + + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + storedFocus.focus(); + } + }); + } + } } diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index ad9d0eac7e..705787d6c8 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -18,11 +18,17 @@ package com.vaadin.client.ui; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.List; +import com.google.gwt.aria.client.Id; +import com.google.gwt.aria.client.RelevantValue; +import com.google.gwt.aria.client.Roles; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.Unit; @@ -30,8 +36,11 @@ import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; +import com.google.gwt.event.dom.client.KeyUpEvent; +import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; import com.google.gwt.event.shared.HandlerRegistration; @@ -39,28 +48,35 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Event.NativePreviewEvent; +import com.google.gwt.user.client.Event.NativePreviewHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.BrowserInfo; +import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorMap; import com.vaadin.client.Focusable; import com.vaadin.client.LayoutManager; import com.vaadin.client.Util; import com.vaadin.client.debug.internal.VDebugWindow; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; +import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.client.ui.window.WindowMoveEvent; import com.vaadin.client.ui.window.WindowMoveHandler; +import com.vaadin.shared.Connector; import com.vaadin.shared.EventId; import com.vaadin.shared.ui.window.WindowMode; +import com.vaadin.shared.ui.window.WindowState.WindowRole; /** * "Sub window" component. * * @author Vaadin Ltd */ -public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, - ScrollHandler, KeyDownHandler, FocusHandler, BlurHandler, Focusable { +public class VWindow extends VWindowOverlay implements + ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler, + KeyUpHandler, FocusHandler, BlurHandler, Focusable { private static ArrayList<VWindow> windowOrder = new ArrayList<VWindow>(); @@ -144,6 +160,22 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, private boolean closable = true; + private Connector[] assistiveConnectors = new Connector[0]; + private String assistivePrefix; + private String assistivePostfix; + + private Element topTabStop; + private Element bottomTabStop; + + private NativePreviewHandler topEventBlocker; + private NativePreviewHandler bottomEventBlocker; + + private HandlerRegistration topBlockerRegistration; + private HandlerRegistration bottomBlockerRegistration; + + // Prevents leaving the window with the Tab key when true + private boolean doTabStop; + /** * If centered (via UIDL), the window should stay in the centered -mode * until a position is received from the server, or the user moves or @@ -178,13 +210,74 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, // Different style of shadow for windows setShadowStyle("window"); + Roles.getDialogRole().set(getElement()); + Roles.getDialogRole().setAriaRelevantProperty(getElement(), + RelevantValue.ADDITIONS); + constructDOM(); contentPanel.addScrollHandler(this); contentPanel.addKeyDownHandler(this); + contentPanel.addKeyUpHandler(this); contentPanel.addFocusHandler(this); contentPanel.addBlurHandler(this); } + @Override + protected void onAttach() { + super.onAttach(); + + /* + * Stores the element that has focus in the application UI when the + * window is opened, so it can be restored when the window closes. + * + * This is currently implemented for the case when one non-modal window + * can be open at the same time, and the focus is not changed while the + * window is open. + */ + getApplicationConnection().getUIConnector().getWidget().storeFocus(); + + /* + * When this window gets reattached, set the tabstop to the previous + * state. + */ + setTabStopEnabled(doTabStop); + } + + @Override + protected void onDetach() { + super.onDetach(); + + /* + * Restores the previously stored focused element. + * + * When the focus was changed outside the window while the window was + * open, the originally stored element is restored. + */ + getApplicationConnection().getUIConnector().getWidget() + .focusStoredElement(); + + removeTabBlockHandlers(); + } + + private void addTabBlockHandlers() { + if (topBlockerRegistration == null) { + topBlockerRegistration = Event + .addNativePreviewHandler(topEventBlocker); + bottomBlockerRegistration = Event + .addNativePreviewHandler(bottomEventBlocker); + } + } + + private void removeTabBlockHandlers() { + if (topBlockerRegistration != null) { + topBlockerRegistration.removeHandler(); + topBlockerRegistration = null; + + bottomBlockerRegistration.removeHandler(); + bottomBlockerRegistration = null; + } + } + public void bringToFront() { int curIndex = windowOrder.indexOf(this); if (curIndex + 1 < windowOrder.size()) { @@ -248,6 +341,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, protected void constructDOM() { setStyleName(CLASSNAME); + topTabStop = DOM.createDiv(); + DOM.setElementAttribute(topTabStop, "tabindex", "0"); + header = DOM.createDiv(); DOM.setElementProperty(header, "className", CLASSNAME + "-outerheader"); headerText = DOM.createDiv(); @@ -262,18 +358,25 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, maximizeRestoreBox = DOM.createDiv(); DOM.setElementProperty(maximizeRestoreBox, "className", CLASSNAME + "-maximizebox"); + DOM.setElementAttribute(maximizeRestoreBox, "tabindex", "0"); DOM.setElementProperty(closeBox, "className", CLASSNAME + "-closebox"); + DOM.setElementAttribute(closeBox, "tabindex", "0"); DOM.appendChild(footer, resizeBox); + bottomTabStop = DOM.createDiv(); + DOM.setElementAttribute(bottomTabStop, "tabindex", "0"); + wrapper = DOM.createDiv(); DOM.setElementProperty(wrapper, "className", CLASSNAME + "-wrap"); + DOM.appendChild(wrapper, topTabStop); DOM.appendChild(wrapper, header); DOM.appendChild(wrapper, maximizeRestoreBox); DOM.appendChild(wrapper, closeBox); DOM.appendChild(header, headerText); DOM.appendChild(wrapper, contents); DOM.appendChild(wrapper, footer); + DOM.appendChild(wrapper, bottomTabStop); DOM.appendChild(super.getContainerElement(), wrapper); sinkEvents(Event.ONDBLCLICK | Event.MOUSEEVENTS | Event.TOUCHEVENTS @@ -281,6 +384,96 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, setWidget(contentPanel); + // Make the closebox accessible for assistive devices + Roles.getButtonRole().set(closeBox); + Roles.getButtonRole().setAriaLabelProperty(closeBox, "close button"); + + // Make the maximizebox accessible for assistive devices + Roles.getButtonRole().set(maximizeRestoreBox); + Roles.getButtonRole().setAriaLabelProperty(maximizeRestoreBox, + "maximize button"); + + // Provide the title to assistive devices + AriaHelper.ensureHasId(headerText); + Roles.getDialogRole().setAriaLabelledbyProperty(getElement(), + Id.of(headerText)); + + // Handlers to Prevent tab to leave the window + topEventBlocker = new NativePreviewHandler() { + @Override + public void onPreviewNativeEvent(NativePreviewEvent event) { + NativeEvent nativeEvent = event.getNativeEvent(); + if (nativeEvent.getEventTarget().cast() == topTabStop + && nativeEvent.getKeyCode() == KeyCodes.KEY_TAB + && nativeEvent.getShiftKey()) { + nativeEvent.preventDefault(); + } + } + }; + + bottomEventBlocker = new NativePreviewHandler() { + @Override + public void onPreviewNativeEvent(NativePreviewEvent event) { + NativeEvent nativeEvent = event.getNativeEvent(); + if (nativeEvent.getEventTarget().cast() == bottomTabStop + && nativeEvent.getKeyCode() == KeyCodes.KEY_TAB + && !nativeEvent.getShiftKey()) { + nativeEvent.preventDefault(); + } + } + }; + } + + /** + * Sets the message that is provided to users of assistive devices when the + * user reaches the top of the window when leaving a window with the tab key + * is prevented. + * <p> + * This message is not visible on the screen. + * + * @param topMessage + * String provided when the user navigates with Shift-Tab keys to + * the top of the window + */ + public void setTabStopTopAssistiveText(String topMessage) { + Roles.getNoteRole().setAriaLabelProperty(topTabStop, topMessage); + } + + /** + * Sets the message that is provided to users of assistive devices when the + * user reaches the bottom of the window when leaving a window with the tab + * key is prevented. + * <p> + * This message is not visible on the screen. + * + * @param bottomMessage + * String provided when the user navigates with the Tab key to + * the bottom of the window + */ + public void setTabStopBottomAssistiveText(String bottomMessage) { + Roles.getNoteRole().setAriaLabelProperty(bottomTabStop, bottomMessage); + } + + /** + * Gets the message that is provided to users of assistive devices when the + * user reaches the top of the window when leaving a window with the tab key + * is prevented. + * + * @return the top message + */ + public String getTabStopTopAssistiveText() { + return Roles.getNoteRole().getAriaLabelProperty(topTabStop); + } + + /** + * Gets the message that is provided to users of assistive devices when the + * user reaches the bottom of the window when leaving a window with the tab + * key is prevented. + * + * @return the bottom message + */ + public String getTabStopBottomAssistiveText() { + return Roles.getNoteRole().getAriaLabelProperty(bottomTabStop); } /** @@ -509,6 +702,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, if (isAttached()) { showModalityCurtain(); } + addTabBlockHandlers(); deferOrdering(); } else { if (modalityCurtain != null) { @@ -517,6 +711,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, } modalityCurtain = null; } + if (!doTabStop) { + removeTabBlockHandlers(); + } } } @@ -674,11 +871,64 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, if (icon != null) { icon = client.translateVaadinUri(icon); html = "<img src=\"" + Util.escapeAttribute(icon) - + "\" class=\"v-icon\" />" + html; + + "\" class=\"v-icon\" alt=\"\" />" + html; } + + // Provide information to assistive device users that a sub window was + // opened + String prefix = "<span class='" + + AriaHelper.ASSISTIVE_DEVICE_ONLY_STYLE + "'>" + + assistivePrefix + "</span>"; + String postfix = "<span class='" + + AriaHelper.ASSISTIVE_DEVICE_ONLY_STYLE + "'>" + + assistivePostfix + "</span>"; + + html = prefix + html + postfix; DOM.setInnerHTML(headerText, html); } + /** + * Setter for the text for assistive devices the window caption is prefixed + * with. + * + * @param assistivePrefix + * the assistivePrefix to set + */ + public void setAssistivePrefix(String assistivePrefix) { + this.assistivePrefix = assistivePrefix; + } + + /** + * Getter for the text for assistive devices the window caption is prefixed + * with. + * + * @return the assistivePrefix + */ + public String getAssistivePrefix() { + return assistivePrefix; + } + + /** + * Setter for the text for assistive devices the window caption is postfixed + * with. + * + * @param assistivePostfix + * the assistivePostfix to set + */ + public void setAssistivePostfix(String assistivePostfix) { + this.assistivePostfix = assistivePostfix; + } + + /** + * Getter for the text for assistive devices the window caption is postfixed + * with. + * + * @return the assistivePostfix + */ + public String getAssistivePostfix() { + return assistivePostfix; + } + @Override protected Element getContainerElement() { // in GWT 1.5 this method is used in PopupPanel constructor @@ -1056,6 +1306,13 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, } @Override + public void onKeyUp(KeyUpEvent event) { + if (isClosable() && event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) { + onCloseClick(); + } + } + + @Override public void onBlur(BlurEvent event) { if (client.hasEventListeners(this, EventId.BLUR)) { client.updateVariable(id, EventId.BLUR, "", true); @@ -1092,9 +1349,104 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, } /** + * Allows to specify which connectors contain the description for the + * window. Text contained in the widgets of the connectors will be read by + * assistive devices when it is opened. + * <p> + * When the provided array is empty, an existing description is removed. + * + * @param connectors + * with the connectors of the widgets to use as description + */ + public void setAssistiveDescription(Connector[] connectors) { + if (connectors != null) { + assistiveConnectors = connectors; + + if (connectors.length == 0) { + Roles.getDialogRole().removeAriaDescribedbyProperty( + getElement()); + } else { + Id[] ids = new Id[connectors.length]; + for (int index = 0; index < connectors.length; index++) { + if (connectors[index] == null) { + throw new IllegalArgumentException( + "All values in parameter description need to be non-null"); + } + + Element element = ((ComponentConnector) connectors[index]) + .getWidget().getElement(); + AriaHelper.ensureHasId(element); + ids[index] = Id.of(element); + } + + Roles.getDialogRole().setAriaDescribedbyProperty(getElement(), + ids); + } + } else { + throw new IllegalArgumentException( + "Parameter description must be non-null"); + } + } + + /** + * Gets the connectors that are used as assistive description. Text + * contained in these connectors will be read by assistive devices when the + * window is opened. + * + * @return list of previously set connectors + */ + public List<Connector> getAssistiveDescription() { + return Collections.unmodifiableList(Arrays.asList(assistiveConnectors)); + } + + /** + * Sets the WAI-ARIA role the window. + * + * This role defines how an assistive device handles a window. Available + * roles are alertdialog and dialog (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>). + * + * The default role is dialog. + * + * @param role + * WAI-ARIA role to set for the window + */ + public void setWaiAriaRole(WindowRole role) { + if ("alertdialog".equals(role)) { + Roles.getAlertdialogRole().set(getElement()); + } else { + Roles.getDialogRole().set(getElement()); + } + } + + /** + * Registers the handlers that prevent to leave the window using the + * Tab-key. + * <p> + * The value of the parameter doTabStop is stored and used for non-modal + * windows. For modal windows, the handlers are always registered, while + * preserving the stored value. + * + * @param doTabStop + * true to prevent leaving the window, false to allow leaving the + * window for non modal windows + */ + public void setTabStopEnabled(boolean doTabStop) { + this.doTabStop = doTabStop; + + if (doTabStop || vaadinModality) { + addTabBlockHandlers(); + } else { + removeTabBlockHandlers(); + } + } + + /** * Adds a Handler for when user moves the window. * * @since 7.1.9 + * * @return {@link HandlerRegistration} used to remove the handler */ public HandlerRegistration addMoveHandler(WindowMoveHandler handler) { diff --git a/client/src/com/vaadin/client/ui/VWindowOverlay.java b/client/src/com/vaadin/client/ui/VWindowOverlay.java new file mode 100644 index 0000000000..efc01cf63e --- /dev/null +++ b/client/src/com/vaadin/client/ui/VWindowOverlay.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.client.ui; + +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.RootPanel; +import com.vaadin.client.ApplicationConnection; + +public class VWindowOverlay extends VOverlay { + public VWindowOverlay() { + } + + public VWindowOverlay(boolean autoHide, boolean modal, boolean showShadow) { + super(autoHide, modal, showShadow); + } + + /** + * Gets the 'overlay container' element. Tries to find the current + * {@link ApplicationConnection} using {@link #getApplicationConnection()}. + * + * @return the overlay container element for the current + * {@link ApplicationConnection} or another element if the current + * {@link ApplicationConnection} cannot be determined. + */ + @Override + public Element getOverlayContainer() { + ApplicationConnection ac = getApplicationConnection(); + if (ac == null) { + return super.getOverlayContainer(); + } else { + Element overlayContainer = getOverlayContainer(ac); + return overlayContainer; + } + } + + /** + * Gets the 'overlay container' element pertaining to the given + * {@link ApplicationConnection}. Each overlay should be created in a + * overlay container element, so that the correct theme and styles can be + * applied. + * + * @param ac + * A reference to {@link ApplicationConnection} + * @return The overlay container + */ + public static Element getOverlayContainer(ApplicationConnection ac) { + String id = ac.getConfiguration().getRootPanelId(); + id = id += "-window-overlays"; + Element container = DOM.getElementById(id); + if (container == null) { + container = DOM.createDiv(); + container.setId(id); + String styles = ac.getUIConnector().getWidget().getParent() + .getStyleName(); + container.addClassName(styles); + container.addClassName(CLASSNAME_CONTAINER); + RootPanel.get().getElement().appendChild(container); + } + + return container; + } +} diff --git a/client/src/com/vaadin/client/ui/button/ButtonConnector.java b/client/src/com/vaadin/client/ui/button/ButtonConnector.java index a6630f28b9..94c2841c3c 100644 --- a/client/src/com/vaadin/client/ui/button/ButtonConnector.java +++ b/client/src/com/vaadin/client/ui/button/ButtonConnector.java @@ -80,21 +80,17 @@ public class ButtonConnector extends AbstractComponentConnector implements addStateChangeHandler("resources", new StateChangeHandler() { @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { - if (getIcon() != null) { - if (getWidget().icon == null) { - getWidget().icon = new Icon(getConnection()); - getWidget().wrapper.insertBefore( - getWidget().icon.getElement(), - getWidget().captionElement); - } - getWidget().icon.setUri(getIcon()); - getWidget().icon.setAlternateText(getState().iconAltText); - } else { - if (getWidget().icon != null) { - getWidget().wrapper.removeChild(getWidget().icon - .getElement()); - getWidget().icon = null; - } + if (getWidget().icon != null) { + getWidget().wrapper.removeChild(getWidget().icon + .getElement()); + getWidget().icon = null; + } + Icon icon = getIcon(); + if (icon != null) { + getWidget().icon = icon; + icon.setAlternateText(getState().iconAltText); + getWidget().wrapper.insertBefore(icon.getElement(), + getWidget().captionElement); } } }); diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java b/client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java index 39de122694..344b5ce739 100644 --- a/client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java +++ b/client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java @@ -42,7 +42,6 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.HorizontalPanel; import com.vaadin.client.Util; -import com.vaadin.client.ui.VCalendar; import com.vaadin.shared.ui.calendar.DateConstants; /** @@ -105,7 +104,6 @@ public class DateCellDayEvent extends FocusableHTML implements eventContent.addClassName("v-calendar-event-content"); getElement().appendChild(eventContent); - VCalendar calendar = weekGrid.getCalendar(); if (weekGrid.getCalendar().isEventResizeAllowed()) { topResizeBar = DOM.createDiv(); bottomResizeBar = DOM.createDiv(); @@ -189,9 +187,11 @@ public class DateCellDayEvent extends FocusableHTML implements String escapedCaption = Util.escapeHTML(calendarEvent.getCaption()); String timeAsText = calendarEvent.getTimeAsText(); if (bigMode) { - innerHtml = "<span>" + timeAsText + "</span><br />" + escapedCaption; + innerHtml = "<span>" + timeAsText + "</span><br />" + + escapedCaption; } else { - innerHtml = "<span>" + timeAsText + "<span>:</span></span> " + escapedCaption; + innerHtml = "<span>" + timeAsText + "<span>:</span></span> " + + escapedCaption; } caption.setInnerHTML(innerHtml); eventContent.setInnerHTML(""); diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/DayToolbar.java b/client/src/com/vaadin/client/ui/calendar/schedule/DayToolbar.java index 6233e8111e..58b5fafa7f 100644 --- a/client/src/com/vaadin/client/ui/calendar/schedule/DayToolbar.java +++ b/client/src/com/vaadin/client/ui/calendar/schedule/DayToolbar.java @@ -72,8 +72,6 @@ public class DayToolbar extends HorizontalPanel implements ClickHandler { setCellWidth(nextLabel, MARGINRIGHT + "px"); setCellHorizontalAlignment(nextLabel, ALIGN_RIGHT); int cellw = width / (count - 2); - int remain = width % (count - 2); - int cellw2 = cellw + 1; if (cellw > 0) { int[] cellWidths = VCalendar .distributeSize(width, count - 2, 0); diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/MonthGrid.java b/client/src/com/vaadin/client/ui/calendar/schedule/MonthGrid.java index df9bc42d2a..3b1c774793 100644 --- a/client/src/com/vaadin/client/ui/calendar/schedule/MonthGrid.java +++ b/client/src/com/vaadin/client/ui/calendar/schedule/MonthGrid.java @@ -35,7 +35,6 @@ public class MonthGrid extends FocusableGrid implements KeyDownHandler { private SimpleDayCell selectionEnd; private final VCalendar calendar; private boolean rangeSelectDisabled; - private boolean disabled; private boolean enabled = true; private final HandlerRegistration keyDownHandler; diff --git a/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java b/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java index cf8006ef66..00fc1ef3ea 100644 --- a/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java +++ b/client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java @@ -83,7 +83,6 @@ public class SimpleDayCell extends FocusableFlowPanel implements private Widget clickedWidget; private HandlerRegistration bottomSpacerMouseDownHandler; private boolean scrollable = false; - private boolean eventCanceled; private MonthGrid monthGrid; private HandlerRegistration keyDownHandler; diff --git a/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java b/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java index 85e4e5ee8b..b40e96ff95 100644 --- a/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java +++ b/client/src/com/vaadin/client/ui/checkbox/CheckBoxConnector.java @@ -30,6 +30,7 @@ import com.vaadin.client.VTooltip; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.Icon; +import com.vaadin.client.ui.ImageIcon; import com.vaadin.client.ui.VCheckBox; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc; @@ -96,21 +97,17 @@ public class CheckBoxConnector extends AbstractFieldConnector implements getWidget().setEnabled(false); } - if (getIcon() != null) { - if (getWidget().icon == null) { - getWidget().icon = new Icon(getConnection()); - DOM.insertChild(getWidget().getElement(), - getWidget().icon.getElement(), 1); - getWidget().icon.sinkEvents(VTooltip.TOOLTIP_EVENTS); - getWidget().icon.sinkEvents(Event.ONCLICK); - } - getWidget().icon.setUri(getIcon()); - } else if (getWidget().icon != null) { - // detach icon - DOM.removeChild(getWidget().getElement(), - getWidget().icon.getElement()); + if (getWidget().icon != null) { + getWidget().getElement().removeChild(getWidget().icon.getElement()); getWidget().icon = null; } + Icon icon = getIcon(); + if (icon != null) { + getWidget().icon = icon; + DOM.insertChild(getWidget().getElement(), icon.getElement(), 1); + icon.sinkEvents(VTooltip.TOOLTIP_EVENTS); + icon.sinkEvents(Event.ONCLICK); + } // Set text getWidget().setText(getState().caption); diff --git a/client/src/com/vaadin/client/ui/dd/VHtml5File.java b/client/src/com/vaadin/client/ui/dd/VHtml5File.java index 4b36e7fd1b..c4ad615fbd 100644 --- a/client/src/com/vaadin/client/ui/dd/VHtml5File.java +++ b/client/src/com/vaadin/client/ui/dd/VHtml5File.java @@ -35,7 +35,13 @@ public class VHtml5File extends JavaScriptObject { return this.type; }-*/; - public native final int getSize() + /* + * Browser implementations support files >2GB dropped and report the value + * as long. Due to JSNI limitations this value needs to be sent as double + * and then cast back to a long value. + * www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html#important + */ + public native final double getSize() /*-{ return this.size ? this.size : 0; }-*/; diff --git a/client/src/com/vaadin/client/ui/dd/VIsOverId.java b/client/src/com/vaadin/client/ui/dd/VIsOverId.java index f8083f8b60..7e2f596a20 100644 --- a/client/src/com/vaadin/client/ui/dd/VIsOverId.java +++ b/client/src/com/vaadin/client/ui/dd/VIsOverId.java @@ -19,7 +19,6 @@ package com.vaadin.client.ui.dd; import com.vaadin.client.ComponentConnector; -import com.vaadin.client.ConnectorMap; import com.vaadin.client.UIDL; import com.vaadin.shared.ui.dd.AcceptCriterion; import com.vaadin.ui.AbstractSelect; @@ -36,8 +35,6 @@ final public class VIsOverId extends VAcceptCriterion { .getCurrentDropHandler(); ComponentConnector dropHandlerConnector = currentDropHandler .getConnector(); - ConnectorMap paintableMap = ConnectorMap.get(currentDropHandler - .getApplicationConnection()); String pid2 = dropHandlerConnector.getConnectorId(); if (pid2.equals(pid)) { diff --git a/client/src/com/vaadin/client/ui/dd/VItemIdIs.java b/client/src/com/vaadin/client/ui/dd/VItemIdIs.java index 7d60eda4f9..b022f434f4 100644 --- a/client/src/com/vaadin/client/ui/dd/VItemIdIs.java +++ b/client/src/com/vaadin/client/ui/dd/VItemIdIs.java @@ -32,8 +32,6 @@ final public class VItemIdIs extends VAcceptCriterion { String pid = configuration.getStringAttribute("s"); ComponentConnector dragSource = drag.getTransferable() .getDragSource(); - VDropHandler currentDropHandler = VDragAndDropManager.get() - .getCurrentDropHandler(); String pid2 = dragSource.getConnectorId(); if (pid2.equals(pid)) { Object searchedId = drag.getTransferable().getData("itemId"); diff --git a/client/src/com/vaadin/client/ui/form/FormConnector.java b/client/src/com/vaadin/client/ui/form/FormConnector.java index acd0e917fc..a6015170c2 100644 --- a/client/src/com/vaadin/client/ui/form/FormConnector.java +++ b/client/src/com/vaadin/client/ui/form/FormConnector.java @@ -27,7 +27,6 @@ import com.vaadin.client.Paintable; import com.vaadin.client.TooltipInfo; import com.vaadin.client.UIDL; import com.vaadin.client.ui.AbstractComponentContainerConnector; -import com.vaadin.client.ui.Icon; import com.vaadin.client.ui.ShortcutActionHandler; import com.vaadin.client.ui.VForm; import com.vaadin.client.ui.layout.ElementResizeEvent; @@ -108,17 +107,14 @@ public class FormConnector extends AbstractComponentContainerConnector } else { getWidget().caption.setInnerText(""); } - if (getIcon() != null) { - if (getWidget().icon == null) { - getWidget().icon = new Icon(client); - getWidget().legend.insertFirst(getWidget().icon.getElement()); - } - getWidget().icon.setUri(getIcon()); + if (getWidget().icon != null) { + getWidget().legend.removeChild(getWidget().icon.getElement()); + } + if (getIconUri() != null) { + getWidget().icon = client.getIcon(getIconUri()); + getWidget().legend.insertFirst(getWidget().icon.getElement()); + legendEmpty = false; - } else { - if (getWidget().icon != null) { - getWidget().legend.removeChild(getWidget().icon.getElement()); - } } if (legendEmpty) { getWidget().addStyleDependentName("nocaption"); diff --git a/client/src/com/vaadin/client/ui/label/LabelConnector.java b/client/src/com/vaadin/client/ui/label/LabelConnector.java index 9639987e8d..6a04c91562 100644 --- a/client/src/com/vaadin/client/ui/label/LabelConnector.java +++ b/client/src/com/vaadin/client/ui/label/LabelConnector.java @@ -36,12 +36,6 @@ public class LabelConnector extends AbstractComponentConnector { } @Override - protected void init() { - super.init(); - getWidget().setConnection(getConnection()); - } - - @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { super.onStateChanged(stateChangeEvent); boolean sinkOnloads = false; diff --git a/client/src/com/vaadin/client/ui/link/LinkConnector.java b/client/src/com/vaadin/client/ui/link/LinkConnector.java index 228897278e..c8bbc426e9 100644 --- a/client/src/com/vaadin/client/ui/link/LinkConnector.java +++ b/client/src/com/vaadin/client/ui/link/LinkConnector.java @@ -17,38 +17,21 @@ package com.vaadin.client.ui.link; import com.google.gwt.user.client.DOM; -import com.vaadin.client.ApplicationConnection; -import com.vaadin.client.Paintable; -import com.vaadin.client.UIDL; import com.vaadin.client.communication.StateChangeEvent; -import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.Icon; import com.vaadin.client.ui.VLink; -import com.vaadin.shared.ui.BorderStyle; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.link.LinkConstants; import com.vaadin.shared.ui.link.LinkState; import com.vaadin.ui.Link; @Connect(Link.class) -public class LinkConnector extends AbstractComponentConnector implements - Paintable { +public class LinkConnector extends AbstractComponentConnector { @Override protected void init() { super.init(); - addStateChangeHandler("resources", new StateChangeHandler() { - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - getWidget().src = getResourceUrl(LinkConstants.HREF_RESOURCE); - if (getWidget().src == null) { - getWidget().anchor.removeAttribute("href"); - } else { - getWidget().anchor.setAttribute("href", getWidget().src); - } - } - }); } @Override @@ -62,35 +45,30 @@ public class LinkConnector extends AbstractComponentConnector implements } @Override - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - - if (!isRealUpdate(uidl)) { - return; - } - - getWidget().client = client; + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); getWidget().enabled = isEnabled(); - if (uidl.hasAttribute("name")) { - getWidget().target = uidl.getStringAttribute("name"); - getWidget().anchor.setAttribute("target", getWidget().target); - } - - if (uidl.hasAttribute("border")) { - if ("none".equals(uidl.getStringAttribute("border"))) { - getWidget().borderStyle = BorderStyle.NONE; + if (stateChangeEvent.hasPropertyChanged("resources")) { + getWidget().src = getResourceUrl(LinkConstants.HREF_RESOURCE); + if (getWidget().src == null) { + getWidget().anchor.removeAttribute("href"); } else { - getWidget().borderStyle = BorderStyle.MINIMAL; + getWidget().anchor.setAttribute("href", getWidget().src); } + } + + getWidget().target = getState().target; + if (getWidget().target == null) { + getWidget().anchor.removeAttribute("target"); } else { - getWidget().borderStyle = BorderStyle.DEFAULT; + getWidget().anchor.setAttribute("target", getWidget().target); } - getWidget().targetHeight = uidl.hasAttribute("targetHeight") ? uidl - .getIntAttribute("targetHeight") : -1; - getWidget().targetWidth = uidl.hasAttribute("targetWidth") ? uidl - .getIntAttribute("targetWidth") : -1; + getWidget().borderStyle = getState().targetBorder; + getWidget().targetWidth = getState().targetWidth; + getWidget().targetHeight = getState().targetHeight; // Set link caption getWidget().captionElement.setInnerText(getState().caption); @@ -109,15 +87,16 @@ public class LinkConnector extends AbstractComponentConnector implements "none"); } - if (getIcon() != null) { - if (getWidget().icon == null) { - getWidget().icon = new Icon(client); - getWidget().anchor.insertBefore(getWidget().icon.getElement(), - getWidget().captionElement); - } - getWidget().icon.setUri(getIcon()); + if (getWidget().icon != null) { + getWidget().anchor.removeChild(getWidget().icon.getElement()); + getWidget().icon = null; + } + Icon icon = getIcon(); + if (icon != null) { + getWidget().icon = icon; + getWidget().anchor.insertBefore(icon.getElement(), + getWidget().captionElement); } - } @Override diff --git a/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java b/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java index 3e22ebb05b..0df413c1c3 100644 --- a/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java +++ b/client/src/com/vaadin/client/ui/menubar/MenuBarConnector.java @@ -27,7 +27,7 @@ import com.vaadin.client.TooltipInfo; import com.vaadin.client.UIDL; import com.vaadin.client.Util; import com.vaadin.client.ui.AbstractComponentConnector; -import com.vaadin.client.ui.Icon; +import com.vaadin.client.ui.ImageIcon; import com.vaadin.client.ui.SimpleManagedLayout; import com.vaadin.client.ui.VMenuBar; import com.vaadin.shared.ui.ComponentStateUtil; @@ -81,7 +81,8 @@ public class MenuBarConnector extends AbstractComponentConnector implements + Util.escapeAttribute(client .translateVaadinUri(moreItemUIDL .getStringAttribute("icon"))) - + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />"); + + "\" class=\"" + ImageIcon.CLASSNAME + + "\" alt=\"\" />"); } String moreItemText = moreItemUIDL.getStringAttribute("text"); diff --git a/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java b/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java index 11a76b483b..e4e88899eb 100644 --- a/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java +++ b/client/src/com/vaadin/client/ui/nativebutton/NativeButtonConnector.java @@ -87,20 +87,16 @@ public class NativeButtonConnector extends AbstractComponentConnector implements getWidget().errorIndicatorElement = null; } - if (getIcon() != null) { - if (getWidget().icon == null) { - getWidget().icon = new Icon(getConnection()); - getWidget().getElement().insertBefore( - getWidget().icon.getElement(), - getWidget().captionElement); - } - getWidget().icon.setUri(getIcon()); - } else { - if (getWidget().icon != null) { - getWidget().getElement().removeChild( - getWidget().icon.getElement()); - getWidget().icon = null; - } + if (getWidget().icon != null) { + getWidget().getElement().removeChild(getWidget().icon.getElement()); + getWidget().icon = null; + } + Icon icon = getIcon(); + if (icon != null) { + getWidget().icon = icon; + getWidget().getElement().insertBefore(icon.getElement(), + getWidget().captionElement); + icon.setAlternateText(getState().iconAltText); } } diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java index 8ee1921ed7..92cf83d038 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java @@ -32,6 +32,7 @@ import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; import com.vaadin.client.ui.AbstractFieldConnector; import com.vaadin.client.ui.AbstractLayoutConnector; +import com.vaadin.client.ui.Icon; import com.vaadin.client.ui.LayoutClickEventHandler; import com.vaadin.client.ui.aria.AriaHelper; import com.vaadin.client.ui.layout.ElementResizeEvent; @@ -244,6 +245,8 @@ public abstract class AbstractOrderedLayoutConnector extends URLReference iconUrl = child.getState().resources .get(ComponentConstants.ICON_RESOURCE); String iconUrlString = iconUrl != null ? iconUrl.getURL() : null; + Icon icon = child.getConnection().getIcon(iconUrlString); + List<String> styles = child.getState().styles; String error = child.getState().errorMessage; boolean showError = error != null; @@ -258,8 +261,8 @@ public abstract class AbstractOrderedLayoutConnector extends } boolean enabled = child.isEnabled(); - slot.setCaption(caption, iconUrlString, styles, error, showError, - required, enabled); + slot.setCaption(caption, icon, styles, error, showError, required, + enabled); AriaHelper.handleInputRequired(child.getWidget(), required); AriaHelper.handleInputInvalid(child.getWidget(), showError); diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java index d9037cda3c..688853f6ec 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java @@ -19,18 +19,21 @@ package com.vaadin.client.ui.orderedlayout; import java.util.List; import com.google.gwt.aria.client.Roles; +import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Document; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.SimplePanel; -import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; import com.vaadin.client.LayoutManager; import com.vaadin.client.StyleConstants; import com.vaadin.client.Util; +import com.vaadin.client.ui.FontIcon; +import com.vaadin.client.ui.Icon; +import com.vaadin.client.ui.ImageIcon; import com.vaadin.client.ui.layout.ElementResizeEvent; import com.vaadin.client.ui.layout.ElementResizeListener; import com.vaadin.shared.ui.AlignmentInfo; @@ -39,44 +42,6 @@ import com.vaadin.shared.ui.AlignmentInfo; * Represents a slot which contains the actual widget in the layout. */ public final class Slot extends SimplePanel { - /** - * The icon for each widget. Located in the caption of the slot. - */ - private static class Icon extends UIObject { - - public static final String CLASSNAME = "v-icon"; - - private String myUrl; - - /** - * Constructor - */ - public Icon() { - setElement(DOM.createImg()); - DOM.setElementProperty(getElement(), "alt", ""); - setStyleName(CLASSNAME); - } - - /** - * Set the URL where the icon is located - * - * @param url - * A fully qualified URL - */ - public void setUri(String url) { - if (!url.equals(myUrl)) { - /* - * Start sinking onload events, widgets responsibility to react. - * We must do this BEFORE we set src as IE fires the event - * immediately if the image is found in cache (#2592). - */ - sinkEvents(Event.ONLOAD); - - DOM.setElementProperty(getElement(), "src", url); - myUrl = url; - } - } - } private static final String ALIGN_CLASS_PREFIX = "v-align-"; @@ -123,15 +88,12 @@ public final class Slot extends SimplePanel { private double expandRatio = -1; /** - * Constructor + * Constructs a slot. * + * @param layout + * The layout to which this slot belongs * @param widget * The widget to put in the slot - * @param layout - * TODO - * - * @param layoutManager - * The layout manager used by the layout */ public Slot(VAbstractOrderedLayout layout, Widget widget) { this.layout = layout; @@ -445,7 +407,7 @@ public final class Slot extends SimplePanel { * @param captionText * The text of the caption * @param iconUrl - * The icon URL + * The icon URL, must already be run trough translateVaadinUri() * @param styles * The style names * @param error @@ -456,10 +418,47 @@ public final class Slot extends SimplePanel { * Is the (field) required * @param enabled * Is the component enabled + * + * @deprecated Use + * {@link #setCaption(String, Icon, List, String, boolean, boolean, boolean)} + * instead */ + @Deprecated public void setCaption(String captionText, String iconUrl, List<String> styles, String error, boolean showError, boolean required, boolean enabled) { + Icon icon; + if (FontIcon.isFontIconUri(iconUrl)) { + icon = GWT.create(FontIcon.class); + } else { + icon = GWT.create(ImageIcon.class); + } + icon.setUri(iconUrl); + + setCaption(captionText, icon, styles, error, showError, required, + enabled); + } + + /** + * Set the caption of the slot + * + * @param captionText + * The text of the caption + * @param icon + * The icon + * @param styles + * The style names + * @param error + * The error message + * @param showError + * Should the error message be shown + * @param required + * Is the (field) required + * @param enabled + * Is the component enabled + */ + public void setCaption(String captionText, Icon icon, List<String> styles, + String error, boolean showError, boolean required, boolean enabled) { // TODO place for optimization: check if any of these have changed // since last time, and only run those changes @@ -469,7 +468,7 @@ public final class Slot extends SimplePanel { final Element focusedElement = Util.getFocusedElement(); // By default focus will not be lost boolean focusLost = false; - if (captionText != null || iconUrl != null || error != null || required) { + if (captionText != null || icon != null || error != null || required) { if (caption == null) { caption = DOM.createDiv(); captionWrap = DOM.createDiv(); @@ -516,16 +515,13 @@ public final class Slot extends SimplePanel { } // Icon - if (iconUrl != null) { - if (icon == null) { - icon = new Icon(); - caption.insertFirst(icon.getElement()); - } - icon.setUri(iconUrl); - } else if (icon != null) { + if (this.icon != null) { icon.getElement().removeFromParent(); - icon = null; } + if (icon != null) { + caption.insertFirst(icon.getElement()); + } + this.icon = icon; // Required if (required) { @@ -576,7 +572,7 @@ public final class Slot extends SimplePanel { } // Caption position - if (captionText != null || iconUrl != null) { + if (captionText != null || icon != null) { setCaptionPosition(CaptionPosition.TOP); } else { setCaptionPosition(CaptionPosition.RIGHT); diff --git a/client/src/com/vaadin/client/ui/panel/PanelConnector.java b/client/src/com/vaadin/client/ui/panel/PanelConnector.java index 4011f86c76..f2e73bae80 100644 --- a/client/src/com/vaadin/client/ui/panel/PanelConnector.java +++ b/client/src/com/vaadin/client/ui/panel/PanelConnector.java @@ -137,8 +137,8 @@ public class PanelConnector extends AbstractSingleComponentContainerConnector getWidget().client = client; getWidget().id = uidl.getId(); - if (getIcon() != null) { - getWidget().setIconUri(getIcon(), client); + if (getIconUri() != null) { + getWidget().setIconUri(getIconUri(), client); } else { getWidget().setIconUri(null, client); } diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java index 80a84f0a19..d2c700ab06 100644 --- a/client/src/com/vaadin/client/ui/table/TableConnector.java +++ b/client/src/com/vaadin/client/ui/table/TableConnector.java @@ -264,7 +264,7 @@ public class TableConnector extends AbstractHasComponentsConnector implements if (getWidget().focusedRow != null) { if (!getWidget().focusedRow.isAttached() - && !getWidget().rowRequestHandler.isRunning()) { + && !getWidget().rowRequestHandler.isRequestHandlerRunning()) { // focused row has been orphaned, can't focus if (getWidget().selectedRowKeys.contains(getWidget().focusedRow .getKey())) { diff --git a/client/src/com/vaadin/client/ui/tree/TreeConnector.java b/client/src/com/vaadin/client/ui/tree/TreeConnector.java index 7560a0f56b..61207ffa53 100644 --- a/client/src/com/vaadin/client/ui/tree/TreeConnector.java +++ b/client/src/com/vaadin/client/ui/tree/TreeConnector.java @@ -46,6 +46,11 @@ public class TreeConnector extends AbstractComponentConnector implements protected final Map<TreeNode, TooltipInfo> tooltipMap = new HashMap<TreeNode, TooltipInfo>(); @Override + protected void init() { + getWidget().connector = this; + } + + @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (!isRealUpdate(uidl)) { return; diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 149d99de17..47a5b5f807 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -49,7 +49,6 @@ import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; import com.vaadin.client.BrowserInfo; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ConnectorHierarchyChangeEvent; -import com.vaadin.client.ConnectorMap; import com.vaadin.client.Focusable; import com.vaadin.client.Paintable; import com.vaadin.client.ServerConnector; @@ -102,10 +101,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector protected void init() { super.init(); registerRpc(PageClientRpc.class, new PageClientRpc() { - @Override - public void setTitle(String title) { - com.google.gwt.user.client.Window.setTitle(title); - } @Override public void reload() { @@ -196,7 +191,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector @Override public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) { - ConnectorMap paintableMap = ConnectorMap.get(getConnection()); getWidget().id = getConnectorId(); boolean firstPaint = getWidget().connection == null; getWidget().connection = client; @@ -685,6 +679,13 @@ public class UIConnector extends AbstractSingleComponentContainerConnector configurePolling(); } + if (stateChangeEvent.hasPropertyChanged("pageState.title")) { + String title = getState().pageState.title; + if (title != null) { + com.google.gwt.user.client.Window.setTitle(title); + } + } + if (stateChangeEvent.hasPropertyChanged("pushConfiguration")) { getConnection().setPushEnabled( getState().pushConfiguration.mode.isEnabled()); diff --git a/client/src/com/vaadin/client/ui/upload/UploadConnector.java b/client/src/com/vaadin/client/ui/upload/UploadConnector.java index 989a913adc..03f1a2802c 100644 --- a/client/src/com/vaadin/client/ui/upload/UploadConnector.java +++ b/client/src/com/vaadin/client/ui/upload/UploadConnector.java @@ -16,13 +16,17 @@ package com.vaadin.client.ui.upload; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; import com.vaadin.client.ui.AbstractComponentConnector; import com.vaadin.client.ui.VUpload; +import com.vaadin.shared.EventId; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.upload.UploadClientRpc; +import com.vaadin.shared.ui.upload.UploadServerRpc; import com.vaadin.ui.Upload; @Connect(Upload.class) @@ -39,6 +43,21 @@ public class UploadConnector extends AbstractComponentConnector implements } @Override + protected void init() { + super.init(); + + getWidget().fu.addChangeHandler(new ChangeHandler() { + @Override + public void onChange(ChangeEvent event) { + if (hasEventListener(EventId.CHANGE)) { + getRpcProxy(UploadServerRpc.class).change( + getWidget().fu.getFilename()); + } + } + }); + } + + @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (!isRealUpdate(uidl)) { return; diff --git a/client/src/com/vaadin/client/ui/window/WindowConnector.java b/client/src/com/vaadin/client/ui/window/WindowConnector.java index 54ea384f5a..b6fe541c00 100644 --- a/client/src/com/vaadin/client/ui/window/WindowConnector.java +++ b/client/src/com/vaadin/client/ui/window/WindowConnector.java @@ -295,11 +295,21 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector // Caption must be set before required header size is measured. If // the caption attribute is missing the caption should be cleared. String iconURL = null; - if (getIcon() != null) { - iconURL = getIcon(); + if (getIconUri() != null) { + iconURL = getIconUri(); } + + window.setAssistivePrefix(state.assistivePrefix); + window.setAssistivePostfix(state.assistivePostfix); window.setCaption(state.caption, iconURL); + window.setWaiAriaRole(getState().role); + window.setAssistiveDescription(state.contentDescription); + + window.setTabStopEnabled(getState().assistiveTabStop); + window.setTabStopTopAssistiveText(getState().assistiveTabStopTopText); + window.setTabStopBottomAssistiveText(getState().assistiveTabStopBottomText); + clickEventHandler.handleEventHandlerRegistration(); window.immediate = state.immediate; diff --git a/common.xml b/common.xml index 0c1581fbf3..cef335035d 100644 --- a/common.xml +++ b/common.xml @@ -139,6 +139,7 @@ <fileset dir="${src}"> <patternset> <include name="**/*.java" /> + <include name="**/*.properties" /> </patternset> </fileset> <fileset refid="common.files.for.all.jars" /> @@ -200,7 +201,7 @@ <property name="src" location="{$result.dir}/../src" /> <union id="jar.files"> - <fileset dir="${classes}" excludes="${classes.exclude}" erroronmissingdir="false" /> + <fileset dir="${classes}" excludes="${classes.exclude}" erroronmissingdir="false"/> <fileset dir="${src}" excludes="${jar.exclude}" erroronmissingdir="false" /> <fileset refid="common.files.for.all.jars" /> <union refid="extra.jar.includes" /> @@ -293,6 +294,9 @@ <classpath refid="classpath.compile.dependencies" /> <classpath refid="classpath.compile.custom" /> </javac> + <copy todir="${classes}"> + <fileset dir="${src}" includes="${extra.classes}"/> + </copy> </target> <target name="exec-buildhelper" depends="compile"> diff --git a/eclipse/Development Server (vaadin).launch b/eclipse/Development Server (vaadin).launch index 8f57c441ec..9505811c0b 100644 --- a/eclipse/Development Server (vaadin).launch +++ b/eclipse/Development Server (vaadin).launch @@ -6,6 +6,13 @@ <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> <listEntry value="1"/> </listAttribute> +<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/> +<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> +<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" javaProject="vaadin" path="1" type="4"/> "/> +<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;ivyXmlPath=uitest%2Fivy.xml&amp;confs=jetty-run" path="3" type="4"/> "/> +<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="vaadin"/> </runtimeClasspathEntry> "/> +</listAttribute> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.vaadin.launcher.DevelopmentServerLauncher"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="vaadin"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/> diff --git a/publish.xml b/publish.xml index d37087d8f9..2fafb68246 100644 --- a/publish.xml +++ b/publish.xml @@ -20,6 +20,9 @@ <property name="file.war" location="result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${version}.war" /> <property name="target" value="${nightly.tests.publish}/${vaadin.version.major}.${vaadin.version.minor}-${build.tag}.war" /> + <fail unless="ant-jsch.present" message="Please install ant-jsch.jar into ANT_HOME/lib" /> + <fail unless="jsch.present" message="Please install jsch.jar into ANT_HOME/lib" /> + <echo>Installing ${src} to ${target}</echo> <scp todir="${nightly.tests.publish}" file="${file.war}"> @@ -34,7 +37,7 @@ <antcontrib:foreach list="${modules.to.publish.to.maven}" target="publish.module.to.maven" param="module" /> </target> - <target name="publish.module.to.download.site"> + <target name="publish.module.to.download.site"> <fail unless="module" message="No module to publish defined" /> <ivy:resolve log="download-only" file="${module}/ivy.xml" /> <ivy:publish publishivy="false" settingsref="publish.settings" conf="*(public)" resolver="sftp-publish"> @@ -65,4 +68,31 @@ </artifact:mvn> </target> + <!-- Use this to publish to local Maven repo --> + <!-- If you have compiled a snapshot build with: --> + <!-- ant -Dvaadin.version=7.x.x.zzz package --> + <!-- Publish with: --> + <!-- ant -f publish.xml -Dvaadin.version=7.x.x.zzz local.maven.publish --> + <!-- Note that if the build is a snapshot build, it will be installed as --> + <!-- 7.x-SNAPSHOT. --> + <target name="local.maven.publish"> + <antcontrib:foreach list="${modules.to.publish.to.maven}" target="publish.module.to.local.maven" param="module" /> + </target> + + <target name="publish.module.to.local.maven"> + <fail unless="module" message="No module to publish defined" /> + + <property name="jar.file" location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}.jar" /> + <property name="javadoc.file" location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}-javadoc.jar" /> + <property name="sources.file" location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}-sources.jar" /> + <property name="pom.file" location="result/artifacts/${vaadin.version}/vaadin-${module}/vaadin-${module}-${vaadin.version}.pom" /> + + <artifact:mvn failonerror="true"> + <arg value="install:install-file" /> + <sysproperty key="file" value="${jar.file}" /> + <sysproperty key="pomFile" value="${pom.file}" /> + <sysproperty key="javadoc" value="${javadoc.file}" /> + <sysproperty key="sources" value="${sources.file}" /> + </artifact:mvn> + </target> </project> diff --git a/push/build.xml b/push/build.xml index 17bc04a8cf..4a618611dd 100644 --- a/push/build.xml +++ b/push/build.xml @@ -16,7 +16,7 @@ <property name="vaadinPush.debug.js" location="${result.dir}/js/VAADIN/vaadinPush.debug.js" /> <!-- Keep the version number in sync with ivy.xml, server/src/com/vaadin/server/Constants.java --> - <property name="atmosphere.runtime.version" value="1.0.18.vaadin3" /> + <property name="atmosphere.runtime.version" value="2.1.1.vaadin2" /> <property name="jquery.version" value="1.9.0" /> <path id="classpath.compile.custom" /> @@ -73,7 +73,7 @@ <target name="jar" depends="vaadinPush.js"> <antcall target="common.jar"> - <param name="require-bundle" value="com.vaadin.external.atmosphere.atmosphere-runtime;bundle-version="${atmosphere.runtime.version}";visibility:=reexport" /> + <param name="require-bundle" value="com.vaadin.external.atmosphere.runtime;bundle-version="${atmosphere.runtime.version}";visibility:=reexport" /> <reference torefid="extra.jar.includes" refid="jar.includes" /> </antcall> </target> diff --git a/push/ivy.xml b/push/ivy.xml index ff6e199b95..4e66de30e8 100644 --- a/push/ivy.xml +++ b/push/ivy.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ivy-module [ <!-- Keep the version number in sync with build.xml --> - <!ENTITY atmosphere.runtime.version "1.0.18.vaadin3"> + <!ENTITY atmosphere.runtime.version "2.1.1.vaadin2"> - <!ENTITY atmosphere.js.version "2.0.3.vaadin2"> + <!ENTITY atmosphere.js.version "2.0.8.vaadin1"> ]> <ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" diff --git a/scripts/automerge7.sh b/scripts/automerge7.sh index bc3a7be0a4..079dec7eea 100755 --- a/scripts/automerge7.sh +++ b/scripts/automerge7.sh @@ -1,10 +1,17 @@ #!/bin/bash -FROM=7.0 -TO=7.1 +IGNORE=7.0 +FROM=7.1 +TO=master +IGNORE_HEAD=origin/$IGNORE FROM_HEAD=origin/$FROM PUSH="origin HEAD:refs/for/$TO" +EMAIL_AUTHOR= +if [ "$1" = "email" ] +then + EMAIL_AUTHOR=1 +fi show() { sCommit=$1 @@ -20,7 +27,7 @@ merge() { if [ "$mCommit" == "" ] then echo "merge() missing commit id" - exit 1 + exit 2 fi # echo "merge($mCommit)" @@ -30,7 +37,7 @@ merge() { then echo "Merge failed for commit $mCommit" echo "Manual merge is needed" - exit 2 + exit 3 fi # Add a change id using git hook git commit --amend --no-edit @@ -43,7 +50,7 @@ pushMerged() { if [ "$?" != "0" ] then echo "Push failed!" - exit 2 + exit 4 fi } @@ -59,7 +66,7 @@ maybe_commit_and_push() { if [ "$cpCommitMsg" == "" ] then echo "Internal error, no commit message passed to maybe_commit_and_push()" - exit 1; + exit 5 fi # echo "maybe_commit_and_push: Merging $cpCommit" merge $cpCommit @@ -80,13 +87,13 @@ if [ "$nothingToCommit" == "" ] then git status echo "Can not merge when there are unstaged changes." - exit 1; + exit 6 fi git checkout $TO git fetch -pending=`git log $TO..$FROM_HEAD --reverse|grep "^commit "|sed "s/commit //"` +pending=`git log $TO..$FROM_HEAD ^$IGNORE_HEAD --reverse|grep "^commit "|sed "s/commit //"` pendingCommit= pendingCommitMessage= @@ -94,7 +101,7 @@ for commit in $pending do echo "Checking $commit..." mergeDirective=`git log -n 1 --format=%B $commit|grep "^Merge:"|sed "s/Merge: //"` - commitMsg=`git log -n 1 --format=oneline --abbrev-commit $commit` + commitMsg=`git log -n 1 --format=oneline --abbrev-commit $commit | sed 's/\\\\/\\\\\\\\/g'` #Multiple levels of unescaping, sed just changes \ to \\ if [ "$mergeDirective" == "" ] then if can_merge $commit @@ -107,10 +114,17 @@ do pendingCommit= pendingCommitMessage= echo - echo "Stopping merge because $commit because of merge conflicts" + echo "Stopping merge at $commit because of merge conflicts" echo "The following commit must be manually merged." show $commit - exit 3 + + if [ "$EMAIL_AUTHOR" = "1" ] + then + author=`git show --format=%aE -s $commit` + echo "Email sent to $author" + (show $commit ; echo ; git merge $commit) |mail -s "Merge of your commit $commit to $TO failed" $author + fi + exit 7 fi elif [ "$mergeDirective" == "no" ] then @@ -134,7 +148,7 @@ do echo "Stopping merge at $commit (merge: manual)" echo "The following commit must be manually merged." show $commit - exit 3 + exit 8 else maybe_commit_and_push $pendingCommit "$pendingCommitMessage" pendingCommit= @@ -143,7 +157,7 @@ do echo "Commit $commit contains an unknown merge directive, Merge: $mergeDirective" echo "Stopping merge." show $commit - exit 3 + exit 9 fi done diff --git a/server/src/com/vaadin/annotations/Widgetset.java b/server/src/com/vaadin/annotations/Widgetset.java index 4cc81b4bd3..006bf59acf 100644 --- a/server/src/com/vaadin/annotations/Widgetset.java +++ b/server/src/com/vaadin/annotations/Widgetset.java @@ -24,7 +24,7 @@ import java.lang.annotation.Target; import com.vaadin.ui.UI; /** - * Defines a specific widget set for a {@link UI}. + * Defines a specific widgetset for a {@link UI}. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/server/src/com/vaadin/data/Container.java b/server/src/com/vaadin/data/Container.java index ef507c5f31..1e053d1091 100644 --- a/server/src/com/vaadin/data/Container.java +++ b/server/src/com/vaadin/data/Container.java @@ -582,6 +582,60 @@ public interface Container extends Serializable { public Item addItemAt(int index, Object newItemId) throws UnsupportedOperationException; + /** + * An <code>Event</code> object specifying information about the added + * items. + */ + public interface ItemAddEvent extends ItemSetChangeEvent { + + /** + * Gets the item id of the first added item. + * + * @return item id of the first added item + */ + public Object getFirstItemId(); + + /** + * Gets the index of the first added item. + * + * @return index of the first added item + */ + public int getFirstIndex(); + + /** + * Gets the number of the added items. + * + * @return the number of added items. + */ + public int getAddedItemsCount(); + } + + /** + * An <code>Event</code> object specifying information about the removed + * items. + */ + public interface ItemRemoveEvent extends ItemSetChangeEvent { + /** + * Gets the item id of the first removed item. + * + * @return item id of the first removed item + */ + public Object getFirstItemId(); + + /** + * Gets the index of the first removed item. + * + * @return index of the first removed item + */ + public int getFirstIndex(); + + /** + * Gets the number of the removed items. + * + * @return the number of removed items + */ + public int getRemovedItemsCount(); + } } /** diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java index 23f2da53ce..7edcc9719c 100644 --- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; -import java.util.logging.Logger; import com.vaadin.data.Item; import com.vaadin.data.Property; @@ -55,9 +54,6 @@ import com.vaadin.util.ReflectTools; */ public class FieldGroup implements Serializable { - private static final Logger logger = Logger.getLogger(FieldGroup.class - .getName()); - private Item itemDataSource; private boolean buffered = true; @@ -1013,9 +1009,7 @@ public class FieldGroup implements Serializable { */ public Field<?> buildAndBind(String caption, Object propertyId) throws BindException { - Class<?> type = getPropertyType(propertyId); return buildAndBind(caption, propertyId, Field.class); - } /** diff --git a/server/src/com/vaadin/data/util/AbstractBeanContainer.java b/server/src/com/vaadin/data/util/AbstractBeanContainer.java index b19cdd980c..d94588bdc9 100644 --- a/server/src/com/vaadin/data/util/AbstractBeanContainer.java +++ b/server/src/com/vaadin/data/util/AbstractBeanContainer.java @@ -222,6 +222,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends @Override public boolean removeAllItems() { int origSize = size(); + IDTYPE firstItem = getFirstVisibleItem(); internalRemoveAllItems(); @@ -234,7 +235,7 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends // fire event only if the visible view changed, regardless of whether // filtered out items were removed or not if (origSize != 0) { - fireItemSetChange(); + fireItemsRemoved(0, firstItem, origSize); } return true; @@ -679,6 +680,8 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends protected void addAll(Collection<? extends BEANTYPE> collection) throws IllegalStateException, IllegalArgumentException { boolean modified = false; + int origSize = size(); + for (BEANTYPE bean : collection) { // TODO skipping invalid beans - should not allow them in javadoc? if (bean == null @@ -699,13 +702,22 @@ public abstract class AbstractBeanContainer<IDTYPE, BEANTYPE> extends if (modified) { // Filter the contents when all items have been added if (isFiltered()) { - filterAll(); - } else { - fireItemSetChange(); + doFilterContainer(!getFilters().isEmpty()); + } + if (visibleNewItemsWasAdded(origSize)) { + // fire event about added items + int firstPosition = origSize; + IDTYPE firstItemId = getVisibleItemIds().get(firstPosition); + int affectedItems = size() - origSize; + fireItemsAdded(firstPosition, firstItemId, affectedItems); } } } + private boolean visibleNewItemsWasAdded(int origSize) { + return size() > origSize; + } + /** * Use the bean resolver to get the identifier for a bean. * diff --git a/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java b/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java index 84304431bc..cae9f30fc9 100644 --- a/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java +++ b/server/src/com/vaadin/data/util/AbstractInMemoryContainer.java @@ -15,8 +15,10 @@ */ package com.vaadin.data.util; +import java.io.Serializable; import java.util.Collection; import java.util.Collections; +import java.util.EventObject; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -146,6 +148,83 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE } } + private static abstract class BaseItemAddOrRemoveEvent extends EventObject + implements Serializable { + protected Object itemId; + protected int index; + protected int count; + + public BaseItemAddOrRemoveEvent(Container source, Object itemId, + int index, int count) { + super(source); + this.itemId = itemId; + this.index = index; + this.count = count; + } + + public Container getContainer() { + return (Container) getSource(); + } + + public Object getFirstItemId() { + return itemId; + } + + public int getFirstIndex() { + return index; + } + + public int getAffectedItemsCount() { + return count; + } + } + + /** + * An <code>Event</code> object specifying information about the added + * items. + * + * <p> + * This class provides information about the first added item and the number + * of added items. + * </p> + */ + protected static class BaseItemAddEvent extends BaseItemAddOrRemoveEvent + implements Container.Indexed.ItemAddEvent { + + public BaseItemAddEvent(Container source, Object itemId, int index, + int count) { + super(source, itemId, index, count); + } + + @Override + public int getAddedItemsCount() { + return getAffectedItemsCount(); + } + } + + /** + * An <code>Event</code> object specifying information about the removed + * items. + * + * <p> + * This class provides information about the first removed item and the + * number of removed items. + * </p> + */ + protected static class BaseItemRemoveEvent extends BaseItemAddOrRemoveEvent + implements Container.Indexed.ItemRemoveEvent { + + public BaseItemRemoveEvent(Container source, Object itemId, int index, + int count) { + super(source, itemId, index, count); + } + + @Override + public int getRemovedItemsCount() { + return getAffectedItemsCount(); + } + } + /** * Get an item even if filtered out. * @@ -898,36 +977,69 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE * Notify item set change listeners that an item has been added to the * container. * - * Unless subclasses specify otherwise, the default notification indicates a - * full refresh. - * * @param postion - * position of the added item in the view (if visible) + * position of the added item in the view * @param itemId * id of the added item * @param item * the added item */ protected void fireItemAdded(int position, ITEMIDTYPE itemId, ITEMCLASS item) { - fireItemSetChange(); + fireItemsAdded(position, itemId, 1); + } + + /** + * Notify item set change listeners that items has been added to the + * container. + * + * @param firstPosition + * position of the first visible added item in the view + * @param firstItemId + * id of the first visible added item + * @param numberOfItems + * the number of visible added items + */ + protected void fireItemsAdded(int firstPosition, ITEMIDTYPE firstItemId, + int numberOfItems) { + BaseItemAddEvent addEvent = new BaseItemAddEvent(this, firstItemId, + firstPosition, numberOfItems); + fireItemSetChange(addEvent); } /** * Notify item set change listeners that an item has been removed from the * container. * - * Unless subclasses specify otherwise, the default notification indicates a - * full refresh. + * @param position + * position of the removed item in the view prior to removal * - * @param postion - * position of the removed item in the view prior to removal (if - * was visible) * @param itemId * id of the removed item, of type {@link Object} to satisfy * {@link Container#removeItem(Object)} API */ protected void fireItemRemoved(int position, Object itemId) { - fireItemSetChange(); + fireItemsRemoved(position, itemId, 1); + } + + /** + * Notify item set change listeners that items has been removed from the + * container. + * + * @param firstPosition + * position of the first visible removed item in the view prior + * to removal + * @param firstItemId + * id of the first visible removed item, of type {@link Object} + * to satisfy {@link Container#removeItem(Object)} API + * @param numberOfItems + * the number of removed visible items + * + */ + protected void fireItemsRemoved(int firstPosition, Object firstItemId, + int numberOfItems) { + BaseItemRemoveEvent removeEvent = new BaseItemRemoveEvent(this, + firstItemId, firstPosition, numberOfItems); + fireItemSetChange(removeEvent); } // visible and filtered item identifier lists @@ -946,6 +1058,21 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE } /** + * Returns the item id of the first visible item after filtering. 'Null' is + * returned if there is no visible items. + * + * For internal use only. + * + * @return item id of the first visible item + */ + protected ITEMIDTYPE getFirstVisibleItem() { + if (!getVisibleItemIds().isEmpty()) { + return getVisibleItemIds().get(0); + } + return null; + } + + /** * Returns true is the container has active filters. * * @return true if the container is currently filtered diff --git a/server/src/com/vaadin/data/util/IndexedContainer.java b/server/src/com/vaadin/data/util/IndexedContainer.java index d7bf70caf6..5d20919208 100644 --- a/server/src/com/vaadin/data/util/IndexedContainer.java +++ b/server/src/com/vaadin/data/util/IndexedContainer.java @@ -226,6 +226,7 @@ public class IndexedContainer extends @Override public boolean removeAllItems() { int origSize = size(); + Object firstItem = getFirstVisibleItem(); internalRemoveAllItems(); @@ -235,7 +236,7 @@ public class IndexedContainer extends // filtered out items were removed or not if (origSize != 0) { // Sends a change event - fireItemSetChange(); + fireItemsRemoved(0, firstItem, origSize); } return true; @@ -620,8 +621,7 @@ public class IndexedContainer extends @Override protected void fireItemAdded(int position, Object itemId, Item item) { if (position >= 0) { - fireItemSetChange(new IndexedContainer.ItemSetChangeEvent(this, - position)); + super.fireItemAdded(position, itemId, item); } } @@ -1211,4 +1211,5 @@ public class IndexedContainer extends public Collection<Filter> getContainerFilters() { return super.getContainerFilters(); } + } diff --git a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java index cadfdcc774..4d3717e9ba 100644 --- a/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java +++ b/server/src/com/vaadin/data/util/converter/DefaultConverterFactory.java @@ -16,6 +16,7 @@ package com.vaadin.data.util.converter; +import java.math.BigDecimal; import java.util.Date; import java.util.logging.Logger; @@ -103,10 +104,10 @@ public class DefaultConverterFactory implements ConverterFactory { return new StringToIntegerConverter(); } else if (Long.class.isAssignableFrom(sourceType)) { return new StringToLongConverter(); + } else if (BigDecimal.class.isAssignableFrom(sourceType)) { + return new StringToBigDecimalConverter(); } else if (Boolean.class.isAssignableFrom(sourceType)) { return new StringToBooleanConverter(); - } else if (Number.class.isAssignableFrom(sourceType)) { - return new StringToNumberConverter(); } else if (Date.class.isAssignableFrom(sourceType)) { return new StringToDateConverter(); } else { diff --git a/server/src/com/vaadin/data/util/converter/StringToBigDecimalConverter.java b/server/src/com/vaadin/data/util/converter/StringToBigDecimalConverter.java new file mode 100644 index 0000000000..75d4cedd23 --- /dev/null +++ b/server/src/com/vaadin/data/util/converter/StringToBigDecimalConverter.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util.converter; + +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.Locale; + +/** + * A converter that converts from {@link String} to {@link BigDecimal} and back. + * Uses the given locale and a {@link NumberFormat} instance for formatting and + * parsing. + * <p> + * Leading and trailing white spaces are ignored when converting from a String. + * </p> + * <p> + * Override and overwrite {@link #getFormat(Locale)} to use a different format. + * </p> + * + * @author Vaadin Ltd + * @since 7.2 + */ +public class StringToBigDecimalConverter extends + AbstractStringToNumberConverter<BigDecimal> { + @Override + protected NumberFormat getFormat(Locale locale) { + NumberFormat numberFormat = super.getFormat(locale); + if (numberFormat instanceof DecimalFormat) { + ((DecimalFormat) numberFormat).setParseBigDecimal(true); + } + + return numberFormat; + } + + @Override + public BigDecimal convertToModel(String value, + Class<? extends BigDecimal> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return (BigDecimal) convertToNumber(value, BigDecimal.class, locale); + } + + @Override + public Class<BigDecimal> getModelType() { + return BigDecimal.class; + } +} diff --git a/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java b/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java deleted file mode 100644 index 22df42403f..0000000000 --- a/server/src/com/vaadin/data/util/converter/StringToNumberConverter.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.data.util.converter; - -import java.text.NumberFormat; -import java.util.Locale; - -/** - * A converter that converts from {@link Number} to {@link String} and back. - * Uses the given locale and {@link NumberFormat} for formatting and parsing. - * <p> - * Override and overwrite {@link #getFormat(Locale)} to use a different format. - * </p> - * - * @author Vaadin Ltd - * @since 7.0 - */ -public class StringToNumberConverter extends - AbstractStringToNumberConverter<Number> { - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.util.converter.Converter#convertToModel(java.lang.Object, - * java.lang.Class, java.util.Locale) - */ - @Override - public Number convertToModel(String value, - Class<? extends Number> targetType, Locale locale) - throws ConversionException { - if (targetType != getModelType()) { - throw new ConversionException("Converter only supports " - + getModelType().getName() + " (targetType was " - + targetType.getName() + ")"); - } - - return convertToNumber(value, targetType, locale); - } - - /* - * (non-Javadoc) - * - * @see com.vaadin.data.util.converter.Converter#getModelType() - */ - @Override - public Class<Number> getModelType() { - return Number.class; - } - -} diff --git a/server/src/com/vaadin/data/util/filter/Like.java b/server/src/com/vaadin/data/util/filter/Like.java index dc2e18363a..e0e2c9275c 100644 --- a/server/src/com/vaadin/data/util/filter/Like.java +++ b/server/src/com/vaadin/data/util/filter/Like.java @@ -23,11 +23,11 @@ public class Like implements Filter { private final String value; private boolean caseSensitive; - public Like(String propertyId, String value) { + public Like(Object propertyId, String value) { this(propertyId, value, true); } - public Like(String propertyId, String value, boolean caseSensitive) { + public Like(Object propertyId, String value, boolean caseSensitive) { this.propertyId = propertyId; this.value = value; setCaseSensitive(caseSensitive); diff --git a/server/src/com/vaadin/data/validator/BeanValidator.java b/server/src/com/vaadin/data/validator/BeanValidator.java index ea7189bc5e..54efa51ac1 100644 --- a/server/src/com/vaadin/data/validator/BeanValidator.java +++ b/server/src/com/vaadin/data/validator/BeanValidator.java @@ -17,8 +17,6 @@ package com.vaadin.data.validator; import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; import java.util.Locale; import java.util.Set; @@ -115,7 +113,9 @@ public class BeanValidator implements Validator { Set<?> violations = getJavaxBeanValidator().validateValue(beanClass, propertyName, value); if (violations.size() > 0) { - List<String> exceptions = new ArrayList<String>(); + InvalidValueException[] causes = new InvalidValueException[violations + .size()]; + int i = 0; for (Object v : violations) { final ConstraintViolation<?> violation = (ConstraintViolation<?>) v; String msg = getJavaxBeanValidatorFactory() @@ -123,16 +123,11 @@ public class BeanValidator implements Validator { violation.getMessageTemplate(), new SimpleContext(value, violation .getConstraintDescriptor()), locale); - exceptions.add(msg); + causes[i] = new InvalidValueException(msg); + ++i; } - StringBuilder b = new StringBuilder(); - for (int i = 0; i < exceptions.size(); i++) { - if (i != 0) { - b.append("<br/>"); - } - b.append(exceptions.get(i)); - } - throw new InvalidValueException(b.toString()); + + throw new InvalidValueException(null, causes); } } diff --git a/server/src/com/vaadin/event/UIEvents.java b/server/src/com/vaadin/event/UIEvents.java new file mode 100644 index 0000000000..321bfc9251 --- /dev/null +++ b/server/src/com/vaadin/event/UIEvents.java @@ -0,0 +1,116 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.event; + +import java.io.Serializable; +import java.lang.reflect.Method; + +import com.vaadin.ui.Component; +import com.vaadin.ui.UI; +import com.vaadin.util.ReflectTools; + +/** + * A class that contains events, listeners and handlers specific to the + * {@link UI} class. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface UIEvents { + + /** + * A {@link PollListener} receives and handles {@link PollEvent PollEvents} + * fired by {@link PollNotifier PollNotifiers}. + * + * @since 7.2 + * @author Vaadin Ltd + */ + public interface PollListener extends Serializable { + public static final Method POLL_METHOD = ReflectTools.findMethod( + PollListener.class, "poll", PollEvent.class); + + /** + * A poll request has been received by the server. + * + * @param event + * poll event + */ + public void poll(PollEvent event); + } + + /** + * An event that is fired whenever a client polls the server for + * asynchronous UI updates. + * + * @since 7.2 + * @author Vaadin Ltd + */ + public static class PollEvent extends Component.Event { + public PollEvent(UI ui) { + super(ui); + } + + /** + * Get the {@link UI} instance that received the poll request. + * + * @return the {@link UI} that received the poll request. Never + * <code>null</code>. + */ + public UI getUI() { + /* + * This cast is safe to make, since this class' constructor + * constrains the source to be a UI instance. + */ + return (UI) getComponent(); + } + } + + /** + * The interface for adding and removing {@link PollEvent} listeners. + * <p> + * By implementing this interface, a class publicly announces that it is + * able to send {@link PollEvent PollEvents} whenever the client sends a + * periodic poll message to the client, to check for asynchronous + * server-side modifications. + * + * @since 7.2 + * @see UI#setPollInterval(int) + */ + public interface PollNotifier extends Serializable { + /** + * Add a poll listener. + * <p> + * The listener is called whenever the client polls the server for + * asynchronous UI updates. + * + * @see UI#setPollInterval(int) + * @see #removePollListener(PollListener) + * @param listener + * the {@link PollListener} to add + */ + public void addPollListener(PollListener listener); + + /** + * Remove a poll listener. + * + * @see #addPollListener(PollListener) + * @param listener + * the listener to be removed + */ + public void removePollListener(PollListener listener); + } + +} diff --git a/server/src/com/vaadin/server/BootstrapHandler.java b/server/src/com/vaadin/server/BootstrapHandler.java index 0a4949ffa7..bfdbea3086 100644 --- a/server/src/com/vaadin/server/BootstrapHandler.java +++ b/server/src/com/vaadin/server/BootstrapHandler.java @@ -146,14 +146,15 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { } @Override + protected boolean canHandleRequest(VaadinRequest request) { + // We do not want to handle /APP requests here, instead let it fall + // through and produce a 404 + return !ServletPortletHelper.isAppRequest(request); + } + + @Override public boolean synchronizedHandleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { - if (ServletPortletHelper.isAppRequest(request)) { - // We do not want to handle /APP requests here, instead let it fall - // through and produce a 404 - return false; - } - try { // Update WebBrowser here only to make WebBrowser information // available in init for LegacyApplications @@ -285,7 +286,7 @@ public abstract class BootstrapHandler extends SynchronizedRequestHandler { * Enable Chrome Frame in all versions of IE if installed. */ head.appendElement("meta").attr("http-equiv", "X-UA-Compatible") - .attr("content", "IE=10;chrome=1"); + .attr("content", "IE=11;chrome=1"); String title = response.getUIProvider().getPageTitle( new UICreateEvent(context.getRequest(), context.getUIClass())); diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java index 430a5153c0..26715eff12 100644 --- a/server/src/com/vaadin/server/Constants.java +++ b/server/src/com/vaadin/server/Constants.java @@ -67,7 +67,7 @@ public interface Constants { // Keep the version number in sync with push/build.xml and other locations // listed in that file - static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "1.0.18.vaadin3"; + static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.1.1.vaadin2"; static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n" + "=================================================================\n" diff --git a/server/src/com/vaadin/server/DefaultErrorHandler.java b/server/src/com/vaadin/server/DefaultErrorHandler.java index 2f46354500..f8b684f1d1 100644 --- a/server/src/com/vaadin/server/DefaultErrorHandler.java +++ b/server/src/com/vaadin/server/DefaultErrorHandler.java @@ -16,11 +16,14 @@ package com.vaadin.server; +import java.lang.reflect.InvocationTargetException; import java.net.SocketException; import java.util.logging.Level; import java.util.logging.Logger; +import com.vaadin.event.ListenerMethod.MethodException; import com.vaadin.server.ClientConnector.ConnectorErrorEvent; +import com.vaadin.server.ServerRpcManager.RpcInvocationException; import com.vaadin.shared.Connector; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; @@ -32,7 +35,7 @@ public class DefaultErrorHandler implements ErrorHandler { } public static void doDefault(ErrorEvent event) { - final Throwable t = event.getThrowable(); + Throwable t = event.getThrowable(); if (t instanceof SocketException) { // Most likely client browser closed socket getLogger().info( @@ -41,6 +44,8 @@ public class DefaultErrorHandler implements ErrorHandler { return; } + t = findRelevantThrowable(t); + // Finds the original source of the error/exception AbstractComponent component = findAbstractComponent(event); if (component != null) { @@ -54,6 +59,40 @@ public class DefaultErrorHandler implements ErrorHandler { getLogger().log(Level.SEVERE, "", t); } + /** + * Vaadin wraps exceptions in its own and due to reflection usage there + * might be also other irrelevant exceptions that make no sense for Vaadin + * users (~developers using Vaadin). This method tries to choose the + * relevant one to be reported. + * + * @since 7.2 + * @param t + * throwable given for default error handler + * @return the throwable that is relevant for Vaadin users + */ + private static Throwable findRelevantThrowable(Throwable t) { + try { + if ((t instanceof RpcInvocationException) + && (t.getCause() instanceof InvocationTargetException)) { + /* + * RpcInvocationException (that always wraps irrelevant + * java.lang.reflect.InvocationTargetException) might only be + * relevant for core Vaadin developers. + */ + return findRelevantThrowable(t.getCause().getCause()); + } else if (t instanceof MethodException) { + /* + * Method exception might only be relevant for core Vaadin + * developers. + */ + return t.getCause(); + } + } catch (Exception e) { + // NOP, just return the original one + } + return t; + } + private static Logger getLogger() { return Logger.getLogger(DefaultErrorHandler.class.getName()); } diff --git a/server/src/com/vaadin/server/FontAwesome.java b/server/src/com/vaadin/server/FontAwesome.java new file mode 100644 index 0000000000..a7f4c7b342 --- /dev/null +++ b/server/src/com/vaadin/server/FontAwesome.java @@ -0,0 +1,447 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server; + +/** + * FontAwesome set of font icons. + * <p> + * Each {@link FontIcon} comes from the FontAwesome font family, which is + * included in the theme.<br/> + * Consider this a starting point: it is unlikely an application needs exactly + * these icons, and all of them, so you might want to consider making a custom + * icon font - either to get other icons, or to minimize the size of the font. + * </p> + * + * @since 7.2 + * @author Vaadin Ltd + * @see http://fortawesome.github.io/Font-Awesome/ + */ +public enum FontAwesome implements FontIcon { + GLASS(0XF000), // + MUSIC(0XF001), // + SEARCH(0XF002), // + ENVELOPE_O(0XF003), // + HEART(0XF004), // + STAR(0XF005), // + STAR_O(0XF006), // + USER(0XF007), // + FILM(0XF008), // + TH_LARGE(0XF009), // + TH(0XF00A), // + TH_LIST(0XF00B), // + CHECK(0XF00C), // + TIMES(0XF00D), // + SEARCH_PLUS(0XF00E), // + SEARCH_MINUS(0XF010), // + POWER_OFF(0XF011), // + SIGNAL(0XF012), // + COG(0XF013), // + TRASH_O(0XF014), // + HOME(0XF015), // + FILE_O(0XF016), // + CLOCK_O(0XF017), // + ROAD(0XF018), // + DOWNLOAD(0XF019), // + ARROW_CIRCLE_O_DOWN(0XF01A), // + ARROW_CIRCLE_O_UP(0XF01B), // + INBOX(0XF01C), // + PLAY_CIRCLE_O(0XF01D), // + REPEAT(0XF01E), // + REFRESH(0XF021), // + LIST_ALT(0XF022), // + LOCK(0XF023), // + FLAG(0XF024), // + HEADPHONES(0XF025), // + VOLUME_OFF(0XF026), // + VOLUME_DOWN(0XF027), // + VOLUME_UP(0XF028), // + QRCODE(0XF029), // + BARCODE(0XF02A), // + TAG(0XF02B), // + TAGS(0XF02C), // + BOOK(0XF02D), // + BOOKMARK(0XF02E), // + PRINT(0XF02F), // + CAMERA(0XF030), // + FONT(0XF031), // + BOLD(0XF032), // + ITALIC(0XF033), // + TEXT_HEIGHT(0XF034), // + TEXT_WIDTH(0XF035), // + ALIGN_LEFT(0XF036), // + ALIGN_CENTER(0XF037), // + ALIGN_RIGHT(0XF038), // + ALIGN_JUSTIFY(0XF039), // + LIST(0XF03A), // + OUTDENT(0XF03B), // + INDENT(0XF03C), // + VIDEO_CAMERA(0XF03D), // + PICTURE_O(0XF03E), // + PENCIL(0XF040), // + MAP_MARKER(0XF041), // + ADJUST(0XF042), // + TINT(0XF043), // + PENCIL_SQUARE_O(0XF044), // + SHARE_SQUARE_O(0XF045), // + CHECK_SQUARE_O(0XF046), // + ARROWS(0XF047), // + STEP_BACKWARD(0XF048), // + FAST_BACKWARD(0XF049), // + BACKWARD(0XF04A), // + PLAY(0XF04B), // + PAUSE(0XF04C), // + STOP(0XF04D), // + FORWARD(0XF04E), // + FAST_FORWARD(0XF050), // + STEP_FORWARD(0XF051), // + EJECT(0XF052), // + CHEVRON_LEFT(0XF053), // + CHEVRON_RIGHT(0XF054), // + PLUS_CIRCLE(0XF055), // + MINUS_CIRCLE(0XF056), // + TIMES_CIRCLE(0XF057), // + CHECK_CIRCLE(0XF058), // + QUESTION_CIRCLE(0XF059), // + INFO_CIRCLE(0XF05A), // + CROSSHAIRS(0XF05B), // + TIMES_CIRCLE_O(0XF05C), // + CHECK_CIRCLE_O(0XF05D), // + BAN(0XF05E), // + ARROW_LEFT(0XF060), // + ARROW_RIGHT(0XF061), // + ARROW_UP(0XF062), // + ARROW_DOWN(0XF063), // + SHARE(0XF064), // + EXPAND(0XF065), // + COMPRESS(0XF066), // + PLUS(0XF067), // + MINUS(0XF068), // + ASTERISK(0XF069), // + EXCLAMATION_CIRCLE(0XF06A), // + GIFT(0XF06B), // + LEAF(0XF06C), // + FIRE(0XF06D), // + EYE(0XF06E), // + EYE_SLASH(0XF070), // + EXCLAMATION_TRIANGLE(0XF071), // + PLANE(0XF072), // + CALENDAR(0XF073), // + RANDOM(0XF074), // + COMMENT(0XF075), // + MAGNET(0XF076), // + CHEVRON_UP(0XF077), // + CHEVRON_DOWN(0XF078), // + RETWEET(0XF079), // + SHOPPING_CART(0XF07A), // + FOLDER(0XF07B), // + FOLDER_OPEN(0XF07C), // + ARROWS_V(0XF07D), // + ARROWS_H(0XF07E), // + BAR_CHART_O(0XF080), // + TWITTER_SQUARE(0XF081), // + FACEBOOK_SQUARE(0XF082), // + CAMERA_RETRO(0XF083), // + KEY(0XF084), // + COGS(0XF085), // + COMMENTS(0XF086), // + THUMBS_O_UP(0XF087), // + THUMBS_O_DOWN(0XF088), // + STAR_HALF(0XF089), // + HEART_O(0XF08A), // + SIGN_OUT(0XF08B), // + LINKEDIN_SQUARE(0XF08C), // + THUMB_TACK(0XF08D), // + EXTERNAL_LINK(0XF08E), // + SIGN_IN(0XF090), // + TROPHY(0XF091), // + GITHUB_SQUARE(0XF092), // + UPLOAD(0XF093), // + LEMON_O(0XF094), // + PHONE(0XF095), // + SQUARE_O(0XF096), // + BOOKMARK_O(0XF097), // + PHONE_SQUARE(0XF098), // + TWITTER(0XF099), // + FACEBOOK(0XF09A), // + GITHUB(0XF09B), // + UNLOCK(0XF09C), // + CREDIT_CARD(0XF09D), // + RSS(0XF09E), // + HDD_O(0XF0A0), // + BULLHORN(0XF0A1), // + BELL(0XF0F3), // + CERTIFICATE(0XF0A3), // + HAND_O_RIGHT(0XF0A4), // + HAND_O_LEFT(0XF0A5), // + HAND_O_UP(0XF0A6), // + HAND_O_DOWN(0XF0A7), // + ARROW_CIRCLE_LEFT(0XF0A8), // + ARROW_CIRCLE_RIGHT(0XF0A9), // + ARROW_CIRCLE_UP(0XF0AA), // + ARROW_CIRCLE_DOWN(0XF0AB), // + GLOBE(0XF0AC), // + WRENCH(0XF0AD), // + TASKS(0XF0AE), // + FILTER(0XF0B0), // + BRIEFCASE(0XF0B1), // + ARROWS_ALT(0XF0B2), // + USERS(0XF0C0), // + LINK(0XF0C1), // + CLOUD(0XF0C2), // + FLASK(0XF0C3), // + SCISSORS(0XF0C4), // + FILES_O(0XF0C5), // + PAPERCLIP(0XF0C6), // + FLOPPY_O(0XF0C7), // + SQUARE(0XF0C8), // + BARS(0XF0C9), // + LIST_UL(0XF0CA), // + LIST_OL(0XF0CB), // + STRIKETHROUGH(0XF0CC), // + UNDERLINE(0XF0CD), // + TABLE(0XF0CE), // + MAGIC(0XF0D0), // + TRUCK(0XF0D1), // + PINTEREST(0XF0D2), // + PINTEREST_SQUARE(0XF0D3), // + GOOGLE_PLUS_SQUARE(0XF0D4), // + GOOGLE_PLUS(0XF0D5), // + MONEY(0XF0D6), // + CARET_DOWN(0XF0D7), // + CARET_UP(0XF0D8), // + CARET_LEFT(0XF0D9), // + CARET_RIGHT(0XF0DA), // + COLUMNS(0XF0DB), // + SORT(0XF0DC), // + SORT_ASC(0XF0DD), // + SORT_DESC(0XF0DE), // + ENVELOPE(0XF0E0), // + LINKEDIN(0XF0E1), // + UNDO(0XF0E2), // + GAVEL(0XF0E3), // + TACHOMETER(0XF0E4), // + COMMENT_O(0XF0E5), // + COMMENTS_O(0XF0E6), // + BOLT(0XF0E7), // + SITEMAP(0XF0E8), // + UMBRELLA(0XF0E9), // + CLIPBOARD(0XF0EA), // + LIGHTBULB_O(0XF0EB), // + EXCHANGE(0XF0EC), // + CLOUD_DOWNLOAD(0XF0ED), // + CLOUD_UPLOAD(0XF0EE), // + USER_MD(0XF0F0), // + STETHOSCOPE(0XF0F1), // + SUITCASE(0XF0F2), // + BELL_O(0XF0A2), // + COFFEE(0XF0F4), // + CUTLERY(0XF0F5), // + FILE_TEXT_O(0XF0F6), // + BUILDING_O(0XF0F7), // + HOSPITAL_O(0XF0F8), // + AMBULANCE(0XF0F9), // + MEDKIT(0XF0FA), // + FIGHTER_JET(0XF0FB), // + BEER(0XF0FC), // + H_SQUARE(0XF0FD), // + PLUS_SQUARE(0XF0FE), // + ANGLE_DOUBLE_LEFT(0XF100), // + ANGLE_DOUBLE_RIGHT(0XF101), // + ANGLE_DOUBLE_UP(0XF102), // + ANGLE_DOUBLE_DOWN(0XF103), // + ANGLE_LEFT(0XF104), // + ANGLE_RIGHT(0XF105), // + ANGLE_UP(0XF106), // + ANGLE_DOWN(0XF107), // + DESKTOP(0XF108), // + LAPTOP(0XF109), // + TABLET(0XF10A), // + MOBILE(0XF10B), // + CIRCLE_O(0XF10C), // + QUOTE_LEFT(0XF10D), // + QUOTE_RIGHT(0XF10E), // + SPINNER(0XF110), // + CIRCLE(0XF111), // + REPLY(0XF112), // + GITHUB_ALT(0XF113), // + FOLDER_O(0XF114), // + FOLDER_OPEN_O(0XF115), // + SMILE_O(0XF118), // + FROWN_O(0XF119), // + MEH_O(0XF11A), // + GAMEPAD(0XF11B), // + KEYBOARD_O(0XF11C), // + FLAG_O(0XF11D), // + FLAG_CHECKERED(0XF11E), // + TERMINAL(0XF120), // + CODE(0XF121), // + REPLY_ALL(0XF122), // + MAIL_REPLY_ALL(0XF122), // + STAR_HALF_O(0XF123), // + LOCATION_ARROW(0XF124), // + CROP(0XF125), // + CODE_FORK(0XF126), // + CHAIN_BROKEN(0XF127), // + QUESTION(0XF128), // + INFO(0XF129), // + EXCLAMATION(0XF12A), // + SUPERSCRIPT(0XF12B), // + SUBSCRIPT(0XF12C), // + ERASER(0XF12D), // + PUZZLE_PIECE(0XF12E), // + MICROPHONE(0XF130), // + MICROPHONE_SLASH(0XF131), // + SHIELD(0XF132), // + CALENDAR_O(0XF133), // + FIRE_EXTINGUISHER(0XF134), // + ROCKET(0XF135), // + MAXCDN(0XF136), // + CHEVRON_CIRCLE_LEFT(0XF137), // + CHEVRON_CIRCLE_RIGHT(0XF138), // + CHEVRON_CIRCLE_UP(0XF139), // + CHEVRON_CIRCLE_DOWN(0XF13A), // + HTML5(0XF13B), // + CSS3(0XF13C), // + ANCHOR(0XF13D), // + UNLOCK_ALT(0XF13E), // + BULLSEYE(0XF140), // + ELLIPSIS_H(0XF141), // + ELLIPSIS_V(0XF142), // + RSS_SQUARE(0XF143), // + PLAY_CIRCLE(0XF144), // + TICKET(0XF145), // + MINUS_SQUARE(0XF146), // + MINUS_SQUARE_O(0XF147), // + LEVEL_UP(0XF148), // + LEVEL_DOWN(0XF149), // + CHECK_SQUARE(0XF14A), // + PENCIL_SQUARE(0XF14B), // + EXTERNAL_LINK_SQUARE(0XF14C), // + SHARE_SQUARE(0XF14D), // + COMPASS(0XF14E), // + CARET_SQUARE_O_DOWN(0XF150), // + CARET_SQUARE_O_UP(0XF151), // + CARET_SQUARE_O_RIGHT(0XF152), // + EUR(0XF153), // + GBP(0XF154), // + USD(0XF155), // + INR(0XF156), // + JPY(0XF157), // + RUB(0XF158), // + KRW(0XF159), // + BTC(0XF15A), // + FILE(0XF15B), // + FILE_TEXT(0XF15C), // + SORT_ALPHA_ASC(0XF15D), // + SORT_ALPHA_DESC(0XF15E), // + SORT_AMOUNT_ASC(0XF160), // + SORT_AMOUNT_DESC(0XF161), // + SORT_NUMERIC_ASC(0XF162), // + SORT_NUMERIC_DESC(0XF163), // + THUMBS_UP(0XF164), // + THUMBS_DOWN(0XF165), // + YOUTUBE_SQUARE(0XF166), // + YOUTUBE(0XF167), // + XING(0XF168), // + XING_SQUARE(0XF169), // + YOUTUBE_PLAY(0XF16A), // + DROPBOX(0XF16B), // + STACK_OVERFLOW(0XF16C), // + INSTAGRAM(0XF16D), // + FLICKR(0XF16E), // + ADN(0XF170), // + BITBUCKET(0XF171), // + BITBUCKET_SQUARE(0XF172), // + TUMBLR(0XF173), // + TUMBLR_SQUARE(0XF174), // + LONG_ARROW_DOWN(0XF175), // + LONG_ARROW_UP(0XF176), // + LONG_ARROW_LEFT(0XF177), // + LONG_ARROW_RIGHT(0XF178), // + APPLE(0XF179), // + WINDOWS(0XF17A), // + ANDROID(0XF17B), // + LINUX(0XF17C), // + DRIBBBLE(0XF17D), // + SKYPE(0XF17E), // + FOURSQUARE(0XF180), // + TRELLO(0XF181), // + FEMALE(0XF182), // + MALE(0XF183), // + GITTIP(0XF184), // + SUN_O(0XF185), // + MOON_O(0XF186), // + ARCHIVE(0XF187), // + BUG(0XF188), // + VK(0XF189), // + WEIBO(0XF18A), // + RENREN(0XF18B), // + PAGELINES(0XF18C), // + STACK_EXCHANGE(0XF18D), // + ARROW_CIRCLE_O_RIGHT(0XF18E), // + ARROW_CIRCLE_O_LEFT(0XF190), // + CARET_SQUARE_O_LEFT(0XF191), // + DOT_CIRCLE_O(0XF192), // + WHEELCHAIR(0XF193), // + VIMEO_SQUARE(0XF194), // + TRY(0XF195), // + PLUS_SQUARE_O(0XF196); + + private static final String fontFamily = "FontAwesome"; + private int codepoint; + + FontAwesome(int codepoint) { + this.codepoint = codepoint; + } + + /** + * Unsupported: {@link FontIcon} does not have a MIME type and is not a + * {@link Resource} that can be used in a context where a MIME type would be + * needed. + */ + @Override + public String getMIMEType() { + throw new UnsupportedOperationException(FontIcon.class.getSimpleName() + + " should not be used where a MIME type is needed."); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.FontIcon#getFontFamily() + */ + @Override + public String getFontFamily() { + return fontFamily; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.FontIcon#getCodepoint() + */ + @Override + public int getCodepoint() { + return codepoint; + } + + @Override + public String getHtml() { + return "<span class=\"v-icon\" style=\"font-family: " + fontFamily + + ";\">&#x" + Integer.toHexString(codepoint) + ";</span>"; + } + +} diff --git a/server/src/com/vaadin/server/FontIcon.java b/server/src/com/vaadin/server/FontIcon.java new file mode 100644 index 0000000000..45279f2c44 --- /dev/null +++ b/server/src/com/vaadin/server/FontIcon.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Label; + +/** + * A font icon is a type of icon that is made by displaying one character from a + * specially constructed font containing icons ("icon font"). + * <p> + * {@link FontIcon} is a custom resource type which uses the URI scheme + * <code>fonticon://<fontfamily>/<codepoint></code> to reference a + * specific icon from a specific icon font. <br/> + * </p> + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface FontIcon extends Resource { + /** + * Returns the name (font family) of the font from which this icon comes. + * The name is used to apply the correct font where the icon is used. + * + * @since 7.2 + * @return + */ + public String getFontFamily(); + + /** + * Returns the unicode codepoint (character location) for this icon within + * the font given in {@link #getFontFamily()}. + * <p> + * For example, 0x0021 would in a regular font be the codepoint for the + * exclamation-point character.<br/> + * When constructing icon fonts, it might be a good idea to use the + * codepoints in the "Private use area", from 0xE000 0xF8FF. + * </p> + * + * @since 7.2 + * @return + */ + public int getCodepoint(); + + /** + * Returns HTML that can be used to display the icon in places where HTML + * can be used, such as a {@link Label} with {@link ContentMode#HTML}. + * + * + * @since 7.2 + * @return HTML needed to display icon + */ + public String getHtml(); +} diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java index d533ed99f3..d05922b40d 100644 --- a/server/src/com/vaadin/server/JsonCodec.java +++ b/server/src/com/vaadin/server/JsonCodec.java @@ -31,6 +31,7 @@ import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -45,6 +46,8 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import com.vaadin.server.communication.DateSerializer; +import com.vaadin.server.communication.JSONSerializer; import com.vaadin.shared.Connector; import com.vaadin.shared.JsonConstants; import com.vaadin.shared.communication.UidlValue; @@ -176,6 +179,11 @@ public class JsonCodec implements Serializable { */ private static Map<String, Class<?>> transportTypeToType = new HashMap<String, Class<?>>(); + private static Map<Class<?>, JSONSerializer<?>> customSerializers = new HashMap<Class<?>, JSONSerializer<?>>(); + static { + customSerializers.put(Date.class, new DateSerializer()); + } + static { registerType(String.class, JsonConstants.VTYPE_STRING); registerType(Connector.class, JsonConstants.VTYPE_CONNECTOR); @@ -283,6 +291,9 @@ public class JsonCodec implements Serializable { Class<?> classForType = getClassForType(targetType); return decodeEnum(classForType.asSubclass(Enum.class), (String) value); + } else if (customSerializers.containsKey(getClassForType(targetType))) { + return customSerializers.get(getClassForType(targetType)) + .deserialize(targetType, value, connectorTracker); } else { return decodeObject(targetType, (JSONObject) value, connectorTracker); @@ -606,7 +617,7 @@ public class JsonCodec implements Serializable { return decodedObject; } catch (Exception e) { - throw new JSONException(e); + throw new JSONException(e.getMessage()); } } @@ -676,6 +687,10 @@ public class JsonCodec implements Serializable { return encodeEnum((Enum<?>) value, connectorTracker); } else if (value instanceof JSONArray || value instanceof JSONObject) { return new EncodeResult(value); + } else if (customSerializers.containsKey(value.getClass())) { + JSONSerializer serializer = customSerializers.get(value.getClass()); + return new EncodeResult(serializer.serialize(value, + connectorTracker)); } else if (valueType instanceof Class<?>) { // Any object that we do not know how to encode we encode by looping // through fields @@ -750,7 +765,7 @@ public class JsonCodec implements Serializable { } } catch (Exception e) { // TODO: Should exceptions be handled in a different way? - throw new JSONException(e); + throw new JSONException(e.getMessage()); } return new EncodeResult(encoded, diff); } diff --git a/server/src/com/vaadin/server/LegacyCommunicationManager.java b/server/src/com/vaadin/server/LegacyCommunicationManager.java index ad662cf6df..8d61968b47 100644 --- a/server/src/com/vaadin/server/LegacyCommunicationManager.java +++ b/server/src/com/vaadin/server/LegacyCommunicationManager.java @@ -316,8 +316,6 @@ public class LegacyCommunicationManager implements Serializable { private final HashMap<Class<? extends ClientConnector>, Integer> typeToKey = new HashMap<Class<? extends ClientConnector>, Integer>(); private int nextTypeKey = 0; - private BootstrapHandler bootstrapHandler; - /** * @deprecated As of 7.1. Will be removed in the future. */ diff --git a/server/src/com/vaadin/server/Page.java b/server/src/com/vaadin/server/Page.java index 037d8e8352..19b84381d5 100644 --- a/server/src/com/vaadin/server/Page.java +++ b/server/src/com/vaadin/server/Page.java @@ -476,6 +476,8 @@ public class Page implements Serializable { private final PageState state; + private String windowName; + public Page(UI uI, PageState state) { this.uI = uI; this.state = state; @@ -637,6 +639,7 @@ public class Page implements Serializable { String location = request.getParameter("v-loc"); String clientWidth = request.getParameter("v-cw"); String clientHeight = request.getParameter("v-ch"); + windowName = request.getParameter("v-wn"); if (location != null) { try { @@ -662,6 +665,17 @@ public class Page implements Serializable { } /** + * Gets the window.name value of the browser window of this page. + * + * @since 7.2 + * + * @return the window name, <code>null</code> if the name is not known + */ + public String getWindowName() { + return windowName; + } + + /** * Updates the internal state with the given values. Does not resize the * Page or browser window. * @@ -1119,12 +1133,15 @@ public class Page implements Serializable { /** * Sets the page title. The page title is displayed by the browser e.g. as * the title of the browser window or as the title of the tab. + * <p> + * If the title is set to null, it will not left as-is. Set to empty string + * to clear the title. * * @param title - * the new page title to set + * the page title to set */ public void setTitle(String title) { - uI.getRpcProxy(PageClientRpc.class).setTitle(title); + getState(true).title = title; } /** diff --git a/server/src/com/vaadin/server/ResourceReference.java b/server/src/com/vaadin/server/ResourceReference.java index 6747dd2b74..4bc8febd72 100644 --- a/server/src/com/vaadin/server/ResourceReference.java +++ b/server/src/com/vaadin/server/ResourceReference.java @@ -67,6 +67,13 @@ public class ResourceReference extends URLReference { final String uri = "theme://" + ((ThemeResource) resource).getResourceId(); return uri; + } else if (resource instanceof FontIcon) { + // fonticon://[font-family]/[codepoint] + final FontIcon icon = (FontIcon) resource; + final String uri = ApplicationConstants.FONTICON_PROTOCOL_PREFIX + + urlEncode(icon.getFontFamily()) + "/" + + Integer.toHexString(icon.getCodepoint()); + return uri; } else { throw new RuntimeException(getClass().getSimpleName() + " does not support resources of type: " diff --git a/server/src/com/vaadin/server/ServiceDestroyEvent.java b/server/src/com/vaadin/server/ServiceDestroyEvent.java new file mode 100644 index 0000000000..2ae4cc10af --- /dev/null +++ b/server/src/com/vaadin/server/ServiceDestroyEvent.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.server; + +import java.util.EventObject; + +/** + * Event fired to {@link ServiceDestroyListener} when a {@link VaadinService} is + * being destroyed. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class ServiceDestroyEvent extends EventObject { + + /** + * Creates a new event for the given service. + * + * @param service + * the service being destroyed + */ + public ServiceDestroyEvent(VaadinService service) { + super(service); + } + + /* + * (non-Javadoc) + * + * @see java.util.EventObject#getSource() + */ + @Override + public VaadinService getSource() { + return (VaadinService) super.getSource(); + } + +} diff --git a/server/src/com/vaadin/server/ServiceDestroyListener.java b/server/src/com/vaadin/server/ServiceDestroyListener.java new file mode 100644 index 0000000000..ad4966dd58 --- /dev/null +++ b/server/src/com/vaadin/server/ServiceDestroyListener.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.server; + +import java.io.Serializable; + +/** + * Listener that gets notified when the {@link VaadinService} to which it has + * been registered is destroyed. + * + * @see VaadinService#addServiceDestroyListener(ServiceDestroyListener) + * @see VaadinService#removeServiceDestroyListener(ServiceDestroyListener) + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface ServiceDestroyListener extends Serializable { + /** + * Invoked when a service is destroyed + * + * @param event + * the event + */ + public void serviceDestroy(ServiceDestroyEvent event); +} diff --git a/server/src/com/vaadin/server/SynchronizedRequestHandler.java b/server/src/com/vaadin/server/SynchronizedRequestHandler.java index ac730dcecb..c695855d7d 100644 --- a/server/src/com/vaadin/server/SynchronizedRequestHandler.java +++ b/server/src/com/vaadin/server/SynchronizedRequestHandler.java @@ -32,6 +32,10 @@ public abstract class SynchronizedRequestHandler implements RequestHandler { @Override public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { + if (!canHandleRequest(request)) { + return false; + } + session.lock(); try { return synchronizedHandleRequest(session, request, response); @@ -62,4 +66,25 @@ public abstract class SynchronizedRequestHandler implements RequestHandler { public abstract boolean synchronizedHandleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException; + /** + * Check whether a request may be handled by this handler. This can be used + * as an optimization to avoid locking the session just to investigate some + * method property. The default implementation just returns + * <code>true</code> which means that all requests will be handled by + * calling + * {@link #synchronizedHandleRequest(VaadinSession, VaadinRequest, VaadinResponse)} + * with the session locked. + * + * @since 7.2 + * @param request + * the request to handle + * @return <code>true</code> if the request handling should continue once + * the session has been locked; <code>false</code> if there's no + * need to lock the session since the request would still not be + * handled. + */ + protected boolean canHandleRequest(VaadinRequest request) { + return true; + } + } diff --git a/server/src/com/vaadin/server/SystemMessages.java b/server/src/com/vaadin/server/SystemMessages.java index 5e0fde1d4a..299c725207 100644 --- a/server/src/com/vaadin/server/SystemMessages.java +++ b/server/src/com/vaadin/server/SystemMessages.java @@ -63,32 +63,32 @@ public class SystemMessages implements Serializable { protected String sessionExpiredURL = null; protected boolean sessionExpiredNotificationEnabled = true; protected String sessionExpiredCaption = "Session Expired"; - protected String sessionExpiredMessage = "Take note of any unsaved data, and <u>click here</u> to continue."; + protected String sessionExpiredMessage = "Take note of any unsaved data, and <u>click here</u> or press ESC key to continue."; protected String communicationErrorURL = null; protected boolean communicationErrorNotificationEnabled = true; protected String communicationErrorCaption = "Communication problem"; - protected String communicationErrorMessage = "Take note of any unsaved data, and <u>click here</u> to continue."; + protected String communicationErrorMessage = "Take note of any unsaved data, and <u>click here</u> or press ESC to continue."; protected String authenticationErrorURL = null; protected boolean authenticationErrorNotificationEnabled = true; protected String authenticationErrorCaption = "Authentication problem"; - protected String authenticationErrorMessage = "Take note of any unsaved data, and <u>click here</u> to continue."; + protected String authenticationErrorMessage = "Take note of any unsaved data, and <u>click here</u> or press ESC to continue."; protected String internalErrorURL = null; protected boolean internalErrorNotificationEnabled = true; protected String internalErrorCaption = "Internal error"; - protected String internalErrorMessage = "Please notify the administrator.<br/>Take note of any unsaved data, and <u>click here</u> to continue."; + protected String internalErrorMessage = "Please notify the administrator.<br/>Take note of any unsaved data, and <u>click here</u> or press ESC to continue."; protected String outOfSyncURL = null; protected boolean outOfSyncNotificationEnabled = true; protected String outOfSyncCaption = "Out of sync"; - protected String outOfSyncMessage = "Something has caused us to be out of sync with the server.<br/>Take note of any unsaved data, and <u>click here</u> to re-sync."; + protected String outOfSyncMessage = "Something has caused us to be out of sync with the server.<br/>Take note of any unsaved data, and <u>click here</u> or press ESC to re-sync."; protected String cookiesDisabledURL = null; protected boolean cookiesDisabledNotificationEnabled = true; protected String cookiesDisabledCaption = "Cookies disabled"; - protected String cookiesDisabledMessage = "This application requires cookies to function.<br/>Please enable cookies in your browser and <u>click here</u> to try again."; + protected String cookiesDisabledMessage = "This application requires cookies to function.<br/>Please enable cookies in your browser and <u>click here</u> or press ESC to try again."; /** * Use {@link CustomizedSystemMessages} to customize diff --git a/server/src/com/vaadin/server/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java index 093a1c9152..6cf30e85e9 100644 --- a/server/src/com/vaadin/server/VaadinPortlet.java +++ b/server/src/com/vaadin/server/VaadinPortlet.java @@ -365,7 +365,6 @@ public class VaadinPortlet extends GenericPortlet implements Constants, if (request instanceof RenderRequest) { return RequestType.RENDER; } else if (request instanceof ResourceRequest) { - ResourceRequest resourceRequest = (ResourceRequest) request; if (ServletPortletHelper.isUIDLRequest(vaadinRequest)) { return RequestType.UIDL; } else if (PortletUIInitHandler.isUIInitRequest(vaadinRequest)) { @@ -503,6 +502,12 @@ public class VaadinPortlet extends GenericPortlet implements Constants, handleRequest(request, response); } + @Override + public void destroy() { + super.destroy(); + getService().destroy(); + } + private static final Logger getLogger() { return Logger.getLogger(VaadinPortlet.class.getName()); } diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index eda794438f..86cd9701c0 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -41,7 +41,9 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; +import javax.portlet.Portlet; import javax.portlet.PortletContext; +import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; @@ -97,6 +99,10 @@ public abstract class VaadinService implements Serializable { .findMethod(SessionDestroyListener.class, "sessionDestroy", SessionDestroyEvent.class); + private static final Method SERVICE_DESTROY_METHOD = ReflectTools + .findMethod(ServiceDestroyListener.class, "serviceDestroy", + ServiceDestroyEvent.class); + /** * @deprecated As of 7.0. Only supported for {@link LegacyApplication}. */ @@ -1568,9 +1574,9 @@ public abstract class VaadinService implements Serializable { meta.put("appError", appError); JSONObject json = new JSONObject(); - json.put("changes", Collections.EMPTY_LIST); - json.put("resources", Collections.EMPTY_MAP); - json.put("locales", Collections.EMPTY_LIST); + json.put("changes", new JSONObject()); + json.put("resources", new JSONObject()); + json.put("locales", new JSONObject()); json.put("meta", meta); returnString = json.toString(); } catch (JSONException e) { @@ -1775,4 +1781,50 @@ public abstract class VaadinService implements Serializable { CurrentInstance.restoreInstances(oldInstances); } } + + /** + * Adds a service destroy listener that gets notified when this service is + * destroyed. + * + * @since 7.2 + * @param listener + * the service destroy listener to add + * + * @see #destroy() + * @see #removeServiceDestroyListener(ServiceDestroyListener) + * @see ServiceDestroyListener + */ + public void addServiceDestroyListener(ServiceDestroyListener listener) { + eventRouter.addListener(ServiceDestroyEvent.class, listener, + SERVICE_DESTROY_METHOD); + } + + /** + * Removes a service destroy listener that was previously added with + * {@link #addServiceDestroyListener(ServiceDestroyListener)}. + * + * @since 7.2 + * @param listener + * the service destroy listener to remove + */ + public void removeServiceDestroyListener(ServiceDestroyListener listener) { + eventRouter.removeListener(ServiceDestroyEvent.class, listener, + SERVICE_DESTROY_METHOD); + } + + /** + * Called when the servlet, portlet or similar for this service is being + * destroyed. After this method has been called, no more requests will be + * handled by this service. + * + * @see #addServiceDestroyListener(ServiceDestroyListener) + * @see Servlet#destroy() + * @see Portlet#destroy() + * + * @since 7.2 + */ + public void destroy() { + eventRouter.fireEvent(new ServiceDestroyEvent(this)); + } + } diff --git a/server/src/com/vaadin/server/VaadinServlet.java b/server/src/com/vaadin/server/VaadinServlet.java index 7c0f9599f3..3da264e0e7 100644 --- a/server/src/com/vaadin/server/VaadinServlet.java +++ b/server/src/com/vaadin/server/VaadinServlet.java @@ -43,7 +43,6 @@ import javax.servlet.http.HttpServletResponse; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.annotations.VaadinServletConfiguration.InitParameterName; import com.vaadin.sass.internal.ScssStylesheet; -import com.vaadin.server.communication.PushRequestHandler; import com.vaadin.server.communication.ServletUIInitHandler; import com.vaadin.shared.JsonConstants; import com.vaadin.ui.UI; @@ -670,21 +669,11 @@ public class VaadinServlet extends HttpServlet implements Constants { // Provide modification timestamp to the browser if it is known. if (lastModifiedTime > 0) { response.setDateHeader("Last-Modified", lastModifiedTime); - /* - * The browser is allowed to cache for 1 hour without checking if - * the file has changed. This forces browsers to fetch a new version - * when the Vaadin version is updated. This will cause more requests - * to the servlet than without this but for high volume sites the - * static files should never be served through the servlet. The - * cache timeout can be configured by setting the resourceCacheTime - * parameter in web.xml - */ - int resourceCacheTime = getService().getDeploymentConfiguration() - .getResourceCacheTime(); - String cacheControl = "max-age=" - + String.valueOf(resourceCacheTime); - if (filename.contains("nocache")) { - cacheControl = "public, max-age=0, must-revalidate"; + + String cacheControl = "public, max-age=0, must-revalidate"; + int resourceCacheTime = getCacheTime(filename); + if (resourceCacheTime > 0) { + cacheControl = "max-age=" + String.valueOf(resourceCacheTime); } response.setHeader("Cache-Control", cacheControl); } @@ -693,6 +682,43 @@ public class VaadinServlet extends HttpServlet implements Constants { } /** + * Calculates the cache lifetime for the given filename in seconds. By + * default filenames containing ".nocache." return 0, filenames containing + * ".cache." return one year, all other return the value defined in the + * web.xml using resourceCacheTime (defaults to 1 hour). + * + * @param filename + * @return cache lifetime for the given filename in seconds + */ + protected int getCacheTime(String filename) { + /* + * GWT conventions: + * + * - files containing .nocache. will not be cached. + * + * - files containing .cache. will be cached for one year. + * + * https://developers.google.com/web-toolkit/doc/latest/ + * DevGuideCompilingAndDebugging#perfect_caching + */ + if (filename.contains(".nocache.")) { + return 0; + } + if (filename.contains(".cache.")) { + return 60 * 60 * 24 * 365; + } + /* + * For all other files, the browser is allowed to cache for 1 hour + * without checking if the file has changed. This forces browsers to + * fetch a new version when the Vaadin version is updated. This will + * cause more requests to the servlet than without this but for high + * volume sites the static files should never be served through the + * servlet. + */ + return getService().getDeploymentConfiguration().getResourceCacheTime(); + } + + /** * Writes the contents of the given resourceUrl in the response. Can be * overridden to add/modify response headers and similar. * @@ -826,7 +852,7 @@ public class VaadinServlet extends HttpServlet implements Constants { // cache it response.setHeader("Cache-Control", "no-cache"); final String mimetype = getService().getMimeType(filename); - writeResponse(response, mimetype, scss.toString()); + writeResponse(response, mimetype, scss.printState()); return true; } @@ -982,20 +1008,8 @@ public class VaadinServlet extends HttpServlet implements Constants { } protected boolean isStaticResourceRequest(HttpServletRequest request) { - String pathInfo = request.getPathInfo(); - if (pathInfo == null) { - return false; - } - - if ((request.getContextPath() != null) - && (request.getRequestURI().startsWith("/VAADIN/"))) { - return true; - } else if (request.getRequestURI().startsWith( - request.getContextPath() + "/VAADIN/")) { - return true; - } - - return false; + return request.getRequestURI().startsWith( + request.getContextPath() + "/VAADIN/"); } /** @@ -1075,15 +1089,15 @@ public class VaadinServlet extends HttpServlet implements Constants { return u; } + /* + * (non-Javadoc) + * + * @see javax.servlet.GenericServlet#destroy() + */ @Override public void destroy() { super.destroy(); - - for (RequestHandler handler : getService().getRequestHandlers()) { - if (handler instanceof PushRequestHandler) { - ((PushRequestHandler) handler).destroy(); - } - } + getService().destroy(); } /** diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java index fd2ed79acd..619a329ab9 100644 --- a/server/src/com/vaadin/server/VaadinSession.java +++ b/server/src/com/vaadin/server/VaadinSession.java @@ -22,12 +22,15 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Queue; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutionException; @@ -43,7 +46,6 @@ import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; -import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.data.util.converter.Converter; import com.vaadin.data.util.converter.ConverterFactory; import com.vaadin.data.util.converter.DefaultConverterFactory; @@ -205,7 +207,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { private int nextUIId = 0; private Map<Integer, UI> uIs = new HashMap<Integer, UI>(); - private final Map<String, Integer> retainOnRefreshUIs = new HashMap<String, Integer>(); + private final Map<String, Integer> embedIdMap = new HashMap<String, Integer>(); private final EventRouter eventRouter = new EventRouter(); @@ -424,6 +426,32 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { } /** + * Retrieves all {@link VaadinSession}s which are stored in the given HTTP + * session + * + * @since 7.2 + * @param httpSession + * the HTTP session + * @return the found VaadinSessions + */ + public static Collection<VaadinSession> getAllSessions( + HttpSession httpSession) { + Set<VaadinSession> sessions = new HashSet<VaadinSession>(); + Enumeration<String> attributeNames = httpSession.getAttributeNames(); + + while (attributeNames.hasMoreElements()) { + String attributeName = attributeNames.nextElement(); + if (attributeName.startsWith(VaadinSession.class.getName() + ".")) { + Object value = httpSession.getAttribute(attributeName); + if (value instanceof VaadinSession) { + sessions.add((VaadinSession) value); + } + } + } + return sessions; + } + + /** * Removes this VaadinSession from the HTTP session. * * @param service @@ -828,10 +856,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { */ public void removeUI(UI ui) { assert hasLock(); - int id = ui.getUIId(); + Integer id = Integer.valueOf(ui.getUIId()); ui.setSession(null); uIs.remove(id); - retainOnRefreshUIs.values().remove(id); + String embedId = ui.getEmbedId(); + if (embedId != null && id.equals(embedIdMap.get(embedId))) { + embedIdMap.remove(embedId); + } } /** @@ -1099,20 +1130,6 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { } /** - * Gets the mapping from <code>window.name</code> to UI id for UIs that are - * should be retained on refresh. - * - * @see VaadinService#preserveUIOnRefresh(VaadinRequest, UI, UIProvider) - * @see PreserveOnRefresh - * - * @return the mapping between window names and UI ids for this session. - */ - public Map<String, Integer> getPreserveOnRefreshUIs() { - assert hasLock(); - return retainOnRefreshUIs; - } - - /** * Adds an initialized UI to this session. * * @param ui @@ -1129,7 +1146,21 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { "The UI belongs to a different session"); } - uIs.put(Integer.valueOf(ui.getUIId()), ui); + Integer uiId = Integer.valueOf(ui.getUIId()); + uIs.put(uiId, ui); + + String embedId = ui.getEmbedId(); + if (embedId != null) { + Integer previousUiId = embedIdMap.put(embedId, uiId); + if (previousUiId != null) { + UI previousUi = uIs.get(previousUiId); + assert previousUi != null + && embedId.equals(previousUi.getEmbedId()) : "UI id map and embed id map not in sync"; + + // Will fire cleanup events at the end of the request handling. + previousUi.close(); + } + } } /** @@ -1340,4 +1371,25 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable { stream.defaultReadObject(); pendingAccessQueue = new ConcurrentLinkedQueue<FutureAccess>(); } + + /** + * Finds the UI with the corresponding embed id. + * + * @since 7.2 + * @param embedId + * the embed id + * @return the UI with the corresponding embed id, or <code>null</code> if + * no UI is found + * + * @see UI#getEmbedId() + */ + public UI getUIByEmbedId(String embedId) { + Integer uiId = embedIdMap.get(embedId); + if (uiId == null) { + return null; + } else { + return getUIById(uiId.intValue()); + } + } + } diff --git a/server/src/com/vaadin/server/WrappedHttpSession.java b/server/src/com/vaadin/server/WrappedHttpSession.java index a425a7e5cf..aed3be1ca0 100644 --- a/server/src/com/vaadin/server/WrappedHttpSession.java +++ b/server/src/com/vaadin/server/WrappedHttpSession.java @@ -85,6 +85,20 @@ public class WrappedHttpSession implements WrappedSession { @Override public void invalidate() { + if (session == null) { + throw new IllegalStateException( + "Session is null and cannot be invalidated"); + } + + if (session.getClass().getName() + .equals("org.atmosphere.util.FakeHttpSession")) { + throw new UnsupportedOperationException( + "FakeHttpSession cannot be invalidated. " + + "This typically means you are using websockets together with Tomcat 7. " + + "Because Tomcat 7 does not support sharing the HTTP session between standard HTTP requests and websockets, a copy of the session is used for websockets. " + + "Invalidating this session does not have the desired effect. " + + "To resolve this, upgrade to Tomcat 8 or use another transport mechanism than websockets."); + } session.invalidate(); } diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java index b9d4955b12..56dd576403 100644 --- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java +++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java @@ -22,22 +22,16 @@ import java.io.Serializable; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import java.util.logging.Logger; import org.atmosphere.cpr.AtmosphereResource; import org.atmosphere.cpr.AtmosphereResource.TRANSPORT; -import org.json.JSONException; import com.vaadin.shared.communication.PushConstants; import com.vaadin.ui.UI; /** - * {@link PushConnection} implementation using the Atmosphere push support that - * is by default included in Vaadin. + * A {@link PushConnection} implementation using the Atmosphere push support + * that is by default included in Vaadin. * * @author Vaadin Ltd * @since 7.1 @@ -92,55 +86,84 @@ public class AtmospherePushConnection implements PushConnection { } } + protected enum State { + /** + * Not connected. Trying to push will set the connection state to + * PUSH_PENDING or RESPONSE_PENDING and defer sending the message until + * a connection is established. + */ + DISCONNECTED, + + /** + * Not connected. An asynchronous push is pending the opening of the + * connection. + */ + PUSH_PENDING, + + /** + * Not connected. A response to a client request is pending the opening + * of the connection. + */ + RESPONSE_PENDING, + + /** + * Connected. Messages can be sent through the connection. + */ + CONNECTED; + } + + private State state = State.DISCONNECTED; private UI ui; private AtmosphereResource resource; - private Future<String> outgoingMessage; private FragmentedMessage incomingMessage; - public AtmospherePushConnection(UI ui, AtmosphereResource resource) { + public AtmospherePushConnection(UI ui) { this.ui = ui; - this.resource = resource; } @Override public void push() { - assert isConnected(); - try { - push(true); - } catch (IOException e) { - // TODO Error handling - throw new RuntimeException("Push failed", e); - } + push(true); } /** - * Pushes pending state changes and client RPC calls to the client. + * Pushes pending state changes and client RPC calls to the client. If + * {@code isConnected()} is false, defers the push until a connection is + * established. * * @param async * True if this push asynchronously originates from the server, * false if it is a response to a client request. - * @throws IOException */ - protected void push(boolean async) throws IOException { - Writer writer = new StringWriter(); - try { - new UidlWriter().write(getUI(), writer, false, async); - } catch (JSONException e) { - throw new IOException("Error writing UIDL", e); + public void push(boolean async) { + if (!isConnected()) { + if (async && state != State.RESPONSE_PENDING) { + state = State.PUSH_PENDING; + } else { + state = State.RESPONSE_PENDING; + } + } else { + try { + Writer writer = new StringWriter(); + new UidlWriter().write(getUI(), writer, false, async); + sendMessage("for(;;);[{" + writer.toString() + "}]"); + } catch (Exception e) { + throw new RuntimeException("Push failed", e); + } } - sendMessage("for(;;);[{" + writer.toString() + "}]"); } /** - * Sends the given message to the current client. + * Sends the given message to the current client. Cannot be called if + * {@isConnected()} is false. * * @param message * The message to send */ void sendMessage(String message) { + assert (isConnected()); // "Broadcast" the changes to the single client only - outgoingMessage = getResource().getBroadcaster().broadcast(message, - getResource()); + getResource().getBroadcaster().broadcast(message, getResource()); } /** @@ -157,7 +180,7 @@ public class AtmospherePushConnection implements PushConnection { */ protected Reader receiveMessage(Reader reader) throws IOException { - if (resource.transport() != TRANSPORT.WEBSOCKET) { + if (resource == null || resource.transport() != TRANSPORT.WEBSOCKET) { return reader; } @@ -179,9 +202,37 @@ public class AtmospherePushConnection implements PushConnection { @Override public boolean isConnected() { - return resource != null - && resource.getBroadcaster().getAtmosphereResources() - .contains(resource); + assert (state == State.CONNECTED) ^ (resource == null); + return state == State.CONNECTED; + } + + /** + * Associates this {@code AtmospherePushConnection} with the given + * {@AtmosphereResource} representing an established + * push connection. If already connected, calls {@link #disconnect()} first. + * If there is a deferred push, carries it out via the new connection. + * + * @since 7.2 + */ + public void connect(AtmosphereResource resource) { + + assert resource != null; + assert resource != this.resource; + + if (isConnected()) { + disconnect(); + } + + this.resource = resource; + State oldState = state; + state = State.CONNECTED; + + if (oldState == State.PUSH_PENDING + || oldState == State.RESPONSE_PENDING) { + // Sending a "response" message (async=false) also takes care of a + // pending push, but not vice versa + push(oldState == State.PUSH_PENDING); + } } /** @@ -202,33 +253,8 @@ public class AtmospherePushConnection implements PushConnection { @Override public void disconnect() { assert isConnected(); - - if (outgoingMessage != null) { - // Wait for the last message to be sent before closing the - // connection (assumes that futures are completed in order) - try { - outgoingMessage.get(1000, TimeUnit.MILLISECONDS); - } catch (TimeoutException e) { - getLogger() - .log(Level.INFO, - "Timeout waiting for messages to be sent to client before disconnect"); - } catch (Exception e) { - getLogger() - .log(Level.INFO, - "Error waiting for messages to be sent to client before disconnect"); - } - outgoingMessage = null; - } - resource.resume(); resource = null; - } - - /** - * @since - * @return - */ - private static Logger getLogger() { - return Logger.getLogger(AtmospherePushConnection.class.getName()); + state = State.DISCONNECTED; } } diff --git a/server/src/com/vaadin/server/communication/DateSerializer.java b/server/src/com/vaadin/server/communication/DateSerializer.java new file mode 100644 index 0000000000..9179eb922b --- /dev/null +++ b/server/src/com/vaadin/server/communication/DateSerializer.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server.communication; + +import java.lang.reflect.Type; +import java.util.Date; + +import com.vaadin.ui.ConnectorTracker; + +/** + * Server side serializer/deserializer for java.util.Date + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class DateSerializer implements JSONSerializer<Date> { + + @Override + public Date deserialize(Type type, Object jsonValue, + ConnectorTracker connectorTracker) { + return new Date(Long.valueOf(String.valueOf(jsonValue))); + } + + @Override + public Object serialize(Date value, ConnectorTracker connectorTracker) { + return value.getTime(); + } + +} diff --git a/server/src/com/vaadin/server/communication/FileUploadHandler.java b/server/src/com/vaadin/server/communication/FileUploadHandler.java index 3f6bfd9267..41a16601fe 100644 --- a/server/src/com/vaadin/server/communication/FileUploadHandler.java +++ b/server/src/com/vaadin/server/communication/FileUploadHandler.java @@ -284,7 +284,7 @@ public class FileUploadHandler implements RequestHandler { // if boundary string does not exist, the posted file is from // XHR2.post(File) doHandleXhrFilePost(session, request, response, streamVariable, - variableName, source, request.getContentLength()); + variableName, source, getContentLength(request)); } return true; } @@ -336,7 +336,7 @@ public class FileUploadHandler implements RequestHandler { final InputStream inputStream = request.getInputStream(); - int contentLength = request.getContentLength(); + long contentLength = getContentLength(request); boolean atStart = false; boolean firstFileFieldFound = false; @@ -403,9 +403,22 @@ public class FileUploadHandler implements RequestHandler { } + /* + * request.getContentLength() is limited to "int" by the Servlet + * specification. To support larger file uploads manually evaluate the + * Content-Length header which can contain long values. + */ + private long getContentLength(VaadinRequest request) { + try { + return Long.parseLong(request.getHeader("Content-Length")); + } catch (NumberFormatException e) { + return -1l; + } + } + private void handleFileUploadValidationAndData(VaadinSession session, InputStream inputStream, StreamVariable streamVariable, - String filename, String mimeType, int contentLength, + String filename, String mimeType, long contentLength, ClientConnector connector, String variableName) throws UploadException { session.lock(); @@ -474,7 +487,7 @@ public class FileUploadHandler implements RequestHandler { protected void doHandleXhrFilePost(VaadinSession session, VaadinRequest request, VaadinResponse response, StreamVariable streamVariable, String variableName, - ClientConnector owner, int contentLength) throws IOException { + ClientConnector owner, long contentLength) throws IOException { // These are unknown in filexhr ATM, maybe add to Accept header that // is accessible in portlets @@ -504,7 +517,7 @@ public class FileUploadHandler implements RequestHandler { */ protected final boolean streamToReceiver(VaadinSession session, final InputStream in, StreamVariable streamVariable, - String filename, String type, int contentLength) + String filename, String type, long contentLength) throws UploadException { if (streamVariable == null) { throw new IllegalStateException( @@ -512,7 +525,7 @@ public class FileUploadHandler implements RequestHandler { } OutputStream out = null; - int totalBytes = 0; + long totalBytes = 0; StreamingStartEventImpl startedEvent = new StreamingStartEventImpl( filename, type, contentLength); try { diff --git a/server/src/com/vaadin/server/communication/HeartbeatHandler.java b/server/src/com/vaadin/server/communication/HeartbeatHandler.java index 4c95859203..04cb1b5a25 100644 --- a/server/src/com/vaadin/server/communication/HeartbeatHandler.java +++ b/server/src/com/vaadin/server/communication/HeartbeatHandler.java @@ -43,6 +43,11 @@ import com.vaadin.ui.UI; public class HeartbeatHandler extends SynchronizedRequestHandler implements SessionExpiredHandler { + @Override + protected boolean canHandleRequest(VaadinRequest request) { + return ServletPortletHelper.isHeartbeatRequest(request); + } + /** * Handles a heartbeat request for the given session. Reads the GET * parameter named {@link UIConstants#UI_ID_PARAMETER} to identify the UI. @@ -53,10 +58,6 @@ public class HeartbeatHandler extends SynchronizedRequestHandler implements @Override public boolean synchronizedHandleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { - if (!ServletPortletHelper.isHeartbeatRequest(request)) { - return false; - } - UI ui = session.getService().findUI(request); if (ui != null) { ui.setLastHeartbeatTimestamp(System.currentTimeMillis()); diff --git a/server/src/com/vaadin/server/communication/JSONSerializer.java b/server/src/com/vaadin/server/communication/JSONSerializer.java new file mode 100644 index 0000000000..fe609c70b6 --- /dev/null +++ b/server/src/com/vaadin/server/communication/JSONSerializer.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server.communication; + +import java.lang.reflect.Type; + +import com.vaadin.ui.ConnectorTracker; + +/** + * Implementors of this interface knows how to serialize an Object of a given + * type to JSON and how to deserialize the JSON back into an object. + * <p> + * The {@link #serialize(Object, ConnectorTracker)} and + * {@link #deserialize(Type, Object, ConnectorTracker)} methods must be + * symmetric so they can be chained and produce the original result (or an equal + * result). + * <p> + * Each {@link JSONSerializer} implementation can handle an object of a single + * type. + * <p> + * This is the server side interface, see + * com.vaadin.client.communication.JSONSerializer for the client side interface. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface JSONSerializer<T> { + /** + * Creates and deserializes an object received from the client. Must be + * compatible with {@link #serialize(Object, ConnectorTracker)} and also + * with the client side com.vaadin.client.communication.JSONSerializer. + * <p> + * The json parameter is of type Object as org.json JSON classes have no + * other common super class + * + * @param type + * The expected return type + * @param jsonValue + * the value from the JSON + * @param connectorTracker + * the connector tracker instance for the UI + * @return A deserialized object + */ + T deserialize(Type type, Object jsonValue, ConnectorTracker connectorTracker); + + /** + * Serialize the given object into JSON. Must be compatible with + * {@link #deserialize(Object, connectorTracker)} and the client side + * com.vaadin.client.communication.JSONSerializer + * + * @param value + * The object to serialize + * @param connectorTracker + * The connector tracker instance for the UI + * @return A JSON serialized version of the object + */ + Object serialize(T value, ConnectorTracker connectorTracker); + +} diff --git a/server/src/com/vaadin/server/communication/PushConnection.java b/server/src/com/vaadin/server/communication/PushConnection.java index 7f78d1d48e..cab3c94824 100644 --- a/server/src/com/vaadin/server/communication/PushConnection.java +++ b/server/src/com/vaadin/server/communication/PushConnection.java @@ -20,7 +20,12 @@ import com.vaadin.ui.UI; /** * Represents a bidirectional ("push") connection between a single UI and its - * client-side. + * client-side. A single {@code PushConnection} instance is bound to a UI as + * long as push is enabled in that UI, even if the actual connection is + * momentarily dropped either due to a network failure or as a normal part of + * the transport mechanism. + * <p> + * This interface is an internal API, only meant to be used by the framework. * * @author Vaadin Ltd * @since 7.1 @@ -28,9 +33,10 @@ import com.vaadin.ui.UI; public interface PushConnection { /** - * Pushes pending state changes and client RPC calls to the client. Cannot - * be called if {@link #isConnected()} is false. It is NOT safe to invoke - * this method if not holding the session lock. + * Pushes pending state changes and client RPC calls to the client. Can be + * called even if {@link #isConnected()} is false; the push will be deferred + * until a connection is available. It is NOT safe to invoke this method if + * not holding the session lock. * <p> * This is internal API; please use {@link UI#push()} instead. */ diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java index 09428e47a9..99aff3780f 100644 --- a/server/src/com/vaadin/server/communication/PushHandler.java +++ b/server/src/com/vaadin/server/communication/PushHandler.java @@ -19,7 +19,6 @@ package com.vaadin.server.communication; import java.io.IOException; import java.io.Reader; import java.io.Writer; -import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,7 +42,6 @@ import com.vaadin.server.VaadinService; import com.vaadin.server.VaadinServletRequest; import com.vaadin.server.VaadinServletService; import com.vaadin.server.VaadinSession; -import com.vaadin.server.WebBrowser; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.communication.PushMode; import com.vaadin.ui.UI; @@ -75,8 +73,8 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter @Override public void run(AtmosphereResource resource, UI ui) throws IOException { getLogger().log(Level.FINER, - "New push connection with transport {0}", - resource.transport()); + "New push connection for resource {0} with transport {1}", + new Object[] { resource.uuid(), resource.transport() }); resource.addEventListener(PushHandler.this); @@ -84,14 +82,6 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter VaadinSession session = ui.getSession(); if (resource.transport() == TRANSPORT.STREAMING) { - // IE8 requires a longer padding to work properly if the - // initial message is small (#11573). Chrome does not work - // without the original padding... - WebBrowser browser = session.getBrowser(); - if (browser.isIE() && browser.getBrowserMajorVersion() == 8) { - resource.padding(LONG_PADDING); - } - // Must ensure that the streaming response contains // "Connection: close", otherwise iOS 6 will wait for the // response to this request before sending another request to @@ -115,10 +105,9 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter resource.suspend(); - AtmospherePushConnection connection = new AtmospherePushConnection( - ui, resource); - - ui.setPushConnection(connection); + AtmospherePushConnection connection = getConnectionForUI(ui); + assert (connection != null); + connection.connect(resource); } }; @@ -182,11 +171,11 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter @Override public void run(AtmosphereResource resource, UI ui) throws IOException { PushMode pushMode = ui.getPushConfiguration().getPushMode(); - AtmospherePushConnection pushConnection = getConnectionForUI(ui); + AtmospherePushConnection connection = getConnectionForUI(ui); String id = resource.uuid(); - if (pushConnection == null) { + if (connection == null) { getLogger() .log(Level.WARNING, "Could not find push connection to close: {0} with transport {1}", @@ -209,19 +198,11 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter "Connection unexpectedly closed for resource {0} with transport {1}", new Object[] { id, resource.transport() }); } - ui.setPushConnection(null); + connection.disconnect(); } } }; - private static final String LONG_PADDING; - - static { - char[] array = new char[4096]; - Arrays.fill(array, '-'); - LONG_PADDING = String.copyValueOf(array); - - } private VaadinServletService service; public PushHandler(VaadinServletService service) { @@ -351,10 +332,10 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter private static AtmospherePushConnection getConnectionForUI(UI ui) { PushConnection pushConnection = ui.getPushConnection(); if (pushConnection instanceof AtmospherePushConnection) { - assert pushConnection.isConnected(); return (AtmospherePushConnection) pushConnection; + } else { + return null; } - return null; } @Override @@ -391,7 +372,7 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter break; case JSONP: case LONG_POLLING: - resource.resume(); + disconnect(event); break; default: getLogger().log(Level.SEVERE, "Unknown transport {0}", @@ -415,13 +396,6 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter } @Override - public void onResume(AtmosphereResourceEvent event) { - // Log event on trace level - super.onResume(event); - disconnect(event); - } - - @Override public void destroy() { } @@ -444,8 +418,8 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter */ private static void sendRefreshAndDisconnect(AtmosphereResource resource) throws IOException { - AtmospherePushConnection connection = new AtmospherePushConnection( - null, resource); + AtmospherePushConnection connection = new AtmospherePushConnection(null); + connection.connect(resource); try { connection.sendMessage(VaadinService .createCriticalNotificationJSON(null, null, null, null)); diff --git a/server/src/com/vaadin/server/communication/PushRequestHandler.java b/server/src/com/vaadin/server/communication/PushRequestHandler.java index 272dd8e05c..aec3aa54c0 100644 --- a/server/src/com/vaadin/server/communication/PushRequestHandler.java +++ b/server/src/com/vaadin/server/communication/PushRequestHandler.java @@ -29,6 +29,8 @@ import org.atmosphere.cpr.AtmosphereRequest; import org.atmosphere.cpr.AtmosphereResponse; import com.vaadin.server.RequestHandler; +import com.vaadin.server.ServiceDestroyEvent; +import com.vaadin.server.ServiceDestroyListener; import com.vaadin.server.ServiceException; import com.vaadin.server.ServletPortletHelper; import com.vaadin.server.SessionExpiredHandler; @@ -75,6 +77,13 @@ public class PushRequestHandler implements RequestHandler, } }; + service.addServiceDestroyListener(new ServiceDestroyListener() { + @Override + public void serviceDestroy(ServiceDestroyEvent event) { + destroy(); + } + }); + pushHandler = new PushHandler(service); atmosphere.addAtmosphereHandler("/*", pushHandler); atmosphere.addInitParameter(ApplicationConfig.PROPERTY_SESSION_SUPPORT, diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java index ea25777525..ce9cec5e2a 100644 --- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java +++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java @@ -20,8 +20,6 @@ import java.io.IOException; import java.io.Reader; import java.io.Serializable; import java.lang.reflect.Type; -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -32,6 +30,7 @@ import java.util.logging.Logger; import org.json.JSONArray; import org.json.JSONException; +import org.json.JSONObject; import com.vaadin.server.ClientConnector; import com.vaadin.server.JsonCodec; @@ -62,10 +61,71 @@ import com.vaadin.ui.UI; */ public class ServerRpcHandler implements Serializable { - /* Variable records indexes */ - public static final char VAR_BURST_SEPARATOR = '\u001d'; + /** + * A data transfer object representing an RPC request sent by the client + * side. + * + * @since 7.2 + * @author Vaadin Ltd + */ + public static class RpcRequest implements Serializable { + + private final String csrfToken; + private final JSONArray invocations; + private final int syncId; + private final JSONObject json; + + public RpcRequest(String jsonString) throws JSONException { + json = new JSONObject(jsonString); + csrfToken = json.getString(ApplicationConstants.CSRF_TOKEN); + syncId = json.getInt(ApplicationConstants.SERVER_SYNC_ID); + invocations = new JSONArray( + json.getString(ApplicationConstants.RPC_INVOCATIONS)); + } - public static final char VAR_ESCAPE_CHARACTER = '\u001b'; + /** + * Gets the CSRF security token (double submit cookie) for this request. + * + * @return the CSRF security token for this current change request + */ + public String getCsrfToken() { + return csrfToken; + } + + /** + * Gets the data to recreate the RPC as requested by the client side. + * + * @return the data describing which RPC should be made, and all their + * data + */ + public JSONArray getRpcInvocationsData() { + return invocations; + } + + /** + * Gets the sync id last seen by the client. + * + * @return the last sync id given by the server, according to the + * client's request + */ + public int getSyncId() { + return syncId; + } + + /** + * Gets the entire request in JSON format, as it was received from the + * client. + * <p> + * <em>Note:</em> This is a shared reference - any modifications made + * will be shared. + * + * @return the raw JSON object that was received from the client + * + */ + public JSONObject getRawJson() { + return json; + } + } private static final int MAX_BUFFER_SIZE = 64 * 1024; @@ -90,45 +150,50 @@ public class ServerRpcHandler implements Serializable { throws IOException, InvalidUIDLSecurityKeyException, JSONException { ui.getSession().setLastRequestTimestamp(System.currentTimeMillis()); - String changes = getMessage(reader); + String changeMessage = getMessage(reader); - final String[] bursts = changes.split(String - .valueOf(VAR_BURST_SEPARATOR)); - - if (bursts.length > 2) { - throw new RuntimeException( - "Multiple variable bursts not supported in Vaadin 7"); - } else if (bursts.length <= 1) { + if (changeMessage == null || changeMessage.equals("")) { // The client sometimes sends empty messages, this is probably a bug return; } + RpcRequest rpcRequest = new RpcRequest(changeMessage); + // Security: double cookie submission pattern unless disabled by // property - if (!VaadinService.isCsrfTokenValid(ui.getSession(), bursts[0])) { + if (!VaadinService.isCsrfTokenValid(ui.getSession(), + rpcRequest.getCsrfToken())) { throw new InvalidUIDLSecurityKeyException(""); } - handleBurst(ui, unescapeBurst(bursts[1])); + handleInvocations(ui, rpcRequest.getSyncId(), + rpcRequest.getRpcInvocationsData()); + + ui.getConnectorTracker().cleanConcurrentlyRemovedConnectorIds( + rpcRequest.getSyncId()); } /** - * Processes a message burst received from the client. - * - * A burst can contain any number of RPC calls, including legacy variable - * change calls that are processed separately. - * + * Processes invocations data received from the client. + * <p> + * The invocations data can contain any number of RPC calls, including + * legacy variable change calls that are processed separately. + * <p> * Consecutive changes to the value of the same variable are combined and * changeVariables() is only called once for them. This preserves the Vaadin * 6 semantics for components and add-ons that do not use Vaadin 7 RPC * directly. * - * @param source * @param uI - * the UI receiving the burst - * @param burst - * the content of the burst as a String to be parsed + * the UI receiving the invocations data + * @param lastSyncIdSeenByClient + * the most recent sync id the client has seen at the time the + * request was sent + * @param invocationsData + * JSON containing all information needed to execute all + * requested RPC calls. */ - private void handleBurst(UI uI, String burst) { + private void handleInvocations(UI uI, int lastSyncIdSeenByClient, + JSONArray invocationsData) { // TODO PUSH Refactor so that this is not needed LegacyCommunicationManager manager = uI.getSession() .getCommunicationManager(); @@ -137,7 +202,8 @@ public class ServerRpcHandler implements Serializable { Set<Connector> enabledConnectors = new HashSet<Connector>(); List<MethodInvocation> invocations = parseInvocations( - uI.getConnectorTracker(), burst); + uI.getConnectorTracker(), invocationsData, + lastSyncIdSeenByClient); for (MethodInvocation invocation : invocations) { final ClientConnector connector = manager.getConnector(uI, invocation.getConnectorId()); @@ -243,21 +309,22 @@ public class ServerRpcHandler implements Serializable { } /** - * Parse a message burst from the client into a list of MethodInvocation - * instances. + * Parse JSON from the client into a list of MethodInvocation instances. * * @param connectorTracker * The ConnectorTracker used to lookup connectors - * @param burst - * message string (JSON) + * @param invocationsJson + * JSON containing all information needed to execute all + * requested RPC calls. + * @param lastSyncIdSeenByClient + * the most recent sync id the client has seen at the time the + * request was sent * @return list of MethodInvocation to perform * @throws JSONException */ private List<MethodInvocation> parseInvocations( - ConnectorTracker connectorTracker, String burst) - throws JSONException { - JSONArray invocationsJson = new JSONArray(burst); - + ConnectorTracker connectorTracker, JSONArray invocationsJson, + int lastSyncIdSeenByClient) throws JSONException { ArrayList<MethodInvocation> invocations = new ArrayList<MethodInvocation>(); MethodInvocation previousInvocation = null; @@ -267,7 +334,8 @@ public class ServerRpcHandler implements Serializable { JSONArray invocationJson = invocationsJson.getJSONArray(i); MethodInvocation invocation = parseInvocation(invocationJson, - previousInvocation, connectorTracker); + previousInvocation, connectorTracker, + lastSyncIdSeenByClient); if (invocation != null) { // Can be null if the invocation was a legacy invocation and it // was merged with the previous one or if the invocation was @@ -281,7 +349,8 @@ public class ServerRpcHandler implements Serializable { private MethodInvocation parseInvocation(JSONArray invocationJson, MethodInvocation previousInvocation, - ConnectorTracker connectorTracker) throws JSONException { + ConnectorTracker connectorTracker, long lastSyncIdSeenByClient) + throws JSONException { String connectorId = invocationJson.getString(0); String interfaceName = invocationJson.getString(1); String methodName = invocationJson.getString(2); @@ -289,18 +358,22 @@ public class ServerRpcHandler implements Serializable { if (connectorTracker.getConnector(connectorId) == null && !connectorId .equals(ApplicationConstants.DRAG_AND_DROP_CONNECTOR_ID)) { - getLogger() - .log(Level.WARNING, - "RPC call to " - + interfaceName - + "." - + methodName - + " received for connector " - + connectorId - + " but no such connector could be found. Resynchronizing client."); - // This is likely an out of sync issue (client tries to update a - // connector which is not present). Force resync. - connectorTracker.markAllConnectorsDirty(); + + if (!connectorTracker.connectorWasPresentAsRequestWasSent( + connectorId, lastSyncIdSeenByClient)) { + getLogger() + .log(Level.WARNING, + "RPC call to " + + interfaceName + + "." + + methodName + + " received for connector " + + connectorId + + " but no such connector could be found. Resynchronizing client."); + // This is likely an out of sync issue (client tries to update a + // connector which is not present). Force resync. + connectorTracker.markAllConnectorsDirty(); + } return null; } @@ -396,50 +469,6 @@ public class ServerRpcHandler implements Serializable { owner.changeVariables(source, m); } - /** - * Unescape encoded burst separator characters in a burst received from the - * client. This protects from separator injection attacks. - * - * @param encodedValue - * to decode - * @return decoded value - */ - protected String unescapeBurst(String encodedValue) { - final StringBuilder result = new StringBuilder(); - final StringCharacterIterator iterator = new StringCharacterIterator( - encodedValue); - char character = iterator.current(); - while (character != CharacterIterator.DONE) { - if (VAR_ESCAPE_CHARACTER == character) { - character = iterator.next(); - switch (character) { - case VAR_ESCAPE_CHARACTER + 0x30: - // escaped escape character - result.append(VAR_ESCAPE_CHARACTER); - break; - case VAR_BURST_SEPARATOR + 0x30: - // +0x30 makes these letters for easier reading - result.append((char) (character - 0x30)); - break; - case CharacterIterator.DONE: - // error - throw new RuntimeException( - "Communication error: Unexpected end of message"); - default: - // other escaped character - probably a client-server - // version mismatch - throw new RuntimeException( - "Invalid escaped character from the client - check that the widgetset and server versions match"); - } - } else { - // not a special character - add it to the result as is - result.append(character); - } - character = iterator.next(); - } - return result.toString(); - } - protected String getMessage(Reader reader) throws IOException { StringBuilder sb = new StringBuilder(MAX_BUFFER_SIZE); diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java index d4b0bc709f..6ab9d9dc58 100644 --- a/server/src/com/vaadin/server/communication/UIInitHandler.java +++ b/server/src/com/vaadin/server/communication/UIInitHandler.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.util.List; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -38,6 +37,7 @@ import com.vaadin.server.VaadinResponse; import com.vaadin.server.VaadinService; import com.vaadin.server.VaadinSession; import com.vaadin.shared.ApplicationConstants; +import com.vaadin.shared.JsonConstants; import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.ui.Transport; import com.vaadin.shared.ui.ui.UIConstants; @@ -56,12 +56,13 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { protected abstract boolean isInitRequest(VaadinRequest request); @Override + protected boolean canHandleRequest(VaadinRequest request) { + return isInitRequest(request); + } + + @Override public boolean synchronizedHandleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { - if (!isInitRequest(request)) { - return false; - } - StringWriter stringWriter = new StringWriter(); try { @@ -107,7 +108,7 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { static boolean commitJsonResponse(VaadinRequest request, VaadinResponse response, String json) throws IOException { // The response was produced without errors so write it to the client - response.setContentType("application/json; charset=UTF-8"); + response.setContentType(JsonConstants.JSON_CONTENT_TYPE); // Ensure that the browser does not cache UIDL responses. // iOS 6 Safari requires this (#9732) @@ -163,31 +164,29 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { return null; } - // Check for an existing UI based on window.name + // Check for an existing UI based on embed id - // Special parameter sent by vaadinBootstrap.js - String windowName = request.getParameter("v-wn"); + String embedId = getEmbedId(request); - Map<String, Integer> retainOnRefreshUIs = session - .getPreserveOnRefreshUIs(); - if (windowName != null && !retainOnRefreshUIs.isEmpty()) { - // Check for a known UI - - Integer retainedUIId = retainOnRefreshUIs.get(windowName); - - if (retainedUIId != null) { - UI retainedUI = session.getUIById(retainedUIId.intValue()); + UI retainedUI = session.getUIByEmbedId(embedId); + if (retainedUI != null) { + if (vaadinService.preserveUIOnRefresh(provider, new UICreateEvent( + request, uiClass))) { if (uiClass.isInstance(retainedUI)) { reinitUI(retainedUI, request); return retainedUI; } else { getLogger().info( - "Not using retained UI in " + windowName - + " because retained UI was of type " + "Not using the preserved UI " + embedId + + " because it is of type " + retainedUI.getClass() + " but " + uiClass + " is expected for the request."); } } + /* + * Previous UI without preserve on refresh will be closed when the + * new UI gets added to the session. + */ } // No existing UI found - go on by creating and initializing one @@ -220,26 +219,45 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { // Set thread local here so it is available in init UI.setCurrent(ui); - ui.doInit(request, uiId.intValue()); + ui.doInit(request, uiId.intValue(), embedId); session.addUI(ui); - // Remember if it should be remembered - if (vaadinService.preserveUIOnRefresh(provider, event)) { - // Remember this UI - if (windowName == null) { - getLogger().warning( - "There is no window.name available for UI " + uiClass - + " that should be preserved."); - } else { - session.getPreserveOnRefreshUIs().put(windowName, uiId); - } + // Warn if the window can't be preserved + if (embedId == null + && vaadinService.preserveUIOnRefresh(provider, event)) { + getLogger().warning( + "There is no embed id available for UI " + uiClass + + " that should be preserved."); } return ui; } /** + * Constructs an embed id based on information in the request. + * + * @since 7.2 + * + * @param request + * the request to get embed information from + * @return the embed id, or <code>null</code> if id is not available. + * + * @see UI#getEmbedId() + */ + protected String getEmbedId(VaadinRequest request) { + // Parameters sent by vaadinBootstrap.js + String windowName = request.getParameter("v-wn"); + String appId = request.getParameter("v-appId"); + + if (windowName != null && appId != null) { + return windowName + '.' + appId; + } else { + return null; + } + } + + /** * Updates a UI that has already been initialized but is now loaded again, * e.g. because of {@link PreserveOnRefresh}. * diff --git a/server/src/com/vaadin/server/communication/UidlRequestHandler.java b/server/src/com/vaadin/server/communication/UidlRequestHandler.java index d52c5e9fe0..cf25910fa4 100644 --- a/server/src/com/vaadin/server/communication/UidlRequestHandler.java +++ b/server/src/com/vaadin/server/communication/UidlRequestHandler.java @@ -60,11 +60,13 @@ public class UidlRequestHandler extends SynchronizedRequestHandler implements } @Override + protected boolean canHandleRequest(VaadinRequest request) { + return ServletPortletHelper.isUIDLRequest(request); + } + + @Override public boolean synchronizedHandleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException { - if (!ServletPortletHelper.isUIDLRequest(request)) { - return false; - } UI uI = session.getService().findUI(request); if (uI == null) { // This should not happen but it will if the UI has been closed. We diff --git a/server/src/com/vaadin/server/communication/UidlWriter.java b/server/src/com/vaadin/server/communication/UidlWriter.java index 60933a75c2..6c23da629e 100644 --- a/server/src/com/vaadin/server/communication/UidlWriter.java +++ b/server/src/com/vaadin/server/communication/UidlWriter.java @@ -38,6 +38,7 @@ import com.vaadin.server.LegacyCommunicationManager; import com.vaadin.server.LegacyCommunicationManager.ClientCache; import com.vaadin.server.SystemMessages; import com.vaadin.server.VaadinSession; +import com.vaadin.shared.ApplicationConstants; import com.vaadin.ui.ConnectorTracker; import com.vaadin.ui.UI; @@ -98,6 +99,9 @@ public class UidlWriter implements Serializable { uiConnectorTracker.setWritingResponse(true); try { + writer.write("\"" + ApplicationConstants.SERVER_SYNC_ID + "\": " + + uiConnectorTracker.getCurrentSyncId() + ", "); + writer.write("\"changes\" : "); JsonPaintTarget paintTarget = new JsonPaintTarget(manager, writer, diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java index 61bcf00ad8..33aa689a88 100644 --- a/server/src/com/vaadin/ui/AbstractComponent.java +++ b/server/src/com/vaadin/ui/AbstractComponent.java @@ -31,13 +31,13 @@ import com.vaadin.event.ConnectorActionManager; import com.vaadin.event.ShortcutListener; import com.vaadin.server.AbstractClientConnector; import com.vaadin.server.ComponentSizeValidator; -import com.vaadin.server.ErrorHandler; import com.vaadin.server.ErrorMessage; import com.vaadin.server.Resource; import com.vaadin.server.VaadinSession; import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.ComponentConstants; import com.vaadin.shared.ui.ComponentStateUtil; +import com.vaadin.ui.Field.ValueChangeEvent; import com.vaadin.util.ReflectTools; /** @@ -85,8 +85,6 @@ public abstract class AbstractComponent extends AbstractClientConnector private static final Pattern sizePattern = Pattern .compile("^(-?\\d+(\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$"); - private ErrorHandler errorHandler = null; - /** * Keeps track of the Actions added to this component; the actual * handling/notifying is delegated, usually to the containing window. @@ -97,6 +95,8 @@ public abstract class AbstractComponent extends AbstractClientConnector private HasComponents parent; + private Boolean explicitImmediateValue; + /* Constructor */ /** @@ -360,25 +360,29 @@ public abstract class AbstractComponent extends AbstractClientConnector } } - /* - * Tests if the component is in the immediate mode. Don't add a JavaDoc - * comment here, we use the default documentation from implemented - * interface. - */ public boolean isImmediate() { - return getState(false).immediate; + if (explicitImmediateValue != null) { + return explicitImmediateValue; + } else if (hasListeners(ValueChangeEvent.class)) { + /* + * Automatic immediate for fields that developers are interested + * about. + */ + return true; + } else { + return false; + } } /** - * Sets the component's immediate mode to the specified status. This method - * will trigger a {@link RepaintRequestEvent}. + * Sets the component's immediate mode to the specified status. * * @param immediate * the boolean value specifying if the component should be in the * immediate mode after the call. - * @see Component#isImmediate() */ public void setImmediate(boolean immediate) { + explicitImmediateValue = immediate; getState().immediate = immediate; } @@ -675,6 +679,8 @@ public abstract class AbstractComponent extends AbstractClientConnector } else { getState().errorMessage = null; } + + getState().immediate = isImmediate(); } /* General event framework */ diff --git a/server/src/com/vaadin/ui/AbstractField.java b/server/src/com/vaadin/ui/AbstractField.java index b96e331889..300e130c4e 100644 --- a/server/src/com/vaadin/ui/AbstractField.java +++ b/server/src/com/vaadin/ui/AbstractField.java @@ -1086,6 +1086,8 @@ public abstract class AbstractField<T> extends AbstractComponent implements public void addValueChangeListener(Property.ValueChangeListener listener) { addListener(AbstractField.ValueChangeEvent.class, listener, VALUE_CHANGE_METHOD); + // ensure "automatic immediate handling" works + markAsDirty(); } /** @@ -1107,6 +1109,8 @@ public abstract class AbstractField<T> extends AbstractComponent implements public void removeValueChangeListener(Property.ValueChangeListener listener) { removeListener(AbstractField.ValueChangeEvent.class, listener, VALUE_CHANGE_METHOD); + // ensure "automatic immediate handling" works + markAsDirty(); } /** diff --git a/server/src/com/vaadin/ui/AbstractSelect.java b/server/src/com/vaadin/ui/AbstractSelect.java index 556b16943f..a32d40b11d 100644 --- a/server/src/com/vaadin/ui/AbstractSelect.java +++ b/server/src/com/vaadin/ui/AbstractSelect.java @@ -878,6 +878,37 @@ public abstract class AbstractSelect extends AbstractField<Object> implements return retval; } + /** + * Adds given items with given item ids to container. + * + * @since 7.2 + * @param itemId + * item identifiers to be added to underlying container + * @throws UnsupportedOperationException + * if the underlying container don't support adding items with + * identifiers + */ + public void addItems(Object... itemId) throws UnsupportedOperationException { + for (Object id : itemId) { + addItem(id); + } + } + + /** + * Adds given items with given item ids to container. + * + * @since 7.2 + * @param itemIds + * item identifiers to be added to underlying container + * @throws UnsupportedOperationException + * if the underlying container don't support adding items with + * identifiers + */ + public void addItems(Collection<Object> itemIds) + throws UnsupportedOperationException { + addItems(itemIds.toArray()); + } + /* * (non-Javadoc) * diff --git a/server/src/com/vaadin/ui/Button.java b/server/src/com/vaadin/ui/Button.java index 1bcf802f12..765c805d37 100644 --- a/server/src/com/vaadin/ui/Button.java +++ b/server/src/com/vaadin/ui/Button.java @@ -100,6 +100,31 @@ public class Button extends AbstractComponent implements } /** + * Creates a new push button with the given icon. + * + * @param icon + * the icon + */ + public Button(Resource icon) { + this(); + setIcon(icon); + } + + /** + * Creates a new push button with the given caption and icon. + * + * @param caption + * the caption + * @param icon + * the icon + */ + public Button(String caption, Resource icon) { + this(); + setCaption(caption); + setIcon(icon); + } + + /** * Creates a new push button with a click listener. * * @param caption diff --git a/server/src/com/vaadin/ui/ComboBox.java b/server/src/com/vaadin/ui/ComboBox.java index 88e895df82..5fb2f81011 100644 --- a/server/src/com/vaadin/ui/ComboBox.java +++ b/server/src/com/vaadin/ui/ComboBox.java @@ -56,8 +56,6 @@ public class ComboBox extends AbstractSelect implements */ protected int pageLength = 10; - private int columns = 0; - // Current page when the user is 'paging' trough options private int currentPage = -1; diff --git a/server/src/com/vaadin/ui/Component.java b/server/src/com/vaadin/ui/Component.java index 485327bb54..c385805675 100644 --- a/server/src/com/vaadin/ui/Component.java +++ b/server/src/com/vaadin/ui/Component.java @@ -651,7 +651,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable { public Locale getLocale(); /** - * Adds an unique id for component that get's transferred to terminal for + * Adds an unique id for component that is used in the client-side for * testing purposes. Keeping identifiers unique is the responsibility of the * programmer. * @@ -661,7 +661,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable { public void setId(String id); /** - * Get's currently set debug identifier + * Gets currently set debug identifier * * @return current id, null if not set */ @@ -669,7 +669,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable { /** * <p> - * Gets the component's description, used in tooltips and can be displayed + * Gets the components description, used in tooltips and can be displayed * directly in certain other components such as forms. The description can * be used to briefly describe the state of the component to the user. The * description string may contain certain XML tags: diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java index 0f8ec60104..33d585adca 100644 --- a/server/src/com/vaadin/ui/ConnectorTracker.java +++ b/server/src/com/vaadin/ui/ConnectorTracker.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; @@ -81,6 +82,16 @@ public class ConnectorTracker implements Serializable { private Map<StreamVariable, String> streamVariableToSeckey; + private int currentSyncId = 0; + + /** + * Map to track on which syncId each connector was removed. + * + * @see #getCurrentSyncId() + * @see #cleanConcurrentlyRemovedConnectorIds(long) + */ + private TreeMap<Integer, Set<String>> syncIdToUnregisteredConnectorIds = new TreeMap<Integer, Set<String>>(); + /** * Gets a logger for this class * @@ -170,6 +181,15 @@ public class ConnectorTracker implements Serializable { + " is not the one that was registered for that id"); } + Set<String> unregisteredConnectorIds = syncIdToUnregisteredConnectorIds + .get(currentSyncId); + if (unregisteredConnectorIds == null) { + unregisteredConnectorIds = new HashSet<String>(); + syncIdToUnregisteredConnectorIds.put(currentSyncId, + unregisteredConnectorIds); + } + unregisteredConnectorIds.add(connectorId); + dirtyConnectors.remove(connector); if (unregisteredConnectors.add(connector)) { if (getLogger().isLoggable(Level.FINE)) { @@ -570,12 +590,18 @@ public class ConnectorTracker implements Serializable { /** * Sets the current response write status. Connectors can not be marked as * dirty when the response is written. + * <p> + * This method has a side-effect of incrementing the sync id by one (see + * {@link #getCurrentSyncId()}), if {@link #isWritingResponse()} returns + * <code>false</code> and <code>writingResponse</code> is set to + * <code>true</code>. * * @param writingResponse * the new response status. * * @see #markDirty(ClientConnector) * @see #isWritingResponse() + * @see #getCurrentSyncId() * * @throws IllegalArgumentException * if the new response status is the same as the previous value. @@ -587,6 +613,14 @@ public class ConnectorTracker implements Serializable { throw new IllegalArgumentException( "The old value is same as the new value"); } + + /* + * the right hand side of the && is unnecessary here because of the + * if-clause above, but rigorous coding is always rigorous coding. + */ + if (writingResponse && !this.writingResponse) { + currentSyncId++; + } this.writingResponse = writingResponse; } @@ -732,4 +766,105 @@ public class ConnectorTracker implements Serializable { } return streamVariableToSeckey.get(variable); } + + /** + * Check whether a connector was present on the client when the it was + * creating this request, but was removed server-side before the request + * arrived. + * + * @since 7.2 + * @param connectorId + * The connector id to check for whether it was removed + * concurrently or not. + * @param lastSyncIdSeenByClient + * the most recent sync id the client has seen at the time the + * request was sent + * @return <code>true</code> if the connector was removed before the client + * had a chance to react to it. + */ + public boolean connectorWasPresentAsRequestWasSent(String connectorId, + long lastSyncIdSeenByClient) { + + assert getConnector(connectorId) == null : "Connector " + connectorId + + " is still attached"; + + boolean clientRequestIsTooOld = lastSyncIdSeenByClient < currentSyncId; + if (clientRequestIsTooOld) { + /* + * The headMap call is present here because we're only interested in + * connectors removed "in the past" (i.e. the server has removed + * them before the client ever knew about that), since those are the + * ones that we choose to handle as a special case. + */ + /*- + * Server Client + * [#1 add table] ---------. + * \ + * [push: #2 remove table]-. `--> [adding table, storing #1] + * \ .- [table from request #1 needs more data] + * \/ + * /`-> [removing table, storing #2] + * [#1 < #2 - ignoring] <---´ + */ + for (Set<String> unregisteredConnectors : syncIdToUnregisteredConnectorIds + .headMap(currentSyncId).values()) { + if (unregisteredConnectors.contains(connectorId)) { + return true; + } + } + } + + return false; + } + + /** + * Gets the most recently generated server sync id. + * <p> + * The sync id is incremented by one whenever a new response is being + * written. This id is then sent over to the client. The client then adds + * the most recent sync id to each communication packet it sends back to the + * server. This way, the server knows at what state the client is when the + * packet is sent. If the state has changed on the server side since that, + * the server can try to adjust the way it handles the actions from the + * client side. + * + * @see #setWritingResponse(boolean) + * @see #connectorWasPresentAsRequestWasSent(String, long) + * @since 7.2 + * @return the current sync id + */ + public int getCurrentSyncId() { + return currentSyncId; + } + + /** + * Maintains the bookkeeping connector removal and concurrency by removing + * entries that have become too old. + * <p> + * <em>It is important to run this call for each transmission from the client</em> + * , otherwise the bookkeeping gets out of date and the results form + * {@link #connectorWasPresentAsRequestWasSent(String, long)} will become + * invalid (that is, even though the client knew the component was removed, + * the aforementioned method would start claiming otherwise). + * <p> + * Entries that both client and server agree upon are removed. Since + * argument is the last sync id that the client has seen from the server, we + * know that entries earlier than that cannot cause any problems anymore. + * + * @see #connectorWasPresentAsRequestWasSent(String, long) + * @since 7.2 + * @param lastSyncIdSeenByClient + * the sync id the client has most recently received from the + * server. + */ + public void cleanConcurrentlyRemovedConnectorIds(int lastSyncIdSeenByClient) { + /* + * We remove all entries _older_ than the one reported right now, + * because the remaining still contain components that might cause + * conflicts. In any case, it's better to clean up too little than too + * much, especially as the data will hardly grow into the kilobytes. + */ + syncIdToUnregisteredConnectorIds.headMap(lastSyncIdSeenByClient) + .clear(); + } } diff --git a/server/src/com/vaadin/ui/DragAndDropWrapper.java b/server/src/com/vaadin/ui/DragAndDropWrapper.java index 5d6825c868..2ab3e872c6 100644 --- a/server/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/server/src/com/vaadin/ui/DragAndDropWrapper.java @@ -56,7 +56,7 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, for (int i = 0; i < fc; i++) { Html5File file = new Html5File( (String) rawVariables.get("fn" + i), // name - (Integer) rawVariables.get("fs" + i), // size + ((Double) rawVariables.get("fs" + i)).longValue(), // size (String) rawVariables.get("ft" + i)); // mime String id = (String) rawVariables.get("fi" + i); files[i] = file; diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java index d7cee2a80d..71d54fc29a 100644 --- a/server/src/com/vaadin/ui/Label.java +++ b/server/src/com/vaadin/ui/Label.java @@ -18,7 +18,6 @@ package com.vaadin.ui; import java.lang.reflect.Method; import java.util.Locale; -import java.util.logging.Logger; import com.vaadin.data.Property; import com.vaadin.data.util.AbstractProperty; @@ -56,9 +55,6 @@ public class Label extends AbstractComponent implements Property<String>, Property.Viewer, Property.ValueChangeListener, Property.ValueChangeNotifier, Comparable<Label> { - private static final Logger logger = Logger - .getLogger(Label.class.getName()); - /** * @deprecated As of 7.0, use {@link ContentMode#TEXT} instead */ @@ -190,7 +186,8 @@ public class Label extends AbstractComponent implements Property<String>, /** * Set the value of the label. Value of the label is the XML contents of the - * label. + * label. Since Vaadin 7.2, changing the value of Label instance with that + * method will fire ValueChangeEvent. * * @param newStringValue * the New value of the label. @@ -198,7 +195,13 @@ public class Label extends AbstractComponent implements Property<String>, @Override public void setValue(String newStringValue) { if (getPropertyDataSource() == null) { - getState().text = newStringValue; + + LabelState state = (LabelState) getState(false); + String oldTextValue = state.text; + if (!SharedUtil.equals(oldTextValue, newStringValue)) { + getState().text = newStringValue; + fireValueChange(); + } } else { throw new IllegalStateException( "Label is only a Property.Viewer and cannot update its data source"); @@ -227,7 +230,8 @@ public class Label extends AbstractComponent implements Property<String>, } /** - * Sets the property as data-source for viewing. + * Sets the property as data-source for viewing. Since Vaadin 7.2 a + * ValueChangeEvent is fired if the new value is different from previous. * * @param newDataSource * the new data source Property @@ -257,7 +261,7 @@ public class Label extends AbstractComponent implements Property<String>, if (dataSource != null) { // Update the value from the data source. If data source was set to // null, retain the old value - getState().text = getDataSourceValue(); + updateValueFromDataSource(); } // Listens the new data source if possible @@ -408,7 +412,8 @@ public class Label extends AbstractComponent implements Property<String>, private void updateValueFromDataSource() { // Update the internal value from the data source String newConvertedValue = getDataSourceValue(); - if (!SharedUtil.equals(newConvertedValue, getState().text)) { + if (!SharedUtil.equals(newConvertedValue, + ((LabelState) getState(false)).text)) { getState().text = newConvertedValue; fireValueChange(); } diff --git a/server/src/com/vaadin/ui/Link.java b/server/src/com/vaadin/ui/Link.java index cf8e1a9693..e1a47777bd 100644 --- a/server/src/com/vaadin/ui/Link.java +++ b/server/src/com/vaadin/ui/Link.java @@ -16,13 +16,10 @@ package com.vaadin.ui; -import java.util.Map; - -import com.vaadin.server.PaintException; -import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; import com.vaadin.shared.ui.BorderStyle; import com.vaadin.shared.ui.link.LinkConstants; +import com.vaadin.shared.ui.link.LinkState; /** * Link is used to create external or internal URL links. @@ -31,7 +28,7 @@ import com.vaadin.shared.ui.link.LinkConstants; * @since 3.0 */ @SuppressWarnings("serial") -public class Link extends AbstractComponent implements LegacyComponent { +public class Link extends AbstractComponent { /** * @deprecated As of 7.0, use {@link BorderStyle#NONE} instead @@ -51,14 +48,6 @@ public class Link extends AbstractComponent implements LegacyComponent { @Deprecated public static final BorderStyle TARGET_BORDER_DEFAULT = BorderStyle.DEFAULT; - private String targetName; - - private BorderStyle targetBorder = BorderStyle.DEFAULT; - - private int targetWidth = -1; - - private int targetHeight = -1; - /** * Creates a new link. */ @@ -105,43 +94,14 @@ public class Link extends AbstractComponent implements LegacyComponent { setTargetBorder(border); } - /** - * Paints the content of this component. - * - * @param target - * the Paint Event. - * @throws PaintException - * if the paint operation failed. - */ @Override - public void paintContent(PaintTarget target) throws PaintException { - if (getResource() == null) { - return; - } - - // Target window name - final String name = getTargetName(); - if (name != null && name.length() > 0) { - target.addAttribute("name", name); - } - - // Target window size - if (getTargetWidth() >= 0) { - target.addAttribute("targetWidth", getTargetWidth()); - } - if (getTargetHeight() >= 0) { - target.addAttribute("targetHeight", getTargetHeight()); - } - - // Target window border - switch (getTargetBorder()) { - case MINIMAL: - target.addAttribute("border", "minimal"); - break; - case NONE: - target.addAttribute("border", "none"); - break; - } + protected LinkState getState() { + return (LinkState) super.getState(); + } + + @Override + protected LinkState getState(boolean markAsDirty) { + return (LinkState) super.getState(markAsDirty); } /** @@ -150,7 +110,7 @@ public class Link extends AbstractComponent implements LegacyComponent { * @return the target window border. */ public BorderStyle getTargetBorder() { - return targetBorder; + return getState(false).targetBorder; } /** @@ -159,7 +119,8 @@ public class Link extends AbstractComponent implements LegacyComponent { * @return the target window height. */ public int getTargetHeight() { - return targetHeight < 0 ? -1 : targetHeight; + return getState(false).targetHeight < 0 ? -1 + : getState(false).targetHeight; } /** @@ -169,7 +130,7 @@ public class Link extends AbstractComponent implements LegacyComponent { * @return the target window name. */ public String getTargetName() { - return targetName; + return getState(false).target; } /** @@ -178,7 +139,8 @@ public class Link extends AbstractComponent implements LegacyComponent { * @return the target window width. */ public int getTargetWidth() { - return targetWidth < 0 ? -1 : targetWidth; + return getState(false).targetWidth < 0 ? -1 + : getState(false).targetWidth; } /** @@ -188,8 +150,7 @@ public class Link extends AbstractComponent implements LegacyComponent { * the targetBorder to set. */ public void setTargetBorder(BorderStyle targetBorder) { - this.targetBorder = targetBorder; - markAsDirty(); + getState().targetBorder = targetBorder; } /** @@ -199,8 +160,7 @@ public class Link extends AbstractComponent implements LegacyComponent { * the targetHeight to set. */ public void setTargetHeight(int targetHeight) { - this.targetHeight = targetHeight; - markAsDirty(); + getState().targetHeight = targetHeight; } /** @@ -210,8 +170,7 @@ public class Link extends AbstractComponent implements LegacyComponent { * the targetName to set. */ public void setTargetName(String targetName) { - this.targetName = targetName; - markAsDirty(); + getState().target = targetName; } /** @@ -221,8 +180,7 @@ public class Link extends AbstractComponent implements LegacyComponent { * the targetWidth to set. */ public void setTargetWidth(int targetWidth) { - this.targetWidth = targetWidth; - markAsDirty(); + getState().targetWidth = targetWidth; } /** @@ -244,8 +202,4 @@ public class Link extends AbstractComponent implements LegacyComponent { setResource(LinkConstants.HREF_RESOURCE, resource); } - @Override - public void changeVariables(Object source, Map<String, Object> variables) { - // TODO Remove once LegacyComponent is no longer implemented - } } diff --git a/server/src/com/vaadin/ui/Notification.java b/server/src/com/vaadin/ui/Notification.java index cf1d03ab5c..31fa265b02 100644 --- a/server/src/com/vaadin/ui/Notification.java +++ b/server/src/com/vaadin/ui/Notification.java @@ -21,6 +21,7 @@ import java.io.Serializable; import com.vaadin.server.Page; import com.vaadin.server.Resource; import com.vaadin.shared.Position; +import com.vaadin.shared.ui.ui.NotificationConfigurationBean.Role; /** * A notification message, used to display temporary messages to the user - for @@ -63,7 +64,7 @@ import com.vaadin.shared.Position; */ public class Notification implements Serializable { public enum Type { - HUMANIZED_MESSAGE, WARNING_MESSAGE, ERROR_MESSAGE, TRAY_NOTIFICATION; + HUMANIZED_MESSAGE, WARNING_MESSAGE, ERROR_MESSAGE, TRAY_NOTIFICATION, ASSISTIVE_NOTIFICATION; } @Deprecated @@ -190,21 +191,38 @@ public class Notification implements Serializable { case WARNING_MESSAGE: delayMsec = 1500; styleName = "warning"; + setNavigationConfiguration("Warning: ", "", Role.ALERT); break; case ERROR_MESSAGE: delayMsec = -1; styleName = "error"; + setNavigationConfiguration("Error: ", " - close with ESC", + Role.ALERT); break; case TRAY_NOTIFICATION: delayMsec = 3000; position = Position.BOTTOM_RIGHT; styleName = "tray"; - + setNavigationConfiguration("Info: ", "", Role.STATUS); + break; + case ASSISTIVE_NOTIFICATION: + delayMsec = 3000; + position = Position.ASSISTIVE; + styleName = "assistive"; + setNavigationConfiguration("Note: ", "", Role.ALERT); + break; case HUMANIZED_MESSAGE: default: + styleName = "humanized"; + setNavigationConfiguration("Info: ", "", Role.ALERT); break; } + } + private void setNavigationConfiguration(String prefix, String postfix, + Role ariaRole) { + UI.getCurrent().getNotificationConfiguration() + .setStyleConfiguration(styleName, prefix, postfix, ariaRole); } /** @@ -322,6 +340,132 @@ public class Notification implements Serializable { } /** + * Sets the accessibility prefix for a notification type. + * + * This prefix is read to assistive device users before the content of the + * notification, but not visible on the page. + * + * @param type + * Type of the notification + * @param prefix + * String that is placed before the notification content + */ + public void setAssistivePrefixForType(Type type, String prefix) { + UI.getCurrent().getNotificationConfiguration() + .setAssistivePrefixForStyle(getStyle(type), prefix); + } + + /** + * Gets the accessibility prefix for a notification type. + * + * This prefix is read to assistive device users before the content of the + * notification, but not visible on the page. + * + * @param type + * Type of the notification + * @return The accessibility prefix for the provided notification type + */ + public String getAssistivePrefixForType(Type type) { + return UI.getCurrent().getNotificationConfiguration() + .getAssistivePrefixForStyle(getStyle(type)); + } + + /** + * Sets the accessibility postfix for a notification type. + * + * This postfix is read to assistive device users after the content of the + * notification, but not visible on the page. + * + * @param type + * Type of the notification + * @param postfix + * String that is placed after the notification content + */ + public void setAssistivePostfixForType(Type type, String postfix) { + UI.getCurrent().getNotificationConfiguration() + .setAssistivePostfixForStyle(getStyle(type), postfix); + } + + /** + * Gets the accessibility postfix for a notification type. + * + * This postfix is read to assistive device users after the content of the + * notification, but not visible on the page. + * + * @param type + * Type of the notification + * @return The accessibility postfix for the provided notification type + */ + public String getAssistivePostfixForType(Type type) { + return UI.getCurrent().getNotificationConfiguration() + .getAssistivePostfixForStyle(getStyle(type)); + } + + /** + * Sets the WAI-ARIA role for a notification type. + * + * This role defines how an assistive device handles a notification. + * Available roles are alert and status (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>). + * + * The default role is alert. + * + * @param type + * Type of the notification + * @param role + * Role to set for the notification type + */ + public void setAssistiveRoleForType(Type type, Role role) { + UI.getCurrent().getNotificationConfiguration() + .setAssistiveRoleForStyle(getStyle(type), role); + } + + /** + * Gets the WAI-ARIA role for a notification type. + * + * This role defines how an assistive device handles a notification. + * Available roles are alert and status (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>) + * + * The default role is alert. + * + * @param type + * Type of the notification + * @return Role to set for the notification type + */ + public Role getAssistiveRoleForType(Type type) { + return UI.getCurrent().getNotificationConfiguration() + .getAssistiveRoleForStyle(getStyle(type)); + } + + private String getStyle(Type type) { + String style = ""; + + switch (type) { + case WARNING_MESSAGE: + style = "warning"; + break; + case ERROR_MESSAGE: + style = "error"; + break; + case TRAY_NOTIFICATION: + style = "tray"; + break; + case ASSISTIVE_NOTIFICATION: + style = "assistive"; + break; + case HUMANIZED_MESSAGE: + default: + style = "humanized"; + break; + } + + return style; + } + + /** * Sets whether html is allowed in the caption and description. If set to * true, the texts are passed to the browser as html and the developer is * responsible for ensuring no harmful html is used. If set to false, the @@ -414,4 +558,4 @@ public class Notification implements Serializable { public static void show(String caption, String description, Type type) { new Notification(caption, description, type).show(Page.getCurrent()); } -}
\ No newline at end of file +} diff --git a/server/src/com/vaadin/ui/NotificationConfiguration.java b/server/src/com/vaadin/ui/NotificationConfiguration.java new file mode 100644 index 0000000000..52d3e76d63 --- /dev/null +++ b/server/src/com/vaadin/ui/NotificationConfiguration.java @@ -0,0 +1,269 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/** + * + */ +package com.vaadin.ui; + +import java.io.Serializable; + +import com.vaadin.shared.ui.ui.NotificationConfigurationBean; +import com.vaadin.shared.ui.ui.NotificationConfigurationBean.Role; +import com.vaadin.shared.ui.ui.UIState.NotificationConfigurationState; + +/** + * Provides methods for configuring the notification. + * + * @author Vaadin Ltd + * @since 7.1 + */ +public interface NotificationConfiguration extends Serializable { + public void setStyleConfiguration(String style, String prefix, + String postfix, Role ariaRole); + + /** + * Returns the complete configuration object for the given notification + * style. + * + * @param style + * String of the notification style to return + * @return The notification configuration object + */ + public NotificationConfigurationBean getStyleConfiguration(String style); + + /** + * Sets the accessibility prefix for the given notification style. + * + * This prefix is read to assistive device users in front of the content of + * the notification, but not visible on the page. + * + * @param style + * String of the notification style + * @param prefix + * String that is placed before the notification content + */ + public void setAssistivePrefixForStyle(String style, String prefix); + + /** + * Returns the accessibility prefix for the given notification style. + * + * This prefix is read to assistive device users in front of the content of + * the notification, but not visible on the page. + * + * @param style + * String of the notification style + * @return The prefix of the provided notification style + */ + public String getAssistivePrefixForStyle(String style); + + /** + * Sets the accessibility postfix for the given notification style. + * + * This postfix is read to assistive device users after the content of the + * notification, but not visible on the page. + * + * @param style + * String of the notification style + * @param postfix + * String that is placed after the notification content + */ + public void setAssistivePostfixForStyle(String style, String postfix); + + /** + * Returns the accessibility postfix for the given notification style. + * + * This postfix is read to assistive device users after the content of the + * notification, but not visible on the page. + * + * @param style + * String of the notification style + * @return The postfix of the provided notification style + */ + public String getAssistivePostfixForStyle(String style); + + /** + * Sets the WAI-ARIA role for a notification style. + * + * This role defines how an assistive device handles a notification. + * Available roles are alert, alertdialog and status (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>) + * + * The default role is alert. + * + * @param style + * String of the notification style + * @param role + * Role to set for the notification type + */ + public void setAssistiveRoleForStyle(String style, Role role); + + /** + * Returns the WAI-ARIA role for a notification style. + * + * This role defines how an assistive device handles a notification. + * Available roles are alert, alertdialog and status (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a> ) + * + * The default role is alert. + * + * @param style + * String of the notification style + * @return The current Role for the notification type + */ + public Role getAssistiveRoleForStyle(String style); +} + +class NotificationConfigurationImpl implements NotificationConfiguration { + + private UI ui; + + public NotificationConfigurationImpl(UI ui) { + this.ui = ui; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.NotificationConfiguration#setStyleConfiguration(java.lang + * .String, java.lang.String, java.lang.String, + * com.vaadin.ui.NotificationConfiguration.Role) + */ + @Override + public void setStyleConfiguration(String style, String prefix, + String postfix, Role ariaRole) { + getState().setup.put(style, new NotificationConfigurationBean(prefix, + postfix, ariaRole)); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.NotificationConfiguration#getStyleConfiguration(java.lang + * .String) + */ + @Override + public NotificationConfigurationBean getStyleConfiguration(String style) { + return getState(false).setup.get(style); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.NotificationConfiguration#setStylePrefix(java.lang.String, + * java.lang.String) + */ + @Override + public void setAssistivePrefixForStyle(String style, String prefix) { + getConfigurationBean(style).setAssistivePrefix(prefix); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.NotificationConfiguration#getStylePrefix(java.lang.String) + */ + @Override + public String getAssistivePrefixForStyle(String style) { + NotificationConfigurationBean styleSetup = getState().setup.get(style); + if (styleSetup != null) { + return styleSetup.getAssistivePrefix(); + } + + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.NotificationConfiguration#setStylePostfix(com.vaadin.ui + * .Notification.Type, java.lang.String) + */ + @Override + public void setAssistivePostfixForStyle(String style, String postfix) { + getConfigurationBean(style).setAssistivePostfix(postfix); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.ui.NotificationConfiguration#getStylePostfix(com.vaadin.ui + * .Notification.Type) + */ + @Override + public String getAssistivePostfixForStyle(String style) { + NotificationConfigurationBean styleSetup = getState().setup.get(style); + if (styleSetup != null) { + return styleSetup.getAssistivePostfix(); + } + + return null; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.NotificationConfiguration#setStyleRole(com.vaadin.ui. + * Notification.Type, com.vaadin.ui.NotificationConfiguration.Role) + */ + @Override + public void setAssistiveRoleForStyle(String style, Role role) { + getConfigurationBean(style).setAssistiveRole(role); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.NotificationConfiguration#getStyleRole(com.vaadin.ui. + * Notification.Type) + */ + @Override + public Role getAssistiveRoleForStyle(String style) { + NotificationConfigurationBean styleSetup = getState().setup.get(style); + if (styleSetup != null) { + return styleSetup.getAssistiveRole(); + } + + return null; + } + + private NotificationConfigurationBean getConfigurationBean(String style) { + NotificationConfigurationBean styleSetup = getState().setup.get(style); + if (styleSetup == null) { + styleSetup = new NotificationConfigurationBean(); + getState().setup.put(style, styleSetup); + } + + return styleSetup; + } + + private NotificationConfigurationState getState() { + return ui.getState().notificationConfiguration; + } + + private NotificationConfigurationState getState(boolean markAsDirty) { + return ui.getState(markAsDirty).notificationConfiguration; + } + +} diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java index a592b39bef..49738c5aff 100644 --- a/server/src/com/vaadin/ui/PushConfiguration.java +++ b/server/src/com/vaadin/ui/PushConfiguration.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.Collections; import com.vaadin.server.VaadinSession; +import com.vaadin.server.communication.AtmospherePushConnection; import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.ui.Transport; import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; @@ -170,20 +171,32 @@ class PushConfigurationImpl implements PushConfiguration { throw new IllegalArgumentException("Push mode cannot be null"); } - if (pushMode.isEnabled()) { - VaadinSession session = ui.getSession(); - if (session != null && !session.getService().ensurePushAvailable()) { - throw new IllegalStateException( - "Push is not available. See previous log messages for more information."); - } + VaadinSession session = ui.getSession(); + + if (session == null) { + throw new UIDetachedException( + "Cannot set the push mode for a detached UI"); + } + + assert session.hasLock(); + + if (pushMode.isEnabled() && !session.getService().ensurePushAvailable()) { + throw new IllegalStateException( + "Push is not available. See previous log messages for more information."); } - /* - * Client-side will open a new connection or disconnect the old - * connection, so there's nothing more to do on the server at this - * point. - */ - getState().mode = pushMode; + PushMode oldMode = getState().mode; + if (oldMode != pushMode) { + getState().mode = pushMode; + + if (!oldMode.isEnabled() && pushMode.isEnabled()) { + // The push connection is initially in a disconnected state; + // the client will establish the connection + ui.setPushConnection(new AtmospherePushConnection(ui)); + } + // Nothing to do here if disabling push; + // the client will close the connection + } } /* @@ -274,9 +287,8 @@ class PushConfigurationImpl implements PushConfiguration { @Override public Collection<String> getParameterNames() { - return Collections - .unmodifiableCollection(ui.getState(false).pushConfiguration.parameters - .keySet()); + return Collections.unmodifiableCollection(getState(false).parameters + .keySet()); } } diff --git a/server/src/com/vaadin/ui/TabSheet.java b/server/src/com/vaadin/ui/TabSheet.java index 36022adb74..a1f9e9dd26 100644 --- a/server/src/com/vaadin/ui/TabSheet.java +++ b/server/src/com/vaadin/ui/TabSheet.java @@ -268,7 +268,34 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @return the created {@link Tab} */ public Tab addTab(Component c, String caption, Resource icon) { - return addTab(c, caption, icon, components.size()); + return addTab(c, caption, icon, "", components.size()); + } + + /** + * Adds a new tab into TabSheet. + * + * The first tab added to a tab sheet is automatically selected and a tab + * selection event is fired. + * + * If the component is already present in the tab sheet, changes its caption + * and icon and icon alternate text and returns the corresponding (old) tab, + * preserving other tab metadata. + * + * @param c + * the component to be added onto tab - should not be null. + * @param caption + * the caption to be set for the component and used rendered in + * tab bar + * @param icon + * the icon to be set for the component and used rendered in tab + * bar + * @param iconAltText + * the alternate text for the icon + * @return the created {@link Tab} + */ + public Tab addTab(Component c, String caption, Resource icon, + String iconAltText) { + return addTab(c, caption, icon, iconAltText, components.size()); } /** @@ -294,12 +321,41 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @return the created {@link Tab} */ public Tab addTab(Component c, String caption, Resource icon, int position) { + return addTab(c, caption, icon, "", position); + } + + /** + * Adds a new tab into TabSheet. + * + * The first tab added to a tab sheet is automatically selected and a tab + * selection event is fired. + * + * If the component is already present in the tab sheet, changes its caption + * and icon and icon alternate text and returns the corresponding (old) tab, + * preserving other tab metadata like the position. + * + * @param c + * the component to be added onto tab - should not be null. + * @param caption + * the caption to be set for the component and used rendered in + * tab bar + * @param icon + * the icon to be set for the component and used rendered in tab + * bar + * @param iconAltText + * the alternate text for the icon + * @param position + * the position at where the the tab should be added. + * @return the created {@link Tab} + */ + public Tab addTab(Component c, String caption, Resource icon, + String iconAltText, int position) { if (c == null) { return null; } else if (tabs.containsKey(c)) { Tab tab = tabs.get(c); tab.setCaption(caption); - tab.setIcon(icon); + tab.setIcon(icon, iconAltText); return tab; } else { components.add(position, c); @@ -371,13 +427,15 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, final Component c = i.next(); String caption = null; Resource icon = null; + String iconAltText = ""; if (TabSheet.class.isAssignableFrom(source.getClass())) { Tab tab = ((TabSheet) source).getTab(c); caption = tab.getCaption(); icon = tab.getIcon(); + iconAltText = tab.getIconAltText(); } source.removeComponent(c); - addTab(c, caption, icon); + addTab(c, caption, icon, iconAltText); } } @@ -429,9 +487,12 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, if (icon != null) { target.addAttribute(TabsheetBaseConstants.ATTRIBUTE_TAB_ICON, icon); + target.addAttribute( + TabsheetBaseConstants.ATTRIBUTE_TAB_ICON_ALT, + tab.getIconAltText()); } final String caption = tab.getCaption(); - if (caption != null && caption.length() > 0) { + if (caption != null && !caption.isEmpty()) { target.addAttribute( TabsheetBaseConstants.ATTRIBUTE_TAB_CAPTION, caption); } @@ -449,10 +510,15 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, } final String styleName = tab.getStyleName(); - if (styleName != null && styleName.length() != 0) { + if (styleName != null && !styleName.isEmpty()) { target.addAttribute(TabsheetConstants.TAB_STYLE_NAME, styleName); } + final String id = tab.getId(); + if (id != null && !id.isEmpty()) { + target.addAttribute("id", id); + } + target.addAttribute("key", keyMapper.key(component)); if (component.equals(selected)) { target.addAttribute("selected", true); @@ -549,6 +615,11 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, // connector if (selected != null) { selected.markAsDirtyRecursive(); + + Tab tab = getTab(c); + if (tab != null && tab.getDefaultFocusComponent() != null) { + tab.getDefaultFocusComponent().focus(); + } } } @@ -889,6 +960,23 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, public void setClosable(boolean closable); /** + * Set the component that should automatically focused when the tab is + * selected. + * + * @param component + * the component to focus + */ + public void setDefaultFocusComponent(Focusable component); + + /** + * Get the component that should be automatically focused when the tab + * is selected. + * + * @return the focusable component + */ + public Focusable getDefaultFocusComponent(); + + /** * Returns the enabled status for the tab. A disabled tab is shown as * such in the tab bar and cannot be selected. * @@ -932,6 +1020,27 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, public void setIcon(Resource icon); /** + * Sets the icon and alt text for the tab. + * + * @param icon + * the icon to set + */ + public void setIcon(Resource icon, String iconAltText); + + /** + * Gets the icon alt text for the tab. + */ + public String getIconAltText(); + + /** + * Sets the icon alt text for the tab. + * + * @param iconAltText + * the icon to set + */ + public void setIconAltText(String iconAltText); + + /** * Gets the description for the tab. The description can be used to * briefly describe the state of the tab to the user, and is typically * shown as a tooltip when hovering over the tab. @@ -1015,6 +1124,23 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, * @see #setStyleName(String) */ public String getStyleName(); + + /** + * Adds an unique id for component that is used in the client-side for + * testing purposes. Keeping identifiers unique is the responsibility of + * the programmer. + * + * @param id + * An alphanumeric id + */ + public void setId(String id); + + /** + * Gets currently set debug identifier + * + * @return current id, null if not set + */ + public String getId(); } /** @@ -1030,6 +1156,9 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, private String description = null; private ErrorMessage componentError = null; private String styleName; + private String id; + private String iconAltText = ""; + private Focusable defaultFocus; public TabSheetTabImpl(String caption, Resource icon) { if (caption == null) { @@ -1061,11 +1190,38 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, @Override public void setIcon(Resource icon) { + setIcon(icon, ""); + } + + @Override + public void setIcon(Resource icon, String iconAltText) { this.icon = icon; + this.iconAltText = iconAltText; markAsDirty(); } @Override + public String getIconAltText() { + return iconAltText; + } + + @Override + public void setIconAltText(String iconAltText) { + this.iconAltText = iconAltText; + markAsDirty(); + } + + @Override + public void setDefaultFocusComponent(Focusable defaultFocus) { + this.defaultFocus = defaultFocus; + } + + @Override + public Focusable getDefaultFocusComponent() { + return defaultFocus; + } + + @Override public boolean isEnabled() { return enabled; } @@ -1150,6 +1306,18 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, public String getStyleName() { return styleName; } + + @Override + public void setId(String id) { + this.id = id; + markAsDirty(); + + } + + @Override + public String getId() { + return id; + } } /** @@ -1309,7 +1477,7 @@ public class TabSheet extends AbstractComponentContainer implements Focusable, */ private static void copyTabMetadata(Tab from, Tab to) { to.setCaption(from.getCaption()); - to.setIcon(from.getIcon()); + to.setIcon(from.getIcon(), from.getIconAltText()); to.setDescription(from.getDescription()); to.setVisible(from.isVisible()); to.setEnabled(from.isEnabled()); diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java index 32ed738697..06e82dedcb 100644 --- a/server/src/com/vaadin/ui/Table.java +++ b/server/src/com/vaadin/ui/Table.java @@ -2165,7 +2165,6 @@ public class Table extends AbstractSelect implements Action.Container, // more efficient implementation for containers supporting access by // index - Container.Indexed indexed = ((Container.Indexed) items); List<?> itemIds = getItemIds(firstIndex, rows); for (int i = 0; i < rows && i < itemIds.size(); i++) { Object id = itemIds.get(i); diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 746fa194ac..e688c06061 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -32,6 +32,9 @@ import com.vaadin.event.Action.Handler; import com.vaadin.event.ActionManager; import com.vaadin.event.MouseEvents.ClickEvent; import com.vaadin.event.MouseEvents.ClickListener; +import com.vaadin.event.UIEvents.PollEvent; +import com.vaadin.event.UIEvents.PollListener; +import com.vaadin.event.UIEvents.PollNotifier; import com.vaadin.navigator.Navigator; import com.vaadin.server.ClientConnector; import com.vaadin.server.ComponentSizeValidator; @@ -52,6 +55,7 @@ import com.vaadin.server.communication.PushConnection; import com.vaadin.shared.Connector; import com.vaadin.shared.EventId; import com.vaadin.shared.MouseEventDetails; +import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.ui.DebugWindowClientRpc; import com.vaadin.shared.ui.ui.DebugWindowServerRpc; import com.vaadin.shared.ui.ui.ScrollClientRpc; @@ -77,7 +81,7 @@ import com.vaadin.util.CurrentInstance; * When a new UI instance is needed, typically because the user opens a URL in a * browser window which points to e.g. {@link VaadinServlet}, all * {@link UIProvider}s registered to the current {@link VaadinSession} are - * queried for the UI class that should be used. The selection is by defaylt + * queried for the UI class that should be used. The selection is by default * based on the <code>UI</code> init parameter from web.xml. * </p> * <p> @@ -95,7 +99,8 @@ import com.vaadin.util.CurrentInstance; * @since 7.0 */ public abstract class UI extends AbstractSingleComponentContainer implements - Action.Container, Action.Notifier, LegacyComponent, Focusable { + Action.Container, Action.Notifier, PollNotifier, LegacyComponent, + Focusable { /** * The application to which this UI belongs @@ -167,10 +172,7 @@ public abstract class UI extends AbstractSingleComponentContainer implements @Override public void poll() { - /* - * No-op. This is only called to cause a server visit to check for - * changes. - */ + fireEvent(new PollEvent(UI.this)); } }; private DebugWindowServerRpc debugRpc = new DebugWindowServerRpc() { @@ -222,6 +224,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements private PushConfiguration pushConfiguration = new PushConfigurationImpl( this); + private NotificationConfiguration notificationConfiguration = new NotificationConfigurationImpl( + this); + /** * Creates a new empty UI without a caption. The content of the UI must be * set by calling {@link #setContent(Component)} before using the UI. @@ -418,8 +423,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements } else { if (session == null) { detach(); - // Close the push connection when UI is detached. Otherwise the + // Disable push when the UI is detached. Otherwise the // push connection and possibly VaadinSession will live on. + getPushConfiguration().setPushMode(PushMode.DISABLED); setPushConnection(null); } this.session = session; @@ -546,11 +552,11 @@ public abstract class UI extends AbstractSingleComponentContainer implements private transient PushConnection pushConnection = null; - private boolean hasPendingPush = false; - private LocaleService localeService = new LocaleService(this, getState(false).localeServiceState); + private String embedId; + /** * This method is used by Component.Focusable objects to request focus to * themselves. Focus renders must be handled at window level (instead of @@ -598,12 +604,19 @@ public abstract class UI extends AbstractSingleComponentContainer implements * the initialization request * @param uiId * the id of the new ui + * @param embedId + * the embed id of this UI, or <code>null</code> if no id is + * known + * + * @see #getUIId() + * @see #getEmbedId() */ - public void doInit(VaadinRequest request, int uiId) { + public void doInit(VaadinRequest request, int uiId, String embedId) { if (this.uiId != -1) { throw new IllegalStateException("UI id has already been defined"); } this.uiId = uiId; + this.embedId = embedId; // Actual theme - used for finding CustomLayout templates theme = request.getParameter("theme"); @@ -1334,6 +1347,15 @@ public abstract class UI extends AbstractSingleComponentContainer implements } /** + * Retrieves the object used for configuring notifications. + * + * @return The instance used for notification configuration + */ + public NotificationConfiguration getNotificationConfiguration() { + return notificationConfiguration; + } + + /** * Retrieves the object used for configuring the loading indicator. * * @return The instance used for configuring the loading indicator @@ -1346,6 +1368,9 @@ public abstract class UI extends AbstractSingleComponentContainer implements * Pushes the pending changes and client RPC invocations of this UI to the * client-side. * <p> + * If push is enabled, but the push connection is not currently open, the + * push will be done when the connection is established. + * <p> * As with all UI methods, the session must be locked when calling this * method. It is also recommended that {@link UI#getCurrent()} is set up to * return this UI since writing the response may invoke logic in any @@ -1363,79 +1388,73 @@ public abstract class UI extends AbstractSingleComponentContainer implements */ public void push() { VaadinSession session = getSession(); - if (session != null) { - assert session.hasLock(); - - /* - * Purge the pending access queue as it might mark a connector as - * dirty when the push would otherwise be ignored because there are - * no changes to push. - */ - session.getService().runPendingAccessTasks(session); - - if (!getConnectorTracker().hasDirtyConnectors()) { - // Do not push if there is nothing to push - return; - } - if (!getPushConfiguration().getPushMode().isEnabled()) { - throw new IllegalStateException("Push not enabled"); - } + if (session == null) { + throw new UIDetachedException("Cannot push a detached UI"); + } + assert session.hasLock(); - if (pushConnection == null) { - hasPendingPush = true; - } else { - pushConnection.push(); - } - } else { - throw new UIDetachedException("Trying to push a detached UI"); + if (!getPushConfiguration().getPushMode().isEnabled()) { + throw new IllegalStateException("Push not enabled"); } + assert pushConnection != null; + + /* + * Purge the pending access queue as it might mark a connector as dirty + * when the push would otherwise be ignored because there are no changes + * to push. + */ + session.getService().runPendingAccessTasks(session); + + if (!getConnectorTracker().hasDirtyConnectors()) { + // Do not push if there is nothing to push + return; + } + + pushConnection.push(); } /** * Returns the internal push connection object used by this UI. This method - * should only be called by the framework. If the returned PushConnection is - * not null, it is guaranteed to have {@code isConnected() == true}. + * should only be called by the framework. * <p> * This method is not intended to be overridden. If it is overridden, care * should be taken since this method might be called in situations where * {@link UI#getCurrent()} does not return this UI. * - * @return the push connection used by this UI, <code>null</code> if there - * is no active push connection. + * @return the push connection used by this UI, or {@code null} if push is + * not available. */ public PushConnection getPushConnection() { - assert (pushConnection == null || pushConnection.isConnected()); + assert !(getPushConfiguration().getPushMode().isEnabled() && pushConnection == null); return pushConnection; } /** * Sets the internal push connection object used by this UI. This method - * should only be called by the framework. If {@pushConnection} is not null, - * its {@code isConnected()} must be true. + * should only be called by the framework. + * <p> + * The {@code pushConnection} argument must be non-null if and only if + * {@code getPushConfiguration().getPushMode().isEnabled()}. * * @param pushConnection * the push connection to use for this UI */ public void setPushConnection(PushConnection pushConnection) { - // If pushMode is disabled then there should never be a pushConnection - assert (pushConnection == null || getPushConfiguration().getPushMode() - .isEnabled()); - assert (pushConnection == null || pushConnection.isConnected()); + // If pushMode is disabled then there should never be a pushConnection; + // if enabled there should always be + assert (pushConnection == null) + ^ getPushConfiguration().getPushMode().isEnabled(); if (pushConnection == this.pushConnection) { return; } - if (this.pushConnection != null) { + if (this.pushConnection != null && this.pushConnection.isConnected()) { this.pushConnection.disconnect(); } this.pushConnection = pushConnection; - if (pushConnection != null && hasPendingPush) { - hasPendingPush = false; - pushConnection.push(); - } } /** @@ -1469,6 +1488,17 @@ public abstract class UI extends AbstractSingleComponentContainer implements return getState(false).pollInterval; } + @Override + public void addPollListener(PollListener listener) { + addListener(EventId.POLL, PollEvent.class, listener, + PollListener.POLL_METHOD); + } + + @Override + public void removePollListener(PollListener listener) { + removeListener(EventId.POLL, PollEvent.class, listener); + } + /** * Retrieves the object used for configuring the push channel. * @@ -1518,4 +1548,18 @@ public abstract class UI extends AbstractSingleComponentContainer implements private static Logger getLogger() { return Logger.getLogger(UI.class.getName()); } + + /** + * Gets a string the uniquely distinguishes this UI instance based on where + * it is embedded. The embed identifier is based on the + * <code>window.name</code> DOM attribute of the browser window where the UI + * is displayed and the id of the div element where the UI is embedded. + * + * @since 7.2 + * @return the embed id for this UI, or <code>null</code> if no id known + */ + public String getEmbedId() { + return embedId; + } + } diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java index 98f5d2ded9..c8d9f3ff09 100644 --- a/server/src/com/vaadin/ui/Upload.java +++ b/server/src/com/vaadin/ui/Upload.java @@ -28,7 +28,10 @@ import com.vaadin.server.NoOutputStreamException; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.StreamVariable.StreamingProgressEvent; +import com.vaadin.shared.EventId; import com.vaadin.shared.ui.upload.UploadClientRpc; +import com.vaadin.shared.ui.upload.UploadServerRpc; +import com.vaadin.util.ReflectTools; /** * Component for uploading files from client to server. @@ -113,9 +116,16 @@ public class Upload extends AbstractComponent implements Component.Focusable, * The receiver must be set before performing an upload. */ public Upload() { + registerRpc(new UploadServerRpc() { + @Override + public void change(String filename) { + fireEvent(new ChangeEvent(Upload.this, filename)); + } + }); } public Upload(String caption, Receiver uploadReceiver) { + this(); setCaption(caption); receiver = uploadReceiver; } @@ -486,6 +496,42 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** + * Upload.ChangeEvent event is sent when the value (filename) of the upload + * changes. + * + * @since 7.2 + */ + public static class ChangeEvent extends Component.Event { + + private final String filename; + + public ChangeEvent(Upload source, String filename) { + super(source); + this.filename = filename; + } + + /** + * Uploads where the event occurred. + * + * @return the Source of the event. + */ + @Override + public Upload getSource() { + return (Upload) super.getSource(); + } + + /** + * Gets the file name. + * + * @return the filename. + */ + public String getFilename() { + return filename; + } + + } + + /** * Receives the events when the upload starts. * * @author Vaadin Ltd. @@ -554,6 +600,25 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** + * Listener for {@link ChangeEvent} + * + * @since 7.2 + */ + public interface ChangeListener extends Serializable { + + Method FILENAME_CHANGED = ReflectTools.findMethod(ChangeListener.class, + "filenameChanged", ChangeEvent.class); + + /** + * A file has been selected but upload has not yet started. + * + * @param event + * the change event + */ + public void filenameChanged(ChangeEvent event); + } + + /** * Adds the upload started event listener. * * @param listener @@ -740,6 +805,27 @@ public class Upload extends AbstractComponent implements Component.Focusable, } /** + * Adds a filename change event listener + * + * @param listener + * the Listener to add + */ + public void addChangeListener(ChangeListener listener) { + super.addListener(EventId.CHANGE, ChangeEvent.class, listener, + ChangeListener.FILENAME_CHANGED); + } + + /** + * Removes a filename change event listener + * + * @param listener + * the listener to be removed + */ + public void removeChangeListener(ChangeListener listener) { + super.removeListener(EventId.CHANGE, ChangeEvent.class, listener); + } + + /** * @deprecated As of 7.0, replaced by * {@link #removeProgressListener(ProgressListener)} **/ @@ -1040,7 +1126,11 @@ public class Upload extends AbstractComponent implements Component.Focusable, @Override public OutputStream getOutputStream() { - OutputStream receiveUpload = receiver.receiveUpload( + if (getReceiver() == null) { + throw new IllegalStateException( + "Upload cannot be performed without a receiver set"); + } + OutputStream receiveUpload = getReceiver().receiveUpload( lastStartedEvent.getFileName(), lastStartedEvent.getMimeType()); lastStartedEvent = null; diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java index c173b401b9..d3afdaacf1 100644 --- a/server/src/com/vaadin/ui/Window.java +++ b/server/src/com/vaadin/ui/Window.java @@ -18,6 +18,9 @@ package com.vaadin.ui; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Map; import com.vaadin.event.FieldEvents.BlurEvent; @@ -33,10 +36,12 @@ import com.vaadin.event.ShortcutAction.ModifierKey; import com.vaadin.event.ShortcutListener; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; +import com.vaadin.shared.Connector; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.ui.window.WindowMode; import com.vaadin.shared.ui.window.WindowServerRpc; import com.vaadin.shared.ui.window.WindowState; +import com.vaadin.shared.ui.window.WindowState.WindowRole; import com.vaadin.util.ReflectTools; /** @@ -238,8 +243,6 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, // Don't do anything if not attached to a UI if (uI != null) { - // focus is restored to the parent window - uI.focus(); // window is removed from the UI uI.removeWindow(this); } @@ -644,7 +647,10 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, /** * Sets window modality. When a modal window is open, components outside - * that window it cannot be accessed. + * that window cannot be accessed. + * <p> + * Keyboard navigation is restricted by blocking the tab key at the top and + * bottom of the window by activating the tab stop function internally. * * @param modal * true if modality is to be turned on @@ -1005,4 +1011,194 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, protected WindowState getState(boolean markAsDirty) { return (WindowState) super.getState(markAsDirty); } + + /** + * Allows to specify which components contain the description for the + * window. Text contained in these components will be read by assistive + * devices when it is opened. + * + * @param connectors + * with the components to use as description + */ + public void setAssistiveDescription(Connector... connectors) { + if (connectors == null) { + throw new IllegalArgumentException( + "Parameter connectors must be non-null"); + } else { + getState().contentDescription = connectors; + } + } + + /** + * Gets the components that are used as assistive description. Text + * contained in these components will be read by assistive devices when the + * window is opened. + * + * @return list of previously set components + */ + public List<Connector> getAssistiveDescription() { + return Collections.unmodifiableList(Arrays + .asList(getState().contentDescription)); + } + + /** + * Sets the accessibility prefix for the window caption. + * + * This prefix is read to assistive device users before the window caption, + * but not visible on the page. + * + * @param prefix + * String that is placed before the window caption + */ + public void setAssistivePrefix(String prefix) { + getState().assistivePrefix = prefix; + } + + /** + * Gets the accessibility prefix for the window caption. + * + * This prefix is read to assistive device users before the window caption, + * but not visible on the page. + * + * @return The accessibility prefix + */ + public String getAssistivePrefix() { + return getState().assistivePrefix; + } + + /** + * Sets the accessibility postfix for the window caption. + * + * This postfix is read to assistive device users after the window caption, + * but not visible on the page. + * + * @param prefix + * String that is placed after the window caption + */ + public void setAssistivePostfix(String assistivePostfix) { + getState().assistivePostfix = assistivePostfix; + } + + /** + * Gets the accessibility postfix for the window caption. + * + * This postfix is read to assistive device users after the window caption, + * but not visible on the page. + * + * @return The accessibility postfix + */ + public String getAssistivePostfix() { + return getState().assistivePostfix; + } + + /** + * Sets the WAI-ARIA role the window. + * + * This role defines how an assistive device handles a window. Available + * roles are alertdialog and dialog (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>). + * + * The default role is dialog. + * + * @param role + * WAI-ARIA role to set for the window + */ + public void setAssistiveRole(WindowRole role) { + getState().role = role; + } + + /** + * Gets the WAI-ARIA role the window. + * + * This role defines how an assistive device handles a window. Available + * roles are alertdialog and dialog (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>). + * + * @return WAI-ARIA role set for the window + */ + public WindowRole getAssistiveRole() { + return getState().role; + } + + /** + * Set if it should be prevented to set the focus to a component outside a + * non-modal window with the tab key. + * <p> + * This is meant to help users of assistive devices to not leaving the + * window unintentionally. + * <p> + * For modal windows, this function is activated automatically, while + * preserving the stored value of tabStop. + * + * @param tabStop + * true to keep the focus inside the window when reaching the top + * or bottom, false (default) to allow leaving the window + */ + public void setTabStopEnabled(boolean tabStop) { + getState().assistiveTabStop = tabStop; + } + + /** + * Get if it is prevented to leave a window with the tab key. + * + * @return true when the focus is limited to inside the window, false when + * focus can leave the window + */ + public boolean isTabStopEnabled() { + return getState().assistiveTabStop; + } + + /** + * Sets the message that is provided to users of assistive devices when the + * user reaches the top of the window when leaving a window with the tab key + * is prevented. + * <p> + * This message is not visible on the screen. + * + * @param topMessage + * String provided when the user navigates with Shift-Tab keys to + * the top of the window + */ + public void setTabStopTopAssistiveText(String topMessage) { + getState().assistiveTabStopTopText = topMessage; + } + + /** + * Sets the message that is provided to users of assistive devices when the + * user reaches the bottom of the window when leaving a window with the tab + * key is prevented. + * <p> + * This message is not visible on the screen. + * + * @param bottomMessage + * String provided when the user navigates with the Tab key to + * the bottom of the window + */ + public void setTabStopBottomAssistiveText(String bottomMessage) { + getState().assistiveTabStopBottomText = bottomMessage; + } + + /** + * Gets the message that is provided to users of assistive devices when the + * user reaches the top of the window when leaving a window with the tab key + * is prevented. + * + * @return the top message + */ + public String getTabStopTopAssistiveText() { + return getState().assistiveTabStopTopText; + } + + /** + * Gets the message that is provided to users of assistive devices when the + * user reaches the bottom of the window when leaving a window with the tab + * key is prevented. + * + * @return the bottom message + */ + public String getTabStopBottomAssistiveText() { + return getState().assistiveTabStopBottomText; + } } diff --git a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java index 684ab5d6bc..a6c3bb0b8b 100644 --- a/server/tests/src/com/vaadin/data/util/BeanContainerTest.java +++ b/server/tests/src/com/vaadin/data/util/BeanContainerTest.java @@ -466,6 +466,8 @@ public class BeanContainerTest extends AbstractBeanContainerTest { assertTrue(container .addNestedContainerProperty("address.postalCodeObject")); assertTrue(container.addNestedContainerProperty("address.street")); + // the nested properties added with allowNullBean setting should return + // null assertNull(container.getContainerProperty("John", "address.street") .getValue()); } diff --git a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java index 767a9e2e4d..b9633753b4 100644 --- a/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java +++ b/server/tests/src/com/vaadin/data/util/BeanItemContainerTest.java @@ -10,8 +10,15 @@ import java.util.Map; import junit.framework.Assert; +import org.easymock.Capture; +import org.easymock.EasyMock; + import com.vaadin.data.Container; +import com.vaadin.data.Container.Indexed.ItemAddEvent; +import com.vaadin.data.Container.Indexed.ItemRemoveEvent; +import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Item; +import com.vaadin.data.util.filter.Compare; /** * Test basic functionality of BeanItemContainer. @@ -723,7 +730,186 @@ public class BeanItemContainerTest extends AbstractBeanContainerTest { assertTrue(container .addNestedContainerProperty("address.postalCodeObject")); assertTrue(container.addNestedContainerProperty("address.street")); + // the nested properties should return null assertNull(container.getContainerProperty(john, "address.street") .getValue()); } + + public void testItemAddedEvent() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + ItemSetChangeListener addListener = createListenerMockFor(container); + addListener.containerItemSetChange(EasyMock.isA(ItemAddEvent.class)); + EasyMock.replay(addListener); + + container.addItem(bean); + + EasyMock.verify(addListener); + } + + public void testItemAddedEvent_AddedItem() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + + container.addItem(bean); + + assertEquals(bean, capturedEvent.getValue().getFirstItemId()); + } + + public void testItemAddedEvent_addItemAt_IndexOfAddedItem() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + container.addItem(bean); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + + container.addItemAt(1, new Person("")); + + assertEquals(1, capturedEvent.getValue().getFirstIndex()); + } + + public void testItemAddedEvent_addItemAfter_IndexOfAddedItem() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + container.addItem(bean); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + + container.addItemAfter(bean, new Person("")); + + assertEquals(1, capturedEvent.getValue().getFirstIndex()); + } + + public void testItemAddedEvent_amountOfAddedItems() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + List<Person> beans = Arrays.asList(new Person("Jack"), new Person( + "John")); + + container.addAll(beans); + + assertEquals(2, capturedEvent.getValue().getAddedItemsCount()); + } + + public void testItemAddedEvent_someItemsAreFiltered_amountOfAddedItemsIsReducedByAmountOfFilteredItems() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + List<Person> beans = Arrays.asList(new Person("Jack"), new Person( + "John")); + container.addFilter(new Compare.Equal("name", "John")); + + container.addAll(beans); + + assertEquals(1, capturedEvent.getValue().getAddedItemsCount()); + } + + public void testItemAddedEvent_someItemsAreFiltered_addedItemIsTheFirstVisibleItem() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + List<Person> beans = Arrays.asList(new Person("Jack"), bean); + container.addFilter(new Compare.Equal("name", "John")); + + container.addAll(beans); + + assertEquals(bean, capturedEvent.getValue().getFirstItemId()); + } + + public void testItemRemovedEvent() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + container.addItem(bean); + ItemSetChangeListener removeListener = createListenerMockFor(container); + removeListener.containerItemSetChange(EasyMock + .isA(ItemRemoveEvent.class)); + EasyMock.replay(removeListener); + + container.removeItem(bean); + + EasyMock.verify(removeListener); + } + + public void testItemRemovedEvent_RemovedItem() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + Person bean = new Person("John"); + container.addItem(bean); + ItemSetChangeListener removeListener = createListenerMockFor(container); + Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener); + EasyMock.replay(removeListener); + + container.removeItem(bean); + + assertEquals(bean, capturedEvent.getValue().getFirstItemId()); + } + + public void testItemRemovedEvent_indexOfRemovedItem() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + container.addItem(new Person("Jack")); + Person secondBean = new Person("John"); + container.addItem(secondBean); + ItemSetChangeListener removeListener = createListenerMockFor(container); + Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener); + EasyMock.replay(removeListener); + + container.removeItem(secondBean); + + assertEquals(1, capturedEvent.getValue().getFirstIndex()); + } + + public void testItemRemovedEvent_amountOfRemovedItems() { + BeanItemContainer<Person> container = new BeanItemContainer<Person>( + Person.class); + container.addItem(new Person("Jack")); + container.addItem(new Person("John")); + ItemSetChangeListener removeListener = createListenerMockFor(container); + Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener); + EasyMock.replay(removeListener); + + container.removeAllItems(); + + assertEquals(2, capturedEvent.getValue().getRemovedItemsCount()); + } + + private Capture<ItemAddEvent> captureAddEvent( + ItemSetChangeListener addListener) { + Capture<ItemAddEvent> capturedEvent = new Capture<ItemAddEvent>(); + addListener.containerItemSetChange(EasyMock.capture(capturedEvent)); + return capturedEvent; + } + + private Capture<ItemRemoveEvent> captureRemoveEvent( + ItemSetChangeListener removeListener) { + Capture<ItemRemoveEvent> capturedEvent = new Capture<ItemRemoveEvent>(); + removeListener.containerItemSetChange(EasyMock.capture(capturedEvent)); + return capturedEvent; + } + + private ItemSetChangeListener createListenerMockFor( + BeanItemContainer<Person> container) { + ItemSetChangeListener listener = EasyMock + .createNiceMock(ItemSetChangeListener.class); + container.addItemSetChangeListener(listener); + return listener; + } } diff --git a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java index 09e5a26c15..5da0bdc8a2 100644 --- a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java +++ b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java @@ -4,6 +4,12 @@ import java.util.List; import junit.framework.Assert; +import org.easymock.Capture; +import org.easymock.EasyMock; + +import com.vaadin.data.Container.Indexed.ItemAddEvent; +import com.vaadin.data.Container.Indexed.ItemRemoveEvent; +import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Item; public class TestIndexedContainer extends AbstractInMemoryContainerTest { @@ -271,6 +277,113 @@ public class TestIndexedContainer extends AbstractInMemoryContainerTest { counter.assertNone(); } + public void testItemAddedEvent() { + IndexedContainer container = new IndexedContainer(); + ItemSetChangeListener addListener = createListenerMockFor(container); + addListener.containerItemSetChange(EasyMock.isA(ItemAddEvent.class)); + EasyMock.replay(addListener); + + container.addItem(); + + EasyMock.verify(addListener); + } + + public void testItemAddedEvent_AddedItem() { + IndexedContainer container = new IndexedContainer(); + ItemSetChangeListener addListener = createListenerMockFor(container); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + + Object itemId = container.addItem(); + + assertEquals(itemId, capturedEvent.getValue().getFirstItemId()); + } + + public void testItemAddedEvent_IndexOfAddedItem() { + IndexedContainer container = new IndexedContainer(); + ItemSetChangeListener addListener = createListenerMockFor(container); + container.addItem(); + Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener); + EasyMock.replay(addListener); + + container.addItemAt(1); + + assertEquals(1, capturedEvent.getValue().getFirstIndex()); + } + + public void testItemRemovedEvent() { + IndexedContainer container = new IndexedContainer(); + Object itemId = container.addItem(); + ItemSetChangeListener removeListener = createListenerMockFor(container); + removeListener.containerItemSetChange(EasyMock + .isA(ItemRemoveEvent.class)); + EasyMock.replay(removeListener); + + container.removeItem(itemId); + + EasyMock.verify(removeListener); + } + + public void testItemRemovedEvent_RemovedItem() { + IndexedContainer container = new IndexedContainer(); + Object itemId = container.addItem(); + ItemSetChangeListener removeListener = createListenerMockFor(container); + Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener); + EasyMock.replay(removeListener); + + container.removeItem(itemId); + + assertEquals(itemId, capturedEvent.getValue().getFirstItemId()); + } + + public void testItemRemovedEvent_indexOfRemovedItem() { + IndexedContainer container = new IndexedContainer(); + container.addItem(); + Object secondItemId = container.addItem(); + ItemSetChangeListener removeListener = createListenerMockFor(container); + Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener); + EasyMock.replay(removeListener); + + container.removeItem(secondItemId); + + assertEquals(1, capturedEvent.getValue().getFirstIndex()); + } + + public void testItemRemovedEvent_amountOfRemovedItems() { + IndexedContainer container = new IndexedContainer(); + container.addItem(); + container.addItem(); + ItemSetChangeListener removeListener = createListenerMockFor(container); + Capture<ItemRemoveEvent> capturedEvent = captureRemoveEvent(removeListener); + EasyMock.replay(removeListener); + + container.removeAllItems(); + + assertEquals(2, capturedEvent.getValue().getRemovedItemsCount()); + } + + private Capture<ItemAddEvent> captureAddEvent( + ItemSetChangeListener addListener) { + Capture<ItemAddEvent> capturedEvent = new Capture<ItemAddEvent>(); + addListener.containerItemSetChange(EasyMock.capture(capturedEvent)); + return capturedEvent; + } + + private Capture<ItemRemoveEvent> captureRemoveEvent( + ItemSetChangeListener removeListener) { + Capture<ItemRemoveEvent> capturedEvent = new Capture<ItemRemoveEvent>(); + removeListener.containerItemSetChange(EasyMock.capture(capturedEvent)); + return capturedEvent; + } + + private ItemSetChangeListener createListenerMockFor( + IndexedContainer container) { + ItemSetChangeListener listener = EasyMock + .createNiceMock(ItemSetChangeListener.class); + container.addItemSetChangeListener(listener); + return listener; + } + // Ticket 8028 public void testGetItemIdsRangeIndexOutOfBounds() { IndexedContainer ic = new IndexedContainer(); diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java index 844ef705b1..4c132eba30 100644 --- a/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java +++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java @@ -1917,7 +1917,6 @@ public class SQLContainerTest { EasyMock.expect(delegate.getCountStatement()) .andAnswer(new IAnswer<StatementHelper>() { @Override - @SuppressWarnings("deprecation") public StatementHelper answer() throws Throwable { StatementHelper sh = new StatementHelper(); StringBuffer query = new StringBuffer( @@ -1990,7 +1989,6 @@ public class SQLContainerTest { EasyMock.expect(delegate.getCountStatement()) .andAnswer(new IAnswer<StatementHelper>() { @Override - @SuppressWarnings("deprecation") public StatementHelper answer() throws Throwable { StatementHelper sh = new StatementHelper(); StringBuffer query = new StringBuffer( @@ -2134,7 +2132,6 @@ public class SQLContainerTest { EasyMock.expect(delegate.getCountStatement()) .andAnswer(new IAnswer<StatementHelper>() { @Override - @SuppressWarnings("deprecation") public StatementHelper answer() throws Throwable { StatementHelper sh = new StatementHelper(); StringBuffer query = new StringBuffer( @@ -2213,7 +2210,6 @@ public class SQLContainerTest { EasyMock.expect(delegate.getCountStatement()) .andAnswer(new IAnswer<StatementHelper>() { @Override - @SuppressWarnings("deprecation") public StatementHelper answer() throws Throwable { StatementHelper sh = new StatementHelper(); StringBuffer query = new StringBuffer( @@ -2292,7 +2288,6 @@ public class SQLContainerTest { EasyMock.expect(delegate.getCountStatement()) .andAnswer(new IAnswer<StatementHelper>() { @Override - @SuppressWarnings("deprecation") public StatementHelper answer() throws Throwable { StatementHelper sh = new StatementHelper(); StringBuffer query = new StringBuffer( diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java index 8e8c83d234..110225e206 100644 --- a/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java +++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java @@ -88,7 +88,6 @@ public class TicketTests { EasyMock.expect(delegate.getCountStatement()) .andAnswer(new IAnswer<StatementHelper>() { @Override - @SuppressWarnings("deprecation") public StatementHelper answer() throws Throwable { StatementHelper sh = new StatementHelper(); StringBuffer query = new StringBuffer( diff --git a/server/tests/src/com/vaadin/server/VaadinSessionTest.java b/server/tests/src/com/vaadin/server/VaadinSessionTest.java index 68f198410c..51ae2a2d13 100644 --- a/server/tests/src/com/vaadin/server/VaadinSessionTest.java +++ b/server/tests/src/com/vaadin/server/VaadinSessionTest.java @@ -100,7 +100,7 @@ public class VaadinSessionTest { } }; - ui.doInit(vaadinRequest, session.getNextUIid()); + ui.doInit(vaadinRequest, session.getNextUIid(), null); ui.setSession(session); session.addUI(ui); diff --git a/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java b/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java index 416563baba..034609764f 100644 --- a/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java +++ b/server/tests/src/com/vaadin/tests/data/bean/BeanToValidate.java @@ -4,6 +4,7 @@ import javax.validation.constraints.Digits; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; public class BeanToValidate { @@ -21,6 +22,10 @@ public class BeanToValidate { @Digits(integer = 3, fraction = 2) private String decimals; + @Pattern(regexp = "V*", message = "Must start with letter V") + @Size(min = 3, max = 6, message = "Must contain 3 - 6 letters") + private String nickname; + public String getFirstname() { return firstname; } @@ -53,4 +58,12 @@ public class BeanToValidate { this.decimals = decimals; } + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + } diff --git a/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java b/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java index 93b2273263..575730d946 100644 --- a/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java +++ b/server/tests/src/com/vaadin/tests/data/bean/PersonWithBeanValidationAnnotations.java @@ -8,12 +8,15 @@ import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Past; +import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; public class PersonWithBeanValidationAnnotations { @NotNull @Size(min = 5, max = 20) + @Pattern(regexp = "A.*") private String firstName; + @NotNull private String lastName; diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestDateToSqlDateConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestDateToSqlDateConverter.java index 685404ded6..d591d10e18 100644 --- a/server/tests/src/com/vaadin/tests/data/converter/TestDateToSqlDateConverter.java +++ b/server/tests/src/com/vaadin/tests/data/converter/TestDateToSqlDateConverter.java @@ -19,7 +19,7 @@ public class TestDateToSqlDateConverter extends TestCase { public void testValueConversion() { Date testDate = new Date(100, 0, 1); long time = testDate.getTime(); - assertEquals(testDate, converter.convertToModel(new java.sql.Date(time), - java.sql.Date.class, Locale.ENGLISH)); + assertEquals(testDate, converter.convertToModel( + new java.sql.Date(time), java.sql.Date.class, Locale.ENGLISH)); } } diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigDecimalConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigDecimalConverter.java new file mode 100644 index 0000000000..5db33691b6 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToBigDecimalConverter.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.data.converter; + +import java.math.BigDecimal; +import java.util.Locale; + +import junit.framework.TestCase; + +import com.vaadin.data.util.converter.StringToBigDecimalConverter; + +public class TestStringToBigDecimalConverter extends TestCase { + + StringToBigDecimalConverter converter = new StringToBigDecimalConverter(); + + public void testNullConversion() { + assertEquals(null, + converter.convertToModel(null, BigDecimal.class, null)); + } + + public void testEmptyStringConversion() { + assertEquals(null, converter.convertToModel("", BigDecimal.class, null)); + } + + public void testValueParsing() { + BigDecimal converted = converter.convertToModel("10", BigDecimal.class, + null); + BigDecimal expected = new BigDecimal(10); + assertEquals(expected, converted); + } + + public void testValueFormatting() { + BigDecimal bd = new BigDecimal(12.5); + String expected = "12,5"; + + String converted = converter.convertToPresentation(bd, String.class, + Locale.GERMAN); + assertEquals(expected, converted); + } +} diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToNumberConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToNumberConverter.java deleted file mode 100644 index 66fc4f6532..0000000000 --- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToNumberConverter.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.vaadin.tests.data.converter; - -import junit.framework.TestCase; - -import com.vaadin.data.util.converter.StringToNumberConverter; - -public class TestStringToNumberConverter extends TestCase { - - StringToNumberConverter converter = new StringToNumberConverter(); - - public void testNullConversion() { - assertEquals(null, converter.convertToModel(null, Number.class, null)); - } - - public void testEmptyStringConversion() { - assertEquals(null, converter.convertToModel("", Number.class, null)); - } - - public void testValueConversion() { - assertEquals(Long.valueOf(10), - converter.convertToModel("10", Number.class, null)); - assertEquals(10.5, converter.convertToModel("10.5", Number.class, null)); - } -} diff --git a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java index e5420b8921..0a36c7f7ce 100644 --- a/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java +++ b/server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java @@ -42,6 +42,7 @@ public class TestClassesSerializable extends TestCase { "com\\.vaadin\\.event\\.FieldEvents", // "com\\.vaadin\\.event\\.LayoutEvents", // "com\\.vaadin\\.event\\.MouseEvents", // + "com\\.vaadin\\.event\\.UIEvents", // "com\\.vaadin\\.server\\.VaadinPortlet", // "com\\.vaadin\\.server\\.MockServletConfig", // "com\\.vaadin\\.server\\.MockServletContext", // @@ -49,6 +50,8 @@ public class TestClassesSerializable extends TestCase { "com\\.vaadin\\.server\\.communication\\.FileUploadHandler\\$SimpleMultiPartInputStream", // "com\\.vaadin\\.server\\.communication\\.PushRequestHandler.*", "com\\.vaadin\\.server\\.communication\\.PushHandler.*", // PushHandler + "com\\.vaadin\\.server\\.communication\\.DateSerializer", // + "com\\.vaadin\\.server\\.communication\\.JSONSerializer", // // and its inner classes do not need to be serializable "com\\.vaadin\\.util\\.SerializerHelper", // fully static // class level filtering, also affecting nested classes and diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java index a5e825bddb..85116dd152 100644 --- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java +++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversions.java @@ -205,14 +205,15 @@ public class AbsFieldValueConversions extends TestCase { } + // Now specific to Integer because StringToNumberConverter has been removed public static class NumberBean { - private Number number; + private Integer number; - public Number getNumber() { + public Integer getNumber() { return number; } - public void setNumber(Number number) { + public void setNumber(Integer number) { this.number = number; } @@ -239,7 +240,7 @@ public class AbsFieldValueConversions extends TestCase { tf.setPropertyDataSource(new MethodProperty<Number>(nb, "number")); Converter c2 = tf.getConverter(); assertTrue( - "StringToNumber converter is ok for integer types and should stay even though property is changed", + "StringToInteger converter is ok for integer types and should stay even though property is changed", c1 == c2); assertEquals(490, tf.getPropertyDataSource().getValue()); assertEquals("490", tf.getValue()); diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java b/server/tests/src/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java new file mode 100644 index 0000000000..c4a3d73652 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/abstractselect/OptionGroupTests.java @@ -0,0 +1,32 @@ +package com.vaadin.tests.server.component.abstractselect; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.ui.OptionGroup; + +public class OptionGroupTests { + + private OptionGroup optionGroup; + + @Before + public void setup() { + optionGroup = new OptionGroup(); + } + + @Test + public void itemsAreAdded() { + optionGroup.addItems("foo", "bar"); + + Collection<?> itemIds = optionGroup.getItemIds(); + + assertEquals(2, itemIds.size()); + assertTrue(itemIds.contains("foo")); + assertTrue(itemIds.contains("bar")); + } +} diff --git a/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java b/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java index 3ed79f5010..9bb4c53ba2 100644 --- a/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java +++ b/server/tests/src/com/vaadin/tests/server/component/label/LabelListeners.java @@ -1,5 +1,14 @@ package com.vaadin.tests.server.component.label; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +import org.easymock.EasyMock; + +import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.tests.server.component.AbstractListenerMethodsTest; import com.vaadin.ui.Label; @@ -10,4 +19,74 @@ public class LabelListeners extends AbstractListenerMethodsTest { testListenerAddGetRemove(Label.class, ValueChangeEvent.class, ValueChangeListener.class); } + + public void testValueChangeFiredWhenSettingValue() { + Label underTest = new Label(); + + // setup the mock listener + ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class); + // record + mockListener + .valueChange(anyObject(com.vaadin.data.Property.ValueChangeEvent.class)); + + // test + underTest.addValueChangeListener(mockListener); + + replay(mockListener); + underTest.setValue("A new value"); + + verify(mockListener); + + } + + public void testValueChangeFiredWhenSettingPropertyDataSource() { + // setup + Label underTest = new Label(); + + Property mockProperty = EasyMock.createMock(Property.class); + + ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class); + // record + mockListener + .valueChange(anyObject(com.vaadin.data.Property.ValueChangeEvent.class)); + + expect(mockProperty.getType()).andReturn(String.class).atLeastOnce(); + expect(mockProperty.getValue()).andReturn("Any").atLeastOnce(); + + // test + + replay(mockListener, mockProperty); + underTest.addValueChangeListener(mockListener); + underTest.setPropertyDataSource(mockProperty); + + verify(mockListener); + + } + + public void testValueChangeNotFiredWhenNotSettingValue() { + Label underTest = new Label(); + // setup the mock listener + ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class); + // record: nothing to record + + // test + underTest.addValueChangeListener(mockListener); + replay(mockListener); + verify(mockListener); + } + + public void testNoValueChangeFiredWhenSettingPropertyDataSourceToNull() { + Label underTest = new Label(); + // setup the mock Listener + ValueChangeListener mockListener = createStrictMock(ValueChangeListener.class); + // record: nothing to record + + // test + underTest.addValueChangeListener(mockListener); + underTest.setPropertyDataSource(null); + + replay(mockListener); + verify(mockListener); + } + } diff --git a/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java b/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java index e1d08a989b..832ae14950 100644 --- a/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java +++ b/server/tests/src/com/vaadin/tests/server/validation/TestBeanValidation.java @@ -1,7 +1,6 @@ package com.vaadin.tests.server.validation; -import junit.framework.Assert; - +import org.junit.Assert; import org.junit.Test; import com.vaadin.data.Validator.InvalidValueException; @@ -59,6 +58,33 @@ public class TestBeanValidation { } @Test + public void testBeanValidationException_OneValidationError() { + InvalidValueException[] causes = null; + BeanValidator validator = new BeanValidator(BeanToValidate.class, + "lastname"); + try { + validator.validate(null); + } catch (InvalidValueException e) { + causes = e.getCauses(); + } + + Assert.assertEquals(1, causes.length); + } + + @Test + public void testBeanValidationsException_TwoValidationErrors() { + InvalidValueException[] causes = null; + BeanValidator validator = new BeanValidator(BeanToValidate.class, + "nickname"); + try { + validator.validate("A"); + } catch (InvalidValueException e) { + causes = e.getCauses(); + } + + Assert.assertEquals(2, causes.length); + } + public void testBeanValidationNotAddedTwice() { // See ticket #11045 BeanFieldGroup<BeanToValidate> fieldGroup = new BeanFieldGroup<BeanToValidate>( diff --git a/shared/ivy.xml b/shared/ivy.xml index b4b5878294..3dfe1a51c2 100644 --- a/shared/ivy.xml +++ b/shared/ivy.xml @@ -20,10 +20,18 @@ <artifact type="pom" ext="pom" /> </publications> <dependencies> - <dependency org="com.vaadin" name="vaadin-shared-deps" - rev="1.0.2" conf="build,ide,test->default" /> + <dependency org="com.vaadin.external.flute" name="flute" + rev="1.3.0.gg2" conf="build,ide,test->default" /> + <dependency org="com.vaadin.external.streamhtmlparser" + name="streamhtmlparser-jsilver" rev="0.0.10.vaadin1" + conf="build,ide,test->default" /> + <dependency org="com.vaadin.external.google" name="guava" + rev="16.0.1.vaadin1" conf="build,ide,test->default" /> + <dependency org="com.vaadin.external.google" name="android-json" + rev="0.0.20131108.vaadin1" conf="build,ide,test->default" /> <dependency org="junit" name="junit" rev="4.11" - conf="test,ide -> default" /> + conf="test,ide -> default" /> + </dependencies> </ivy-module> diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java index 4b5dc9140b..d54823ee60 100644 --- a/shared/src/com/vaadin/shared/ApplicationConstants.java +++ b/shared/src/com/vaadin/shared/ApplicationConstants.java @@ -35,6 +35,7 @@ public class ApplicationConstants implements Serializable { public static final String APP_PROTOCOL_PREFIX = "app://"; public static final String VAADIN_PROTOCOL_PREFIX = "vaadin://"; + public static final String FONTICON_PROTOCOL_PREFIX = "fonticon://"; public static final String PUBLISHED_PROTOCOL_NAME = "published"; public static final String PUBLISHED_PROTOCOL_PREFIX = PUBLISHED_PROTOCOL_NAME + "://"; @@ -94,4 +95,26 @@ public class ApplicationConstants implements Serializable { * Name of the parameter used to transmit the CSRF token. */ public static final String CSRF_TOKEN_PARAMETER = "v-csrfToken"; + + /** + * The name of the parameter used to transmit RPC invocations + * + * @since 7.2 + */ + public static final String RPC_INVOCATIONS = "rpc"; + + /** + * The name of the parameter used to transmit the CSRF token + * + * @since 7.2 + */ + public static final String CSRF_TOKEN = "csrfToken"; + + /** + * The name of the parameter used to transmit the sync id + * + * @see com.vaadin.ui.ConnectorTracker#getCurrentSyncId() + * @since 7.2 + */ + public static final String SERVER_SYNC_ID = "syncId"; } diff --git a/shared/src/com/vaadin/shared/EventId.java b/shared/src/com/vaadin/shared/EventId.java index dd30379d41..7cf760b885 100644 --- a/shared/src/com/vaadin/shared/EventId.java +++ b/shared/src/com/vaadin/shared/EventId.java @@ -22,5 +22,7 @@ public interface EventId extends Serializable { public static final String FOCUS = "focus"; public static final String CLICK_EVENT_IDENTIFIER = "click"; public static final String LAYOUT_CLICK_EVENT_IDENTIFIER = "lClick"; + public static final String POLL = "poll"; + public static final String CHANGE = "change"; } diff --git a/shared/src/com/vaadin/shared/Position.java b/shared/src/com/vaadin/shared/Position.java index cd34ee8b87..3df42d65d8 100755 --- a/shared/src/com/vaadin/shared/Position.java +++ b/shared/src/com/vaadin/shared/Position.java @@ -16,5 +16,10 @@ package com.vaadin.shared; public enum Position { - TOP_LEFT, TOP_CENTER, TOP_RIGHT, MIDDLE_LEFT, MIDDLE_CENTER, MIDDLE_RIGHT, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT; + TOP_LEFT, TOP_CENTER, TOP_RIGHT, MIDDLE_LEFT, MIDDLE_CENTER, MIDDLE_RIGHT, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT, + /** + * Position that is only accessible for assistive devices, invisible for + * visual users. + **/ + ASSISTIVE; } diff --git a/shared/src/com/vaadin/shared/ui/link/LinkState.java b/shared/src/com/vaadin/shared/ui/link/LinkState.java index 269496767d..33ede86378 100644 --- a/shared/src/com/vaadin/shared/ui/link/LinkState.java +++ b/shared/src/com/vaadin/shared/ui/link/LinkState.java @@ -16,9 +16,15 @@ package com.vaadin.shared.ui.link; import com.vaadin.shared.AbstractComponentState; +import com.vaadin.shared.ui.BorderStyle; public class LinkState extends AbstractComponentState { { primaryStyleName = "v-link"; } + public String name = ""; + public String target = null; + public BorderStyle targetBorder = BorderStyle.DEFAULT; + public int targetWidth = -1; + public int targetHeight = -1; } diff --git a/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetBaseConstants.java b/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetBaseConstants.java index 7eb23a9887..b7f337a5a8 100644 --- a/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetBaseConstants.java +++ b/shared/src/com/vaadin/shared/ui/tabsheet/TabsheetBaseConstants.java @@ -29,5 +29,7 @@ public class TabsheetBaseConstants implements Serializable { public static final String ATTRIBUTE_TAB_CAPTION = "caption"; @Deprecated public static final String ATTRIBUTE_TAB_ICON = "icon"; + @Deprecated + public static final String ATTRIBUTE_TAB_ICON_ALT = "iconalt"; } diff --git a/shared/src/com/vaadin/shared/ui/ui/NotificationConfigurationBean.java b/shared/src/com/vaadin/shared/ui/ui/NotificationConfigurationBean.java new file mode 100644 index 0000000000..05a1706763 --- /dev/null +++ b/shared/src/com/vaadin/shared/ui/ui/NotificationConfigurationBean.java @@ -0,0 +1,137 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/** + * + */ +package com.vaadin.shared.ui.ui; + +import java.io.Serializable; + +/** + * Holds configuration information for a notification type. + * + * @author Vaadin Ltd + */ +public class NotificationConfigurationBean implements Serializable { + /** + * Available WAI-ARIA roles for a notification. + */ + public enum Role { + ALERT, STATUS + }; + + private String prefix; + private String postfix; + private Role role = Role.ALERT; + + public NotificationConfigurationBean() { + } + + public NotificationConfigurationBean(String prefix, String postfix, + Role role) { + this.prefix = prefix; + this.postfix = postfix; + this.role = role; + } + + /** + * Returns the accessibility prefix, which is placed before the notification + * content. + * + * @return the prefix + */ + public String getAssistivePrefix() { + return prefix; + } + + /** + * Sets the accessibility prefix, which is placed before the notification + * content. + * + * @param pefix + * the prefix to set + */ + public void setAssistivePrefix(String prefix) { + this.prefix = prefix; + } + + /** + * Checks if an accessibility prefix is set. + * + * @return true when assistivePrefix is not null and has a length > 0, false + * otherwise + */ + public boolean hasAssistivePrefix() { + return prefix != null && !prefix.isEmpty(); + } + + /** + * Returns the accessibility postfix, which is placed after the notification + * content. + * + * @return the postfix + */ + public String getAssistivePostfix() { + return postfix; + } + + /** + * Sets the accessibility postfix, which is placed after the notification + * content. + * + * @param postfix + * the postfix to set + */ + public void setAssistivePostfix(String postfix) { + this.postfix = postfix; + } + + /** + * Checks if an accessibility postfix is set. + * + * @return true when postfix is not null and has a length > 0, false + * otherwise + */ + public boolean hasAssistivePostfix() { + return postfix != null && !postfix.isEmpty(); + } + + /** + * Returns the WAI-ARIA role that defines how an assistive device will + * inform the user about a notification. + * + * @return the role + */ + public Role getAssistiveRole() { + return role; + } + + /** + * Sets the WAI-ARIA role that defines how an assistive device will inform + * the user about a notification. + * + * Available roles are alert, alertdialog and status (@see <a + * href="http://www.w3.org/TR/2011/CR-wai-aria-20110118/roles">Roles + * Model</a>). + * + * @param role + * the role to set + */ + public void setAssistiveRole(Role role) { + this.role = role; + } +} diff --git a/shared/src/com/vaadin/shared/ui/ui/PageClientRpc.java b/shared/src/com/vaadin/shared/ui/ui/PageClientRpc.java index eb847bacd0..76a3fbfdb6 100644 --- a/shared/src/com/vaadin/shared/ui/ui/PageClientRpc.java +++ b/shared/src/com/vaadin/shared/ui/ui/PageClientRpc.java @@ -20,8 +20,6 @@ import com.vaadin.shared.communication.ClientRpc; public interface PageClientRpc extends ClientRpc { - public void setTitle(String title); - public void reload(); } diff --git a/shared/src/com/vaadin/shared/ui/ui/PageState.java b/shared/src/com/vaadin/shared/ui/ui/PageState.java index 0b51eb4bba..4d2768787f 100644 --- a/shared/src/com/vaadin/shared/ui/ui/PageState.java +++ b/shared/src/com/vaadin/shared/ui/ui/PageState.java @@ -30,4 +30,9 @@ public class PageState implements Serializable { * True if the page has browser window resize listeners. */ public boolean hasResizeListeners = false; + + /** + * Non-null if the title is set. Null means Vaadin does not touch the title. + */ + public String title = null; }
\ No newline at end of file diff --git a/shared/src/com/vaadin/shared/ui/ui/Transport.java b/shared/src/com/vaadin/shared/ui/ui/Transport.java index ea641c0a3c..ebc0ba3aea 100644 --- a/shared/src/com/vaadin/shared/ui/ui/Transport.java +++ b/shared/src/com/vaadin/shared/ui/ui/Transport.java @@ -30,7 +30,11 @@ public enum Transport { /** * HTTP streaming */ - STREAMING("streaming"); + STREAMING("streaming"), + /** + * HTTP long polling + */ + LONG_POLLING("long-polling"); private String identifier; diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index 8d042a835f..4cde452a2b 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -23,10 +23,12 @@ import java.util.Map; import com.vaadin.shared.communication.PushMode; import com.vaadin.shared.ui.TabIndexState; +import com.vaadin.shared.ui.ui.NotificationConfigurationBean.Role; public class UIState extends TabIndexState { public TooltipConfigurationState tooltipConfiguration = new TooltipConfigurationState(); public LoadingIndicatorConfigurationState loadingIndicatorConfiguration = new LoadingIndicatorConfigurationState(); + public NotificationConfigurationState notificationConfiguration = new NotificationConfigurationState(); public int pollInterval = -1; // Informing users of assistive devices, that the content of this container @@ -48,6 +50,22 @@ public class UIState extends TabIndexState { public int maxWidth = 500; } + public static class NotificationConfigurationState implements Serializable { + public Map<String, NotificationConfigurationBean> setup = new HashMap<String, NotificationConfigurationBean>(); + { + setup.put("error", new NotificationConfigurationBean("Error: ", + " - close with ESC-key", Role.ALERT)); + setup.put("warning", new NotificationConfigurationBean("Warning: ", + null, Role.ALERT)); + setup.put("humanized", new NotificationConfigurationBean("Info: ", + null, Role.ALERT)); + setup.put("tray", new NotificationConfigurationBean("Status: ", + null, Role.STATUS)); + setup.put("assistive", new NotificationConfigurationBean("Note: ", + null, Role.STATUS)); + }; + } + public static class PushConfigurationState implements Serializable { public static final String TRANSPORT_PARAM = "transport"; public static final String FALLBACK_TRANSPORT_PARAM = "fallbackTransport"; diff --git a/shared/src/com/vaadin/shared/ui/upload/UploadServerRpc.java b/shared/src/com/vaadin/shared/ui/upload/UploadServerRpc.java new file mode 100644 index 0000000000..79a6778da3 --- /dev/null +++ b/shared/src/com/vaadin/shared/ui/upload/UploadServerRpc.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.shared.ui.upload; + +import com.vaadin.shared.communication.ServerRpc; + +public interface UploadServerRpc extends ServerRpc { + + /** + * Event sent when the file name of the upload component is changed. + * + * @param filename + * The filename + */ + void change(String filename); + +} diff --git a/shared/src/com/vaadin/shared/ui/window/WindowState.java b/shared/src/com/vaadin/shared/ui/window/WindowState.java index 5a2d2b81b0..3cb6bbe61e 100644 --- a/shared/src/com/vaadin/shared/ui/window/WindowState.java +++ b/shared/src/com/vaadin/shared/ui/window/WindowState.java @@ -15,6 +15,7 @@ */ package com.vaadin.shared.ui.window; +import com.vaadin.shared.Connector; import com.vaadin.shared.ui.panel.PanelState; public class WindowState extends PanelState { @@ -22,6 +23,13 @@ public class WindowState extends PanelState { primaryStyleName = "v-window"; } + /** + * Available WAI-ARIA roles for a window. + */ + public enum WindowRole { + ALERTDIALOG, DIALOG + }; + public boolean modal = false; public boolean resizable = true; public boolean resizeLazy = false; @@ -30,4 +38,12 @@ public class WindowState extends PanelState { public int positionX = -1; public int positionY = -1; public WindowMode windowMode = WindowMode.NORMAL; + + public String assistivePrefix = ""; + public String assistivePostfix = ""; + public Connector[] contentDescription = new Connector[0]; + public WindowRole role = WindowRole.DIALOG; + public boolean assistiveTabStop = false; + public String assistiveTabStopTopText = "Top of dialog"; + public String assistiveTabStopBottomText = "Bottom of Dialog"; }
\ No newline at end of file diff --git a/shared/tests/src/readme.txt b/shared/tests/src/readme.txt new file mode 100644 index 0000000000..0cffbcdcbb --- /dev/null +++ b/shared/tests/src/readme.txt @@ -0,0 +1 @@ +Add tests here. A dummy so that Git creates the directory structure diff --git a/theme-compiler/build.xml b/theme-compiler/build.xml index 576b402ff4..dbdc7e3e80 100644 --- a/theme-compiler/build.xml +++ b/theme-compiler/build.xml @@ -20,8 +20,8 @@ </path> <path id="classpath.test.custom" /> - <!--<property name="classes.exclude" value="com/vaadin/buildhelpers/**" - /> --> + <property name="classes.exclude" value="**/*.properties"/> + <property name="extra.classes" value="${classes.exclude}"/> <target name="parser"> <!-- Copy javacc-5.0.jar to ${result.dir}/javacc/javacc.jar as the diff --git a/theme-compiler/ivy.xml b/theme-compiler/ivy.xml index 7b99b2cdaa..0f84966508 100644 --- a/theme-compiler/ivy.xml +++ b/theme-compiler/ivy.xml @@ -42,6 +42,8 @@ <!-- Testing libs --> <dependency org="junit" name="junit" rev="4.11" conf="ide,test -> default" /> + <dependency org="org.jsoup" name="jsoup" rev="1.6.3" + conf="ide,test -> default" /> <!-- Internally used, for now --> <dependency org="com.carrotsearch" name="smartsprites" diff --git a/theme-compiler/src/com/vaadin/buildhelpers/CompileTheme.java b/theme-compiler/src/com/vaadin/buildhelpers/CompileTheme.java index dece1691f0..11e3b91800 100644 --- a/theme-compiler/src/com/vaadin/buildhelpers/CompileTheme.java +++ b/theme-compiler/src/com/vaadin/buildhelpers/CompileTheme.java @@ -103,11 +103,11 @@ public class CompileTheme { scss.compile(); BufferedWriter out = new BufferedWriter(new FileWriter(stylesCssName)); out.write(cssHeader.toString()); - out.write(scss.toString().replace("@version@", version)); + out.write(scss.printState().replace("@version@", version)); out.close(); System.out.println("Compiled CSS to " + stylesCssName + " (" - + scss.toString().length() + " bytes)"); + + scss.printState().length() + " bytes)"); createSprites(themeFolder, themeName); File oldCss = new File(stylesCssName); diff --git a/theme-compiler/src/com/vaadin/sass/CustomConsoleHandler.java b/theme-compiler/src/com/vaadin/sass/CustomConsoleHandler.java new file mode 100644 index 0000000000..44c9e345db --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/CustomConsoleHandler.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass; + +import java.io.PrintStream; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.LogRecord; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class CustomConsoleHandler extends ConsoleHandler { + + private ConsoleHandler stdoutHandler; + + public CustomConsoleHandler() { + PrintStream err = System.err; + /* + * ConsoleHandler uses System.err to output all messages. Replace + * System.err temporary to construct ConsoleHandler and set it back + * after construction. + */ + System.setErr(System.out); + stdoutHandler = new ConsoleHandler(); + System.setErr(err); + } + + @Override + public void publish(LogRecord record) { + if (!Level.SEVERE.equals(record.getLevel())) { + stdoutHandler.publish(record); + } else { + super.publish(record); + } + } +} diff --git a/theme-compiler/src/com/vaadin/sass/SassCompiler.java b/theme-compiler/src/com/vaadin/sass/SassCompiler.java index 6a83425ca1..b554ce2b01 100644 --- a/theme-compiler/src/com/vaadin/sass/SassCompiler.java +++ b/theme-compiler/src/com/vaadin/sass/SassCompiler.java @@ -56,9 +56,9 @@ public class SassCompiler { scss.compile(); if (output == null) { - System.out.println(scss.toString()); + System.out.println(scss.printState()); } else { - writeFile(output, scss.toString()); + writeFile(output, scss.printState()); } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java b/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java index dbb3e571dc..42325fde29 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java +++ b/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java @@ -19,24 +19,27 @@ package com.vaadin.sass.internal; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.logging.LogManager; import java.util.logging.Logger; import org.w3c.css.sac.CSSException; import org.w3c.css.sac.InputSource; +import com.vaadin.buildhelpers.CompileTheme; import com.vaadin.sass.internal.handler.SCSSDocumentHandler; import com.vaadin.sass.internal.handler.SCSSDocumentHandlerImpl; import com.vaadin.sass.internal.handler.SCSSErrorHandler; import com.vaadin.sass.internal.parser.ParseException; import com.vaadin.sass.internal.parser.Parser; import com.vaadin.sass.internal.parser.SCSSParseException; +import com.vaadin.sass.internal.resolver.ClassloaderResolver; +import com.vaadin.sass.internal.resolver.FilesystemResolver; import com.vaadin.sass.internal.resolver.ScssStylesheetResolver; -import com.vaadin.sass.internal.resolver.VaadinResolver; import com.vaadin.sass.internal.tree.BlockNode; import com.vaadin.sass.internal.tree.MixinDefNode; import com.vaadin.sass.internal.tree.Node; @@ -59,10 +62,12 @@ public class ScssStylesheet extends Node { private static HashMap<Node, Node> lastNodeAdded = new HashMap<Node, Node>(); - private String fileName; + private File file; private String charset; + private List<ScssStylesheetResolver> resolvers = new ArrayList<ScssStylesheetResolver>(); + /** * Read in a file SCSS and parse it into a ScssStylesheet * @@ -76,7 +81,7 @@ public class ScssStylesheet extends Node { /** * Main entry point for the SASS compiler. Takes in a file and builds up a * ScssStylesheet tree out of it. Calling compile() on it will transform - * SASS into CSS. Calling toString() will print out the SCSS/CSS. + * SASS into CSS. Calling printState() will print out the SCSS/CSS. * * @param identifier * The file path. If null then null is returned. @@ -90,18 +95,48 @@ public class ScssStylesheet extends Node { } /** - * Main entry point for the SASS compiler. Takes in a file and encoding then - * builds up a ScssStylesheet tree out of it. Calling compile() on it will - * transform SASS into CSS. Calling toString() will print out the SCSS/CSS. + * Main entry point for the SASS compiler. Takes in a file and an optional + * parent style sheet, then builds up a ScssStylesheet tree out of it. + * Calling compile() on it will transform SASS into CSS. Calling + * printState() will print out the SCSS/CSS. + * + * @param identifier + * The file path. If null then null is returned. + * @param parentStylesheet + * Style sheet from which to inherit resolvers and encoding. May + * be null. + * @return + * @throws CSSException + * @throws IOException + */ + public static ScssStylesheet get(String identifier, + ScssStylesheet parentStylesheet) throws CSSException, IOException { + return get(identifier, parentStylesheet, new SCSSDocumentHandlerImpl(), + new SCSSErrorHandler()); + } + + /** + * Main entry point for the SASS compiler. Takes in a file, an optional + * parent stylesheet, and document and error handlers. Then builds up a + * ScssStylesheet tree out of it. Calling compile() on it will transform + * SASS into CSS. Calling printState() will print out the SCSS/CSS. * * @param identifier * The file path. If null then null is returned. - * @param encoding + * @param parentStylesheet + * Style sheet from which to inherit resolvers and encoding. May + * be null. + * @param documentHandler + * Instance of document handler. May not be null. + * @param errorHandler + * Instance of error handler. May not be null. * @return * @throws CSSException * @throws IOException */ - public static ScssStylesheet get(String identifier, String encoding) + public static ScssStylesheet get(String identifier, + ScssStylesheet parentStylesheet, + SCSSDocumentHandler documentHandler, SCSSErrorHandler errorHandler) throws CSSException, IOException { /* * The encoding to be used is passed through "encoding" parameter. the @@ -120,18 +155,27 @@ public class ScssStylesheet extends Node { File file = new File(identifier); file = file.getCanonicalFile(); - SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl(); - ScssStylesheet stylesheet = handler.getStyleSheet(); - - InputSource source = stylesheet.resolveStylesheet(identifier); + ScssStylesheet stylesheet = documentHandler.getStyleSheet(); + if (parentStylesheet == null) { + // Use default resolvers + stylesheet.addResolver(new FilesystemResolver()); + stylesheet.addResolver(new ClassloaderResolver()); + } else { + // Use parent resolvers + stylesheet.setResolvers(parentStylesheet.getResolvers()); + } + InputSource source = stylesheet.resolveStylesheet(identifier, + parentStylesheet); if (source == null) { return null; } - source.setEncoding(encoding); + if (parentStylesheet != null) { + source.setEncoding(parentStylesheet.getCharset()); + } Parser parser = new Parser(); - parser.setErrorHandler(new SCSSErrorHandler()); - parser.setDocumentHandler(handler); + parser.setErrorHandler(errorHandler); + parser.setDocumentHandler(documentHandler); try { parser.parseStyleSheet(source); @@ -145,24 +189,13 @@ public class ScssStylesheet extends Node { return stylesheet; } - private static ScssStylesheetResolver[] resolvers = null; - - public static void setStylesheetResolvers( - ScssStylesheetResolver... styleSheetResolvers) { - resolvers = Arrays.copyOf(styleSheetResolvers, - styleSheetResolvers.length); - } - - public InputSource resolveStylesheet(String identifier) { - if (resolvers == null) { - setStylesheetResolvers(new VaadinResolver()); - } - - for (ScssStylesheetResolver resolver : resolvers) { - InputSource source = resolver.resolve(identifier); + public InputSource resolveStylesheet(String identifier, + ScssStylesheet parentStylesheet) { + for (ScssStylesheetResolver resolver : getResolvers()) { + InputSource source = resolver.resolve(parentStylesheet, identifier); if (source != null) { File f = new File(source.getURI()); - setFileName(f.getParent()); + setFile(f); return source; } } @@ -171,6 +204,38 @@ public class ScssStylesheet extends Node { } /** + * Retrieves a list of resolvers to use when resolving imports + * + * @since 7.2 + * @return the resolvers used to resolving imports + */ + public List<ScssStylesheetResolver> getResolvers() { + return Collections.unmodifiableList(resolvers); + } + + /** + * Sets the list of resolvers to use when resolving imports + * + * @since 7.2 + * @param resolvers + * the resolvers to set + */ + public void setResolvers(List<ScssStylesheetResolver> resolvers) { + this.resolvers = new ArrayList<ScssStylesheetResolver>(resolvers); + } + + /** + * Adds the given resolver to the resolver list + * + * @since 7.2 + * @param resolver + * The resolver to add + */ + public void addResolver(ScssStylesheetResolver resolver) { + resolvers.add(resolver); + } + + /** * Applies all the visitors and compiles SCSS into Css. * * @throws Exception @@ -214,27 +279,13 @@ public class ScssStylesheet extends Node { * types will implement themselves. */ @Override + public String printState() { + return buildString(PRINT_STRATEGY); + } + + @Override public String toString() { - StringBuilder string = new StringBuilder(""); - String delimeter = "\n\n"; - // add charset declaration, if it is not default "ASCII". - if (!"ASCII".equals(getCharset())) { - string.append("@charset \"").append(getCharset()).append("\";") - .append(delimeter); - } - if (children.size() > 0) { - string.append(children.get(0).toString()); - } - if (children.size() > 1) { - for (int i = 1; i < children.size(); i++) { - String childString = children.get(i).toString(); - if (childString != null) { - string.append(delimeter).append(childString); - } - } - } - String output = string.toString(); - return output; + return "Stylesheet node [" + buildString(TO_STRING_STRATEGY) + "]"; } public void addChild(int index, VariableNode node) { @@ -355,12 +406,28 @@ public class ScssStylesheet extends Node { return mixinDefs.get(name); } - public void setFileName(String fileName) { - this.fileName = fileName; + public void setFile(File file) { + this.file = file; } + /** + * Returns the directory containing this style sheet + * + * @since 7.2 + * @return The directory containing this style sheet + */ + public String getDirectory() { + return file.getParent(); + } + + /** + * Returns the full file name for this style sheet + * + * @since 7.2 + * @return The full file name for this style sheet + */ public String getFileName() { - return fileName; + return file.getPath(); } public static HashMap<Node, Node> getLastNodeAdded() { @@ -378,4 +445,43 @@ public class ScssStylesheet extends Node { public void setCharset(String charset) { this.charset = charset; } + + private String buildString(BuildStringStrategy strategy) { + StringBuilder string = new StringBuilder(""); + String delimeter = "\n\n"; + // add charset declaration, if it is not default "ASCII". + if (!"ASCII".equals(getCharset())) { + string.append("@charset \"").append(getCharset()).append("\";") + .append(delimeter); + } + if (children.size() > 0) { + string.append(strategy.build(children.get(0))); + } + if (children.size() > 1) { + for (int i = 1; i < children.size(); i++) { + String childString = strategy.build(children.get(i)); + if (childString != null) { + string.append(delimeter).append(childString); + } + } + } + String output = string.toString(); + return output; + } + + static { + String logFile = System.getProperty("java.util.logging.config.file"); + if (logFile == null) { + try { + LogManager.getLogManager().readConfiguration( + CompileTheme.class + .getResourceAsStream("/logging.properties")); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } diff --git a/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandlerImpl.java b/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandlerImpl.java index 633ab98b9c..8c09e44f7c 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandlerImpl.java +++ b/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandlerImpl.java @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Stack; +import java.util.logging.Level; +import java.util.logging.Logger; import org.w3c.css.sac.CSSException; import org.w3c.css.sac.InputSource; @@ -98,7 +100,7 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler { public ForNode forDirective(String var, String from, String to, boolean exclusive, String body) { ForNode node = new ForNode(var, from, to, exclusive, body); - System.out.println(node); + log(node); return node; } @@ -126,7 +128,7 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler { @Override public WhileNode whileDirective(String condition, String body) { WhileNode node = new WhileNode(condition, body); - System.out.println(node); + log(node); return node; } @@ -138,14 +140,14 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler { @Override public void ignorableAtRule(String atRule) throws CSSException { - System.out.println("ignorableAtRule(String atRule): " + atRule); + log("ignorableAtRule(String atRule): " + atRule); } @Override public void namespaceDeclaration(String prefix, String uri) throws CSSException { - System.out.println("namespaceDeclaration(String prefix, String uri): " - + prefix + ", " + uri); + log("namespaceDeclaration(String prefix, String uri): " + prefix + ", " + + uri); } @Override @@ -167,14 +169,14 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler { @Override public void startPage(String name, String pseudo_page) throws CSSException { - System.out.println("startPage(String name, String pseudo_page): " - + name + ", " + pseudo_page); + log("startPage(String name, String pseudo_page): " + name + ", " + + pseudo_page); } @Override public void endPage(String name, String pseudo_page) throws CSSException { - System.out.println("endPage(String name, String pseudo_page): " + name - + ", " + pseudo_page); + log("endPage(String name, String pseudo_page): " + name + ", " + + pseudo_page); } @Override @@ -380,4 +382,17 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler { public void endInclude() { nodeStack.pop(); } + + private void log(Object object) { + if (object != null) { + log(object.toString()); + } else { + log(null); + } + } + + private void log(String msg) { + Logger.getLogger(SCSSDocumentHandlerImpl.class.getName()).log( + Level.INFO, msg); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSErrorHandler.java b/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSErrorHandler.java index 2e51c686d4..a7c65073ee 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSErrorHandler.java +++ b/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSErrorHandler.java @@ -15,34 +15,42 @@ */ package com.vaadin.sass.internal.handler; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.w3c.css.sac.CSSException; import org.w3c.css.sac.CSSParseException; import org.w3c.css.sac.ErrorHandler; public class SCSSErrorHandler implements ErrorHandler { + public SCSSErrorHandler() { + } + @Override public void error(CSSParseException arg0) throws CSSException { - System.out.println("Error when parsing file \n" + arg0.getURI() - + " on line " + arg0.getLineNumber() + ", column " - + arg0.getColumnNumber()); - System.out.println(arg0.getMessage() + "\n"); + log("Error when parsing file \n" + arg0.getURI() + " on line " + + arg0.getLineNumber() + ", column " + arg0.getColumnNumber()); + log(arg0.getMessage() + "\n"); } @Override public void fatalError(CSSParseException arg0) throws CSSException { - System.out.println("FATAL Error when parsing file \n" + arg0.getURI() - + " on line " + arg0.getLineNumber() + ", column " - + arg0.getColumnNumber()); - System.out.println(arg0.getMessage() + "\n"); + log("FATAL Error when parsing file \n" + arg0.getURI() + " on line " + + arg0.getLineNumber() + ", column " + arg0.getColumnNumber()); + log(arg0.getMessage() + "\n"); } @Override public void warning(CSSParseException arg0) throws CSSException { - System.out.println("Warning when parsing file \n" + arg0.getURI() - + " on line " + arg0.getLineNumber() + ", column " - + arg0.getColumnNumber()); - System.out.println(arg0.getMessage() + "\n"); + log("Warning when parsing file \n" + arg0.getURI() + " on line " + + arg0.getLineNumber() + ", column " + arg0.getColumnNumber()); + log(arg0.getMessage() + "\n"); + } + + private void log(String msg) { + Logger.getLogger(SCSSDocumentHandlerImpl.class.getName()).log( + Level.SEVERE, msg); } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/LexicalUnitImpl.java b/theme-compiler/src/com/vaadin/sass/internal/parser/LexicalUnitImpl.java index 5035263588..97314c6e8c 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/parser/LexicalUnitImpl.java +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/LexicalUnitImpl.java @@ -24,11 +24,24 @@ package com.vaadin.sass.internal.parser; import java.io.Serializable; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import org.w3c.css.sac.LexicalUnit; import com.vaadin.sass.internal.expression.exception.IncompatibleUnitsException; -import com.vaadin.sass.internal.util.ColorUtil; +import com.vaadin.sass.internal.parser.function.AbsFunctionGenerator; +import com.vaadin.sass.internal.parser.function.CeilFunctionGenerator; +import com.vaadin.sass.internal.parser.function.DarkenFunctionGenerator; +import com.vaadin.sass.internal.parser.function.DefaultFunctionGenerator; +import com.vaadin.sass.internal.parser.function.FloorFunctionGenerator; +import com.vaadin.sass.internal.parser.function.LightenFunctionGenerator; +import com.vaadin.sass.internal.parser.function.RoundFunctionGenerator; +import com.vaadin.sass.internal.parser.function.SCSSFunctionGenerator; +import com.vaadin.sass.internal.tree.Node; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; import com.vaadin.sass.internal.util.DeepCopy; /** @@ -41,6 +54,9 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, Serializable { private static final long serialVersionUID = -6649833716809789399L; + private static int PRECISION = 100000; + private static int PERC_PRECISION_FACTOR = 100 * PRECISION; + LexicalUnitImpl prev; LexicalUnitImpl next; @@ -239,150 +255,33 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, return params; } + /** + * Prints out the current state of the node tree. Will return SCSS before + * compile and CSS after. + * + * Result value could be null. + * + * @since 7.2 + * @return State as a string + */ + public String printState() { + return buildString(Node.PRINT_STRATEGY); + } + @Override public String toString() { - short type = getLexicalUnitType(); - String text = null; - switch (type) { - case SCSS_VARIABLE: - text = "$" + s; - break; - case SCSS_NULL: - text = ""; - break; - case LexicalUnit.SAC_OPERATOR_COMMA: - text = ","; - break; - case LexicalUnit.SAC_OPERATOR_PLUS: - text = "+"; - break; - case LexicalUnit.SAC_OPERATOR_MINUS: - text = "-"; - break; - case LexicalUnit.SAC_OPERATOR_MULTIPLY: - text = "*"; - break; - case LexicalUnit.SAC_OPERATOR_SLASH: - text = "/"; - break; - case LexicalUnit.SAC_OPERATOR_MOD: - text = "%"; - break; - case LexicalUnit.SAC_OPERATOR_EXP: - text = "^"; - break; - case LexicalUnit.SAC_OPERATOR_LT: - text = "<"; - break; - case LexicalUnit.SAC_OPERATOR_GT: - text = ">"; - break; - case LexicalUnit.SAC_OPERATOR_LE: - text = "<="; - break; - case LexicalUnit.SAC_OPERATOR_GE: - text = "=>"; - break; - case LexicalUnit.SAC_OPERATOR_TILDE: - text = "~"; - break; - case LexicalUnit.SAC_INHERIT: - text = "inherit"; - break; - case LexicalUnit.SAC_INTEGER: - text = Integer.toString(getIntegerValue(), 10); - break; - case LexicalUnit.SAC_REAL: - text = getFloatOrInteger(); - break; - case LexicalUnit.SAC_EM: - case SCSSLexicalUnit.SAC_LEM: - case SCSSLexicalUnit.SAC_REM: - case LexicalUnit.SAC_EX: - case LexicalUnit.SAC_PIXEL: - case LexicalUnit.SAC_INCH: - case LexicalUnit.SAC_CENTIMETER: - case LexicalUnit.SAC_MILLIMETER: - case LexicalUnit.SAC_POINT: - case LexicalUnit.SAC_PICA: - case LexicalUnit.SAC_PERCENTAGE: - case LexicalUnit.SAC_DEGREE: - case LexicalUnit.SAC_GRADIAN: - case LexicalUnit.SAC_RADIAN: - case LexicalUnit.SAC_MILLISECOND: - case LexicalUnit.SAC_SECOND: - case LexicalUnit.SAC_HERTZ: - case LexicalUnit.SAC_KILOHERTZ: - case LexicalUnit.SAC_DIMENSION: - text = getFloatOrInteger() + getDimensionUnitText(); - break; - case LexicalUnit.SAC_URI: - text = "url(" + getStringValue() + ")"; - break; - case LexicalUnit.SAC_RGBCOLOR: - case LexicalUnit.SAC_COUNTER_FUNCTION: - case LexicalUnit.SAC_COUNTERS_FUNCTION: - case LexicalUnit.SAC_RECT_FUNCTION: - case LexicalUnit.SAC_FUNCTION: - String funcName = getFunctionName(); - LexicalUnitImpl firstParam = getParameters(); - if ("round".equals(funcName)) { - firstParam - .setFloatValue(Math.round(firstParam.getFloatValue())); - text = firstParam.toString(); - } else if ("ceil".equals(funcName)) { - firstParam.setFloatValue((float) Math.ceil(firstParam - .getFloatValue())); - text = firstParam.toString(); - } else if ("floor".equals(funcName)) { - firstParam.setFloatValue((float) Math.floor(firstParam - .getFloatValue())); - text = firstParam.toString(); - } else if ("abs".equals(funcName)) { - firstParam.setFloatValue(Math.abs(firstParam.getFloatValue())); - text = firstParam.toString(); - } else if ("darken".equals(funcName)) { - LexicalUnitImpl dark = ColorUtil.darken(this); - text = dark.toString(); - } else if ("lighten".equals(funcName)) { - text = ColorUtil.lighten(this).toString(); - } else { - text = getFunctionName() + "(" + getParameters() + ")"; - } - break; - case LexicalUnit.SAC_IDENT: - text = getStringValue(); - break; - case LexicalUnit.SAC_STRING_VALUE: - // @@SEEME. not exact - text = "\"" + getStringValue() + "\""; - break; - case LexicalUnit.SAC_ATTR: - text = "attr(" + getStringValue() + ")"; - break; - case LexicalUnit.SAC_UNICODERANGE: - text = "@@TODO"; - break; - case LexicalUnit.SAC_SUB_EXPRESSION: - text = getSubValues().toString(); - break; - default: - text = "@unknown"; - break; - } - if (getNextLexicalUnit() != null) { - if (getNextLexicalUnit().getLexicalUnitType() == SAC_OPERATOR_COMMA) { - return text + getNextLexicalUnit(); - } - return text + ' ' + getNextLexicalUnit(); + String result = simpleAsString(); + if (result == null) { + return "Lexical unit node [" + buildString(Node.TO_STRING_STRATEGY) + + "]"; } else { - return text; + return result; } } // A helper method for sass interpolation public String unquotedString() { - String result = toString(); + String result = printState(); if (result.length() >= 2 && ((result.charAt(0) == '"' && result .charAt(result.length() - 1) == '"') || (result @@ -398,7 +297,7 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, if (denominator.getLexicalUnitType() != SAC_INTEGER && denominator.getLexicalUnitType() != SAC_REAL && getLexicalUnitType() != denominator.getLexicalUnitType()) { - throw new IncompatibleUnitsException(toString()); + throw new IncompatibleUnitsException(printState()); } setFloatValue(getFloatValue() / denominator.getFloatValue()); if (getLexicalUnitType() == denominator.getLexicalUnitType()) { @@ -435,7 +334,7 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, && another.getLexicalUnitType() != SAC_INTEGER && another.getLexicalUnitType() != SAC_REAL && getLexicalUnitType() != another.getLexicalUnitType()) { - throw new IncompatibleUnitsException(toString()); + throw new IncompatibleUnitsException(printState()); } if (another.getLexicalUnitType() != SAC_INTEGER && another.getLexicalUnitType() != SAC_REAL) { @@ -447,7 +346,7 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, @Override public LexicalUnitImpl modulo(LexicalUnitImpl another) { if (getLexicalUnitType() != another.getLexicalUnitType()) { - throw new IncompatibleUnitsException(toString()); + throw new IncompatibleUnitsException(printState()); } setIntegerValue(getIntegerValue() % another.getIntegerValue()); setNextLexicalUnit(another.getNextLexicalUnit()); @@ -739,13 +638,6 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, previous); } - @Override - public LexicalUnitImpl clone() { - LexicalUnitImpl cloned = new LexicalUnitImpl(type, line, column, prev); - cloned.replaceValue(this); - return cloned; - } - /** * Tries to return the value for this {@link LexicalUnitImpl} without * considering any related units. @@ -764,6 +656,15 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, } } + public String getValueAsString() { + Object value = getValue(); + if (value == null) { + return null; + } else { + return value.toString(); + } + } + public void setFunctionName(String functionName) { fname = functionName; } @@ -785,4 +686,203 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit, } } + + private static SCSSFunctionGenerator getGenerator(String funcName) { + SCSSFunctionGenerator serializer = SERIALIZERS.get(funcName); + if (serializer == null) { + return DEFAULT_SERIALIZER; + } else { + return serializer; + } + } + + private static List<SCSSFunctionGenerator> initSerializers() { + List<SCSSFunctionGenerator> list = new LinkedList<SCSSFunctionGenerator>(); + list.add(new AbsFunctionGenerator()); + list.add(new CeilFunctionGenerator()); + list.add(new DarkenFunctionGenerator()); + list.add(new FloorFunctionGenerator()); + list.add(new LightenFunctionGenerator()); + list.add(new RoundFunctionGenerator()); + list.add(new PercentageFunctionGenerator()); + return list; + } + + private static class PercentageFunctionGenerator implements + SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "percentage"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + StringBuilder builder = new StringBuilder(); + LexicalUnitImpl firstParam = function.getParameters(); + float value = firstParam.getFloatValue(); + value *= PERC_PRECISION_FACTOR; + int intValue = Math.round(value); + value = ((float) intValue) / PRECISION; + + int resultIntValue = (int) value; + + firstParam.type = SAC_PERCENTAGE; + + if (intValue == resultIntValue * PRECISION) { + builder.append(resultIntValue); + firstParam.setIntegerValue(resultIntValue); + } else { + builder.append(value); + firstParam.setFloatValue(value); + } + + firstParam.setStringValue(builder.append('%').toString()); + + return strategy.build(firstParam); + } + + } + + private static final Map<String, SCSSFunctionGenerator> SERIALIZERS = new HashMap<String, SCSSFunctionGenerator>(); + + private static final SCSSFunctionGenerator DEFAULT_SERIALIZER = new DefaultFunctionGenerator(); + + private String simpleAsString() { + short type = getLexicalUnitType(); + String text = null; + switch (type) { + case SCSS_VARIABLE: + text = "$" + s; + break; + case SCSS_NULL: + text = ""; + break; + case LexicalUnit.SAC_OPERATOR_COMMA: + text = ","; + break; + case LexicalUnit.SAC_OPERATOR_PLUS: + text = "+"; + break; + case LexicalUnit.SAC_OPERATOR_MINUS: + text = "-"; + break; + case LexicalUnit.SAC_OPERATOR_MULTIPLY: + text = "*"; + break; + case LexicalUnit.SAC_OPERATOR_SLASH: + text = "/"; + break; + case LexicalUnit.SAC_OPERATOR_MOD: + text = "%"; + break; + case LexicalUnit.SAC_OPERATOR_EXP: + text = "^"; + break; + case LexicalUnit.SAC_OPERATOR_LT: + text = "<"; + break; + case LexicalUnit.SAC_OPERATOR_GT: + text = ">"; + break; + case LexicalUnit.SAC_OPERATOR_LE: + text = "<="; + break; + case LexicalUnit.SAC_OPERATOR_GE: + text = "=>"; + break; + case LexicalUnit.SAC_OPERATOR_TILDE: + text = "~"; + break; + case LexicalUnit.SAC_INHERIT: + text = "inherit"; + break; + case LexicalUnit.SAC_INTEGER: + text = Integer.toString(getIntegerValue(), 10); + break; + case LexicalUnit.SAC_REAL: + text = getFloatOrInteger(); + break; + case LexicalUnit.SAC_EM: + case SCSSLexicalUnit.SAC_LEM: + case SCSSLexicalUnit.SAC_REM: + case LexicalUnit.SAC_EX: + case LexicalUnit.SAC_PIXEL: + case LexicalUnit.SAC_INCH: + case LexicalUnit.SAC_CENTIMETER: + case LexicalUnit.SAC_MILLIMETER: + case LexicalUnit.SAC_POINT: + case LexicalUnit.SAC_PICA: + case LexicalUnit.SAC_PERCENTAGE: + case LexicalUnit.SAC_DEGREE: + case LexicalUnit.SAC_GRADIAN: + case LexicalUnit.SAC_RADIAN: + case LexicalUnit.SAC_MILLISECOND: + case LexicalUnit.SAC_SECOND: + case LexicalUnit.SAC_HERTZ: + case LexicalUnit.SAC_KILOHERTZ: + case LexicalUnit.SAC_DIMENSION: + text = getFloatOrInteger() + getDimensionUnitText(); + break; + } + return text; + } + + private String buildString(BuildStringStrategy strategy) { + short type = getLexicalUnitType(); + String text = simpleAsString(); + if (text == null) { + switch (type) { + case LexicalUnit.SAC_URI: + text = "url(" + getStringValue() + ")"; + break; + case LexicalUnit.SAC_RGBCOLOR: + case LexicalUnit.SAC_COUNTER_FUNCTION: + case LexicalUnit.SAC_COUNTERS_FUNCTION: + case LexicalUnit.SAC_RECT_FUNCTION: + case LexicalUnit.SAC_FUNCTION: + text = buildFunctionString(strategy); + break; + case LexicalUnit.SAC_IDENT: + text = getStringValue(); + break; + case LexicalUnit.SAC_STRING_VALUE: + // @@SEEME. not exact + text = "\"" + getStringValue() + "\""; + break; + case LexicalUnit.SAC_ATTR: + text = "attr(" + getStringValue() + ")"; + break; + case LexicalUnit.SAC_UNICODERANGE: + text = "@@TODO"; + break; + case LexicalUnit.SAC_SUB_EXPRESSION: + text = strategy.build(getSubValues()); + break; + default: + text = "@unknown"; + break; + } + } + if (getNextLexicalUnit() != null) { + if (getNextLexicalUnit().getLexicalUnitType() == SAC_OPERATOR_COMMA) { + return text + strategy.build(getNextLexicalUnit()); + } + return text + ' ' + strategy.build(getNextLexicalUnit()); + } else { + return text; + } + } + + private String buildFunctionString(BuildStringStrategy strategy) { + SCSSFunctionGenerator generator = getGenerator(getFunctionName()); + return generator.printState(this, strategy); + } + + static { + for (SCSSFunctionGenerator serializer : initSerializers()) { + SERIALIZERS.put(serializer.getFunctionName(), serializer); + } + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/LocatorImpl.java b/theme-compiler/src/com/vaadin/sass/internal/parser/LocatorImpl.java index ac244a9582..35589e0a94 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/parser/LocatorImpl.java +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/LocatorImpl.java @@ -23,8 +23,13 @@ */ package com.vaadin.sass.internal.parser; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.w3c.css.sac.Locator; +import com.vaadin.sass.internal.handler.SCSSDocumentHandlerImpl; + /** * @version $Revision: 1.2 $ * @author Philippe Le Hegaret @@ -51,14 +56,17 @@ public class LocatorImpl implements Locator { int line; int column; + @Override public String getURI() { return uri; } + @Override public int getLineNumber() { return line; } + @Override public int getColumnNumber() { return column; } @@ -68,7 +76,7 @@ public class LocatorImpl implements Locator { */ public LocatorImpl(Parser p) { if (W3CDebug) { - System.err.println("LocatorImpl::newLocator(" + p + ");"); + log("LocatorImpl::newLocator(" + p + ");"); } uri = p.source.getURI(); line = p.token.beginLine; @@ -80,8 +88,7 @@ public class LocatorImpl implements Locator { */ public LocatorImpl(Parser p, Token tok) { if (W3CDebug) { - System.err.println("LocatorImpl::newLocator(" + p + ", " + tok - + ");"); + log("LocatorImpl::newLocator(" + p + ", " + tok + ");"); } uri = p.source.getURI(); line = tok.beginLine; @@ -93,8 +100,8 @@ public class LocatorImpl implements Locator { */ public LocatorImpl(Parser p, int line, int column) { if (W3CDebug) { - System.err.println("LocatorImpl::newLocator(" + p + ", " + line - + ", " + column + ");"); + log("LocatorImpl::newLocator(" + p + ", " + line + ", " + column + + ");"); } uri = p.source.getURI(); this.line = line; @@ -106,7 +113,7 @@ public class LocatorImpl implements Locator { */ public LocatorImpl reInit(Parser p) { if (W3CDebug) { - System.err.println("LocatorImpl::reInit(" + p + ");"); + log("LocatorImpl::reInit(" + p + ");"); } uri = p.source.getURI(); line = p.token.beginLine; @@ -119,7 +126,7 @@ public class LocatorImpl implements Locator { */ public LocatorImpl reInit(Parser p, Token tok) { if (W3CDebug) { - System.err.println("LocatorImpl::reInit(" + p + ", " + tok + ");"); + log("LocatorImpl::reInit(" + p + ", " + tok + ");"); } uri = p.source.getURI(); line = tok.beginLine; @@ -132,12 +139,16 @@ public class LocatorImpl implements Locator { */ public LocatorImpl reInit(Parser p, int line, int column) { if (W3CDebug) { - System.err.println("LocatorImpl::reInit(" + p + ", " + line + ", " - + column + ");"); + log("LocatorImpl::reInit(" + p + ", " + line + ", " + column + ");"); } uri = p.source.getURI(); this.line = line; this.column = column; return this; } + + private void log(String msg) { + Logger.getLogger(SCSSDocumentHandlerImpl.class.getName()).log( + Level.SEVERE, msg); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java index bc25042a5c..d1460ea2fc 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java @@ -19,9 +19,12 @@ package com.vaadin.sass.internal.parser; import java.io.*; import java.net.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Locale; import java.util.Map; import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; import org.w3c.css.sac.ConditionFactory; import org.w3c.css.sac.Condition; @@ -559,16 +562,23 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { } jj_consume_token(S); } - jj_consume_token(SEMICOLON); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SEMICOLON: + jj_consume_token(SEMICOLON); + break; + default: + jj_la1[8] = jj_gen; + acceptMissingSemicolon(EOF); + } } catch (ParseException e) { reportError(getLocator(e.currentToken.next), e); - skipStatement(); - // reportWarningSkipText(getLocator(), skipStatement()); + skipStatement(); + // reportWarningSkipText(getLocator(), skipStatement()); } catch (Exception e) { reportError(getLocator(), e); - skipStatement(); - // reportWarningSkipText(getLocator(), skipStatement()); + skipStatement(); + // reportWarningSkipText(getLocator(), skipStatement()); } } @@ -620,7 +630,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { keyframes(); break; default: - jj_la1[8] = jj_gen; + jj_la1[9] = jj_gen; if (jj_2_1(2147483647)) { variable(); } else { @@ -629,7 +639,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { listModifyDirective(); break; default: - jj_la1[9] = jj_gen; + jj_la1[10] = jj_gen; l = getLocator(); ret = skipStatement(); if ((ret == null) || (ret.length() == 0)) { @@ -652,7 +662,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[10] = jj_gen; + jj_la1[11] = jj_gen; break label_8; } ignoreStatement(); @@ -663,7 +673,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[11] = jj_gen; + jj_la1[12] = jj_gen; break label_9; } jj_consume_token(S); @@ -684,7 +694,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { atRuleDeclaration(); break; default: - jj_la1[12] = jj_gen; + jj_la1[13] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -709,7 +719,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[13] = jj_gen; + jj_la1[14] = jj_gen; break label_10; } jj_consume_token(S); @@ -730,7 +740,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { } break; default: - jj_la1[14] = jj_gen; + jj_la1[15] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -741,13 +751,20 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[15] = jj_gen; + jj_la1[16] = jj_gen; break label_11; } jj_consume_token(S); } mediaStatement(ml); - jj_consume_token(SEMICOLON); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SEMICOLON: + jj_consume_token(SEMICOLON); + break; + default: + jj_la1[17] = jj_gen; + acceptMissingSemicolon(RBRACE, EOF); + } label_12: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -755,7 +772,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[16] = jj_gen; + jj_la1[18] = jj_gen; break label_12; } jj_consume_token(S); @@ -790,7 +807,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[17] = jj_gen; + jj_la1[19] = jj_gen; break label_13; } jj_consume_token(S); @@ -808,7 +825,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { animationname += n.image; break; default: - jj_la1[18] = jj_gen; + jj_la1[20] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -818,7 +835,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[19] = jj_gen; + jj_la1[21] = jj_gen; break label_14; } } @@ -829,7 +846,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[20] = jj_gen; + jj_la1[22] = jj_gen; break label_15; } jj_consume_token(S); @@ -843,7 +860,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[21] = jj_gen; + jj_la1[23] = jj_gen; break label_16; } jj_consume_token(S); @@ -858,7 +875,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[22] = jj_gen; + jj_la1[24] = jj_gen; break label_17; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -871,7 +888,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { contentDirective(); break; default: - jj_la1[23] = jj_gen; + jj_la1[25] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -884,7 +901,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[24] = jj_gen; + jj_la1[26] = jj_gen; break label_18; } jj_consume_token(S); @@ -915,7 +932,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { n = jj_consume_token(PERCENTAGE); break; default: - jj_la1[25] = jj_gen; + jj_la1[27] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -927,7 +944,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[26] = jj_gen; + jj_la1[28] = jj_gen; break label_19; } jj_consume_token(S); @@ -939,7 +956,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[27] = jj_gen; + jj_la1[29] = jj_gen; break label_20; } jj_consume_token(COMMA); @@ -950,7 +967,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[28] = jj_gen; + jj_la1[30] = jj_gen; break label_21; } jj_consume_token(S); @@ -966,7 +983,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { n = jj_consume_token(PERCENTAGE); break; default: - jj_la1[29] = jj_gen; + jj_la1[31] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -978,7 +995,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[30] = jj_gen; + jj_la1[32] = jj_gen; break label_22; } jj_consume_token(S); @@ -992,7 +1009,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[31] = jj_gen; + jj_la1[33] = jj_gen; break label_23; } jj_consume_token(S); @@ -1028,7 +1045,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[32] = jj_gen; + jj_la1[34] = jj_gen; break label_24; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1060,7 +1077,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { microsoftExtension(); break; default: - jj_la1[33] = jj_gen; + jj_la1[35] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1073,7 +1090,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[34] = jj_gen; + jj_la1[36] = jj_gen; break label_25; } jj_consume_token(S); @@ -1116,7 +1133,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[35] = jj_gen; + jj_la1[37] = jj_gen; break label_26; } jj_consume_token(S); @@ -1131,7 +1148,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[36] = jj_gen; + jj_la1[38] = jj_gen; break label_27; } jj_consume_token(S); @@ -1158,6 +1175,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { case NONASCII: case DEBUG_SYM: case WARN_SYM: + case CONTENT_SYM: case STRING: case IDENT: case NUMBER: @@ -1177,56 +1195,10 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[37] = jj_gen; + jj_la1[39] = jj_gen; break label_28; } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case DEBUG_SYM: - case WARN_SYM: - debuggingDirective(); - break; - case PLUS: - case PRECEDES: - case SIBLING: - case LBRACKET: - case ANY: - case PARENT: - case DOT: - case COLON: - case INTERPOLATION: - case IDENT: - case HASH: - styleRule(); - break; - case CDO: - case LBRACE: - case DASHMATCH: - case INCLUDES: - case MINUS: - case COMMA: - case SEMICOLON: - case NONASCII: - case STRING: - case NUMBER: - case URL: - case PERCENTAGE: - case IMPORT_SYM: - case MEDIA_SYM: - case CHARSET_SYM: - case PAGE_SYM: - case FONT_FACE_SYM: - case ATKEYWORD: - case IMPORTANT_SYM: - case UNICODERANGE: - case FUNCTION: - case UNKNOWN: - skipUnknownRule(); - break; - default: - jj_la1[38] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } + mediaDirective(); } jj_consume_token(RBRACE); label_29: @@ -1236,7 +1208,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[39] = jj_gen; + jj_la1[40] = jj_gen; break label_29; } jj_consume_token(S); @@ -1248,11 +1220,64 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { } finally { if (start) { - documentHandler.endMedia(ml); + documentHandler.endMedia(ml); } } } + final public void mediaDirective() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case DEBUG_SYM: + case WARN_SYM: + debuggingDirective(); + break; + case PLUS: + case PRECEDES: + case SIBLING: + case LBRACKET: + case ANY: + case PARENT: + case DOT: + case COLON: + case INTERPOLATION: + case IDENT: + case HASH: + styleRule(); + break; + case CDO: + case LBRACE: + case DASHMATCH: + case INCLUDES: + case MINUS: + case COMMA: + case SEMICOLON: + case NONASCII: + case STRING: + case NUMBER: + case URL: + case PERCENTAGE: + case IMPORT_SYM: + case MEDIA_SYM: + case CHARSET_SYM: + case PAGE_SYM: + case FONT_FACE_SYM: + case ATKEYWORD: + case IMPORTANT_SYM: + case UNICODERANGE: + case FUNCTION: + case UNKNOWN: + skipUnknownRule(); + break; + case CONTENT_SYM: + contentDirective(); + break; + default: + jj_la1[41] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } + final public void mediaStatement(MediaListImpl ml) throws ParseException { Token t; t = getToken(1); @@ -1305,7 +1330,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[40] = jj_gen; + jj_la1[42] = jj_gen; break label_30; } jj_consume_token(S); @@ -1320,14 +1345,14 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[41] = jj_gen; + jj_la1[43] = jj_gen; break label_31; } jj_consume_token(S); } break; default: - jj_la1[42] = jj_gen; + jj_la1[44] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1335,7 +1360,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { pseudo = pseudo_page(); break; default: - jj_la1[43] = jj_gen; + jj_la1[45] = jj_gen; ; } if (n != null) { @@ -1349,7 +1374,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[44] = jj_gen; + jj_la1[46] = jj_gen; break label_32; } jj_consume_token(S); @@ -1362,7 +1387,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { declaration(); break; default: - jj_la1[45] = jj_gen; + jj_la1[47] = jj_gen; ; } label_33: @@ -1372,7 +1397,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[46] = jj_gen; + jj_la1[48] = jj_gen; break label_33; } jj_consume_token(SEMICOLON); @@ -1383,7 +1408,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[47] = jj_gen; + jj_la1[49] = jj_gen; break label_34; } jj_consume_token(S); @@ -1394,7 +1419,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { declaration(); break; default: - jj_la1[48] = jj_gen; + jj_la1[50] = jj_gen; ; } } @@ -1406,7 +1431,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[49] = jj_gen; + jj_la1[51] = jj_gen; break label_35; } jj_consume_token(S); @@ -1440,7 +1465,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[50] = jj_gen; + jj_la1[52] = jj_gen; break label_36; } jj_consume_token(S); @@ -1460,7 +1485,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[51] = jj_gen; + jj_la1[53] = jj_gen; break label_37; } jj_consume_token(S); @@ -1473,7 +1498,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[52] = jj_gen; + jj_la1[54] = jj_gen; break label_38; } jj_consume_token(S); @@ -1485,7 +1510,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { declaration(); break; default: - jj_la1[53] = jj_gen; + jj_la1[55] = jj_gen; ; } label_39: @@ -1495,7 +1520,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[54] = jj_gen; + jj_la1[56] = jj_gen; break label_39; } jj_consume_token(SEMICOLON); @@ -1506,7 +1531,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[55] = jj_gen; + jj_la1[57] = jj_gen; break label_40; } jj_consume_token(S); @@ -1517,7 +1542,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { declaration(); break; default: - jj_la1[56] = jj_gen; + jj_la1[58] = jj_gen; ; } } @@ -1529,7 +1554,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { ; break; default: - jj_la1[57] = jj_gen; + jj_la1[59] = jj_gen; break label_41; } jj_consume_token(S); @@ -1631,7 +1656,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants { n = jj_consume_token(UNKNOWN); break; default: - jj_la1[58] = jj_gen; + jj_la1[60] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1665,12 +1690,12 @@ char connector = ' '; connector = combinatorChar(); break; default: - jj_la1[59] = jj_gen; + jj_la1[61] = jj_gen; ; } break; default: - jj_la1[60] = jj_gen; + jj_la1[62] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1692,7 +1717,7 @@ char connector = ' '; t = jj_consume_token(SIBLING); break; default: - jj_la1[61] = jj_gen; + jj_la1[63] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1703,7 +1728,7 @@ char connector = ' '; ; break; default: - jj_la1[62] = jj_gen; + jj_la1[64] = jj_gen; break label_42; } jj_consume_token(S); @@ -1725,7 +1750,7 @@ char connector = ' '; ; break; default: - jj_la1[63] = jj_gen; + jj_la1[65] = jj_gen; break label_43; } jj_consume_token(S); @@ -1781,7 +1806,7 @@ char connector = ' '; { value += n.image; } break; default: - jj_la1[64] = jj_gen; + jj_la1[66] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1800,7 +1825,7 @@ char connector = ' '; ; break; default: - jj_la1[65] = jj_gen; + jj_la1[67] = jj_gen; break label_44; } } @@ -1812,7 +1837,7 @@ char connector = ' '; ; break; default: - jj_la1[66] = jj_gen; + jj_la1[68] = jj_gen; break label_45; } jj_consume_token(S); @@ -1837,7 +1862,7 @@ char connector = ' '; s += t.image; break; default: - jj_la1[67] = jj_gen; + jj_la1[69] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -1847,7 +1872,7 @@ char connector = ' '; ; break; default: - jj_la1[68] = jj_gen; + jj_la1[70] = jj_gen; break label_46; } } @@ -1858,7 +1883,7 @@ char connector = ' '; ; break; default: - jj_la1[69] = jj_gen; + jj_la1[71] = jj_gen; break label_47; } jj_consume_token(S); @@ -1877,7 +1902,7 @@ char connector = ' '; ; break; default: - jj_la1[70] = jj_gen; + jj_la1[72] = jj_gen; break label_48; } jj_consume_token(S); @@ -1896,7 +1921,7 @@ char connector = ' '; ; break; default: - jj_la1[71] = jj_gen; + jj_la1[73] = jj_gen; break label_49; } jj_consume_token(S); @@ -1924,7 +1949,7 @@ char connector = ' '; ; break; default: - jj_la1[72] = jj_gen; + jj_la1[74] = jj_gen; break label_50; } jj_consume_token(S); @@ -1961,7 +1986,7 @@ char connector = ' '; ; break; default: - jj_la1[73] = jj_gen; + jj_la1[75] = jj_gen; break label_51; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -1996,7 +2021,7 @@ char connector = ' '; importDeclaration(); break; default: - jj_la1[74] = jj_gen; + jj_la1[76] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2009,7 +2034,7 @@ char connector = ' '; ; break; default: - jj_la1[75] = jj_gen; + jj_la1[77] = jj_gen; break label_52; } jj_consume_token(S); @@ -2046,7 +2071,7 @@ char connector = ' '; ; break; default: - jj_la1[76] = jj_gen; + jj_la1[78] = jj_gen; break label_53; } jj_consume_token(COMMA); @@ -2057,7 +2082,7 @@ char connector = ' '; ; break; default: - jj_la1[77] = jj_gen; + jj_la1[79] = jj_gen; break label_54; } jj_consume_token(S); @@ -2095,7 +2120,7 @@ char connector = ' '; selector = simple_selector(selector, comb); break; default: - jj_la1[78] = jj_gen; + jj_la1[80] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2116,7 +2141,7 @@ char connector = ' '; ; break; default: - jj_la1[79] = jj_gen; + jj_la1[81] = jj_gen; break label_56; } jj_consume_token(S); @@ -2171,7 +2196,7 @@ char connector = ' '; ; break; default: - jj_la1[80] = jj_gen; + jj_la1[82] = jj_gen; break label_57; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2188,94 +2213,19 @@ char connector = ' '; cond = pseudo(cond); break; default: - jj_la1[81] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - } - break; - case HASH: - cond = hash(cond); - label_58: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case LBRACKET: - case DOT: - case COLON: - ; - break; - default: - jj_la1[82] = jj_gen; - break label_58; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case DOT: - cond = _class(cond); - break; - case LBRACKET: - cond = attrib(cond); - break; - case COLON: - cond = pseudo(cond); - break; - default: jj_la1[83] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } break; + case LBRACKET: case DOT: - cond = _class(cond); - label_59: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case LBRACKET: - case DOT: - case COLON: - case HASH: - ; - break; - default: - jj_la1[84] = jj_gen; - break label_59; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case HASH: - cond = hash(cond); - break; - case DOT: - cond = _class(cond); - break; - case LBRACKET: - cond = attrib(cond); - break; - case COLON: - cond = pseudo(cond); - break; - default: - jj_la1[85] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); - } - } - break; case COLON: - cond = pseudo(cond); - label_60: + case HASH: + label_58: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case LBRACKET: - case DOT: - case COLON: - case HASH: - ; - break; - default: - jj_la1[86] = jj_gen; - break label_60; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case HASH: cond = hash(cond); break; @@ -2289,16 +2239,10 @@ char connector = ' '; cond = pseudo(cond); break; default: - jj_la1[87] = jj_gen; + jj_la1[84] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - } - break; - case LBRACKET: - cond = attrib(cond); - label_61: - while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case LBRACKET: case DOT: @@ -2307,31 +2251,13 @@ char connector = ' '; ; break; default: - jj_la1[88] = jj_gen; - break label_61; - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case HASH: - cond = hash(cond); - break; - case DOT: - cond = _class(cond); - break; - case LBRACKET: - cond = attrib(cond); - break; - case COLON: - cond = pseudo(cond); - break; - default: - jj_la1[89] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[85] = jj_gen; + break label_58; } } break; default: - jj_la1[90] = jj_gen; + jj_la1[86] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2376,7 +2302,7 @@ char connector = ' '; Token t; String s = "."; jj_consume_token(DOT); - label_62: + label_59: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENT: @@ -2388,7 +2314,7 @@ String s = "."; s += t.image; break; default: - jj_la1[91] = jj_gen; + jj_la1[87] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2398,8 +2324,8 @@ String s = "."; ; break; default: - jj_la1[92] = jj_gen; - break label_62; + jj_la1[88] = jj_gen; + break label_59; } } if (pred == null) { @@ -2418,7 +2344,7 @@ String s = "."; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case INTERPOLATION: case IDENT: - label_63: + label_60: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IDENT: @@ -2430,7 +2356,7 @@ String s = "."; s += t.image; break; default: - jj_la1[93] = jj_gen; + jj_la1[89] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2440,8 +2366,8 @@ String s = "."; ; break; default: - jj_la1[94] = jj_gen; - break label_63; + jj_la1[90] = jj_gen; + break label_60; } } {if (true) return s;} @@ -2455,7 +2381,7 @@ String s = "."; {if (true) return "&";} break; default: - jj_la1[95] = jj_gen; + jj_la1[91] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2471,28 +2397,28 @@ String s = "."; Token val = null; String attValue = null; jj_consume_token(LBRACKET); - label_64: + label_61: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[96] = jj_gen; - break label_64; + jj_la1[92] = jj_gen; + break label_61; } jj_consume_token(S); } att = jj_consume_token(IDENT); - label_65: + label_62: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[97] = jj_gen; - break label_65; + jj_la1[93] = jj_gen; + break label_62; } jj_consume_token(S); } @@ -2529,19 +2455,19 @@ String s = "."; cases = 6; break; default: - jj_la1[98] = jj_gen; + jj_la1[94] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - label_66: + label_63: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[99] = jj_gen; - break label_66; + jj_la1[95] = jj_gen; + break label_63; } jj_consume_token(S); } @@ -2555,25 +2481,25 @@ String s = "."; attValue = val.image; break; default: - jj_la1[100] = jj_gen; + jj_la1[96] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - label_67: + label_64: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[101] = jj_gen; - break label_67; + jj_la1[97] = jj_gen; + break label_64; } jj_consume_token(S); } break; default: - jj_la1[102] = jj_gen; + jj_la1[98] = jj_gen; ; } jj_consume_token(RBRACKET); @@ -2629,7 +2555,7 @@ boolean isPseudoElement = false; isPseudoElement=true; break; default: - jj_la1[103] = jj_gen; + jj_la1[99] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -2655,15 +2581,15 @@ boolean isPseudoElement = false; break; case FUNCTION: n = jj_consume_token(FUNCTION); - label_68: + label_65: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[104] = jj_gen; - break label_68; + jj_la1[100] = jj_gen; + break label_65; } jj_consume_token(S); } @@ -2680,7 +2606,7 @@ boolean isPseudoElement = false; } break; default: - jj_la1[105] = jj_gen; + jj_la1[101] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2710,15 +2636,15 @@ boolean isPseudoElement = false; try { name = variableName(); jj_consume_token(COLON); - label_69: + label_66: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[106] = jj_gen; - break label_69; + jj_la1[102] = jj_gen; + break label_66; } jj_consume_token(S); } @@ -2728,33 +2654,10 @@ boolean isPseudoElement = false; guarded = guarded(); break; default: - jj_la1[107] = jj_gen; + jj_la1[103] = jj_gen; ; } - label_70: - while (true) { - jj_consume_token(SEMICOLON); - label_71: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case S: - ; - break; - default: - jj_la1[108] = jj_gen; - break label_71; - } - jj_consume_token(S); - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case SEMICOLON: - ; - break; - default: - jj_la1[109] = jj_gen; - break label_70; - } - } + semicolonTerminator(); exp = replaceNullValues(exp); documentHandler.variable(name, exp, guarded); } catch (JumpException e) { @@ -2810,7 +2713,7 @@ boolean isPseudoElement = false; eachDirective(); break; default: - jj_la1[110] = jj_gen; + jj_la1[104] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2849,7 +2752,7 @@ boolean isPseudoElement = false; keyframes(); break; default: - jj_la1[111] = jj_gen; + jj_la1[105] = jj_gen; if (jj_2_3(2147483647)) { variable(); } else { @@ -2865,7 +2768,7 @@ boolean isPseudoElement = false; atRuleDeclaration(); break; default: - jj_la1[112] = jj_gen; + jj_la1[106] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -2878,7 +2781,7 @@ boolean isPseudoElement = false; String s = null; String evaluator = ""; jj_consume_token(IF_SYM); - label_72: + label_67: while (true) { s = booleanExpressionToken(); evaluator += s; @@ -2904,26 +2807,26 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[113] = jj_gen; - break label_72; + jj_la1[107] = jj_gen; + break label_67; } } jj_consume_token(LBRACE); - label_73: + label_68: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[114] = jj_gen; - break label_73; + jj_la1[108] = jj_gen; + break label_68; } jj_consume_token(S); } documentHandler.startIfElseDirective(); documentHandler.ifDirective(evaluator); - label_74: + label_69: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -2952,8 +2855,8 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[115] = jj_gen; - break label_74; + jj_la1[109] = jj_gen; + break label_69; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -2984,33 +2887,33 @@ boolean isPseudoElement = false; fontFace(); break; default: - jj_la1[116] = jj_gen; + jj_la1[110] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } jj_consume_token(RBRACE); - label_75: + label_70: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[117] = jj_gen; - break label_75; + jj_la1[111] = jj_gen; + break label_70; } jj_consume_token(S); } - label_76: + label_71: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case ELSE_SYM: ; break; default: - jj_la1[118] = jj_gen; - break label_76; + jj_la1[112] = jj_gen; + break label_71; } elseDirective(); } @@ -3022,22 +2925,22 @@ boolean isPseudoElement = false; Token n = null; String s = null; jj_consume_token(ELSE_SYM); - label_77: + label_72: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[119] = jj_gen; - break label_77; + jj_la1[113] = jj_gen; + break label_72; } jj_consume_token(S); } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case IF: jj_consume_token(IF); - label_78: + label_73: while (true) { s = booleanExpressionToken(); evaluator += s; @@ -3063,31 +2966,31 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[120] = jj_gen; - break label_78; + jj_la1[114] = jj_gen; + break label_73; } } break; default: - jj_la1[121] = jj_gen; + jj_la1[115] = jj_gen; ; } jj_consume_token(LBRACE); - label_79: + label_74: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[122] = jj_gen; - break label_79; + jj_la1[116] = jj_gen; + break label_74; } jj_consume_token(S); } if(!evaluator.trim().equals("")){ documentHandler.ifDirective(evaluator); } else{ documentHandler.elseDirective(); } - label_80: + label_75: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3116,8 +3019,8 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[123] = jj_gen; - break label_80; + jj_la1[117] = jj_gen; + break label_75; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3148,21 +3051,21 @@ boolean isPseudoElement = false; fontFace(); break; default: - jj_la1[124] = jj_gen; + jj_la1[118] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } jj_consume_token(RBRACE); - label_81: + label_76: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[125] = jj_gen; - break label_81; + jj_la1[119] = jj_gen; + break label_76; } jj_consume_token(S); } @@ -3227,7 +3130,7 @@ boolean isPseudoElement = false; n = jj_consume_token(NOT_EQ); break; default: - jj_la1[126] = jj_gen; + jj_la1[120] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -3242,41 +3145,41 @@ boolean isPseudoElement = false; ArrayList<String> list = null; String listVariable = null; jj_consume_token(EACH_SYM); - label_82: + label_77: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[127] = jj_gen; - break label_82; + jj_la1[121] = jj_gen; + break label_77; } jj_consume_token(S); } var = jj_consume_token(VARIABLE); - label_83: + label_78: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[128] = jj_gen; - break label_83; + jj_la1[122] = jj_gen; + break label_78; } jj_consume_token(S); } jj_consume_token(EACH_IN); - label_84: + label_79: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[129] = jj_gen; - break label_84; + jj_la1[123] = jj_gen; + break label_79; } jj_consume_token(S); } @@ -3290,24 +3193,24 @@ boolean isPseudoElement = false; documentHandler.startEachDirective(var.image, listVariable); break; default: - jj_la1[130] = jj_gen; + jj_la1[124] = jj_gen; jj_consume_token(-1); throw new ParseException(); } jj_consume_token(LBRACE); - label_85: + label_80: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[131] = jj_gen; - break label_85; + jj_la1[125] = jj_gen; + break label_80; } jj_consume_token(S); } - label_86: + label_81: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3335,21 +3238,21 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[132] = jj_gen; - break label_86; + jj_la1[126] = jj_gen; + break label_81; } ifContentStatement(); } jj_consume_token(RBRACE); - label_87: + label_82: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[133] = jj_gen; - break label_87; + jj_la1[127] = jj_gen; + break label_82; } jj_consume_token(S); } @@ -3360,53 +3263,53 @@ boolean isPseudoElement = false; ArrayList<String > strings = new ArrayList<String >(); Token input; input = jj_consume_token(IDENT); - label_88: + label_83: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[134] = jj_gen; - break label_88; + jj_la1[128] = jj_gen; + break label_83; } jj_consume_token(S); } strings.add(input.image); - label_89: + label_84: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: ; break; default: - jj_la1[135] = jj_gen; - break label_89; + jj_la1[129] = jj_gen; + break label_84; } jj_consume_token(COMMA); - label_90: + label_85: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[136] = jj_gen; - break label_90; + jj_la1[130] = jj_gen; + break label_85; } jj_consume_token(S); } input = jj_consume_token(IDENT); strings.add(input.image); - label_91: + label_86: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[137] = jj_gen; - break label_91; + jj_la1[131] = jj_gen; + break label_86; } jj_consume_token(S); } @@ -3420,15 +3323,15 @@ boolean isPseudoElement = false; ArrayList<VariableNode> args = null; String body; jj_consume_token(MIXIN_SYM); - label_92: + label_87: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[138] = jj_gen; - break label_92; + jj_la1[132] = jj_gen; + break label_87; } jj_consume_token(S); } @@ -3441,39 +3344,39 @@ boolean isPseudoElement = false; name = functionName(); args = arglist(); jj_consume_token(RPARAN); - label_93: + label_88: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[139] = jj_gen; - break label_93; + jj_la1[133] = jj_gen; + break label_88; } jj_consume_token(S); } break; default: - jj_la1[140] = jj_gen; + jj_la1[134] = jj_gen; jj_consume_token(-1); throw new ParseException(); } jj_consume_token(LBRACE); - label_94: + label_89: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[141] = jj_gen; - break label_94; + jj_la1[135] = jj_gen; + break label_89; } jj_consume_token(S); } documentHandler.startMixinDirective(name, args); - label_95: + label_90: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3503,8 +3406,8 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[142] = jj_gen; - break label_95; + jj_la1[136] = jj_gen; + break label_90; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3538,21 +3441,21 @@ boolean isPseudoElement = false; page(); break; default: - jj_la1[143] = jj_gen; + jj_la1[137] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } jj_consume_token(RBRACE); - label_96: + label_91: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[144] = jj_gen; - break label_96; + jj_la1[138] = jj_gen; + break label_91; } jj_consume_token(S); } @@ -3566,26 +3469,26 @@ boolean isPseudoElement = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case VARIABLE: arg = mixinArg(); - label_97: + label_92: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: ; break; default: - jj_la1[145] = jj_gen; - break label_97; + jj_la1[139] = jj_gen; + break label_92; } jj_consume_token(COMMA); - label_98: + label_93: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[146] = jj_gen; - break label_98; + jj_la1[140] = jj_gen; + break label_93; } jj_consume_token(S); } @@ -3595,7 +3498,7 @@ boolean isPseudoElement = false; hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg); break; default: - jj_la1[147] = jj_gen; + jj_la1[141] = jj_gen; ; } {if (true) return args;} @@ -3631,45 +3534,45 @@ boolean isPseudoElement = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COLON: jj_consume_token(COLON); - label_99: + label_94: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[148] = jj_gen; - break label_99; + jj_la1[142] = jj_gen; + break label_94; } jj_consume_token(S); } first = nonVariableTerm(null); prev = first; - label_100: + label_95: while (true) { if (jj_2_5(3)) { ; } else { - break label_100; + break label_95; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: jj_consume_token(COMMA); - label_101: + label_96: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[149] = jj_gen; - break label_101; + jj_la1[143] = jj_gen; + break label_96; } jj_consume_token(S); } break; default: - jj_la1[150] = jj_gen; + jj_la1[144] = jj_gen; ; } prev = nonVariableTerm(prev); @@ -3681,13 +3584,13 @@ boolean isPseudoElement = false; prev, variable.image); break; default: - jj_la1[151] = jj_gen; + jj_la1[145] = jj_gen; jj_consume_token(-1); throw new ParseException(); } break; default: - jj_la1[152] = jj_gen; + jj_la1[146] = jj_gen; ; } VariableNode arg = new VariableNode(name, first, false); @@ -3736,7 +3639,7 @@ boolean isPseudoElement = false; case FUNCTION: first = term(null); args.add(first); prev = first; - label_102: + label_97: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3776,58 +3679,58 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[153] = jj_gen; - break label_102; + jj_la1[147] = jj_gen; + break label_97; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COLON: jj_consume_token(COLON); - label_103: + label_98: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[154] = jj_gen; - break label_103; + jj_la1[148] = jj_gen; + break label_98; } jj_consume_token(S); } break; default: - jj_la1[155] = jj_gen; + jj_la1[149] = jj_gen; ; } next = term(prev); prev.setNextLexicalUnit(next); prev = next; } - label_104: + label_99: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: ; break; default: - jj_la1[156] = jj_gen; - break label_104; + jj_la1[150] = jj_gen; + break label_99; } jj_consume_token(COMMA); - label_105: + label_100: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[157] = jj_gen; - break label_105; + jj_la1[151] = jj_gen; + break label_100; } jj_consume_token(S); } first = term(null); args.add(first); prev = first; - label_106: + label_101: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -3867,27 +3770,27 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[158] = jj_gen; - break label_106; + jj_la1[152] = jj_gen; + break label_101; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COLON: jj_consume_token(COLON); - label_107: + label_102: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[159] = jj_gen; - break label_107; + jj_la1[153] = jj_gen; + break label_102; } jj_consume_token(S); } break; default: - jj_la1[160] = jj_gen; + jj_la1[154] = jj_gen; ; } next = term(prev); @@ -3896,7 +3799,7 @@ boolean isPseudoElement = false; } break; default: - jj_la1[161] = jj_gen; + jj_la1[155] = jj_gen; ; } {if (true) return args;} @@ -3907,15 +3810,15 @@ boolean isPseudoElement = false; String name; ArrayList<LexicalUnitImpl> args=null; jj_consume_token(INCLUDE_SYM); - label_108: + label_103: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[162] = jj_gen; - break label_108; + jj_la1[156] = jj_gen; + break label_103; } jj_consume_token(S); } @@ -3932,21 +3835,21 @@ boolean isPseudoElement = false; name = functionName(); args = argValuelist(); jj_consume_token(RPARAN); - label_109: + label_104: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[163] = jj_gen; - break label_109; + jj_la1[157] = jj_gen; + break label_104; } jj_consume_token(S); } break; default: - jj_la1[164] = jj_gen; + jj_la1[158] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -3955,31 +3858,28 @@ boolean isPseudoElement = false; case LBRACE: includeDirectiveBlockContents(); break; - case SEMICOLON: - includeDirectiveTerminator(); - break; default: - jj_la1[165] = jj_gen; - jj_consume_token(-1); - throw new ParseException(); + jj_la1[159] = jj_gen; + semicolonTerminator(); } documentHandler.endInclude(); } - final public void includeDirectiveTerminator() throws ParseException { - try { - label_110: + final public void semicolonTerminator() throws ParseException { + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SEMICOLON: + label_105: while (true) { jj_consume_token(SEMICOLON); - label_111: + label_106: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[166] = jj_gen; - break label_111; + jj_la1[160] = jj_gen; + break label_106; } jj_consume_token(S); } @@ -3988,30 +3888,45 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[167] = jj_gen; - break label_110; + jj_la1[161] = jj_gen; + break label_105; } } - } catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + break; + default: + jj_la1[162] = jj_gen; + acceptMissingSemicolon(RBRACE, EOF); + } + } + + void acceptMissingSemicolon(Integer... acceptedTerminators) throws ParseException, ParseException { + Token next = getToken(1); + ArrayList<Integer> terminators = new ArrayList<Integer>(Arrays.asList(acceptedTerminators)); + if (!terminators.contains(next.kind)){ + String message = "encountered \u005c"" + next.image + "\u005c". Was expecting one of \u005c";\u005c""; + for(int term : acceptedTerminators){ + message += ", " + tokenImage[term]; + } + ParseException e = new ParseException(message); + throw e; } } final public void includeDirectiveBlockContents() throws ParseException { jj_consume_token(LBRACE); - label_112: + label_107: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[168] = jj_gen; - break label_112; + jj_la1[163] = jj_gen; + break label_107; } jj_consume_token(S); } - label_113: + label_108: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -4033,8 +3948,8 @@ boolean isPseudoElement = false; ; break; default: - jj_la1[169] = jj_gen; - break label_113; + jj_la1[164] = jj_gen; + break label_108; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case PLUS: @@ -4058,21 +3973,21 @@ boolean isPseudoElement = false; keyframeSelector(); break; default: - jj_la1[170] = jj_gen; + jj_la1[165] = jj_gen; jj_consume_token(-1); throw new ParseException(); } } jj_consume_token(RBRACE); - label_114: + label_109: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[171] = jj_gen; - break label_114; + jj_la1[166] = jj_gen; + break label_109; } jj_consume_token(S); } @@ -4095,28 +4010,28 @@ boolean isPseudoElement = false; //refactor, remove those 3 LOOKAHEAD(5). n = jj_consume_token(VARIABLE); variable = n.image; - label_115: + label_110: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[172] = jj_gen; - break label_115; + jj_la1[167] = jj_gen; + break label_110; } jj_consume_token(S); } jj_consume_token(COLON); - label_116: + label_111: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[173] = jj_gen; - break label_116; + jj_la1[168] = jj_gen; + break label_111; } jj_consume_token(S); } @@ -4131,19 +4046,19 @@ boolean isPseudoElement = false; type = jj_consume_token(CONTAINS); break; default: - jj_la1[174] = jj_gen; + jj_la1[169] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - label_117: + label_112: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[175] = jj_gen; - break label_117; + jj_la1[170] = jj_gen; + break label_112; } jj_consume_token(S); } @@ -4153,19 +4068,19 @@ boolean isPseudoElement = false; jj_consume_token(RPARAN); break; default: - jj_la1[176] = jj_gen; + jj_la1[171] = jj_gen; ; } jj_consume_token(COMMA); - label_118: + label_113: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[177] = jj_gen; - break label_118; + jj_la1[172] = jj_gen; + break label_113; } jj_consume_token(S); } @@ -4173,35 +4088,35 @@ boolean isPseudoElement = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: jj_consume_token(COMMA); - label_119: + label_114: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[178] = jj_gen; - break label_119; + jj_la1[173] = jj_gen; + break label_114; } jj_consume_token(S); } n = jj_consume_token(IDENT); separator = n.image; - label_120: + label_115: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[179] = jj_gen; - break label_120; + jj_la1[174] = jj_gen; + break label_115; } jj_consume_token(S); } break; default: - jj_la1[180] = jj_gen; + jj_la1[175] = jj_gen; ; } jj_consume_token(RPARAN); @@ -4221,28 +4136,28 @@ boolean isPseudoElement = false; default: break; } - label_121: + label_116: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[181] = jj_gen; - break label_121; + jj_la1[176] = jj_gen; + break label_116; } jj_consume_token(S); } jj_consume_token(SEMICOLON); - label_122: + label_117: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[182] = jj_gen; - break label_122; + jj_la1[177] = jj_gen; + break label_117; } jj_consume_token(S); } @@ -4259,41 +4174,41 @@ boolean isPseudoElement = false; Token n = null; n = jj_consume_token(VARIABLE); variable = n.image; - label_123: + label_118: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[183] = jj_gen; - break label_123; + jj_la1[178] = jj_gen; + break label_118; } jj_consume_token(S); } jj_consume_token(COLON); - label_124: + label_119: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[184] = jj_gen; - break label_124; + jj_la1[179] = jj_gen; + break label_119; } jj_consume_token(S); } jj_consume_token(APPEND); - label_125: + label_120: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[185] = jj_gen; - break label_125; + jj_la1[180] = jj_gen; + break label_120; } jj_consume_token(S); } @@ -4303,19 +4218,19 @@ boolean isPseudoElement = false; jj_consume_token(RPARAN); break; default: - jj_la1[186] = jj_gen; + jj_la1[181] = jj_gen; ; } jj_consume_token(COMMA); - label_126: + label_121: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[187] = jj_gen; - break label_126; + jj_la1[182] = jj_gen; + break label_121; } jj_consume_token(S); } @@ -4323,35 +4238,35 @@ boolean isPseudoElement = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: jj_consume_token(COMMA); - label_127: + label_122: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[188] = jj_gen; - break label_127; + jj_la1[183] = jj_gen; + break label_122; } jj_consume_token(S); } n = jj_consume_token(IDENT); separator = n.image; - label_128: + label_123: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[189] = jj_gen; - break label_128; + jj_la1[184] = jj_gen; + break label_123; } jj_consume_token(S); } break; default: - jj_la1[190] = jj_gen; + jj_la1[185] = jj_gen; ; } jj_consume_token(RPARAN); @@ -4369,41 +4284,41 @@ boolean isPseudoElement = false; Token n = null; n = jj_consume_token(VARIABLE); variable = n.image; - label_129: + label_124: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[191] = jj_gen; - break label_129; + jj_la1[186] = jj_gen; + break label_124; } jj_consume_token(S); } jj_consume_token(COLON); - label_130: + label_125: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[192] = jj_gen; - break label_130; + jj_la1[187] = jj_gen; + break label_125; } jj_consume_token(S); } jj_consume_token(REMOVE); - label_131: + label_126: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[193] = jj_gen; - break label_131; + jj_la1[188] = jj_gen; + break label_126; } jj_consume_token(S); } @@ -4413,19 +4328,19 @@ boolean isPseudoElement = false; jj_consume_token(RPARAN); break; default: - jj_la1[194] = jj_gen; + jj_la1[189] = jj_gen; ; } jj_consume_token(COMMA); - label_132: + label_127: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[195] = jj_gen; - break label_132; + jj_la1[190] = jj_gen; + break label_127; } jj_consume_token(S); } @@ -4433,35 +4348,35 @@ boolean isPseudoElement = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: jj_consume_token(COMMA); - label_133: + label_128: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[196] = jj_gen; - break label_133; + jj_la1[191] = jj_gen; + break label_128; } jj_consume_token(S); } n = jj_consume_token(IDENT); separator = n.image; - label_134: + label_129: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[197] = jj_gen; - break label_134; + jj_la1[192] = jj_gen; + break label_129; } jj_consume_token(S); } break; default: - jj_la1[198] = jj_gen; + jj_la1[193] = jj_gen; ; } jj_consume_token(RPARAN); @@ -4481,46 +4396,46 @@ boolean isPseudoElement = false; case VARIABLE: n = jj_consume_token(VARIABLE); variable = n.image; - label_135: + label_130: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[199] = jj_gen; - break label_135; + jj_la1[194] = jj_gen; + break label_130; } jj_consume_token(S); } jj_consume_token(COLON); - label_136: + label_131: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[200] = jj_gen; - break label_136; + jj_la1[195] = jj_gen; + break label_131; } jj_consume_token(S); } break; default: - jj_la1[201] = jj_gen; + jj_la1[196] = jj_gen; ; } jj_consume_token(CONTAINS); - label_137: + label_132: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[202] = jj_gen; - break label_137; + jj_la1[197] = jj_gen; + break label_132; } jj_consume_token(S); } @@ -4530,19 +4445,19 @@ boolean isPseudoElement = false; jj_consume_token(RPARAN); break; default: - jj_la1[203] = jj_gen; + jj_la1[198] = jj_gen; ; } jj_consume_token(COMMA); - label_138: + label_133: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[204] = jj_gen; - break label_138; + jj_la1[199] = jj_gen; + break label_133; } jj_consume_token(S); } @@ -4550,35 +4465,35 @@ boolean isPseudoElement = false; switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case COMMA: jj_consume_token(COMMA); - label_139: + label_134: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[205] = jj_gen; - break label_139; + jj_la1[200] = jj_gen; + break label_134; } jj_consume_token(S); } n = jj_consume_token(IDENT); separator = n.image; - label_140: + label_135: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[206] = jj_gen; - break label_140; + jj_la1[201] = jj_gen; + break label_135; } jj_consume_token(S); } break; default: - jj_la1[207] = jj_gen; + jj_la1[202] = jj_gen; ; } jj_consume_token(RPARAN); @@ -4683,7 +4598,7 @@ boolean isPseudoElement = false; warnDirective(); break; default: - jj_la1[208] = jj_gen; + jj_la1[203] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -4693,23 +4608,26 @@ boolean isPseudoElement = false; jj_consume_token(DEBUG_SYM); String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF}); // TODO should evaluate the content expression, call documentHandler.debugDirective() etc. - System.out.println(content); - try { + Logger.getLogger(Parser.class.getName()).log(Level.INFO, content); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SEMICOLON: jj_consume_token(SEMICOLON); - label_141: + label_136: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[209] = jj_gen; - break label_141; + jj_la1[204] = jj_gen; + break label_136; } jj_consume_token(S); } - } catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + break; + default: + jj_la1[205] = jj_gen; + acceptMissingSemicolon(RBRACE, EOF); } } @@ -4717,23 +4635,26 @@ boolean isPseudoElement = false; jj_consume_token(WARN_SYM); String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF}); // TODO should evaluate the content expression, call documentHandler.warnDirective() etc. - System.err.println(content); - try { + Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, content); + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SEMICOLON: jj_consume_token(SEMICOLON); - label_142: + label_137: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[210] = jj_gen; - break label_142; + jj_la1[206] = jj_gen; + break label_137; } jj_consume_token(S); } - } catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + break; + default: + jj_la1[207] = jj_gen; + acceptMissingSemicolon(RBRACE, EOF); } } @@ -4757,20 +4678,20 @@ boolean isPseudoElement = false; exclusive = false; break; default: - jj_la1[211] = jj_gen; + jj_la1[208] = jj_gen; jj_consume_token(-1); throw new ParseException(); } to = skipStatementUntilLeftBrace(); - label_143: + label_138: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[212] = jj_gen; - break label_143; + jj_la1[209] = jj_gen; + break label_138; } jj_consume_token(S); } @@ -4791,91 +4712,56 @@ boolean isPseudoElement = false; final public void extendDirective() throws ParseException { ArrayList<String> list; jj_consume_token(EXTEND_SYM); - label_144: + label_139: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[213] = jj_gen; - break label_144; + jj_la1[210] = jj_gen; + break label_139; } jj_consume_token(S); } list = selectorList(); documentHandler.extendDirective(list); - try { - label_145: - while (true) { - jj_consume_token(SEMICOLON); - label_146: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case S: - ; - break; - default: - jj_la1[214] = jj_gen; - break label_146; - } - jj_consume_token(S); - } - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case SEMICOLON: - ; - break; - default: - jj_la1[215] = jj_gen; - break label_145; - } - } - } catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); - } + semicolonTerminator(); } final public void contentDirective() throws ParseException { jj_consume_token(CONTENT_SYM); - label_147: + label_140: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[216] = jj_gen; - break label_147; + jj_la1[211] = jj_gen; + break label_140; } jj_consume_token(S); } - try { - label_148: + switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case SEMICOLON: + jj_consume_token(SEMICOLON); + label_141: while (true) { - jj_consume_token(SEMICOLON); - label_149: - while (true) { - switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case S: - ; - break; - default: - jj_la1[217] = jj_gen; - break label_149; - } - jj_consume_token(S); - } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { - case SEMICOLON: + case S: ; break; default: - jj_la1[218] = jj_gen; - break label_148; + jj_la1[212] = jj_gen; + break label_141; } + jj_consume_token(S); } - } catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + break; + default: + jj_la1[213] = jj_gen; + acceptMissingSemicolon(RBRACE, EOF); } documentHandler.contentDirective(); } @@ -4901,28 +4787,28 @@ boolean isPseudoElement = false; LexicalUnit exp; name = property(); jj_consume_token(COLON); - label_150: + label_142: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[219] = jj_gen; - break label_150; + jj_la1[214] = jj_gen; + break label_142; } jj_consume_token(S); } jj_consume_token(LBRACE); - label_151: + label_143: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[220] = jj_gen; - break label_151; + jj_la1[215] = jj_gen; + break label_143; } jj_consume_token(S); } @@ -4933,29 +4819,29 @@ LexicalUnit exp; declaration(); break; default: - jj_la1[221] = jj_gen; + jj_la1[216] = jj_gen; ; } - label_152: + label_144: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SEMICOLON: ; break; default: - jj_la1[222] = jj_gen; - break label_152; + jj_la1[217] = jj_gen; + break label_144; } jj_consume_token(SEMICOLON); - label_153: + label_145: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[223] = jj_gen; - break label_153; + jj_la1[218] = jj_gen; + break label_145; } jj_consume_token(S); } @@ -4965,21 +4851,21 @@ LexicalUnit exp; declaration(); break; default: - jj_la1[224] = jj_gen; + jj_la1[219] = jj_gen; ; } } jj_consume_token(RBRACE); documentHandler.endNestedProperties(name); - label_154: + label_146: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[225] = jj_gen; - break label_154; + jj_la1[220] = jj_gen; + break label_146; } jj_consume_token(S); } @@ -4996,7 +4882,7 @@ LexicalUnit exp; debuggingDirective(); break; default: - jj_la1[226] = jj_gen; + jj_la1[221] = jj_gen; if (jj_2_6(2147483647)) { styleRule(); } else if (jj_2_7(3)) { @@ -5017,7 +4903,7 @@ LexicalUnit exp; styleRule(); break; default: - jj_la1[227] = jj_gen; + jj_la1[222] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5062,15 +4948,15 @@ LexicalUnit exp; name = property(); save = token; jj_consume_token(COLON); - label_155: + label_147: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[228] = jj_gen; - break label_155; + jj_la1[223] = jj_gen; + break label_147; } jj_consume_token(S); } @@ -5114,7 +5000,7 @@ LexicalUnit exp; important = prio(); break; default: - jj_la1[229] = jj_gen; + jj_la1[224] = jj_gen; ; } Token next = getToken(1); @@ -5133,15 +5019,15 @@ LexicalUnit exp; break; case LBRACE: jj_consume_token(LBRACE); - label_156: + label_148: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[230] = jj_gen; - break label_156; + jj_la1[225] = jj_gen; + break label_148; } jj_consume_token(S); } @@ -5152,29 +5038,29 @@ LexicalUnit exp; declaration(); break; default: - jj_la1[231] = jj_gen; + jj_la1[226] = jj_gen; ; } - label_157: + label_149: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SEMICOLON: ; break; default: - jj_la1[232] = jj_gen; - break label_157; + jj_la1[227] = jj_gen; + break label_149; } jj_consume_token(SEMICOLON); - label_158: + label_150: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[233] = jj_gen; - break label_158; + jj_la1[228] = jj_gen; + break label_150; } jj_consume_token(S); } @@ -5184,27 +5070,27 @@ LexicalUnit exp; declaration(); break; default: - jj_la1[234] = jj_gen; + jj_la1[229] = jj_gen; ; } } jj_consume_token(RBRACE); - label_159: + label_151: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[235] = jj_gen; - break label_159; + jj_la1[230] = jj_gen; + break label_151; } jj_consume_token(S); } documentHandler.endNestedProperties(name); break; default: - jj_la1[236] = jj_gen; + jj_la1[231] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5254,15 +5140,15 @@ LexicalUnit exp; name = property(); save = token; jj_consume_token(COLON); - label_160: + label_152: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[237] = jj_gen; - break label_160; + jj_la1[232] = jj_gen; + break label_152; } jj_consume_token(S); } @@ -5272,7 +5158,7 @@ LexicalUnit exp; important = prio(); break; default: - jj_la1[238] = jj_gen; + jj_la1[233] = jj_gen; ; } documentHandler.property(name, exp, important); @@ -5315,15 +5201,15 @@ LexicalUnit exp; */ final public boolean prio() throws ParseException { jj_consume_token(IMPORTANT_SYM); - label_161: + label_153: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[239] = jj_gen; - break label_161; + jj_la1[234] = jj_gen; + break label_153; } jj_consume_token(S); } @@ -5333,15 +5219,15 @@ LexicalUnit exp; final public boolean guarded() throws ParseException { jj_consume_token(GUARDED_SYM); - label_162: + label_154: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[240] = jj_gen; - break label_162; + jj_la1[235] = jj_gen; + break label_154; } jj_consume_token(S); } @@ -5366,15 +5252,15 @@ LexicalUnit exp; * 3. parenthesis is not supported now. */ n = jj_consume_token(COMMA); - label_163: + label_155: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[241] = jj_gen; - break label_163; + jj_la1[236] = jj_gen; + break label_155; } jj_consume_token(S); } @@ -5384,15 +5270,15 @@ LexicalUnit exp; break; case DIV: n = jj_consume_token(DIV); - label_164: + label_156: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[242] = jj_gen; - break label_164; + jj_la1[237] = jj_gen; + break label_156; } jj_consume_token(S); } @@ -5402,15 +5288,15 @@ LexicalUnit exp; break; case ANY: n = jj_consume_token(ANY); - label_165: + label_157: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[243] = jj_gen; - break label_165; + jj_la1[238] = jj_gen; + break label_157; } jj_consume_token(S); } @@ -5420,15 +5306,15 @@ LexicalUnit exp; break; case MOD: n = jj_consume_token(MOD); - label_166: + label_158: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[244] = jj_gen; - break label_166; + jj_la1[239] = jj_gen; + break label_158; } jj_consume_token(S); } @@ -5438,7 +5324,7 @@ LexicalUnit exp; break; case PLUS: n = jj_consume_token(PLUS); - label_167: + label_159: while (true) { jj_consume_token(S); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -5446,8 +5332,8 @@ LexicalUnit exp; ; break; default: - jj_la1[245] = jj_gen; - break label_167; + jj_la1[240] = jj_gen; + break label_159; } } {if (true) return LexicalUnitImpl.createAdd(n.beginLine, @@ -5456,7 +5342,7 @@ LexicalUnit exp; break; case MINUS: n = jj_consume_token(MINUS); - label_168: + label_160: while (true) { jj_consume_token(S); switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -5464,8 +5350,8 @@ LexicalUnit exp; ; break; default: - jj_la1[246] = jj_gen; - break label_168; + jj_la1[241] = jj_gen; + break label_160; } } {if (true) return LexicalUnitImpl.createMinus(n.beginLine, @@ -5473,7 +5359,7 @@ LexicalUnit exp; prev);} break; default: - jj_la1[247] = jj_gen; + jj_la1[242] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5488,12 +5374,12 @@ LexicalUnit exp; char op; first = term(null); res = first; - label_169: + label_161: while (true) { if (jj_2_8(2)) { ; } else { - break label_169; + break label_161; } if (jj_2_9(2)) { res = operator(res); @@ -5520,7 +5406,7 @@ LexicalUnit exp; {if (true) return '+';} break; default: - jj_la1[248] = jj_gen; + jj_la1[243] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5573,7 +5459,7 @@ LexicalUnit exp; result = variableTerm(prev); break; default: - jj_la1[249] = jj_gen; + jj_la1[244] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5626,7 +5512,7 @@ LexicalUnitImpl result = null; op = unaryOperator(); break; default: - jj_la1[250] = jj_gen; + jj_la1[245] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -5742,7 +5628,7 @@ LexicalUnitImpl result = null; result = function(op, prev); break; default: - jj_la1[251] = jj_gen; + jj_la1[246] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5775,7 +5661,7 @@ LexicalUnitImpl result = null; s+="."; break; default: - jj_la1[252] = jj_gen; + jj_la1[247] = jj_gen; ; } switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { @@ -5792,7 +5678,7 @@ LexicalUnitImpl result = null; n = jj_consume_token(FROM); break; default: - jj_la1[253] = jj_gen; + jj_la1[248] = jj_gen; jj_consume_token(-1); throw new ParseException(); } @@ -5839,25 +5725,25 @@ LexicalUnitImpl result = null; result = unicode(prev); break; default: - jj_la1[254] = jj_gen; + jj_la1[249] = jj_gen; jj_consume_token(-1); throw new ParseException(); } break; default: - jj_la1[255] = jj_gen; + jj_la1[250] = jj_gen; jj_consume_token(-1); throw new ParseException(); } - label_170: + label_162: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[256] = jj_gen; - break label_170; + jj_la1[251] = jj_gen; + break label_162; } jj_consume_token(S); } @@ -5873,15 +5759,15 @@ LexicalUnitImpl result = null; Token n; LexicalUnit params = null; n = jj_consume_token(FUNCTION); - label_171: + label_163: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[257] = jj_gen; - break label_171; + jj_la1[252] = jj_gen; + break label_163; } jj_consume_token(S); } @@ -5932,7 +5818,7 @@ LexicalUnitImpl result = null; params = expr(); break; default: - jj_la1[258] = jj_gen; + jj_la1[253] = jj_gen; ; } jj_consume_token(RPARAN); @@ -5946,12 +5832,15 @@ LexicalUnitImpl result = null; if ("rgb(".equals(f)) { // this is a RGB declaration (e.g. rgb(255, 50%, 0) ) int i = 0; + boolean hasVariables = false; while (loop && l != null && i < 5) { switch (i) { case 0: case 2: case 4: - if ((l.getLexicalUnitType() != LexicalUnit.SAC_INTEGER) + if (l.getLexicalUnitType() == SCSSLexicalUnit.SCSS_VARIABLE) { + hasVariables = true; + } else if ((l.getLexicalUnitType() != LexicalUnit.SAC_INTEGER) && (l.getLexicalUnitType() != LexicalUnit.SAC_PERCENTAGE)) { loop = false; } @@ -5971,9 +5860,15 @@ LexicalUnitImpl result = null; } } if ((i == 5) && loop && (l == null)) { - {if (true) return LexicalUnitImpl.createRGBColor(n.beginLine, - n.beginColumn, - prev, params);} + if (hasVariables) { + {if (true) return LexicalUnitImpl.createFunction(n.beginLine, + n.beginColumn, prev, + f.substring(0, f.length() - 1), params);} + } else { + {if (true) return LexicalUnitImpl.createRGBColor(n.beginLine, + n.beginColumn, + prev, params);} + } } else { if (errorHandler != null) { String errorText; @@ -6415,15 +6310,15 @@ LexicalUnitImpl result = null; // TODO required by original parser but not used by Vaadin? final public void _parseRule() throws ParseException { String ret = null; - label_172: + label_164: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[259] = jj_gen; - break label_172; + jj_la1[254] = jj_gen; + break label_164; } jj_consume_token(S); } @@ -6458,7 +6353,7 @@ LexicalUnitImpl result = null; fontFace(); break; default: - jj_la1[260] = jj_gen; + jj_la1[255] = jj_gen; ret = skipStatement(); if ((ret == null) || (ret.length() == 0)) { {if (true) return;} @@ -6473,15 +6368,15 @@ LexicalUnitImpl result = null; } final public void _parseImportRule() throws ParseException { - label_173: + label_165: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[261] = jj_gen; - break label_173; + jj_la1[256] = jj_gen; + break label_165; } jj_consume_token(S); } @@ -6489,15 +6384,15 @@ LexicalUnitImpl result = null; } final public void _parseMediaRule() throws ParseException { - label_174: + label_166: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[262] = jj_gen; - break label_174; + jj_la1[257] = jj_gen; + break label_166; } jj_consume_token(S); } @@ -6505,15 +6400,15 @@ LexicalUnitImpl result = null; } final public void _parseDeclarationBlock() throws ParseException { - label_175: + label_167: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[263] = jj_gen; - break label_175; + jj_la1[258] = jj_gen; + break label_167; } jj_consume_token(S); } @@ -6523,29 +6418,29 @@ LexicalUnitImpl result = null; declaration(); break; default: - jj_la1[264] = jj_gen; + jj_la1[259] = jj_gen; ; } - label_176: + label_168: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case SEMICOLON: ; break; default: - jj_la1[265] = jj_gen; - break label_176; + jj_la1[260] = jj_gen; + break label_168; } jj_consume_token(SEMICOLON); - label_177: + label_169: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[266] = jj_gen; - break label_177; + jj_la1[261] = jj_gen; + break label_169; } jj_consume_token(S); } @@ -6555,7 +6450,7 @@ LexicalUnitImpl result = null; declaration(); break; default: - jj_la1[267] = jj_gen; + jj_la1[262] = jj_gen; ; } } @@ -6564,15 +6459,15 @@ LexicalUnitImpl result = null; final public ArrayList<String> _parseSelectors() throws ParseException { ArrayList<String> p = null; try { - label_178: + label_170: while (true) { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { case S: ; break; default: - jj_la1[268] = jj_gen; - break label_178; + jj_la1[263] = jj_gen; + break label_170; } jj_consume_token(S); } @@ -6584,13 +6479,6 @@ LexicalUnitImpl result = null; throw new Error("Missing return statement in function"); } - void acceptMissingSemicolonBeforeRbrace(ParseException parseException) throws ParseException { - Token next = getToken(1); - if (next.kind != RBRACE && next.kind!=EOF) { - throw parseException; - } - } - private boolean jj_2_1(int xla) { jj_la = xla; jj_lastpos = jj_scanpos = token; try { return !jj_3_1(); } @@ -6654,25 +6542,10 @@ LexicalUnitImpl result = null; finally { jj_save(8, xla); } } - private boolean jj_3R_200() { - if (jj_scan_token(VARIABLE)) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_scan_token(1)) { jj_scanpos = xsp; break; } - } - if (jj_scan_token(COLON)) return true; - while (true) { - xsp = jj_scanpos; - if (jj_scan_token(1)) { jj_scanpos = xsp; break; } - } - return false; - } - - private boolean jj_3R_182() { + private boolean jj_3R_174() { Token xsp; xsp = jj_scanpos; - if (jj_3R_200()) jj_scanpos = xsp; + if (jj_3R_189()) jj_scanpos = xsp; if (jj_scan_token(CONTAINS)) return true; while (true) { xsp = jj_scanpos; @@ -6682,12 +6555,12 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_218() { - if (jj_3R_217()) return true; + private boolean jj_3R_209() { + if (jj_3R_208()) return true; return false; } - private boolean jj_3R_217() { + private boolean jj_3R_208() { Token xsp; xsp = jj_scanpos; if (jj_scan_token(18)) { @@ -6704,64 +6577,55 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_179() { - if (jj_3R_189()) return true; - if (jj_scan_token(COLON)) return true; + private boolean jj_3R_186() { + if (jj_scan_token(S)) return true; Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_scan_token(1)) { jj_scanpos = xsp; break; } - } - if (jj_3R_190()) return true; xsp = jj_scanpos; - if (jj_3R_191()) jj_scanpos = xsp; - if (jj_3R_192()) return true; - while (true) { - xsp = jj_scanpos; - if (jj_3R_192()) { jj_scanpos = xsp; break; } - } + if (jj_3R_209()) jj_scanpos = xsp; return false; } - private boolean jj_3R_194() { - if (jj_scan_token(S)) return true; + private boolean jj_3R_171() { + if (jj_3R_181()) return true; + if (jj_scan_token(COLON)) return true; Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_scan_token(1)) { jj_scanpos = xsp; break; } + } + if (jj_3R_182()) return true; xsp = jj_scanpos; - if (jj_3R_218()) jj_scanpos = xsp; + if (jj_3R_183()) jj_scanpos = xsp; + if (jj_3R_184()) return true; return false; } - private boolean jj_3R_193() { - if (jj_3R_217()) return true; + private boolean jj_3R_185() { + if (jj_3R_208()) return true; return false; } - private boolean jj_3R_180() { + private boolean jj_3R_172() { Token xsp; xsp = jj_scanpos; - if (jj_3R_193()) { + if (jj_3R_185()) { jj_scanpos = xsp; - if (jj_3R_194()) return true; + if (jj_3R_186()) return true; } return false; } - private boolean jj_3R_220() { + private boolean jj_3R_260() { if (jj_scan_token(HASH)) return true; return false; } - private boolean jj_3_7() { - if (jj_3R_186()) return true; - return false; - } - - private boolean jj_3R_290() { + private boolean jj_3R_277() { if (jj_scan_token(IDENT)) return true; return false; } - private boolean jj_3R_291() { + private boolean jj_3R_278() { if (jj_scan_token(FUNCTION)) return true; Token xsp; while (true) { @@ -6772,42 +6636,47 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_207() { - if (jj_scan_token(LBRACE)) return true; + private boolean jj_3_7() { + if (jj_3R_178()) return true; return false; } - private boolean jj_3R_289() { - if (jj_scan_token(COLON)) return true; + private boolean jj_3R_196() { + if (jj_scan_token(LBRACE)) return true; return false; } - private boolean jj_3R_206() { - if (jj_3R_190()) return true; + private boolean jj_3R_276() { + if (jj_scan_token(COLON)) return true; return false; } - private boolean jj_3R_222() { + private boolean jj_3R_263() { if (jj_scan_token(COLON)) return true; Token xsp; xsp = jj_scanpos; - if (jj_3R_289()) jj_scanpos = xsp; + if (jj_3R_276()) jj_scanpos = xsp; xsp = jj_scanpos; - if (jj_3R_290()) { + if (jj_3R_277()) { jj_scanpos = xsp; - if (jj_3R_291()) return true; + if (jj_3R_278()) return true; } return false; } + private boolean jj_3R_195() { + if (jj_3R_182()) return true; + return false; + } + private boolean jj_3_6() { - if (jj_3R_185()) return true; + if (jj_3R_177()) return true; if (jj_scan_token(LBRACE)) return true; return false; } - private boolean jj_3R_186() { - if (jj_3R_205()) return true; + private boolean jj_3R_178() { + if (jj_3R_194()) return true; if (jj_scan_token(COLON)) return true; Token xsp; while (true) { @@ -6815,105 +6684,140 @@ LexicalUnitImpl result = null; if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } xsp = jj_scanpos; - if (jj_3R_206()) { + if (jj_3R_195()) { jj_scanpos = xsp; - if (jj_3R_207()) return true; + if (jj_3R_196()) return true; } return false; } - private boolean jj_3R_269() { - if (jj_3R_190()) return true; + private boolean jj_3R_266() { + if (jj_3R_182()) return true; return false; } - private boolean jj_3R_259() { - if (jj_scan_token(FUNCTION)) return true; + private boolean jj_3R_207() { + if (true) { jj_la = 0; jj_scanpos = jj_lastpos; return false;} + return false; + } + + private boolean jj_3R_243() { + if (jj_scan_token(SEMICOLON)) return true; Token xsp; while (true) { xsp = jj_scanpos; if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } - xsp = jj_scanpos; - if (jj_3R_269()) jj_scanpos = xsp; - if (jj_scan_token(RPARAN)) return true; return false; } - private boolean jj_3R_250() { - if (jj_3R_263()) return true; + private boolean jj_3R_252() { + if (jj_scan_token(FUNCTION)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_scan_token(1)) { jj_scanpos = xsp; break; } + } + xsp = jj_scanpos; + if (jj_3R_266()) jj_scanpos = xsp; + if (jj_scan_token(RPARAN)) return true; return false; } - private boolean jj_3R_249() { - if (jj_3R_262()) return true; + private boolean jj_3R_206() { + Token xsp; + if (jj_3R_243()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_243()) { jj_scanpos = xsp; break; } + } return false; } - private boolean jj_3R_248() { - if (jj_3R_261()) return true; + private boolean jj_3R_184() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_206()) { + jj_scanpos = xsp; + if (jj_3R_207()) return true; + } return false; } - private boolean jj_3R_310() { + private boolean jj_3R_288() { if (jj_scan_token(STRING)) return true; return false; } - private boolean jj_3R_308() { + private boolean jj_3R_286() { if (jj_scan_token(STARMATCH)) return true; return false; } - private boolean jj_3R_309() { + private boolean jj_3R_287() { if (jj_scan_token(IDENT)) return true; return false; } - private boolean jj_3R_307() { + private boolean jj_3R_285() { if (jj_scan_token(DOLLARMATCH)) return true; return false; } - private boolean jj_3R_306() { + private boolean jj_3R_238() { + if (jj_3R_256()) return true; + return false; + } + + private boolean jj_3R_284() { if (jj_scan_token(CARETMATCH)) return true; return false; } - private boolean jj_3R_305() { + private boolean jj_3R_237() { + if (jj_3R_255()) return true; + return false; + } + + private boolean jj_3R_283() { if (jj_scan_token(DASHMATCH)) return true; return false; } - private boolean jj_3R_304() { + private boolean jj_3R_236() { + if (jj_3R_254()) return true; + return false; + } + + private boolean jj_3R_282() { if (jj_scan_token(INCLUDES)) return true; return false; } - private boolean jj_3R_271() { + private boolean jj_3R_268() { if (jj_scan_token(INTERPOLATION)) return true; return false; } - private boolean jj_3R_303() { + private boolean jj_3R_281() { if (jj_scan_token(EQ)) return true; return false; } - private boolean jj_3R_296() { + private boolean jj_3R_275() { Token xsp; xsp = jj_scanpos; - if (jj_3R_303()) { + if (jj_3R_281()) { jj_scanpos = xsp; - if (jj_3R_304()) { + if (jj_3R_282()) { jj_scanpos = xsp; - if (jj_3R_305()) { + if (jj_3R_283()) { jj_scanpos = xsp; - if (jj_3R_306()) { + if (jj_3R_284()) { jj_scanpos = xsp; - if (jj_3R_307()) { + if (jj_3R_285()) { jj_scanpos = xsp; - if (jj_3R_308()) return true; + if (jj_3R_286()) return true; } } } @@ -6924,9 +6828,9 @@ LexicalUnitImpl result = null; if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } xsp = jj_scanpos; - if (jj_3R_309()) { + if (jj_3R_287()) { jj_scanpos = xsp; - if (jj_3R_310()) return true; + if (jj_3R_288()) return true; } while (true) { xsp = jj_scanpos; @@ -6935,7 +6839,7 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_223() { + private boolean jj_3R_262() { if (jj_scan_token(LBRACKET)) return true; Token xsp; while (true) { @@ -6948,12 +6852,12 @@ LexicalUnitImpl result = null; if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } xsp = jj_scanpos; - if (jj_3R_296()) jj_scanpos = xsp; + if (jj_3R_275()) jj_scanpos = xsp; if (jj_scan_token(RBRACKET)) return true; return false; } - private boolean jj_3R_183() { + private boolean jj_3R_175() { if (jj_scan_token(COMMA)) return true; Token xsp; while (true) { @@ -6963,548 +6867,414 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_302() { + private boolean jj_3R_280() { if (jj_scan_token(INTERPOLATION)) return true; return false; } - private boolean jj_3R_257() { + private boolean jj_3R_246() { if (jj_scan_token(PARENT)) return true; return false; } - private boolean jj_3R_256() { + private boolean jj_3R_245() { if (jj_scan_token(ANY)) return true; return false; } - private boolean jj_3R_260() { - if (jj_scan_token(DOT)) return true; - return false; - } - - private boolean jj_3R_247() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_260()) jj_scanpos = xsp; - xsp = jj_scanpos; - if (jj_scan_token(72)) { - jj_scanpos = xsp; - if (jj_scan_token(49)) { - jj_scanpos = xsp; - if (jj_scan_token(50)) { - jj_scanpos = xsp; - if (jj_scan_token(52)) return true; - } - } - } - return false; - } - private boolean jj_3_5() { Token xsp; xsp = jj_scanpos; - if (jj_3R_183()) jj_scanpos = xsp; - if (jj_3R_184()) return true; + if (jj_3R_175()) jj_scanpos = xsp; + if (jj_3R_176()) return true; return false; } - private boolean jj_3R_266() { + private boolean jj_3R_259() { Token xsp; xsp = jj_scanpos; - if (jj_3R_270()) { + if (jj_3R_267()) { jj_scanpos = xsp; - if (jj_3R_271()) return true; + if (jj_3R_268()) return true; } return false; } - private boolean jj_3R_270() { + private boolean jj_3R_267() { if (jj_scan_token(IDENT)) return true; return false; } - private boolean jj_3R_246() { - if (jj_scan_token(STRING)) return true; - return false; - } - - private boolean jj_3R_219() { + private boolean jj_3R_210() { Token xsp; xsp = jj_scanpos; - if (jj_3R_255()) { + if (jj_3R_244()) { jj_scanpos = xsp; - if (jj_3R_256()) { + if (jj_3R_245()) { jj_scanpos = xsp; - if (jj_3R_257()) return true; + if (jj_3R_246()) return true; } } return false; } - private boolean jj_3R_255() { + private boolean jj_3R_244() { Token xsp; - if (jj_3R_266()) return true; + if (jj_3R_259()) return true; while (true) { xsp = jj_scanpos; - if (jj_3R_266()) { jj_scanpos = xsp; break; } + if (jj_3R_259()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_245() { - if (jj_3R_259()) return true; + private boolean jj_3R_253() { + if (jj_scan_token(DOT)) return true; return false; } - private boolean jj_3R_202() { + private boolean jj_3R_235() { Token xsp; xsp = jj_scanpos; - if (jj_3R_246()) { - jj_scanpos = xsp; - if (jj_3R_247()) { + if (jj_3R_253()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(72)) { jj_scanpos = xsp; - if (jj_3R_248()) { + if (jj_scan_token(49)) { jj_scanpos = xsp; - if (jj_3R_249()) { + if (jj_scan_token(50)) { jj_scanpos = xsp; - if (jj_3R_250()) return true; - } + if (jj_scan_token(52)) return true; } } } return false; } - private boolean jj_3R_244() { - if (jj_scan_token(DIMEN)) return true; + private boolean jj_3R_234() { + if (jj_scan_token(STRING)) return true; return false; } - private boolean jj_3R_301() { - if (jj_scan_token(IDENT)) return true; + private boolean jj_3R_233() { + if (jj_3R_252()) return true; return false; } - private boolean jj_3R_284() { + private boolean jj_3R_191() { Token xsp; xsp = jj_scanpos; - if (jj_3R_301()) { + if (jj_3R_234()) { + jj_scanpos = xsp; + if (jj_3R_235()) { + jj_scanpos = xsp; + if (jj_3R_236()) { jj_scanpos = xsp; - if (jj_3R_302()) return true; + if (jj_3R_237()) { + jj_scanpos = xsp; + if (jj_3R_238()) return true; + } + } + } } return false; } - private boolean jj_3R_243() { - if (jj_scan_token(KHZ)) return true; + private boolean jj_3R_274() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_279()) { + jj_scanpos = xsp; + if (jj_3R_280()) return true; + } return false; } - private boolean jj_3R_300() { - if (jj_3R_222()) return true; + private boolean jj_3R_279() { + if (jj_scan_token(IDENT)) return true; return false; } - private boolean jj_3R_221() { + private boolean jj_3R_261() { if (jj_scan_token(DOT)) return true; Token xsp; - if (jj_3R_284()) return true; + if (jj_3R_274()) return true; while (true) { xsp = jj_scanpos; - if (jj_3R_284()) { jj_scanpos = xsp; break; } + if (jj_3R_274()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_242() { - if (jj_scan_token(HZ)) return true; + private boolean jj_3R_232() { + if (jj_scan_token(DIMEN)) return true; return false; } - private boolean jj_3R_298() { - if (jj_3R_221()) return true; + private boolean jj_3R_231() { + if (jj_scan_token(KHZ)) return true; return false; } - private boolean jj_3R_241() { - if (jj_scan_token(MS)) return true; + private boolean jj_3R_230() { + if (jj_scan_token(HZ)) return true; return false; } - private boolean jj_3R_293() { - if (jj_3R_221()) return true; + private boolean jj_3R_250() { + if (jj_3R_263()) return true; return false; } - private boolean jj_3R_295() { - if (jj_3R_222()) return true; + private boolean jj_3R_273() { + if (jj_3R_263()) return true; return false; } - private boolean jj_3R_283() { - if (jj_3R_222()) return true; + private boolean jj_3R_229() { + if (jj_scan_token(MS)) return true; return false; } - private boolean jj_3R_286() { - if (jj_3R_221()) return true; + private boolean jj_3R_271() { + if (jj_3R_261()) return true; return false; } - private boolean jj_3R_288() { - if (jj_3R_222()) return true; + private boolean jj_3R_228() { + if (jj_scan_token(SECOND)) return true; return false; } - private boolean jj_3R_240() { - if (jj_scan_token(SECOND)) return true; + private boolean jj_3R_248() { + if (jj_3R_261()) return true; return false; } - private boolean jj_3R_239() { + private boolean jj_3R_227() { if (jj_scan_token(GRAD)) return true; return false; } - private boolean jj_3R_238() { + private boolean jj_3R_226() { if (jj_scan_token(RAD)) return true; return false; } - private boolean jj_3R_237() { + private boolean jj_3R_225() { if (jj_scan_token(DEG)) return true; return false; } - private boolean jj_3R_299() { - if (jj_3R_223()) return true; - return false; - } - - private boolean jj_3R_236() { + private boolean jj_3R_224() { if (jj_scan_token(EXS)) return true; return false; } - private boolean jj_3R_276() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_297()) { - jj_scanpos = xsp; - if (jj_3R_298()) { - jj_scanpos = xsp; - if (jj_3R_299()) { - jj_scanpos = xsp; - if (jj_3R_300()) return true; - } - } - } + private boolean jj_3R_249() { + if (jj_3R_262()) return true; return false; } - private boolean jj_3R_297() { - if (jj_3R_220()) return true; + private boolean jj_3R_272() { + if (jj_3R_262()) return true; return false; } - private boolean jj_3R_235() { + private boolean jj_3R_223() { if (jj_scan_token(REM)) return true; return false; } - private boolean jj_3R_275() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_292()) { - jj_scanpos = xsp; - if (jj_3R_293()) { - jj_scanpos = xsp; - if (jj_3R_294()) { - jj_scanpos = xsp; - if (jj_3R_295()) return true; - } - } - } - return false; - } - - private boolean jj_3R_292() { - if (jj_3R_220()) return true; - return false; - } - - private boolean jj_3R_280() { - if (jj_3R_222()) return true; - return false; - } - - private boolean jj_3R_274() { + private boolean jj_3R_269() { Token xsp; xsp = jj_scanpos; - if (jj_3R_285()) { + if (jj_3R_270()) { jj_scanpos = xsp; - if (jj_3R_286()) { + if (jj_3R_271()) { jj_scanpos = xsp; - if (jj_3R_287()) { + if (jj_3R_272()) { jj_scanpos = xsp; - if (jj_3R_288()) return true; + if (jj_3R_273()) return true; } } } return false; } - private boolean jj_3R_285() { - if (jj_3R_220()) return true; - return false; - } - - private boolean jj_3R_294() { - if (jj_3R_223()) return true; + private boolean jj_3R_270() { + if (jj_3R_260()) return true; return false; } - private boolean jj_3R_234() { + private boolean jj_3R_222() { if (jj_scan_token(LEM)) return true; return false; } - private boolean jj_3R_282() { - if (jj_3R_223()) return true; - return false; - } - - private boolean jj_3R_287() { - if (jj_3R_223()) return true; - return false; - } - - private boolean jj_3R_233() { + private boolean jj_3R_221() { if (jj_scan_token(EMS)) return true; return false; } - private boolean jj_3R_273() { + private boolean jj_3R_211() { Token xsp; xsp = jj_scanpos; - if (jj_3R_281()) { + if (jj_3R_247()) { jj_scanpos = xsp; - if (jj_3R_282()) { + if (jj_3R_248()) { + jj_scanpos = xsp; + if (jj_3R_249()) { jj_scanpos = xsp; - if (jj_3R_283()) return true; + if (jj_3R_250()) return true; + } } } return false; } - private boolean jj_3R_278() { - if (jj_3R_221()) return true; - return false; - } - - private boolean jj_3R_281() { - if (jj_3R_221()) return true; - return false; - } - - private boolean jj_3R_232() { - if (jj_scan_token(PX)) return true; - return false; - } - - private boolean jj_3R_231() { - if (jj_scan_token(IN)) return true; - return false; - } - - private boolean jj_3R_230() { - if (jj_scan_token(PC)) return true; - return false; - } - - private boolean jj_3R_229() { - if (jj_scan_token(MM)) return true; - return false; - } - - private boolean jj_3R_199() { - if (jj_3R_223()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_276()) { jj_scanpos = xsp; break; } - } + private boolean jj_3R_247() { + if (jj_3R_260()) return true; return false; } - private boolean jj_3R_198() { - if (jj_3R_222()) return true; + private boolean jj_3R_188() { Token xsp; + if (jj_3R_211()) return true; while (true) { xsp = jj_scanpos; - if (jj_3R_275()) { jj_scanpos = xsp; break; } + if (jj_3R_211()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_228() { - if (jj_scan_token(CM)) return true; - return false; - } - - private boolean jj_3R_279() { - if (jj_3R_223()) return true; + private boolean jj_3R_220() { + if (jj_scan_token(PX)) return true; return false; } - private boolean jj_3R_197() { - if (jj_3R_221()) return true; + private boolean jj_3R_187() { + if (jj_3R_210()) return true; Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3R_274()) { jj_scanpos = xsp; break; } + if (jj_3R_269()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_227() { - if (jj_scan_token(PT)) return true; + private boolean jj_3R_219() { + if (jj_scan_token(IN)) return true; return false; } - private boolean jj_3R_196() { - if (jj_3R_220()) return true; + private boolean jj_3R_173() { Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_273()) { jj_scanpos = xsp; break; } + xsp = jj_scanpos; + if (jj_3R_187()) { + jj_scanpos = xsp; + if (jj_3R_188()) return true; } return false; } - private boolean jj_3R_272() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_277()) { - jj_scanpos = xsp; - if (jj_3R_278()) { - jj_scanpos = xsp; - if (jj_3R_279()) { - jj_scanpos = xsp; - if (jj_3R_280()) return true; - } - } - } + private boolean jj_3R_218() { + if (jj_scan_token(PC)) return true; return false; } - private boolean jj_3R_277() { - if (jj_3R_220()) return true; + private boolean jj_3R_240() { + if (jj_3R_208()) return true; + if (jj_3R_173()) return true; return false; } - private boolean jj_3R_226() { - if (jj_scan_token(PERCENTAGE)) return true; + private boolean jj_3R_217() { + if (jj_scan_token(MM)) return true; return false; } - private boolean jj_3R_209() { - if (jj_3R_254()) return true; + private boolean jj_3R_216() { + if (jj_scan_token(CM)) return true; return false; } - private boolean jj_3R_195() { - if (jj_3R_219()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3R_272()) { jj_scanpos = xsp; break; } - } + private boolean jj_3R_215() { + if (jj_scan_token(PT)) return true; return false; } - private boolean jj_3R_225() { - if (jj_scan_token(NUMBER)) return true; + private boolean jj_3R_214() { + if (jj_scan_token(PERCENTAGE)) return true; return false; } - private boolean jj_3R_181() { - Token xsp; - xsp = jj_scanpos; - if (jj_3R_195()) { - jj_scanpos = xsp; - if (jj_3R_196()) { - jj_scanpos = xsp; - if (jj_3R_197()) { - jj_scanpos = xsp; - if (jj_3R_198()) { - jj_scanpos = xsp; - if (jj_3R_199()) return true; - } - } - } - } + private boolean jj_3R_198() { + if (jj_3R_242()) return true; return false; } - private boolean jj_3R_224() { - if (jj_3R_258()) return true; + private boolean jj_3R_254() { + if (jj_scan_token(HASH)) return true; return false; } - private boolean jj_3R_252() { - if (jj_3R_217()) return true; - if (jj_3R_181()) return true; + private boolean jj_3R_213() { + if (jj_scan_token(NUMBER)) return true; return false; } - private boolean jj_3R_201() { + private boolean jj_3R_212() { + if (jj_3R_251()) return true; + return false; + } + + private boolean jj_3R_190() { Token xsp; xsp = jj_scanpos; - if (jj_3R_224()) jj_scanpos = xsp; + if (jj_3R_212()) jj_scanpos = xsp; xsp = jj_scanpos; - if (jj_3R_225()) { + if (jj_3R_213()) { jj_scanpos = xsp; - if (jj_3R_226()) { + if (jj_3R_214()) { jj_scanpos = xsp; - if (jj_3R_227()) { + if (jj_3R_215()) { jj_scanpos = xsp; - if (jj_3R_228()) { + if (jj_3R_216()) { jj_scanpos = xsp; - if (jj_3R_229()) { + if (jj_3R_217()) { jj_scanpos = xsp; - if (jj_3R_230()) { + if (jj_3R_218()) { jj_scanpos = xsp; - if (jj_3R_231()) { + if (jj_3R_219()) { jj_scanpos = xsp; - if (jj_3R_232()) { + if (jj_3R_220()) { jj_scanpos = xsp; - if (jj_3R_233()) { + if (jj_3R_221()) { jj_scanpos = xsp; - if (jj_3R_234()) { + if (jj_3R_222()) { jj_scanpos = xsp; - if (jj_3R_235()) { + if (jj_3R_223()) { jj_scanpos = xsp; - if (jj_3R_236()) { + if (jj_3R_224()) { jj_scanpos = xsp; - if (jj_3R_237()) { + if (jj_3R_225()) { jj_scanpos = xsp; - if (jj_3R_238()) { + if (jj_3R_226()) { jj_scanpos = xsp; - if (jj_3R_239()) { + if (jj_3R_227()) { jj_scanpos = xsp; - if (jj_3R_240()) { + if (jj_3R_228()) { jj_scanpos = xsp; - if (jj_3R_241()) { + if (jj_3R_229()) { jj_scanpos = xsp; - if (jj_3R_242()) { + if (jj_3R_230()) { jj_scanpos = xsp; - if (jj_3R_243()) { + if (jj_3R_231()) { jj_scanpos = xsp; - if (jj_3R_244()) { + if (jj_3R_232()) { jj_scanpos = xsp; - if (jj_3R_245()) return true; + if (jj_3R_233()) return true; } } } @@ -7528,12 +7298,12 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_184() { + private boolean jj_3R_176() { Token xsp; xsp = jj_scanpos; - if (jj_3R_201()) { + if (jj_3R_190()) { jj_scanpos = xsp; - if (jj_3R_202()) return true; + if (jj_3R_191()) return true; } while (true) { xsp = jj_scanpos; @@ -7542,102 +7312,112 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_261() { - if (jj_scan_token(HASH)) return true; + private boolean jj_3R_255() { + if (jj_scan_token(URL)) return true; return false; } - private boolean jj_3R_254() { - if (jj_3R_189()) return true; + private boolean jj_3_2() { + if (jj_3R_172()) return true; + if (jj_3R_173()) return true; return false; } - private boolean jj_3R_262() { - if (jj_scan_token(URL)) return true; + private boolean jj_3R_242() { + if (jj_3R_181()) return true; return false; } - private boolean jj_3R_208() { - if (jj_3R_184()) return true; + private boolean jj_3R_193() { + if (jj_scan_token(COMMA)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_scan_token(1)) { jj_scanpos = xsp; break; } + } + if (jj_3R_192()) return true; return false; } - private boolean jj_3R_187() { + private boolean jj_3R_239() { + if (jj_3R_173()) return true; + return false; + } + + private boolean jj_3R_197() { + if (jj_3R_176()) return true; + return false; + } + + private boolean jj_3R_192() { Token xsp; xsp = jj_scanpos; - if (jj_3R_208()) { + if (jj_3R_239()) { jj_scanpos = xsp; - if (jj_3R_209()) return true; + if (jj_3R_240()) return true; + } + while (true) { + xsp = jj_scanpos; + if (jj_3_2()) { jj_scanpos = xsp; break; } + } + while (true) { + xsp = jj_scanpos; + if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3_9() { - if (jj_3R_188()) return true; + private boolean jj_3R_179() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_197()) { + jj_scanpos = xsp; + if (jj_3R_198()) return true; + } return false; } - private boolean jj_3_2() { + private boolean jj_3_9() { if (jj_3R_180()) return true; - if (jj_3R_181()) return true; return false; } - private boolean jj_3R_204() { - if (jj_scan_token(COMMA)) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_scan_token(1)) { jj_scanpos = xsp; break; } - } - if (jj_3R_203()) return true; + private boolean jj_3R_256() { + if (jj_scan_token(UNICODERANGE)) return true; return false; } - private boolean jj_3R_251() { - if (jj_3R_181()) return true; + private boolean jj_3_4() { + if (jj_3R_174()) return true; return false; } - private boolean jj_3R_268() { + private boolean jj_3R_265() { if (jj_scan_token(PLUS)) return true; return false; } - private boolean jj_3R_258() { + private boolean jj_3R_251() { Token xsp; xsp = jj_scanpos; - if (jj_3R_267()) { + if (jj_3R_264()) { jj_scanpos = xsp; - if (jj_3R_268()) return true; + if (jj_3R_265()) return true; } return false; } - private boolean jj_3R_267() { + private boolean jj_3R_264() { if (jj_scan_token(MINUS)) return true; return false; } - private boolean jj_3R_263() { - if (jj_scan_token(UNICODERANGE)) return true; - return false; - } - - private boolean jj_3R_203() { + private boolean jj_3R_177() { + if (jj_3R_192()) return true; Token xsp; - xsp = jj_scanpos; - if (jj_3R_251()) { - jj_scanpos = xsp; - if (jj_3R_252()) return true; - } while (true) { xsp = jj_scanpos; - if (jj_3_2()) { jj_scanpos = xsp; break; } - } - while (true) { - xsp = jj_scanpos; - if (jj_scan_token(1)) { jj_scanpos = xsp; break; } + if (jj_3R_193()) { jj_scanpos = xsp; break; } } return false; } @@ -7646,41 +7426,26 @@ LexicalUnitImpl result = null; Token xsp; xsp = jj_scanpos; if (jj_3_9()) jj_scanpos = xsp; - if (jj_3R_187()) return true; - return false; - } - - private boolean jj_3_4() { - if (jj_3R_182()) return true; - return false; - } - - private boolean jj_3R_190() { - if (jj_3R_187()) return true; - Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_3_8()) { jj_scanpos = xsp; break; } - } + if (jj_3R_179()) return true; return false; } private boolean jj_3_1() { - if (jj_3R_179()) return true; + if (jj_3R_171()) return true; return false; } - private boolean jj_3R_185() { - if (jj_3R_203()) return true; + private boolean jj_3R_182() { + if (jj_3R_179()) return true; Token xsp; while (true) { xsp = jj_scanpos; - if (jj_3R_204()) { jj_scanpos = xsp; break; } + if (jj_3_8()) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_215() { + private boolean jj_3R_204() { if (jj_scan_token(MINUS)) return true; Token xsp; if (jj_scan_token(1)) return true; @@ -7691,7 +7456,12 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_214() { + private boolean jj_3_3() { + if (jj_3R_171()) return true; + return false; + } + + private boolean jj_3R_203() { if (jj_scan_token(PLUS)) return true; Token xsp; if (jj_scan_token(1)) return true; @@ -7702,12 +7472,12 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3_3() { - if (jj_3R_179()) return true; + private boolean jj_3R_258() { + if (jj_scan_token(INTERPOLATION)) return true; return false; } - private boolean jj_3R_213() { + private boolean jj_3R_202() { if (jj_scan_token(MOD)) return true; Token xsp; while (true) { @@ -7717,7 +7487,7 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_212() { + private boolean jj_3R_201() { if (jj_scan_token(ANY)) return true; Token xsp; while (true) { @@ -7727,7 +7497,7 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_211() { + private boolean jj_3R_200() { if (jj_scan_token(DIV)) return true; Token xsp; while (true) { @@ -7737,7 +7507,7 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_210() { + private boolean jj_3R_199() { if (jj_scan_token(COMMA)) return true; Token xsp; while (true) { @@ -7747,20 +7517,20 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_188() { + private boolean jj_3R_180() { Token xsp; xsp = jj_scanpos; - if (jj_3R_210()) { + if (jj_3R_199()) { jj_scanpos = xsp; - if (jj_3R_211()) { + if (jj_3R_200()) { jj_scanpos = xsp; - if (jj_3R_212()) { + if (jj_3R_201()) { jj_scanpos = xsp; - if (jj_3R_213()) { + if (jj_3R_202()) { jj_scanpos = xsp; - if (jj_3R_214()) { + if (jj_3R_203()) { jj_scanpos = xsp; - if (jj_3R_215()) return true; + if (jj_3R_204()) return true; } } } @@ -7769,13 +7539,8 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_265() { - if (jj_scan_token(INTERPOLATION)) return true; - return false; - } - - private boolean jj_3R_216() { - if (jj_scan_token(GUARDED_SYM)) return true; + private boolean jj_3R_181() { + if (jj_scan_token(VARIABLE)) return true; Token xsp; while (true) { xsp = jj_scanpos; @@ -7784,19 +7549,28 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_192() { - if (jj_scan_token(SEMICOLON)) return true; + private boolean jj_3R_241() { Token xsp; - while (true) { - xsp = jj_scanpos; - if (jj_scan_token(1)) { jj_scanpos = xsp; break; } + xsp = jj_scanpos; + if (jj_3R_257()) { + jj_scanpos = xsp; + if (jj_3R_258()) return true; } return false; } - private boolean jj_3R_189() { - if (jj_scan_token(VARIABLE)) return true; + private boolean jj_3R_257() { + if (jj_scan_token(IDENT)) return true; + return false; + } + + private boolean jj_3R_194() { Token xsp; + if (jj_3R_241()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_241()) { jj_scanpos = xsp; break; } + } while (true) { xsp = jj_scanpos; if (jj_scan_token(1)) { jj_scanpos = xsp; break; } @@ -7804,28 +7578,29 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_253() { + private boolean jj_3R_205() { + if (jj_scan_token(GUARDED_SYM)) return true; Token xsp; - xsp = jj_scanpos; - if (jj_3R_264()) { - jj_scanpos = xsp; - if (jj_3R_265()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } return false; } - private boolean jj_3R_264() { - if (jj_scan_token(IDENT)) return true; + private boolean jj_3R_183() { + if (jj_3R_205()) return true; return false; } - private boolean jj_3R_205() { + private boolean jj_3R_189() { + if (jj_scan_token(VARIABLE)) return true; Token xsp; - if (jj_3R_253()) return true; while (true) { xsp = jj_scanpos; - if (jj_3R_253()) { jj_scanpos = xsp; break; } + if (jj_scan_token(1)) { jj_scanpos = xsp; break; } } + if (jj_scan_token(COLON)) return true; while (true) { xsp = jj_scanpos; if (jj_scan_token(1)) { jj_scanpos = xsp; break; } @@ -7833,11 +7608,6 @@ LexicalUnitImpl result = null; return false; } - private boolean jj_3R_191() { - if (jj_3R_216()) return true; - return false; - } - /** Generated Token Manager. */ public ParserTokenManager token_source; /** Current token. */ @@ -7848,7 +7618,7 @@ LexicalUnitImpl result = null; private Token jj_scanpos, jj_lastpos; private int jj_la; private int jj_gen; - final private int[] jj_la1 = new int[269]; + final private int[] jj_la1 = new int[264]; static private int[] jj_la1_0; static private int[] jj_la1_1; static private int[] jj_la1_2; @@ -7860,16 +7630,16 @@ LexicalUnitImpl result = null; jj_la1_init_3(); } private static void jj_la1_init_0() { - jj_la1_0 = new int[] {0x0,0x302,0x302,0x0,0x300,0x2,0x2,0x2,0xd4c40000,0x0,0x300,0x2,0x300,0x2,0x0,0x2,0x2,0x2,0x0,0x0,0x2,0x2,0x0,0x0,0x2,0x0,0x2,0x100000,0x2,0x0,0x2,0x2,0xd4c40000,0xd4c40000,0x2,0x2,0x2,0xd4fd1500,0xd4fd1500,0x2,0x2,0x2,0x0,0x0,0x2,0x0,0x200000,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x200000,0x2,0x0,0x2,0x391500,0xc40000,0xc40002,0xc40000,0x2,0x2,0x80120002,0x80120002,0x2,0x0,0x0,0x2,0x2,0x2,0x2,0xd4c40000,0xd4c40000,0x2,0x100000,0x2,0xd4c40000,0x2,0x84000000,0x84000000,0x84000000,0x84000000,0x84000000,0x84000000,0x84000000,0x84000000,0x84000000,0x84000000,0xd4000000,0x0,0x0,0x0,0x0,0x50000000,0x2,0x2,0x3f000,0x2,0x0,0x2,0x3f000,0x0,0x2,0x0,0x2,0x0,0x2,0x200000,0x0,0xd4c40000,0x0,0x134e0002,0x2,0xd4c40000,0xd4c40000,0x2,0x0,0x2,0x134e0002,0x0,0x2,0xd4c40000,0xd4c40000,0x2,0x134e0002,0x2,0x2,0x2,0x0,0x2,0xd4c40000,0x2,0x2,0x100000,0x2,0x2,0x2,0x2,0x0,0x2,0xd4c40000,0xd4c40000,0x2,0x100000,0x2,0x0,0x2,0x2,0x100000,0x0,0x0,0x800c0000,0x2,0x0,0x100000,0x2,0x800c0000,0x2,0x0,0x800c0000,0x2,0x2,0x0,0x200400,0x2,0x200000,0x2,0xd4c40000,0xd4c40000,0x2,0x2,0x2,0x0,0x2,0x0,0x2,0x2,0x2,0x100000,0x2,0x2,0x2,0x2,0x2,0x0,0x2,0x2,0x2,0x100000,0x2,0x2,0x2,0x0,0x2,0x2,0x2,0x100000,0x2,0x2,0x0,0x2,0x0,0x2,0x2,0x2,0x100000,0x0,0x2,0x2,0x0,0x2,0x2,0x2,0x200000,0x2,0x2,0x200000,0x2,0x2,0x0,0x200000,0x2,0x0,0x2,0x0,0xd4c40000,0x2,0x0,0x2,0x0,0x200000,0x2,0x0,0x2,0x800c0400,0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x321c0000,0xc0000,0x800c0000,0xc0000,0x0,0x80000000,0x0,0x80000000,0x800c0000,0x2,0x2,0x800c0000,0x2,0xd4c40000,0x2,0x2,0x2,0x0,0x200000,0x2,0x0,0x2,}; + jj_la1_0 = new int[] {0x0,0x302,0x302,0x0,0x300,0x2,0x2,0x2,0x200000,0xd4c40000,0x0,0x300,0x2,0x300,0x2,0x0,0x2,0x200000,0x2,0x2,0x0,0x0,0x2,0x2,0x0,0x0,0x2,0x0,0x2,0x100000,0x2,0x0,0x2,0x2,0xd4c40000,0xd4c40000,0x2,0x2,0x2,0xd4fd1500,0x2,0xd4fd1500,0x2,0x2,0x0,0x0,0x2,0x0,0x200000,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x200000,0x2,0x0,0x2,0x391500,0xc40000,0xc40002,0xc40000,0x2,0x2,0x80120002,0x80120002,0x2,0x0,0x0,0x2,0x2,0x2,0x2,0xd4c40000,0xd4c40000,0x2,0x100000,0x2,0xd4c40000,0x2,0x84000000,0x84000000,0x84000000,0x84000000,0xd4000000,0x0,0x0,0x0,0x0,0x50000000,0x2,0x2,0x3f000,0x2,0x0,0x2,0x3f000,0x0,0x2,0x0,0x2,0x0,0x0,0xd4c40000,0x0,0x134e0002,0x2,0xd4c40000,0xd4c40000,0x2,0x0,0x2,0x134e0002,0x0,0x2,0xd4c40000,0xd4c40000,0x2,0x134e0002,0x2,0x2,0x2,0x0,0x2,0xd4c40000,0x2,0x2,0x100000,0x2,0x2,0x2,0x2,0x0,0x2,0xd4c40000,0xd4c40000,0x2,0x100000,0x2,0x0,0x2,0x2,0x100000,0x0,0x0,0x800c0000,0x2,0x0,0x100000,0x2,0x800c0000,0x2,0x0,0x800c0000,0x2,0x2,0x0,0x400,0x2,0x200000,0x200000,0x2,0xd4c40000,0xd4c40000,0x2,0x2,0x2,0x0,0x2,0x0,0x2,0x2,0x2,0x100000,0x2,0x2,0x2,0x2,0x2,0x0,0x2,0x2,0x2,0x100000,0x2,0x2,0x2,0x0,0x2,0x2,0x2,0x100000,0x2,0x2,0x0,0x2,0x0,0x2,0x2,0x2,0x100000,0x0,0x2,0x200000,0x2,0x200000,0x0,0x2,0x2,0x2,0x2,0x200000,0x2,0x2,0x0,0x200000,0x2,0x0,0x2,0x0,0xd4c40000,0x2,0x0,0x2,0x0,0x200000,0x2,0x0,0x2,0x800c0400,0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x321c0000,0xc0000,0x800c0000,0xc0000,0x0,0x80000000,0x0,0x80000000,0x800c0000,0x2,0x2,0x800c0000,0x2,0xd4c40000,0x2,0x2,0x2,0x0,0x200000,0x2,0x0,0x2,}; } private static void jj_la1_init_1() { - jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x566000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x0,0x0,0x120000,0x120000,0x0,0x120000,0x0,0x0,0x0,0x120000,0x0,0x0,0x564000c0,0x564000c0,0x0,0x0,0x0,0x60001c0,0x60001c0,0x0,0x0,0x0,0x0,0x40,0x0,0x80,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0xc2,0xc2,0x0,0x80,0x80,0x0,0x0,0x0,0x0,0x564000c0,0x564000c0,0x0,0x0,0x0,0xc0,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xc0,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x50000000,0x64000c0,0x50000000,0x3f,0x0,0x564000c0,0x564000c0,0x0,0x80000000,0x0,0x3f,0x0,0x0,0x564000c0,0x564000c0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x564000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x564000c0,0x564000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x160040,0x0,0x40,0x0,0x0,0x160040,0x0,0x40,0x160000,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x61200c0,0x61200c0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x6000000,0x0,0x0,0x60000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x6000000,0xc0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x160000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160000,0x0,0x0,0x0,0x160000,0x160000,0x160000,0x0,0x0,0x160000,0x0,0x60000c0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,}; + jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x566000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x0,0x0,0x120000,0x120000,0x0,0x120000,0x0,0x0,0x0,0x120000,0x0,0x0,0x564000c0,0x564000c0,0x0,0x0,0x0,0x60001c0,0x0,0x60001c0,0x0,0x0,0x0,0x40,0x0,0x80,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0xc2,0xc2,0x0,0x80,0x80,0x0,0x0,0x0,0x0,0x564000c0,0x564000c0,0x0,0x0,0x0,0xc0,0x0,0x40,0x40,0x40,0x40,0xc0,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x50000000,0x64000c0,0x50000000,0x3f,0x0,0x564000c0,0x564000c0,0x0,0x80000000,0x0,0x3f,0x0,0x0,0x564000c0,0x564000c0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x564000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x564000c0,0x564000c0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x160040,0x0,0x40,0x0,0x0,0x160040,0x0,0x40,0x160000,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x61200c0,0x61200c0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x6000000,0x0,0x0,0x0,0x0,0x60000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x6000000,0xc0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x160000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x160000,0x0,0x0,0x0,0x160000,0x160000,0x160000,0x0,0x0,0x160000,0x0,0x60000c0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,}; } private static void jj_la1_init_2() { - jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x1000,0x0,0x0,0x0,0x0,0x880,0x0,0x0,0x0,0x100,0x100,0x0,0x0,0x2008,0x2008,0x0,0x2000,0x0,0x0,0x0,0x2000,0x0,0x0,0x1119,0x1119,0x0,0x0,0x0,0x2b80,0x2b80,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x2a80,0x0,0x0,0x0,0x0,0x0,0x380,0x380,0x0,0x100,0x100,0x0,0x0,0x0,0x0,0x1119,0x1119,0x0,0x0,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x100,0x100,0x100,0x100,0x100,0x0,0x0,0x0,0x0,0x180,0x0,0x0,0x0,0x0,0x100,0x0,0x40,0x0,0x0,0x0,0x109,0x1000,0x1300,0x0,0x1109,0x1109,0x0,0x0,0x0,0x1300,0x20,0x0,0x1109,0x1109,0x0,0x1300,0x0,0x0,0x0,0x1100,0x0,0x1109,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x0,0x1109,0x1109,0x0,0x0,0x0,0x1000,0x0,0x0,0x0,0x1000,0x1000,0xfffffb80,0x0,0x0,0x0,0x0,0xfffffb80,0x0,0x0,0xfffffb80,0x0,0x0,0x1100,0x0,0x0,0x0,0x0,0x2100,0x2100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0xfffffb80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffffb80,0x0,0xffffe200,0x0,0x100,0x980,0xffffeb80,0x0,0x0,0xfffffb80,0x0,0x100,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,}; + jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x1000,0x0,0x0,0x0,0x0,0x880,0x0,0x0,0x0,0x0,0x100,0x100,0x0,0x0,0x2008,0x2008,0x0,0x2000,0x0,0x0,0x0,0x2000,0x0,0x0,0x1119,0x1119,0x0,0x0,0x0,0x2b88,0x0,0x2b88,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x2a80,0x0,0x0,0x0,0x0,0x0,0x380,0x380,0x0,0x100,0x100,0x0,0x0,0x0,0x0,0x1119,0x1119,0x0,0x0,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x100,0x100,0x100,0x100,0x100,0x100,0x0,0x0,0x0,0x0,0x180,0x0,0x0,0x0,0x0,0x100,0x0,0x40,0x0,0x109,0x1000,0x1300,0x0,0x1109,0x1109,0x0,0x0,0x0,0x1300,0x20,0x0,0x1109,0x1109,0x0,0x1300,0x0,0x0,0x0,0x1100,0x0,0x1109,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x0,0x1109,0x1109,0x0,0x0,0x0,0x1000,0x0,0x0,0x0,0x1000,0x1000,0xfffffb80,0x0,0x0,0x0,0x0,0xfffffb80,0x0,0x0,0xfffffb80,0x0,0x0,0x1100,0x0,0x0,0x0,0x0,0x0,0x2100,0x2100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,0xfffffb80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfffffb80,0x0,0xffffe200,0x0,0x100,0x980,0xffffeb80,0x0,0x0,0xfffffb80,0x0,0x100,0x0,0x0,0x0,0x100,0x0,0x0,0x100,0x0,}; } private static void jj_la1_init_3() { - jj_la1_3 = new int[] {0x8,0x80,0x80,0x2,0x80,0x0,0x0,0x0,0x75,0x0,0x80,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc5,0xc5,0x0,0x0,0x0,0xc401bf,0xc401bf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc401be,0x0,0x0,0x0,0x0,0x0,0x400000,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc7,0xc7,0x0,0x0,0x0,0x1,0x0,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x0,0x45,0x80,0x200000,0x0,0xe5,0xe5,0x0,0x0,0x0,0x200000,0x0,0x0,0xe5,0xe5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0xf5,0xf5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x440001,0x0,0x0,0x0,0x0,0x440001,0x0,0x0,0x440001,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x0,0x440001,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x440001,0x0,0x400000,0x0,0x0,0x40001,0x440001,0x0,0x0,0x440001,0x0,0x37,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,}; + jj_la1_3 = new int[] {0x8,0x80,0x80,0x2,0x80,0x0,0x0,0x0,0x0,0x75,0x0,0x80,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc5,0xc5,0x0,0x0,0x0,0xc401bf,0x0,0xc401bf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc401be,0x0,0x0,0x0,0x0,0x0,0x400000,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc7,0xc7,0x0,0x0,0x0,0x1,0x0,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0x0,0x0,0x45,0x80,0x200000,0x0,0xe5,0xe5,0x0,0x0,0x0,0x200000,0x0,0x0,0xe5,0xe5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0xf5,0xf5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x440001,0x0,0x0,0x0,0x0,0x440001,0x0,0x0,0x440001,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x380000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x0,0x440001,0x0,0x100,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x440001,0x0,0x400000,0x0,0x0,0x40001,0x440001,0x0,0x0,0x440001,0x0,0x37,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,}; } final private JJCalls[] jj_2_rtns = new JJCalls[9]; private boolean jj_rescan = false; @@ -7881,7 +7651,7 @@ LexicalUnitImpl result = null; token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 269; i++) jj_la1[i] = -1; + for (int i = 0; i < 264; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -7891,7 +7661,7 @@ LexicalUnitImpl result = null; token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 269; i++) jj_la1[i] = -1; + for (int i = 0; i < 264; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -7901,7 +7671,7 @@ LexicalUnitImpl result = null; token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 269; i++) jj_la1[i] = -1; + for (int i = 0; i < 264; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -7911,7 +7681,7 @@ LexicalUnitImpl result = null; token = new Token(); jj_ntk = -1; jj_gen = 0; - for (int i = 0; i < 269; i++) jj_la1[i] = -1; + for (int i = 0; i < 264; i++) jj_la1[i] = -1; for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls(); } @@ -8028,7 +7798,7 @@ LexicalUnitImpl result = null; la1tokens[jj_kind] = true; jj_kind = -1; } - for (int i = 0; i < 269; i++) { + for (int i = 0; i < 264; i++) { if (jj_la1[i] == jj_gen) { for (int j = 0; j < 32; j++) { if ((jj_la1_0[i] & (1<<j)) != 0) { diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj index 44e06a33b1..e52ad18223 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj @@ -37,9 +37,12 @@ package com.vaadin.sass.internal.parser; import java.io.*; import java.net.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Locale; import java.util.Map; import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; import org.w3c.css.sac.ConditionFactory; import org.w3c.css.sac.Condition; @@ -750,15 +753,15 @@ void charset() : { Token n; } { try { - <CHARSET_SYM> ( <S> )* n=<STRING> ( <S> )* ";" + <CHARSET_SYM> ( <S> )* n=<STRING> ( <S> )* (";" | acceptMissingSemicolon(EOF)) } catch (ParseException e) { reportError(getLocator(e.currentToken.next), e); - skipStatement(); - // reportWarningSkipText(getLocator(), skipStatement()); + skipStatement(); + // reportWarningSkipText(getLocator(), skipStatement()); } catch (Exception e) { reportError(getLocator(), e); - skipStatement(); - // reportWarningSkipText(getLocator(), skipStatement()); + skipStatement(); + // reportWarningSkipText(getLocator(), skipStatement()); } } @@ -817,7 +820,7 @@ void importDeclaration() : } } ) - ( <S> )* mediaStatement(ml) ";" + ( <S> )* mediaStatement(ml) (";" | acceptMissingSemicolon(RBRACE, EOF)) ( <S> )* { if (ml.getLength() == 0) { @@ -912,18 +915,24 @@ void media() : <MEDIA_SYM> ( <S> )* mediaStatement(ml) { start = true; documentHandler.startMedia(ml); } - <LBRACE> ( <S> )* ( debuggingDirective() | styleRule() | skipUnknownRule() )* <RBRACE> ( <S> )* + <LBRACE> ( <S> )* ( mediaDirective() )* <RBRACE> ( <S> )* } catch (ParseException e) { reportError(getLocator(), e); skipStatement(); // reportWarningSkipText(getLocator(), skipStatement()); } finally { if (start) { - documentHandler.endMedia(ml); + documentHandler.endMedia(ml); } } } +void mediaDirective() : +{} +{ + debuggingDirective() | styleRule() | skipUnknownRule() | contentDirective() +} + void mediaStatement(MediaListImpl ml) : { Token t; @@ -1272,18 +1281,12 @@ String simple_selector(String selector, char comb) : pseudoElt = null; } { - ( simple_current=element_name() - ( cond=hash(cond) | cond=_class(cond) - | cond=attrib(cond) | cond=pseudo(cond) )* - | cond=hash(cond) ( cond=_class(cond) - | cond=attrib(cond) | cond=pseudo(cond) )* - | cond=_class(cond) ( cond=hash(cond) | cond=_class(cond) - | cond=attrib(cond) | cond=pseudo(cond) )* - | cond=pseudo(cond) ( cond=hash(cond) | cond=_class(cond) - | cond=attrib(cond) | cond=pseudo(cond) )* - | cond=attrib(cond) ( cond=hash(cond) | cond=_class(cond) - | cond=attrib(cond) | cond=pseudo(cond) )* - ) + ( (simple_current=element_name() + ( cond=hash(cond) | cond=_class(cond) + | cond=attrib(cond) | cond=pseudo(cond) )* ) + | ( cond = hash(cond) | cond=_class(cond) + | cond=attrib(cond) | cond=pseudo(cond) )+ + ) { if (simple_current == null) { simple_current = ""; @@ -1488,7 +1491,7 @@ void variable() : { try{ name = variableName() - ":" ( <S> )* exp=expr() ( guarded=guarded() )?(";"(<S>)*)+ + ":" ( <S> )* exp=expr() ( guarded=guarded() )? semicolonTerminator() //raw=skipStatementUntilSemiColon() { exp = replaceNullValues(exp); @@ -1763,18 +1766,27 @@ void includeDirective() : (name = property() | name = variableName(){ name = "$"+name;} | (name = functionName() args = argValuelist()) <RPARAN>(<S>)*) {documentHandler.startInclude(name, args);} - (includeDirectiveBlockContents() | includeDirectiveTerminator()) + (includeDirectiveBlockContents() | semicolonTerminator()) {documentHandler.endInclude();} } -void includeDirectiveTerminator(): +void semicolonTerminator(): {} { - try { - (";"(<S>)*)+ - } - catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + (";"(<S>)*)+ | acceptMissingSemicolon(RBRACE, EOF) +} + +JAVACODE +void acceptMissingSemicolon(Integer... acceptedTerminators) throws ParseException { + Token next = getToken(1); + ArrayList<Integer> terminators = new ArrayList<Integer>(Arrays.asList(acceptedTerminators)); + if (!terminators.contains(next.kind)){ + String message = "encountered \"" + next.image + "\". Was expecting one of \";\""; + for(int term : acceptedTerminators){ + message += ", " + tokenImage[term]; + } + ParseException e = new ParseException(message); + throw e; } } @@ -2013,14 +2025,9 @@ void debugDirective() : { String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF}); // TODO should evaluate the content expression, call documentHandler.debugDirective() etc. - System.out.println(content); - } - try { - ";" (<S>)* - } - catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + Logger.getLogger(Parser.class.getName()).log(Level.INFO, content); } + ( (";" (<S>)*) | acceptMissingSemicolon(RBRACE, EOF)) } void warnDirective() : @@ -2030,14 +2037,9 @@ void warnDirective() : { String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF}); // TODO should evaluate the content expression, call documentHandler.warnDirective() etc. - System.err.println(content); - } - try { - ";" (<S>)* - } - catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); + Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, content); } + ( (";" (<S>)*) | acceptMissingSemicolon(RBRACE, EOF)) } Node forDirective() : @@ -2081,12 +2083,7 @@ void extendDirective() : (<S>)* list = selectorList() {documentHandler.extendDirective(list);} - try { - (";"(<S>)*)+ - } - catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); - } + semicolonTerminator() } void contentDirective() : @@ -2094,12 +2091,7 @@ void contentDirective() : { <CONTENT_SYM> (<S>)* - try { - (";"(<S>)*)+ - } - catch (ParseException e) { - acceptMissingSemicolonBeforeRbrace(e); - } + ( (";" (<S>)*) | acceptMissingSemicolon(RBRACE, EOF)) {documentHandler.contentDirective();} } @@ -2573,12 +2565,15 @@ LexicalUnitImpl function(char operator, LexicalUnitImpl prev) : if ("rgb(".equals(f)) { // this is a RGB declaration (e.g. rgb(255, 50%, 0) ) int i = 0; + boolean hasVariables = false; while (loop && l != null && i < 5) { switch (i) { case 0: case 2: case 4: - if ((l.getLexicalUnitType() != LexicalUnit.SAC_INTEGER) + if (l.getLexicalUnitType() == SCSSLexicalUnit.SCSS_VARIABLE) { + hasVariables = true; + } else if ((l.getLexicalUnitType() != LexicalUnit.SAC_INTEGER) && (l.getLexicalUnitType() != LexicalUnit.SAC_PERCENTAGE)) { loop = false; } @@ -2598,9 +2593,15 @@ LexicalUnitImpl function(char operator, LexicalUnitImpl prev) : } } if ((i == 5) && loop && (l == null)) { - return LexicalUnitImpl.createRGBColor(n.beginLine, - n.beginColumn, - prev, params); + if (hasVariables) { + return LexicalUnitImpl.createFunction(n.beginLine, + n.beginColumn, prev, + f.substring(0, f.length() - 1), params); + } else { + return LexicalUnitImpl.createRGBColor(n.beginLine, + n.beginColumn, + prev, params); + } } else { if (errorHandler != null) { String errorText; @@ -3131,15 +3132,6 @@ ArrayList<String> _parseSelectors() : } } -JAVACODE -void acceptMissingSemicolonBeforeRbrace( ParseException parseException ) { - Token next = getToken(1); - if (next.kind != RBRACE && next.kind!=EOF) { - throw parseException; - } -} - - /* * Local Variables: * compile-command: javacc Parser.jj & javac Parser.java diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java b/theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java index d54ab4fa7e..bb0f4cbf40 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java @@ -18,9 +18,12 @@ package com.vaadin.sass.internal.parser; import java.io.*; import java.net.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Locale; import java.util.Map; import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; import org.w3c.css.sac.ConditionFactory; import org.w3c.css.sac.Condition; import org.w3c.css.sac.SelectorFactory; diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/AbsFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/AbsFunctionGenerator.java new file mode 100644 index 0000000000..7eeae85eba --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/AbsFunctionGenerator.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class AbsFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "abs"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + LexicalUnitImpl firstParam = function.getParameters(); + firstParam.setFloatValue(Math.abs(firstParam.getFloatValue())); + return strategy.build(firstParam); + } + +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/CeilFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/CeilFunctionGenerator.java new file mode 100644 index 0000000000..23a6bc5edd --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/CeilFunctionGenerator.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class CeilFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "ceil"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + LexicalUnitImpl firstParam = function.getParameters(); + firstParam.setFloatValue((float) Math.ceil(firstParam.getFloatValue())); + return strategy.build(firstParam); + } + +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/DarkenFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/DarkenFunctionGenerator.java new file mode 100644 index 0000000000..70481be84c --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/DarkenFunctionGenerator.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; +import com.vaadin.sass.internal.util.ColorUtil; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class DarkenFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "darken"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + LexicalUnitImpl dark = ColorUtil.darken(function); + return strategy.build(dark); + } +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/DefaultFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/DefaultFunctionGenerator.java new file mode 100644 index 0000000000..8ab9b3fb14 --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/DefaultFunctionGenerator.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class DefaultFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return null; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + StringBuilder builder = new StringBuilder(function.getFunctionName()); + return builder.append('(').append(printParameters(function, strategy)) + .append(')').toString(); + } + + private String printParameters(LexicalUnitImpl function, + BuildStringStrategy strategy) { + if (function.getParameters() == null) { + return null; + } + return strategy.build(function.getParameters()); + } +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/FloorFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/FloorFunctionGenerator.java new file mode 100644 index 0000000000..dc30f06ef0 --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/FloorFunctionGenerator.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class FloorFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "floor"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + LexicalUnitImpl firstParam = function.getParameters(); + firstParam + .setFloatValue((float) Math.floor(firstParam.getFloatValue())); + return strategy.build(firstParam); + } + +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/LightenFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/LightenFunctionGenerator.java new file mode 100644 index 0000000000..c78e63e104 --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/LightenFunctionGenerator.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; +import com.vaadin.sass.internal.util.ColorUtil; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class LightenFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "lighten"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + return strategy.build(ColorUtil.lighten(function)); + } + +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/RoundFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/RoundFunctionGenerator.java new file mode 100644 index 0000000000..3eacba3b38 --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/RoundFunctionGenerator.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; + +/** + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class RoundFunctionGenerator implements SCSSFunctionGenerator { + + @Override + public String getFunctionName() { + return "round"; + } + + @Override + public String printState(LexicalUnitImpl function, + BuildStringStrategy strategy) { + LexicalUnitImpl firstParam = function.getParameters(); + firstParam.setFloatValue(Math.round(firstParam.getFloatValue())); + return strategy.build(firstParam); + } + +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/parser/function/SCSSFunctionGenerator.java b/theme-compiler/src/com/vaadin/sass/internal/parser/function/SCSSFunctionGenerator.java new file mode 100644 index 0000000000..112fc1e395 --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/SCSSFunctionGenerator.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.internal.parser.function; + +import com.vaadin.sass.internal.parser.LexicalUnitImpl; +import com.vaadin.sass.internal.tree.Node.BuildStringStrategy; + +/** + * Generator class is used to handle SCSS functions. Generator is applied to the + * function lexical unit if its method {@link #getFunctionName()} returns name + * of the function. + * + * If there are no dedicated generator for the function then default generator + * is used. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public interface SCSSFunctionGenerator { + + /** + * Returns function name handled by this generator. Default generator + * returns <code>null</code> and is used if there is no dedicated generator + * for given function. + * + * @since 7.2 + * @return + */ + String getFunctionName(); + + /** + * Prints out the current state of the function. State is SCSS content of + * the function before compilation and compiled CSS content after + * compilation. + * + * @since 7.2 + * @param function + * Function lexical unit to print its state + * @param strategy + * Strategy to build string from nodes + * @return String state representation of the function + */ + String printState(LexicalUnitImpl function, BuildStringStrategy strategy); +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java new file mode 100644 index 0000000000..5de1f95264 --- /dev/null +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/AbstractResolver.java @@ -0,0 +1,200 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.sass.internal.resolver; + +import java.io.File; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import org.w3c.css.sac.InputSource; + +import com.vaadin.sass.internal.ScssStylesheet; + +/** + * Base class for resolvers. Implements functionality for locating paths which + * an import can be relative to and helpers for extracting path information from + * the identifier. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public abstract class AbstractResolver implements ScssStylesheetResolver, + Serializable { + /* + * (non-Javadoc) + * + * @see + * com.vaadin.sass.internal.resolver.ScssStylesheetResolver#resolve(java + * .lang.String) + */ + @Override + public InputSource resolve(ScssStylesheet parentStylesheet, + String identifier) { + // Remove a possible ".scss" suffix + identifier = identifier.replaceFirst(".scss$", ""); + + List<String> potentialParentPaths = getPotentialParentPaths( + parentStylesheet, identifier); + + // remove path from identifier as it has already been added to the + // parent path + if (identifier.contains("/")) { + identifier = identifier.substring(identifier.lastIndexOf("/") + 1); + } + + for (String path : potentialParentPaths) { + InputSource source = normalizeAndResolve(path + "/" + identifier); + + if (source != null) { + return source; + } + + // Try to find partial import (_identifier.scss) + source = normalizeAndResolve(path + "/_" + identifier); + + if (source != null) { + return source; + } + + } + + return normalizeAndResolve(identifier); + } + + /** + * Retrieves the parent paths which should be used while resolving relative + * identifiers. By default uses the parent stylesheet location and a + * possible absolute path in the identifier. + * + * @param parentStylesheet + * The parent stylesheet or null if there is no parent + * @param identifier + * The identifier to be resolved + * @return a list of paths in which to look for the relative import + */ + protected List<String> getPotentialParentPaths( + ScssStylesheet parentStylesheet, String identifier) { + List<String> potentialParents = new ArrayList<String>(); + if (parentStylesheet != null) { + potentialParents.add(extractFullPath( + parentStylesheet.getDirectory(), identifier)); + } + + // Identifier can be a full path so extract the path part also as a + // potential parent + if (identifier.contains("/")) { + potentialParents.add(extractFullPath("", identifier)); + } + + return potentialParents; + + } + + /** + * Extracts the full path from the path combined with the identifier + * + * @param path + * The base path + * @param identifier + * The identifier which may contain a path part, separated by "/" + * from the real identifier + * @return a normalized version of the path where identifier does not + * contain any directory information + */ + protected String extractFullPath(String path, String identifier) { + int lastSlashPosition = identifier.lastIndexOf("/"); + if (lastSlashPosition == -1) { + return path; + } + String identifierPath = identifier.substring(0, lastSlashPosition); + if ("".equals(path)) { + return identifierPath; + } else { + return path + "/" + identifierPath; + } + } + + /** + * Resolves the normalized version of the given identifier + * + * @param identifier + * The identifier to resolve + * @return An input source if the resolver found one or null otherwise + */ + protected InputSource normalizeAndResolve(String identifier) { + String normalized = normalize(identifier); + return resolveNormalized(normalized); + } + + /** + * Resolves the identifier after it has been normalized using + * {@link #normalize(String)}. + * + * @param identifier + * The normalized identifier + * @return an InputSource if the resolver found a source or null otherwise + */ + protected abstract InputSource resolveNormalized(String identifier); + + /** + * Normalizes "." and ".." from the path string where parent path segments + * can be removed. Preserve leading "..". Also ensure / is used instead of \ + * in all places. + * + * @param path + * A relative or absolute file path + * @return The normalized path + */ + protected String normalize(String path) { + + // Ensure only "/" is used, also in Windows + path = path.replace(File.separatorChar, '/'); + + // Split into segments + String[] segments = path.split("/"); + Stack<String> result = new Stack<String>(); + + // Replace '.' and '..' segments + for (int i = 0; i < segments.length; i++) { + if (segments[i].equals(".")) { + // Segments marked '.' are ignored + + } else if (segments[i].equals("..") && !result.isEmpty() + && !result.lastElement().equals("..")) { + // If segment is ".." then remove the previous iff the previous + // element is not a ".." and the result stack is not empty + result.pop(); + } else { + // Other segments are just added to the stack + result.push(segments[i]); + } + } + + // Reconstruct path + StringBuilder pathBuilder = new StringBuilder(); + for (int i = 0; i < result.size(); i++) { + if (i > 0) { + pathBuilder.append("/"); + } + pathBuilder.append(result.get(i)); + } + return pathBuilder.toString(); + } + +} diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java index 8711a0a3e9..755073bc4c 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/ClassloaderResolver.java @@ -15,31 +15,19 @@ */ package com.vaadin.sass.internal.resolver; -import java.io.File; import java.io.InputStream; import org.w3c.css.sac.InputSource; -public class ClassloaderResolver implements ScssStylesheetResolver { +public class ClassloaderResolver extends AbstractResolver { @Override - public InputSource resolve(String identifier) { - // identifier should not have .scss, fileName should - String ext = ".scss"; - if (identifier.endsWith(".css")) { - ext = ".css"; - } + public InputSource resolveNormalized(String identifier) { String fileName = identifier; - if (identifier.endsWith(ext)) { - identifier = identifier.substring(0, - identifier.length() - ext.length()); - } else { - fileName = fileName + ext; + if (!fileName.endsWith(".css")) { + fileName += ".scss"; } - // Ensure only "/" is used, also in Windows - fileName = fileName.replace(File.separatorChar, '/'); - // Filename should be a relative path starting with VAADIN/... int vaadinIdx = fileName.lastIndexOf("VAADIN/"); if (vaadinIdx > -1) { diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java index 9bb1969ab1..786d0875da 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/FilesystemResolver.java @@ -18,24 +18,46 @@ package com.vaadin.sass.internal.resolver; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; +import java.util.List; import org.w3c.css.sac.InputSource; -public class FilesystemResolver implements ScssStylesheetResolver { +import com.vaadin.sass.internal.ScssStylesheet; +public class FilesystemResolver extends AbstractResolver { + + private String[] customPaths = null; + + public FilesystemResolver(String... customPaths) { + this.customPaths = customPaths; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.sass.internal.resolver.AbstractResolver#getPotentialPaths( + * com.vaadin.sass.internal.ScssStylesheet, java.lang.String) + */ @Override - public InputSource resolve(String identifier) { - // identifier should not have .scss, fileName should - String ext = ".scss"; - if (identifier.endsWith(".css")) { - ext = ".css"; + protected List<String> getPotentialParentPaths( + ScssStylesheet parentStyleSheet, String identifier) { + List<String> potentialPaths = super.getPotentialParentPaths( + parentStyleSheet, identifier); + if (customPaths != null) { + for (String path : customPaths) { + potentialPaths.add(extractFullPath(path, identifier)); + } } + + return potentialPaths; + } + + @Override + public InputSource resolveNormalized(String identifier) { String fileName = identifier; - if (identifier.endsWith(ext)) { - identifier = identifier.substring(0, - identifier.length() - ext.length()); - } else { - fileName = fileName + ext; + if (!fileName.endsWith(".css")) { + fileName += ".scss"; } try { diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/ScssStylesheetResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/ScssStylesheetResolver.java index 45f10836a3..64b3d10d88 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/ScssStylesheetResolver.java +++ b/theme-compiler/src/com/vaadin/sass/internal/resolver/ScssStylesheetResolver.java @@ -17,6 +17,8 @@ package com.vaadin.sass.internal.resolver; import org.w3c.css.sac.InputSource; +import com.vaadin.sass.internal.ScssStylesheet; + public interface ScssStylesheetResolver { /** * Called with the "identifier" of a stylesheet that the resolver should try @@ -26,9 +28,12 @@ public interface ScssStylesheetResolver { * stylesheet was found, e.g "runo.scss" might result in a URI like * "VAADIN/themes/runo/runo.scss". * + * @param parentStylesheet + * The parent style sheet * @param identifier * used fo find stylesheet * @return InputSource for stylesheet (with URI set) or null if not found */ - public InputSource resolve(String identifier); + public InputSource resolve(ScssStylesheet parentStylesheet, + String identifier); }
\ No newline at end of file diff --git a/theme-compiler/src/com/vaadin/sass/internal/resolver/VaadinResolver.java b/theme-compiler/src/com/vaadin/sass/internal/resolver/VaadinResolver.java deleted file mode 100644 index fec16a54c8..0000000000 --- a/theme-compiler/src/com/vaadin/sass/internal/resolver/VaadinResolver.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.vaadin.sass.internal.resolver; - -import java.io.File; -import java.util.Stack; - -import org.w3c.css.sac.InputSource; - -public class VaadinResolver implements ScssStylesheetResolver { - - @Override - public InputSource resolve(String identifier) { - - // Remove extra "." and ".." - identifier = normalize(identifier); - - InputSource source = null; - - // Can we find the scss from the file system? - ScssStylesheetResolver resolver = new FilesystemResolver(); - source = resolver.resolve(identifier); - - if (source == null) { - // How about the classpath? - resolver = new ClassloaderResolver(); - source = resolver.resolve(identifier); - } - - return source; - } - - /** - * Normalizes "." and ".." from the path string where parent path segments - * can be removed. Preserve leading "..". - * - * @param path - * A relative or absolute file path - * @return The normalized path - */ - private static String normalize(String path) { - - // Ensure only "/" is used, also in Windows - path = path.replace(File.separatorChar, '/'); - - // Split into segments - String[] segments = path.split("/"); - Stack<String> result = new Stack<String>(); - - // Replace '.' and '..' segments - for (int i = 0; i < segments.length; i++) { - if (segments[i].equals(".")) { - // Segments marked '.' are ignored - - } else if (segments[i].equals("..") && !result.isEmpty() - && !result.lastElement().equals("..")) { - // If segment is ".." then remove the previous iff the previous - // element is not a ".." and the result stack is not empty - result.pop(); - } else { - // Other segments are just added to the stack - result.push(segments[i]); - } - } - - // Reconstruct path - StringBuilder pathBuilder = new StringBuilder(); - for (int i = 0; i < result.size(); i++) { - if (i > 0) { - pathBuilder.append("/"); - } - pathBuilder.append(result.get(i)); - } - return pathBuilder.toString(); - } - -} diff --git a/theme-compiler/src/com/vaadin/sass/internal/selector/SelectorUtil.java b/theme-compiler/src/com/vaadin/sass/internal/selector/SelectorUtil.java index 744b560116..c1f26f968e 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/selector/SelectorUtil.java +++ b/theme-compiler/src/com/vaadin/sass/internal/selector/SelectorUtil.java @@ -16,6 +16,9 @@ package com.vaadin.sass.internal.selector; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.w3c.css.sac.CombinatorCondition; import org.w3c.css.sac.Condition; import org.w3c.css.sac.ConditionFactory; @@ -115,7 +118,7 @@ public class SelectorUtil { } else if (selector.getSelectorType() == CompositeSelector.SCSS_COMPOSITE_SELECTOR) { return toString((CompositeSelector) selector); } else { - System.out.println("SU !Unknown selector type, type: " + log("SU !Unknown selector type, type: " + selector.getSelectorType() + ", " + selector.toString()); } return ""; @@ -162,8 +165,8 @@ public class SelectorUtil { PseudoClassConditionImpl pseudoClassCondition = (PseudoClassConditionImpl) condition; return ":" + pseudoClassCondition.getValue(); } else { - System.out.println("CU !condition type not identified, type: " - + conditionType + ", " + condition.toString()); + log("CU !condition type not identified, type: " + conditionType + + ", " + condition.toString()); return ""; } } @@ -330,4 +333,8 @@ public class SelectorUtil { throw new Exception("Invalid selector type"); } } + + private static void log(String msg) { + Logger.getLogger(SelectorUtil.class.getName()).log(Level.INFO, msg); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/BlockNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/BlockNode.java index 6ce67a3abd..5e7674e3b2 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/BlockNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/BlockNode.java @@ -17,6 +17,8 @@ package com.vaadin.sass.internal.tree; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; import com.vaadin.sass.internal.ScssStylesheet; import com.vaadin.sass.internal.visitor.BlockNodeHandler; @@ -39,33 +41,18 @@ public class BlockNode extends Node implements IVariableNode { this.selectorList = selectorList; } - public String toString(boolean indent) { - StringBuilder string = new StringBuilder(); - int i = 0; - for (final String s : selectorList) { - string.append(s); - if (i != selectorList.size() - 1) { - string.append(", "); - } - i++; - } - string.append(" {\n"); - for (Node child : children) { - if (indent) { - string.append("\t"); - } - string.append("\t" + child.toString() + "\n"); - } - if (indent) { - string.append("\t"); - } - string.append("}"); - return string.toString(); + public String buildString(boolean indent) { + return buildString(indent, PRINT_STRATEGY); + } + + @Override + public String printState() { + return buildString(false); } @Override public String toString() { - return toString(false); + return "BlockNode [" + buildString(true, TO_STRING_STRATEGY) + "]"; } @Override @@ -109,8 +96,33 @@ public class BlockNode extends Node implements IVariableNode { BlockNodeHandler.traverse(this); replaceVariables(ScssStylesheet.getVariables()); } catch (Exception e) { - e.printStackTrace(); + Logger.getLogger(BlockNode.class.getName()).log(Level.SEVERE, null, + e); } } + private String buildString(boolean indent, BuildStringStrategy strategy) { + StringBuilder string = new StringBuilder(); + int i = 0; + for (final String s : selectorList) { + string.append(s); + if (i != selectorList.size() - 1) { + string.append(", "); + } + i++; + } + string.append(" {\n"); + for (Node child : children) { + if (indent) { + string.append("\t"); + } + string.append("\t" + strategy.build(child) + "\n"); + } + if (indent) { + string.append("\t"); + } + string.append("}"); + return string.toString(); + } + } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/CommentNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/CommentNode.java index 70947d6022..968d0f7798 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/CommentNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/CommentNode.java @@ -32,11 +32,16 @@ public class CommentNode extends Node { } @Override - public String toString() { + public String printState() { return comment; } @Override + public String toString() { + return "Comment node [" + comment + "]"; + } + + @Override public void traverse() { // Not used in CommentNode } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/ExtendNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/ExtendNode.java index 417849d13b..7614f7c606 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/ExtendNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/ExtendNode.java @@ -17,6 +17,8 @@ package com.vaadin.sass.internal.tree; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; import com.vaadin.sass.internal.visitor.ExtendNodeHandler; @@ -39,6 +41,11 @@ public class ExtendNode extends Node implements IVariableNode { } + @Override + public String toString() { + return "Extend node [" + getListAsString() + "]"; + } + public String getListAsString() { StringBuilder b = new StringBuilder(); for (final String s : list) { @@ -54,7 +61,8 @@ public class ExtendNode extends Node implements IVariableNode { ExtendNodeHandler.traverse(this); getParentNode().removeChild(this); } catch (Exception e) { - e.printStackTrace(); + Logger.getLogger(ExtendNode.class.getName()).log(Level.SEVERE, + null, e); } } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/FontFaceNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/FontFaceNode.java index 8986691984..b953b1af11 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/FontFaceNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/FontFaceNode.java @@ -18,21 +18,30 @@ package com.vaadin.sass.internal.tree; public class FontFaceNode extends Node { @Override + public String printState() { + return buildString(PRINT_STRATEGY); + } + + @Override public String toString() { + return "FontFace node [" + buildString(TO_STRING_STRATEGY) + "]"; + } + + @Override + public void traverse() { + // Not in use for FontFaceNode + } + + private String buildString(BuildStringStrategy strategy) { StringBuilder builder = new StringBuilder(); builder.append("@font-face {\n"); for (final Node child : children) { - builder.append("\t" + child.toString() + "\n"); + builder.append("\t" + strategy.build(child) + "\n"); } builder.append("}"); return builder.toString(); } - @Override - public void traverse() { - // Not in use for FontFaceNode - } - } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/FunctionNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/FunctionNode.java index ced4671051..2d1001f47f 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/FunctionNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/FunctionNode.java @@ -50,7 +50,7 @@ public class FunctionNode extends Node implements IVariableNode { for (final VariableNode node : variables) { if (StringUtil.containsVariable(args, node.getName())) { args = StringUtil.replaceVariable(args, node.getName(), node - .getExpr().toString()); + .getExpr().printState()); } } } @@ -59,4 +59,5 @@ public class FunctionNode extends Node implements IVariableNode { public void traverse() { replaceVariables(ScssStylesheet.getVariables()); } + } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java index 6dc95db5c2..e112752138 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java @@ -43,7 +43,7 @@ public class ImportNode extends Node { } @Override - public String toString() { + public String printState() { StringBuilder builder = new StringBuilder("@import "); if (isURL) { builder.append("url(").append(uri).append(")"); @@ -59,6 +59,11 @@ public class ImportNode extends Node { return builder.toString(); } + @Override + public String toString() { + return "Import node [" + printState() + "]"; + } + public String getUri() { return uri; } @@ -76,4 +81,5 @@ public class ImportNode extends Node { // nested imports ImportNodeHandler.traverse(getParentNode()); } + } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframeSelectorNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframeSelectorNode.java index 085cd46d31..e89b9b2494 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframeSelectorNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframeSelectorNode.java @@ -24,14 +24,14 @@ public class KeyframeSelectorNode extends Node { } @Override + public String printState() { + return buildString(PRINT_STRATEGY); + } + + @Override public String toString() { - StringBuilder string = new StringBuilder(); - string.append(selector).append(" {\n"); - for (Node child : children) { - string.append("\t\t").append(child.toString()).append("\n"); - } - string.append("\t}"); - return string.toString(); + return "Key frame selector node [" + buildString(TO_STRING_STRATEGY) + + "]"; } @Override @@ -39,4 +39,13 @@ public class KeyframeSelectorNode extends Node { } + public String buildString(BuildStringStrategy strategy) { + StringBuilder string = new StringBuilder(); + string.append(selector).append(" {\n"); + for (Node child : children) { + string.append("\t\t").append(strategy.build(child)).append("\n"); + } + string.append("\t}"); + return string.toString(); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframesNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframesNode.java index b5e7491639..28b1b0d42f 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframesNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/KeyframesNode.java @@ -31,15 +31,13 @@ public class KeyframesNode extends Node implements IVariableNode { } @Override + public String printState() { + return buildString(PRINT_STRATEGY); + } + + @Override public String toString() { - StringBuilder string = new StringBuilder(); - string.append(keyframeName).append(" ").append(animationName) - .append(" {\n"); - for (Node child : children) { - string.append("\t\t").append(child.toString()).append("\n"); - } - string.append("\t}"); - return string.toString(); + return "Key frames node [" + buildString(TO_STRING_STRATEGY) + "]"; } @Override @@ -61,4 +59,14 @@ public class KeyframesNode extends Node implements IVariableNode { } } + private String buildString(BuildStringStrategy strategy) { + StringBuilder string = new StringBuilder(); + string.append(keyframeName).append(" ").append(animationName) + .append(" {\n"); + for (Node child : children) { + string.append("\t\t").append(strategy.build(child)).append("\n"); + } + string.append("\t}"); + return string.toString(); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/ListContainsNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/ListContainsNode.java index d2701647ee..54ec7550d7 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/ListContainsNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/ListContainsNode.java @@ -39,6 +39,5 @@ public class ListContainsNode extends ListModifyNode { VariableNode node = new VariableNode(variable.substring(1), LexicalUnitImpl.createString(contains), false); return node; - } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/ListModifyNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/ListModifyNode.java index 0c2327c90e..9da810d37b 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/ListModifyNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/ListModifyNode.java @@ -32,6 +32,12 @@ public abstract class ListModifyNode extends Node implements IVariableNode { return variable; } + @Override + public String toString() { + return "List append node [var = " + variable + " , list =" + list + + ", separator =" + separator + ", modify =" + modify + "]"; + } + public VariableNode getModifiedList() { final ArrayList<String> newList = new ArrayList<String>(list); modifyList(newList); @@ -95,10 +101,10 @@ public abstract class ListModifyNode extends Node implements IVariableNode { if (var.getName().equals(listVar.substring(1))) { String[] split = null; - if (var.getExpr().toString().contains(",")) { - split = var.getExpr().toString().split(","); + if (var.getExpr().printState().contains(",")) { + split = var.getExpr().printState().split(","); } else { - split = var.getExpr().toString().split(" "); + split = var.getExpr().printState().split(" "); } int i = list.indexOf(listVar); for (final String s : split) { diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/MediaNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/MediaNode.java index 34d8ccbf7d..c5494cb665 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/MediaNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/MediaNode.java @@ -37,7 +37,21 @@ public class MediaNode extends Node { } @Override + public String printState() { + return buildString(PRINT_STRATEGY, true); + } + + @Override public String toString() { + return buildString(TO_STRING_STRATEGY, true); + } + + @Override + public void traverse() { + + } + + private String buildString(BuildStringStrategy strategy, boolean indent) { StringBuilder builder = new StringBuilder("@media "); if (media != null) { for (int i = 0; i < media.getLength(); i++) { @@ -49,20 +63,20 @@ public class MediaNode extends Node { } builder.append(" {\n"); for (Node child : children) { + builder.append('\t'); if (child instanceof BlockNode) { - builder.append("\t" + ((BlockNode) child).toString(true) + "\n"); + if (PRINT_STRATEGY.equals(strategy)) { + builder.append(((BlockNode) child).buildString(indent)); + } else { + builder.append(strategy.build(child)); + + } } else { - builder.append("\t" + child.toString() + "\n"); + builder.append(strategy.build(child)); } - + builder.append('\n'); } builder.append("}"); return builder.toString(); } - - @Override - public void traverse() { - - } - } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/MicrosoftRuleNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/MicrosoftRuleNode.java index 3938188a72..18946d7279 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/MicrosoftRuleNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/MicrosoftRuleNode.java @@ -35,17 +35,22 @@ public class MicrosoftRuleNode extends Node implements IVariableNode { for (final VariableNode var : variables) { if (StringUtil.containsVariable(value, var.getName())) { value = StringUtil.replaceVariable(value, var.getName(), var - .getExpr().toString()); + .getExpr().printState()); } } } @Override - public String toString() { + public String printState() { return name + ": " + value + ";"; } @Override + public String toString() { + return "MicrosoftRule node [" + printState() + "]"; + } + + @Override public void traverse() { replaceVariables(ScssStylesheet.getVariables()); } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/MixinNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/MixinNode.java index e702bc8577..23d65e1660 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/MixinNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/MixinNode.java @@ -19,6 +19,8 @@ package com.vaadin.sass.internal.tree; import java.util.ArrayList; import java.util.Collection; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import com.vaadin.sass.internal.ScssStylesheet; import com.vaadin.sass.internal.parser.LexicalUnitImpl; @@ -43,10 +45,15 @@ public class MixinNode extends Node implements IVariableNode { } @Override - public String toString() { + public String printState() { return "name: " + name + " args: " + arglist; } + @Override + public String toString() { + return "Mixin node [" + printState() + "]"; + } + public String getName() { return name; } @@ -86,11 +93,11 @@ public class MixinNode extends Node implements IVariableNode { if (name.startsWith("$")) { if (name.equals("$" + var.getName())) { - name = var.getExpr().toString(); + name = var.getExpr().printState(); } } else if (name.startsWith("#{") && name.endsWith("}")) { if (name.equals("#{$" + var.getName() + "}")) { - name = var.getExpr().toString(); + name = var.getExpr().printState(); } } } @@ -119,7 +126,8 @@ public class MixinNode extends Node implements IVariableNode { ScssStylesheet.closeVariableScope(variableScope); } catch (Exception e) { - e.printStackTrace(); + Logger.getLogger(MixinNode.class.getName()).log(Level.SEVERE, null, + e); } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/NestPropertiesNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/NestPropertiesNode.java index fc50cfda61..fb35e13175 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/NestPropertiesNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/NestPropertiesNode.java @@ -40,6 +40,11 @@ public class NestPropertiesNode extends Node implements IVariableNode { this.name = name; } + @Override + public String toString() { + return "Nest properties node [ name = " + name + " ]"; + } + public Collection<RuleNode> unNesting() { List<RuleNode> result = new ArrayList<RuleNode>(); for (Node child : children) { @@ -71,4 +76,9 @@ public class NestPropertiesNode extends Node implements IVariableNode { NestedNodeHandler.traverse(this); } + @Override + public String printState() { + return null; + } + } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/Node.java b/theme-compiler/src/com/vaadin/sass/internal/tree/Node.java index 98b701d5a9..ea01655571 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/Node.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/Node.java @@ -20,7 +20,14 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; +import com.vaadin.sass.internal.parser.LexicalUnitImpl; + public abstract class Node implements Serializable { + + public static BuildStringStrategy PRINT_STRATEGY = new PrintStrategy(); + + public static BuildStringStrategy TO_STRING_STRATEGY = new ToStringStrategy(); + private static final long serialVersionUID = 5914711715839294816L; protected ArrayList<Node> children; @@ -108,11 +115,6 @@ public abstract class Node implements Serializable { return !children.isEmpty(); } - @Override - public String toString() { - return ""; - } - /** * Method for manipulating the data contained within the {@link Node}. * @@ -123,6 +125,19 @@ public abstract class Node implements Serializable { */ public abstract void traverse(); + /** + * Prints out the current state of the node tree. Will return SCSS before + * compile and CSS after. + * + * Result value could be null. + * + * @since 7.2 + * @return State as a string + */ + public String printState() { + return null; + } + public Node getParentNode() { return parentNode; } @@ -131,4 +146,39 @@ public abstract class Node implements Serializable { this.parentNode = parentNode; } + public static interface BuildStringStrategy { + + String build(Node node); + + String build(LexicalUnitImpl unit); + } + + public static class PrintStrategy implements BuildStringStrategy { + + @Override + public String build(Node node) { + return node.printState(); + } + + @Override + public String build(LexicalUnitImpl unit) { + return unit.printState(); + } + + } + + public static class ToStringStrategy implements BuildStringStrategy { + + @Override + public String build(Node node) { + return node.toString(); + } + + @Override + public String build(LexicalUnitImpl unit) { + return unit.toString(); + } + + } + } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java index a8fa87eb0a..e9886e6871 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java @@ -57,19 +57,13 @@ public class RuleNode extends Node implements IVariableNode { } @Override - public String toString() { - String stringValue = value.toString() - + (important ? " !important" : ""); - if (!"".equals(stringValue.trim())) { - stringValue = variable + ": " + stringValue + ";"; - } else { - stringValue = ""; - } + public String printState() { + return buildString(PRINT_STRATEGY); + } - if (comment != null) { - stringValue += comment; - } - return stringValue; + @Override + public String toString() { + return "Rule node [" + buildString(TO_STRING_STRATEGY) + "]"; } public boolean isImportant() { @@ -104,12 +98,12 @@ public class RuleNode extends Node implements IVariableNode { if (value.getParameters() != null) { if (StringUtil.containsVariable(value.getParameters() - .toString(), node.getName())) { + .printState(), node.getName())) { LexicalUnitImpl param = value.getParameters(); while (param != null) { if (param.getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE - && param.getValue().toString() - .equals(node.getName())) { + && param.getValueAsString().equals( + node.getName())) { param.replaceValue(node.getExpr()); } param = param.getNextLexicalUnit(); @@ -120,11 +114,9 @@ public class RuleNode extends Node implements IVariableNode { && value.getStringValue().contains(interpolation)) { LexicalUnitImpl current = value; while (current != null) { - if (current.getValue().toString().contains(interpolation)) { + if (current.getValueAsString().contains(interpolation)) { - current.setStringValue(current - .getValue() - .toString() + current.setStringValue(current.getValueAsString() .replaceAll(Pattern.quote(interpolation), node.getExpr().unquotedString())); } @@ -134,7 +126,7 @@ public class RuleNode extends Node implements IVariableNode { LexicalUnitImpl current = value; while (current != null) { if (current.getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE - && current.getValue().toString() + && current.getValueAsString() .equals(node.getName())) { current.replaceValue(node.getExpr()); @@ -163,4 +155,21 @@ public class RuleNode extends Node implements IVariableNode { replaceVariables(ScssStylesheet.getVariables()); } } + + private String buildString(BuildStringStrategy strategy) { + String stringValue = strategy.build(value) + + (important ? " !important" : ""); + StringBuilder builder = new StringBuilder(); + if (!"".equals(stringValue.trim())) { + builder.append(variable); + builder.append(": "); + builder.append(stringValue); + builder.append(';'); + } + + if (comment != null) { + builder.append(comment); + } + return builder.toString(); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/SimpleNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/SimpleNode.java index 796f4d8d1d..91d9767b89 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/SimpleNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/SimpleNode.java @@ -38,16 +38,21 @@ public class SimpleNode extends Node implements IVariableNode { } @Override - public String toString() { + public String printState() { return text; } @Override + public String toString() { + return printState(); + } + + @Override public void replaceVariables(ArrayList<VariableNode> variables) { for (final VariableNode node : variables) { if (StringUtil.containsVariable(text, node.getName())) { text = StringUtil.replaceVariable(text, node.getName(), node - .getExpr().toString()); + .getExpr().printState()); } } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/VariableNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/VariableNode.java index f2499d72ab..6884ae6f36 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/VariableNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/VariableNode.java @@ -59,10 +59,13 @@ public class VariableNode extends Node implements IVariableNode { } @Override + public String printState() { + return buildString(PRINT_STRATEGY); + } + + @Override public String toString() { - StringBuilder builder = new StringBuilder("$"); - builder.append(name).append(": ").append(expr); - return builder.toString(); + return "Variable node [" + buildString(TO_STRING_STRATEGY) + "]"; } public void setGuarded(boolean guarded) { @@ -74,11 +77,11 @@ public class VariableNode extends Node implements IVariableNode { for (final VariableNode node : variables) { if (!equals(node)) { - if (StringUtil - .containsVariable(expr.toString(), node.getName())) { + if (StringUtil.containsVariable(expr.printState(), + node.getName())) { if (expr.getParameters() != null && StringUtil.containsVariable(expr.getParameters() - .toString(), node.getName())) { + .printState(), node.getName())) { replaceValues(expr.getParameters(), node); } else if (expr.getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE) { replaceValues(expr, node); @@ -92,7 +95,7 @@ public class VariableNode extends Node implements IVariableNode { while (unit != null) { if (unit.getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE - && unit.getValue().toString().equals(node.getName())) { + && unit.getValueAsString().equals(node.getName())) { LexicalUnitImpl.replaceValues(unit, node.getExpr()); } @@ -119,4 +122,10 @@ public class VariableNode extends Node implements IVariableNode { } VariableNodeHandler.traverse(this); } + + private String buildString(BuildStringStrategy strategy) { + StringBuilder builder = new StringBuilder("$"); + builder.append(name).append(": ").append(strategy.build(expr)); + return builder.toString(); + } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/EachDefNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/EachDefNode.java index fe1775f26b..88dbf2c25b 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/EachDefNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/EachDefNode.java @@ -80,7 +80,7 @@ public class EachDefNode extends Node implements IVariableNode { while (current != null) { if (current.getValue() != null && current.getLexicalUnitType() != LexicalUnitImpl.SAC_OPERATOR_COMMA) { - list.add(current.getValue().toString()); + list.add(current.getValueAsString()); } current = current.getNextLexicalUnit(); } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfElseDefNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfElseDefNode.java index 735d83a898..8c7fa86596 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfElseDefNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfElseDefNode.java @@ -15,19 +15,22 @@ */ package com.vaadin.sass.internal.tree.controldirective; +import java.util.logging.Level; +import java.util.logging.Logger; + import com.vaadin.sass.internal.tree.Node; import com.vaadin.sass.internal.visitor.IfElseNodeHandler; public class IfElseDefNode extends Node { @Override + public String printState() { + return buildString(PRINT_STRATEGY); + } + + @Override public String toString() { - StringBuilder b = new StringBuilder(); - for (final Node child : getChildren()) { - b.append(child.toString()); - b.append("\n"); - } - return b.toString(); + return "IfElseDef node [" + buildString(TO_STRING_STRATEGY) + "]"; } @Override @@ -40,8 +43,18 @@ public class IfElseDefNode extends Node { IfElseNodeHandler.traverse(this); } catch (Exception e) { - e.printStackTrace(); + Logger.getLogger(IfElseDefNode.class.getName()).log(Level.SEVERE, + null, e); + } + } + + private String buildString(BuildStringStrategy strategy) { + StringBuilder b = new StringBuilder(); + for (final Node child : getChildren()) { + b.append(strategy.build(child)); + b.append("\n"); } + return b.toString(); } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfNode.java index af795a58c3..6c98927110 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfNode.java +++ b/theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfNode.java @@ -41,7 +41,7 @@ public class IfNode extends Node implements IfElseNode, IVariableNode { @Override public String toString() { - return "@if" + expression; + return "@if " + expression; } @Override @@ -49,7 +49,7 @@ public class IfNode extends Node implements IfElseNode, IVariableNode { for (final VariableNode node : variables) { if (StringUtil.containsVariable(expression, node.getName())) { expression = StringUtil.replaceVariable(expression, - node.getName(), node.getExpr().toString()); + node.getName(), node.getExpr().printState()); } } } diff --git a/theme-compiler/src/com/vaadin/sass/internal/util/DeepCopy.java b/theme-compiler/src/com/vaadin/sass/internal/util/DeepCopy.java index bc30ffdd6c..af66eb9a74 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/util/DeepCopy.java +++ b/theme-compiler/src/com/vaadin/sass/internal/util/DeepCopy.java @@ -22,13 +22,15 @@ import java.io.ObjectOutputStream; import java.util.Collection; import java.util.LinkedList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Utility for making deep copies (vs. clone()'s shallow copies) of objects. * Objects are first serialized and then deserialized. Error checking is fairly * minimal in this implementation. If an object is encountered that cannot be * serialized (or that references an object that cannot be serialized) an error - * is printed to System.err and null is returned. Depending on your specific + * is printed to the logger and null is returned. Depending on your specific * application, it might make more sense to have copy(...) re-throw the * exception. */ @@ -56,9 +58,9 @@ public class DeepCopy { obj = in.readObject(); in.close(); } catch (IOException e) { - e.printStackTrace(); + log(e); } catch (ClassNotFoundException cnfe) { - cnfe.printStackTrace(); + log(cnfe); } return obj; } else { @@ -80,4 +82,8 @@ public class DeepCopy { } return copies; } + + private static void log(Throwable e) { + Logger.getLogger(DeepCopy.class.getName()).log(Level.SEVERE, null, e); + } }
\ No newline at end of file diff --git a/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java b/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java index cb9896967a..daf01a3eab 100644 --- a/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java +++ b/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java @@ -16,10 +16,11 @@ package com.vaadin.sass.internal.visitor; -import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; import org.w3c.css.sac.CSSException; import org.w3c.css.sac.LexicalUnit; @@ -57,25 +58,14 @@ public class ImportNodeHandler { ImportNode importNode = (ImportNode) n; if (!importNode.isPureCssImport()) { try { - StringBuilder filePathBuilder = new StringBuilder( - styleSheet.getFileName()); - filePathBuilder.append(File.separatorChar).append( - importNode.getUri()); - if (!filePathBuilder.toString().endsWith(".scss")) { - filePathBuilder.append(".scss"); - } - // set parent's charset to imported node. ScssStylesheet imported = ScssStylesheet.get( - filePathBuilder.toString(), - styleSheet.getCharset()); - if (imported == null) { - imported = ScssStylesheet.get(importNode.getUri()); - } + importNode.getUri(), styleSheet); if (imported == null) { - throw new FileNotFoundException(importNode.getUri() - + " (parent: " - + ScssStylesheet.get().getFileName() + ")"); + throw new FileNotFoundException("Import '" + + importNode.getUri() + "' in '" + + styleSheet.getFileName() + + "' could not be found"); } traverse(imported); @@ -90,9 +80,11 @@ public class ImportNodeHandler { importNode); node.removeChild(importNode); } catch (CSSException e) { - e.printStackTrace(); + Logger.getLogger(ImportNodeHandler.class.getName()) + .log(Level.SEVERE, null, e); } catch (IOException e) { - e.printStackTrace(); + Logger.getLogger(ImportNodeHandler.class.getName()) + .log(Level.SEVERE, null, e); } } else { if (styleSheet != node) { diff --git a/theme-compiler/src/logging.properties b/theme-compiler/src/logging.properties new file mode 100644 index 0000000000..b563d4b68e --- /dev/null +++ b/theme-compiler/src/logging.properties @@ -0,0 +1,2 @@ +handlers = com.vaadin.sass.CustomConsoleHandler +.level = ALL
\ No newline at end of file diff --git a/theme-compiler/tests/resources/automatic/css/media.css b/theme-compiler/tests/resources/automatic/css/media.css index f4183d9a07..5f7267fa9a 100644 --- a/theme-compiler/tests/resources/automatic/css/media.css +++ b/theme-compiler/tests/resources/automatic/css/media.css @@ -1,3 +1,14 @@ +@media screen { + .v-view { + overflow: visible; + } + .details { + font-size: 1pt; + font-weight: bold; + } + width: 100%; +} + @media screen and (max-width: 480px) { .abc { background: red; diff --git a/theme-compiler/tests/resources/automatic/css/mixin-empty-paramlist.css b/theme-compiler/tests/resources/automatic/css/mixin-empty-paramlist.css deleted file mode 100644 index 59ef68680d..0000000000 --- a/theme-compiler/tests/resources/automatic/css/mixin-empty-paramlist.css +++ /dev/null @@ -1,15 +0,0 @@ -body { - color: blue; -} - -h1 { - text-align: center; -} - -p { - font-style: italic; -} - -table { - width: 100%; -}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/automatic/scss/media.scss b/theme-compiler/tests/resources/automatic/scss/media.scss index 7db52de9ed..311c5088c8 100644 --- a/theme-compiler/tests/resources/automatic/scss/media.scss +++ b/theme-compiler/tests/resources/automatic/scss/media.scss @@ -1,3 +1,24 @@ +@mixin media-settings { + @media screen { + .v-view { + overflow: visible; + } + @content; + } +} + +@include media-settings { + .details { + font: { + size : 1pt; + weight: bold; + } + } + + width:100%; +} + + @media screen and (max-width: 480px) { .abc { background: red; diff --git a/theme-compiler/tests/resources/automatic/scss/mixin-empty-paramlist.scss b/theme-compiler/tests/resources/automatic/scss/mixin-empty-paramlist.scss deleted file mode 100644 index 27033ba850..0000000000 --- a/theme-compiler/tests/resources/automatic/scss/mixin-empty-paramlist.scss +++ /dev/null @@ -1,28 +0,0 @@ -@mixin emptyarglist1(){ - body{ - color: blue; - } -} - -@mixin emptyarglist2(){ - h1{ - text-align:center; - } -} - -@mixin emptyarglist3{ - p{ - font-style:italic; - } -} - -@mixin emptyarglist4{ - table{ - width: 100%; - } -} - -@include emptyarglist1(); -@include emptyarglist2; -@include emptyarglist3(); -@include emptyarglist4;
\ No newline at end of file diff --git a/theme-compiler/tests/resources/css/compass-import.css b/theme-compiler/tests/resources/css/compass-import.css new file mode 100644 index 0000000000..e3d4b5fcca --- /dev/null +++ b/theme-compiler/tests/resources/css/compass-import.css @@ -0,0 +1,49 @@ +.content-navigation { + border-color: #3bbfce; + color: #0000ff; +} + +.border { + padding: 8px; + margin: 8px; + border-color: #3bbfce; +} + +.body { + background-image: url(compass/folder-test2/bg.png); + background: transparent url(compass/folder-test2/img/loading-indicator.gif); + background-image: url(http://abc/bg.png); + background-image: url(/abc/bg.png); +} + +.base { + color: red; +} + +.text { + font-weight: bold; +} + +.footer { + border: 2px solid black; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; +} + +.banner { + border: 1px solid black; + font-color: red; +} + +.interpolation-test { + font-size: 14px; +} + +.header { + width: 100%; +} + +.badError { + border-width: 3px; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/css/functions.css b/theme-compiler/tests/resources/css/functions.css index 3f6c2bd810..4486599450 100644 --- a/theme-compiler/tests/resources/css/functions.css +++ b/theme-compiler/tests/resources/css/functions.css @@ -13,4 +13,7 @@ color: #f00; color: hsl(33, 7%, 89%); color: hsl(33, 7%, 95%); + color: rgb(1, 2, 3); + percents: -20%; + percents: 33.33%; }
\ No newline at end of file diff --git a/theme-compiler/tests/resources/sasslang/css/100-test_optional_extend_does_not_warn_when_extension_fails.css b/theme-compiler/tests/resources/sasslangbroken/css/100-test_optional_extend_does_not_warn_when_extension_fails.css index 29116d880b..29116d880b 100644 --- a/theme-compiler/tests/resources/sasslang/css/100-test_optional_extend_does_not_warn_when_extension_fails.css +++ b/theme-compiler/tests/resources/sasslangbroken/css/100-test_optional_extend_does_not_warn_when_extension_fails.css diff --git a/theme-compiler/tests/resources/sasslang/css/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.css b/theme-compiler/tests/resources/sasslangbroken/css/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.css index 8b13789179..8b13789179 100644 --- a/theme-compiler/tests/resources/sasslang/css/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.css +++ b/theme-compiler/tests/resources/sasslangbroken/css/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.css diff --git a/theme-compiler/tests/resources/sasslang/scss/100-test_optional_extend_does_not_warn_when_extension_fails.scss b/theme-compiler/tests/resources/sasslangbroken/scss/100-test_optional_extend_does_not_warn_when_extension_fails.scss index 6d707236f2..6d707236f2 100644 --- a/theme-compiler/tests/resources/sasslang/scss/100-test_optional_extend_does_not_warn_when_extension_fails.scss +++ b/theme-compiler/tests/resources/sasslangbroken/scss/100-test_optional_extend_does_not_warn_when_extension_fails.scss diff --git a/theme-compiler/tests/resources/sasslang/scss/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.scss b/theme-compiler/tests/resources/sasslangbroken/scss/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.scss index 551764036f..551764036f 100644 --- a/theme-compiler/tests/resources/sasslang/scss/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.scss +++ b/theme-compiler/tests/resources/sasslangbroken/scss/99-test_optional_extend_does_not_warn_when_extendee_doesnt_exist.scss diff --git a/theme-compiler/tests/resources/scss/compass-test/compass-import.scss b/theme-compiler/tests/resources/scss/compass-test/compass-import.scss new file mode 100644 index 0000000000..36d041b33c --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test/compass-import.scss @@ -0,0 +1,4 @@ +@import "compass"; +.badError { + border-width: 3px; +} diff --git a/theme-compiler/tests/resources/scss/compass-test2/_compass.scss b/theme-compiler/tests/resources/scss/compass-test2/_compass.scss new file mode 100644 index 0000000000..9b741c0f03 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/_compass.scss @@ -0,0 +1,3 @@ +@import "compass/utilities"; +@import "compass/typography"; +@import "compass/css3"; diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass-import2.scss b/theme-compiler/tests/resources/scss/compass-test2/compass-import2.scss new file mode 100644 index 0000000000..36d041b33c --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass-import2.scss @@ -0,0 +1,4 @@ +@import "compass"; +.badError { + border-width: 3px; +} diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/_css3.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/_css3.scss new file mode 100644 index 0000000000..42163ba193 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/_css3.scss @@ -0,0 +1,3 @@ +@import "css3/border-radius"; +@import "css3/inline-block"; +@import "css3/opacity"; diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/_typography.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/_typography.scss new file mode 100644 index 0000000000..a65c1ff292 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/_typography.scss @@ -0,0 +1,3 @@ +@import "typography/links"; +@import "typography/lists"; +@import "typography/text"; diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/_utilities.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/_utilities.scss new file mode 100644 index 0000000000..644ad3368b --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/_utilities.scss @@ -0,0 +1,3 @@ +@import "utilities/color"; +@import "utilities/general"; +@import "utilities/sprites"; diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_border-radius.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_border-radius.scss new file mode 100644 index 0000000000..752003104b --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_border-radius.scss @@ -0,0 +1,4 @@ +.banner { + border: 1px solid black; + font-color: red; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_inline-block.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_inline-block.scss new file mode 100644 index 0000000000..3fefab83b2 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_inline-block.scss @@ -0,0 +1,3 @@ +.interpolation-test { + font-size: 14px; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_opacity.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_opacity.scss new file mode 100644 index 0000000000..f6bf34fe24 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/css3/_opacity.scss @@ -0,0 +1,3 @@ +.header { + width: 100%; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_links.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_links.scss new file mode 100644 index 0000000000..bc7318558e --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_links.scss @@ -0,0 +1,3 @@ +.base { + color: red; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_lists.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_lists.scss new file mode 100644 index 0000000000..af174b7095 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_lists.scss @@ -0,0 +1,3 @@ +.text { + font-weight: bold; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_text.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_text.scss new file mode 100644 index 0000000000..8239527f7b --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/typography/_text.scss @@ -0,0 +1,6 @@ +.footer { + border: 2px solid black; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_color.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_color.scss new file mode 100644 index 0000000000..ea1b7a55f0 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_color.scss @@ -0,0 +1,4 @@ +.content-navigation { + border-color: #3bbfce; + color: #0000ff; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_general.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_general.scss new file mode 100644 index 0000000000..0c58c6433d --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_general.scss @@ -0,0 +1,5 @@ +.border { + padding: 8px; + margin: 8px; + border-color: #3bbfce; +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_sprites.scss b/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_sprites.scss new file mode 100644 index 0000000000..28960f89fc --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/compass/utilities/_sprites.scss @@ -0,0 +1,6 @@ +.body { + background-image: url(../folder-test2/bg.png); + background: transparent url(../folder-test2/img/loading-indicator.gif); + background-image: url(http://abc/bg.png); + background-image: url(/abc/bg.png); +}
\ No newline at end of file diff --git a/theme-compiler/tests/resources/scss/compass-test2/license-readme.txt b/theme-compiler/tests/resources/scss/compass-test2/license-readme.txt new file mode 100644 index 0000000000..90ba808179 --- /dev/null +++ b/theme-compiler/tests/resources/scss/compass-test2/license-readme.txt @@ -0,0 +1,26 @@ +The design here is to use the stylesheets located at: +https://github com/chriseppstein/compass/tree/stable/frameworks/compass/stylesheets + +and update the VAADIN code to be able to read them in such that an existing JRuby implementation can be replaced with VAADIN without any changes to one's *.scss and *.css files. + +The current short snippets of SCSS that are included here only for testing Compass compatibility might not qualify as significant or substantial parts, but in any case Compass is being mentioned for related tests pointing to the original implementation. These small portions of Compass are copied and modified for the testing of compatibility only. + +The license for Compass mentioned here: +https://github.com/chriseppstein/compass/blob/stable/LICENSE.markdown + +is as follows: + + + + +Copyright (c) 2009 Christopher M. Eppstein + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. No attribution is required by products that make use of this software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization. + +Contributors to this project agree to grant all rights to the copyright holder of the primary product. Attribution is maintained in the source control history of the product. diff --git a/theme-compiler/tests/resources/scss/functions.scss b/theme-compiler/tests/resources/scss/functions.scss index 93c1a6a64a..8638d0afaa 100644 --- a/theme-compiler/tests/resources/scss/functions.scss +++ b/theme-compiler/tests/resources/scss/functions.scss @@ -1,5 +1,8 @@ $base-color : hsl(33, 7%, 89%); $app-bg-color : lighten($base-color, 6%); +$red:1; +$green:2; +$blue:3; .main { margin: abs(-2px); border: ceil(10.4px); @@ -15,4 +18,7 @@ $app-bg-color : lighten($base-color, 6%); color: lighten(#800, 20%); color : $base-color; color : $app-bg-color; -}
\ No newline at end of file + color: rgb($red, $green, $blue); + percents: percentage(-0.2); + percents: percentage(0.3333); +} diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.0.scss new file mode 100644 index 0000000000..2f1e55e87e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-001.htm */ + +html { margin:10px; border:20px solid black; padding:30px; } +body { height:10000px; margin:0; } +div { position:absolute; width:100px; height:100px; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.1.scss new file mode 100644 index 0000000000..7b5eace311 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-001.htm */ +.style { top:0; background:yellow; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.2.scss new file mode 100644 index 0000000000..c94661f654 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-001.htm */ +.style { right:0; background:orange; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.3.scss new file mode 100644 index 0000000000..893b95ca14 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-001.htm */ +.style { bottom:0; background:brown; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.4.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.4.scss new file mode 100644 index 0000000000..71d199866c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-001.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-001.htm */ +.style { left:0; background:pink; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004a.0.scss new file mode 100644 index 0000000000..457f6a2d2f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004a.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004a.htm */ +.style { position:absolute; left:100px; top:100px; width:100px; height:100px; background:yellow; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004b.0.scss new file mode 100644 index 0000000000..8990089fb6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004b.htm */ +.style { position:fixed; left:100px; top:100px; width:100px; height:100px; background:yellow; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004c.0.scss new file mode 100644 index 0000000000..1bad688abe --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004c.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004c.htm */ +.style { position:absolute; left:100px; top:100px; width:100px; height:100px; background:yellow; border:10px solid black; display:table; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004d.0.scss new file mode 100644 index 0000000000..8f8b50e4c7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004d.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004d.htm */ +.style { position:fixed; left:100px; top:100px; width:100px; height:100px; background:yellow; border:10px solid black; display:table } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004e.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004e.0.scss new file mode 100644 index 0000000000..0c460b5c3f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004e.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004e.htm */ +.style { display:table } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004e.1.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004e.1.scss new file mode 100644 index 0000000000..29c22194fd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004e.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004e.htm */ +.style { position:absolute; left:100px; top:100px; width:100px; height:100px; border:10px solid black; background:yellow; margin:0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004f.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004f.0.scss new file mode 100644 index 0000000000..33f39b6ab6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004f.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004f.htm */ +.style { display:table } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004f.1.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004f.1.scss new file mode 100644 index 0000000000..c458e5dc33 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-004f.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-004f.htm */ +.style { position:fixed; left:100px; top:100px; width:100px; height:100px; border:10px solid black; background:yellow; margin:0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005a.0.scss new file mode 100644 index 0000000000..a724d1b918 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005a.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-005a.htm */ +.style { position:absolute; width:100px; height:100px; background:yellow; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005b.0.scss new file mode 100644 index 0000000000..d9b1214a4b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-005b.htm */ +.style { position:absolute; width:100px; height:100px; display:table; background:yellow; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005c.0.scss new file mode 100644 index 0000000000..e6e7f6b90b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005c.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-005c.htm */ +.style { position:fixed; width:100px; height:100px; background:yellow; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005d.0.scss new file mode 100644 index 0000000000..1bc05d796a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-005d.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-005d.htm */ +.style { position:fixed; width:100px; height:100px; display:table; background:yellow; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-007.0.scss new file mode 100644 index 0000000000..9080cba258 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-007.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-007.htm */ +.style { position:relative; top:100px; left:100px; height:100px; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-007.1.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-007.1.scss new file mode 100644 index 0000000000..40f293c03b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-007.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-007.htm */ +.style { position:absolute; margin:0; bottom:0; height:30px; border:10px solid orange; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009a.0.scss new file mode 100644 index 0000000000..ac865fb846 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009a.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-009a.htm */ +.style { width:50%; height:50%; margin:50px; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009b.0.scss new file mode 100644 index 0000000000..0b108fff62 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-009b.htm */ +.style { position:absolute; left:50px; top:50px; width:50%; height:50%; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009e.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009e.0.scss new file mode 100644 index 0000000000..f5bda4dc9f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009e.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-009e.htm */ +.style { position:absolute; width:50%; height:50%; top:50px; left:50px; margin:0; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009f.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009f.0.scss new file mode 100644 index 0000000000..788e50c119 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009f.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-009f.htm */ +.style { position:relative; height:50%; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009f.1.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009f.1.scss new file mode 100644 index 0000000000..e1c3142ad8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-containing-block-initial-009f.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-containing-block-initial-009f.htm */ +.style { position:absolute; width:50%; top:50px; left:50px; height:100%; margin:0; border:10px solid black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-non-replaced-width-margin-000.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-non-replaced-width-margin-000.0.scss new file mode 100644 index 0000000000..69f5c2fa6a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-non-replaced-width-margin-000.0.scss @@ -0,0 +1,93 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-non-replaced-width-margin-000.htm */ + + +div { height: 1px; direction: ltr; } + +/* + * Every case here has three divs nested inside of each other. The + * innermost div (absolutely positioned) is the testcase (and has + * color). The middle div's content edge establishes the containing + * block it would have if it were statically positioned. The outermost + * div is actually its containing block. + * + * the abs pos containing block runs from 50px to 700px from the left edge + * the static pos containing block runs from 150px to 650px from the left edge + */ + +/* totals for html and body: 21px on the left, 34px on the right */ +html, body { border: transparent medium solid; } +html { margin: 0 3px 0 2px; padding: 0 4px 0 3px; border-width: 0 3px 0 8px; } +body { margin: 0 6px 0 3px; padding: 0 7px 0 1px; border-width: 0 11px 0 4px; } + +body > div { + position: relative; + + top: 0; + left: 4px; + + margin-left: 16px; + border-left: 9px solid transparent; + /* sum of above items (29px), plus 21px above, is 50px */ + padding-left: 40px; + + width: 595px; + + padding-right: 15px; + /* sum of above items (650px), plus 50px above, is 700px */ + + border-right: 27px solid transparent; + margin-right: 13px; +} + +body > div > div { + /* padding-left above: 40px */ + margin-left: 7px; + border-left: 29px solid transparent; + padding-left: 24px; + /* sum of above items (100px), plus 50px above, is 150px */ + + /* padding-right above: 15px */ + padding-right: 14px; + border-right: 3px solid transparent; + margin-right: 18px; + /* sum of above items (50px), subtracted from 700px, is 650px */ +} + +body > div > div > div { + background: navy; + position: absolute; + top: 0; + bottom: 0; + + /* specify everything; we'll put the autos as overrides below */ + left: 3px; + margin-left: 17px; + border-left: 6px solid transparent; + padding-left: 1px; + padding-right: 9px; + border-right: 8px solid transparent; + margin-right: 19px; + right: 8px; +} + +/* and give it 72px of intrinsic width for the case where it has width:auto */ +body > div > div > div > div { + width: 72px; +} + +/* now we want to test all 128 combinations of presence of the following */ + +body > div.adir { direction: rtl; } +body > div.sdir > div { direction: rtl; } +body > div.edir > div > div { direction: rtl; } +body > div.ol > div > div { left: auto; } +body > div.or > div > div { right: auto; } +body > div.ml > div > div { margin-left: auto; } +body > div.mr > div > div { margin-right: auto; } + +/* combined with each of these three */ +body > div.narrowwidth > div > div { width: 153px; } +body > div.autowidth > div > div { width: auto; } +body > div.widewidth > div > div { width: 660px; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/abspos-replaced-width-margin-000.0.scss b/theme-compiler/tests/resources/w3ctests/scss/abspos-replaced-width-margin-000.0.scss new file mode 100644 index 0000000000..99f2a308f3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/abspos-replaced-width-margin-000.0.scss @@ -0,0 +1,88 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/abspos-replaced-width-margin-000.htm */ + + +div { height: 1px; direction: ltr; } + +/* + * Every case here has two divs and an image nested inside of each other. The + * innermost div (absolutely positioned) is the testcase (and has + * color). The middle div's content edge establishes the containing + * block it would have if it were statically positioned. The outermost + * div is actually its containing block. + * + * the abs pos containing block runs from 50px to 700px from the left edge + * the static pos containing block runs from 150px to 650px from the left edge + */ + +/* totals for html and body: 21px on the left, 34px on the right */ +html, body { border: transparent medium solid; } +html { margin: 0 3px 0 2px; padding: 0 4px 0 3px; border-width: 0 3px 0 8px; } +body { margin: 0 6px 0 3px; padding: 0 7px 0 1px; border-width: 0 11px 0 4px; } + +body > div { + position: relative; + + top: 0; + left: 4px; + + margin-left: 16px; + border-left: 9px solid transparent; + /* sum of above items (29px), plus 21px above, is 50px */ + padding-left: 40px; + + width: 595px; + + padding-right: 15px; + /* sum of above items (650px), plus 50px above, is 700px */ + + border-right: 27px solid transparent; + margin-right: 13px; +} + +body > div > div { + /* padding-left above: 40px */ + margin-left: 7px; + border-left: 29px solid transparent; + padding-left: 24px; + /* sum of above items (100px), plus 50px above, is 150px */ + + /* padding-right above: 15px */ + padding-right: 14px; + border-right: 3px solid transparent; + margin-right: 18px; + /* sum of above items (50px), subtracted from 700px, is 650px */ +} + +body > div > div > img { + background: navy; + position: absolute; + top: 0; + bottom: 0; + + /* specify everything; we'll put the autos as overrides below */ + left: 3px; + margin-left: 17px; + border-left: 6px solid transparent; + padding-left: 1px; + padding-right: 9px; + border-right: 8px solid transparent; + margin-right: 19px; + right: 8px; +} + +/* now we want to test all 128 combinations of presence of the following */ + +body > div.adir { direction: rtl; } +body > div.sdir > div { direction: rtl; } +body > div.edir > div > img { direction: rtl; } +body > div.ol > div > img { left: auto; } +body > div.or > div > img { right: auto; } +body > div.ml > div > img { margin-left: auto; } +body > div.mr > div > img { margin-right: auto; } + +/* combined with each of these three (as appropriate for narrow/wide images) */ +body > div.narrowwidth > div > img { width: 153px; height: 1px; } +body > div.autowidth > div > img { width: auto; } +body > div.widewidth > div > img { width: 660px; height: 1px; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/anonymous-boxes-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/anonymous-boxes-001.0.scss new file mode 100644 index 0000000000..3c30052779 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/anonymous-boxes-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/anonymous-boxes-001.htm */ + + #parent { height: 200px; position: relative; } + #child { float: left; height: 50%; width: 100px; background: green; position: relative } + #background { position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: red } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-quotes-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-quotes-001.0.scss new file mode 100644 index 0000000000..3a4f2c68a2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-quotes-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-quotes-001.htm */ + + body { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-quotes-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-quotes-001.1.scss Binary files differnew file mode 100644 index 0000000000..f9ff59ef63 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-quotes-001.1.scss diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-001.0.scss new file mode 100644 index 0000000000..e81cd566d8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-space-001.htm */ + + body { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-001.1.scss Binary files differnew file mode 100644 index 0000000000..89cf375ace --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-001.1.scss diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-002.0.scss new file mode 100644 index 0000000000..f37bd48b03 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-002.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-space-002.htm */ + + body { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-002.1.scss Binary files differnew file mode 100644 index 0000000000..4ca1f3465a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-space-002.1.scss diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-be-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-be-001.0.scss new file mode 100644 index 0000000000..82b8dcb50a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-be-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-utf16-be-001.htm */ + + body { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-be-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-be-001.1.scss Binary files differnew file mode 100644 index 0000000000..3bf9f5f6b4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-be-001.1.scss diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-le-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-le-001.0.scss new file mode 100644 index 0000000000..92ca00bc53 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-le-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-utf16-le-001.htm */ + + body { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-le-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-le-001.1.scss Binary files differnew file mode 100644 index 0000000000..483b8494dd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/at-charset-utf16-le-001.1.scss diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-001.0.scss new file mode 100644 index 0000000000..ed10b1ea02 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-001.0.scss @@ -0,0 +1,40 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-001.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + /* 100 x 120 bgpaint area */ + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-none.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-none.svg); + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-002.0.scss new file mode 100644 index 0000000000..849421d055 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-002.0.scss @@ -0,0 +1,42 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-002.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-width.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-width.svg); + } + .control { + width: 60px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-003.0.scss new file mode 100644 index 0000000000..baac57662f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-003.0.scss @@ -0,0 +1,42 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-003.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-height.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-height.svg); + } + .control { + height: 60px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-004.0.scss new file mode 100644 index 0000000000..22a6983830 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-004.0.scss @@ -0,0 +1,45 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-004.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-ratio-portrait.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-ratio-portrait.svg); + } + .cover .control { + width: 66px; + } + .limit .control { + width: 67px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-005.0.scss new file mode 100644 index 0000000000..cc0e002964 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-005.0.scss @@ -0,0 +1,45 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-005.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-ratio-landscape.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-ratio-landscape.svg); + } + .cover .control { + height: 53px; + } + .limit .control { + height: 54px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-006.0.scss new file mode 100644 index 0000000000..fda8699018 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-006.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-006.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-width-pc-height-pc.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-width-pc-height-pc.svg); + } + .control { + width: 32px; + height: 60px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-007.0.scss new file mode 100644 index 0000000000..09b38ffacb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-007.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-007.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-width-ratio.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-width-ratio.svg); + } + .control { + width: 40px; + height: 60px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-008.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-008.0.scss new file mode 100644 index 0000000000..f54ce9a61a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-008.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-008.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-height-ratio.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-height-ratio.svg); + } + .control { + width: 40px; + height: 60px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-009.0.scss b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-009.0.scss new file mode 100644 index 0000000000..6b9b2d6456 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/background-intrinsic-009.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/background-intrinsic-009.htm */ + + /* Setup. Use 5:6 ratio because it's weird and unlikely to be hard-coded anywhere. */ + div { + position: relative; + } + .cover, .limit { + width: 120px; + height: 120px; + margin: 0.5em; + background: green; /* Used to match reference; remove for debugging. */ + } + .control { + position: absolute; + top: 10px; bottom: 10px; + left: 10px; right: 30px; + } + .cover .control { + background: red; + } + .limit .control { + background: green; + } + .test { + /* 80x100 bgpos area */ + height: 80px; + width: 60px; + padding: 10px; + border: 10px solid transparent; + } + + /* Test */ + .cover .test { + background: no-repeat url(support/green-intrinsic-width-height.svg); + } + .limit .test { + background: no-repeat url(support/red-intrinsic-width-height.svg); + } + .control { + width: 40px; + height: 60px; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-display-types-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-display-types-001.0.scss new file mode 100644 index 0000000000..5a3d20fd24 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-display-types-001.0.scss @@ -0,0 +1,25 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-display-types-001.htm */ + +div { counter-reset:ctr; quotes:"\0022" "\0022" "\0022" "\0022"} + +div:before { + content:counter(ctr) url(support/square-outline-32x32.png) open-quote "Before " attr(class); + counter-increment:ctr; +} +div:after { + content:counter(ctr) url(support/square-outline-32x32.png) "After " attr(class) close-quote; + counter-increment:ctr; +} + +.block:before, .block:after { display:block; } +.inline:before, .inline:after { display:inline; } +.inline-block:before, .inline-block:after { display:inline-block; } +.table:before, .table:after { display:table; } +.inline-table:before, .inline-table:after { display:inline-table; } +.table-row-group:before, .table-row-group:after { display:table-row-group; } +.table-row:before, .table-row:after { display:table-row; } +.table-cell:before, .table-cell:after { display:table-cell; } +.table-caption:before, .table-caption:after { display:table-caption; } + +div { border:1px solid green; margin:5px; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-dynamic-attr-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-dynamic-attr-001.0.scss new file mode 100644 index 0000000000..b2b28a5c97 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-dynamic-attr-001.0.scss @@ -0,0 +1,12 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-dynamic-attr-001.htm */ + +body { + font-family:sans-serif; +} +body:before { + content:attr(my-attr); +} +body:after { + content:attr(my-attr-2); +} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-dynamic-restyle-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-dynamic-restyle-001.0.scss new file mode 100644 index 0000000000..4a1861941e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-dynamic-restyle-001.0.scss @@ -0,0 +1,11 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-dynamic-restyle-001.htm */ + +body:before { + content:"Before"; + border:inherit; +} +.cl:after { + display:block; + content:"After"; +} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-floated-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-floated-001.0.scss new file mode 100644 index 0000000000..324cae53d2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-floated-001.0.scss @@ -0,0 +1,29 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-floated-001.htm */ + +div { counter-reset:ctr; quotes:"\0022" "\0022" "\0022" "\0022"; } + +div:before { + content:counter(ctr) url(support/square-outline-32x32.png) open-quote "Before " attr(class); + counter-increment:ctr; +} +div:after { + content:counter(ctr) url(support/square-outline-32x32.png) "After " attr(class) close-quote; + counter-increment:ctr; +} + +.beforeleft:before { + float:left; +} +.beforeright:before { + float:right; +} +.afterleft:after { + float:left; +} +.afterright:after { + float:right; +} + +div { border:1px solid green; margin:5px; } +div { overflow:auto; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-images-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-images-001.0.scss new file mode 100644 index 0000000000..c419306c2a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-images-001.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-images-001.htm */ + +div:before { + content:url(missing-image.png); +} +div { border:1px solid green; margin:5px; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-positioned-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-positioned-001.0.scss new file mode 100644 index 0000000000..a5b7d7b26b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-positioned-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-positioned-001.htm */ + +div { counter-reset:ctr; quotes:"\0022" "\0022" "\0022" "\0022"; } + +.gen:before { + content:counter(ctr) url(support/square-outline-32x32.png) open-quote "Before " attr(class); + counter-increment:ctr; +} +.gen:after { + content:counter(ctr) url(support/square-outline-32x32.png) "After " attr(class) close-quote; + counter-increment:ctr; +} + +.abs:before { + position:absolute; + left:0; +} +.abs:after { + position:absolute; + right:0; +} + +.rel:before { + position:relative; + top:-10px; +} +.rel:after { + position:relative; + top:10px; +} + +div { border:1px solid green; margin:5px; height:100px; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-positioned-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-positioned-001.1.scss new file mode 100644 index 0000000000..33ee1ef76b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-positioned-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-positioned-001.htm */ +.style { position:relative; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-table-parts-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-table-parts-001.0.scss new file mode 100644 index 0000000000..f199f3ae10 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-table-parts-001.0.scss @@ -0,0 +1,44 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-table-parts-001.htm */ + +table, div.gen { counter-reset:ctr; quotes:"\0022" "\0022" "\0022" "\0022"; } + +.gen:before { + content:counter(ctr) url(support/square-outline-32x32.png) open-quote "Before " attr(class); + counter-increment:ctr; +} +.gen:after { + content:counter(ctr) url(support/square-outline-32x32.png) "After " attr(class) close-quote; + counter-increment:ctr; +} + +table { border:1px solid blue; } +td { border:1px solid cyan; } +td { border-spacing:0; padding:0; } + +tr.gen:before, tr.gen:after { display:table-cell; } +tbody.gen:before, tbody.gen:after { display:table-row; } +table.gen:before, table.gen:after { display:table-row-group; } +table.col:before, table.gen.col:after { display:table-column-group; } +/* note reordering here! */ +table.headfoot:after { display:table-header-group; } +table.headfoot:before { display:table-footer-group; } + +.cell { display:table-cell; } +.row { display:table-row; } +.rowgroup { display:table-row-group; } +.table { display:table; } +div.gencell:before, div.gencell:after { display:table-cell; } +div.genrow:before, div.genrow:after { display:table-row; } +div.genblock:before, div.genblock:after { display:block; } +div.geninline:before, div.geninline:after { display:inline; } + +div { border:1px solid green; margin:5px; } + +.varyheight:before { height:100px; background:yellow; } +.varyheight > div { height:80px; background:orange; } +.varyheight:after { height:60px; background:brown; } + +.varywidth:before { background:yellow; } +.varywidth > div { background:orange; } +.varywidth:after { background:brown; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-table-parts-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-table-parts-001.1.scss new file mode 100644 index 0000000000..652b7fb64f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-table-parts-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-table-parts-001.htm */ +.style { border:none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/before-after-table-whitespace-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/before-after-table-whitespace-001.0.scss new file mode 100644 index 0000000000..a4bd9b3f27 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/before-after-table-whitespace-001.0.scss @@ -0,0 +1,17 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/before-after-table-whitespace-001.htm */ + +.gen0:before { + padding:1px; +} +.gen1:before { + content: " "; +} +.gen2:before { + content: attr(missing); +} +.gen3:before { + content: url(missing-image.png); +} + +div { border:1px solid green; margin:5px; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-001.0.scss new file mode 100644 index 0000000000..f2d73053d4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-001.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-append-001.htm */ + + + body > span { outline: 1px dotted black; } + body > span > span { display: block; width: 10em; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-002.0.scss new file mode 100644 index 0000000000..15821f265e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-002.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-append-002.htm */ + + #outermost { border: 2px solid; } + #outer { border: 4px solid yellow; } + #inner { border: 6px sold green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-002.1.scss new file mode 100644 index 0000000000..92b70020f2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-append-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-append-002.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.0.scss new file mode 100644 index 0000000000..c59fe1cefd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-001.htm */ +.style { direction: ltr } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.1.scss new file mode 100644 index 0000000000..24f75e5c03 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-001.htm */ +.style { border: 5px solid blue; border-left: none; border-right: none; padding-right: 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.2.scss new file mode 100644 index 0000000000..578cdb672b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-001.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.0.scss new file mode 100644 index 0000000000..ebd82de172 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-002.htm */ +.style { direction: rtl } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.1.scss new file mode 100644 index 0000000000..800d89067f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-002.htm */ +.style { border: 5px solid blue; border-left: none; border-right: none; padding-right: 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.2.scss new file mode 100644 index 0000000000..47d968fb36 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-002.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.0.scss new file mode 100644 index 0000000000..bec0ff7a45 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-003.htm */ +.style { direction: ltr } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.1.scss new file mode 100644 index 0000000000..d55949134e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-003.htm */ +.style { border: 5px solid blue; border-left: none; border-right: none; padding-left: 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.2.scss new file mode 100644 index 0000000000..972cbf30eb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-003.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.0.scss new file mode 100644 index 0000000000..6259effef6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-004.htm */ +.style { direction: rtl } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.1.scss new file mode 100644 index 0000000000..85f7e37a8c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-004.htm */ +.style { border: 5px solid blue; border-left: none; border-right: none; padding-left: 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.2.scss new file mode 100644 index 0000000000..e4dfb13524 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-empty-004.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-empty-004.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.0.scss new file mode 100644 index 0000000000..081e58affc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-float-between-001.htm */ +.style { position: relative; left: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.1.scss new file mode 100644 index 0000000000..99babd326f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-float-between-001.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.2.scss new file mode 100644 index 0000000000..8f5a27f693 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-float-between-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-float-between-001.htm */ +.style { float: left } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001a.0.scss new file mode 100644 index 0000000000..4482654240 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001a.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001a.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001b.0.scss new file mode 100644 index 0000000000..d0b1193abc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001b.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001c.0.scss new file mode 100644 index 0000000000..a820d992bc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001c.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001c.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001d.0.scss new file mode 100644 index 0000000000..dc7c044309 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001d.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001d.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001e.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001e.0.scss new file mode 100644 index 0000000000..4ee59b7c3c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001e.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001e.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001f.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001f.0.scss new file mode 100644 index 0000000000..544fddaee6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001f.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001f.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001g.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001g.0.scss new file mode 100644 index 0000000000..5bbfb01512 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001g.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001g.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001h.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001h.0.scss new file mode 100644 index 0000000000..d03bbf51a7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001h.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001h.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001i.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001i.0.scss new file mode 100644 index 0000000000..d48cc6477c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001i.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001i.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001j.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001j.0.scss new file mode 100644 index 0000000000..8662fec547 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001j.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001j.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001k.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001k.0.scss new file mode 100644 index 0000000000..ed1c00b772 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001k.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001k.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001l.0.scss new file mode 100644 index 0000000000..7e792b2f0b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-001l.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-001l.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002a.0.scss new file mode 100644 index 0000000000..76a2977e4f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002a.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002a.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002b.0.scss new file mode 100644 index 0000000000..1c468dc942 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002b.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002c.0.scss new file mode 100644 index 0000000000..17517332ea --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002c.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002c.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002d.0.scss new file mode 100644 index 0000000000..697822ae0a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002d.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002d.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002e.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002e.0.scss new file mode 100644 index 0000000000..20d8d46d16 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002e.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002e.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002f.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002f.0.scss new file mode 100644 index 0000000000..b0680028e7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002f.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002f.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002g.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002g.0.scss new file mode 100644 index 0000000000..67bc7ebadc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002g.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002g.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002h.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002h.0.scss new file mode 100644 index 0000000000..5c7c0a767d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002h.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002h.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002i.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002i.0.scss new file mode 100644 index 0000000000..810b088676 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-002i.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-002i.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-003.0.scss new file mode 100644 index 0000000000..71760d321c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-003.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-003.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-004.0.scss new file mode 100644 index 0000000000..7d18b5f0bb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-004.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-004.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-006.0.scss new file mode 100644 index 0000000000..5fae99411f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-006.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-006.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-007.0.scss new file mode 100644 index 0000000000..3e59471379 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-007.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-007.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008a.0.scss new file mode 100644 index 0000000000..840e4c41ac --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008a.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-008a.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008b.0.scss new file mode 100644 index 0000000000..b1e3f46489 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-008b.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008c.0.scss new file mode 100644 index 0000000000..9ccc845aa6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-008c.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-008c.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-009.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-009.0.scss new file mode 100644 index 0000000000..134414535f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-009.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-009.htm */ + + body > span { border: 3px solid blue } + body > span > span { border: 3px solid cyan } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-010.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-010.0.scss new file mode 100644 index 0000000000..62431c82a3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-010.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-010.htm */ + + body > span { border: 3px solid blue } + body > span > span { border: 3px solid cyan } + body > span > span:after { content: "Ten" } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-011.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-011.0.scss new file mode 100644 index 0000000000..2844241d70 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-011.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-011.htm */ + + body > span { border: 3px solid blue } + body > span > span { border: 3px solid cyan } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-012.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-012.0.scss new file mode 100644 index 0000000000..105753b69f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-012.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-012.htm */ + + #i { display: inline; border: 2px solid; } + #i:after { display: block; content: "Three"; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-013.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-013.0.scss new file mode 100644 index 0000000000..dd0da56c7d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-013.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-013.htm */ + + #i { border: 2px solid; } + #i:before { display: block; content: "One"; } + #i:after { content: "Three"; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-013.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-013.1.scss new file mode 100644 index 0000000000..fce9f7e44a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-013.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-013.htm */ +.style { display: none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-014.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-014.0.scss new file mode 100644 index 0000000000..0d1f7f3a3e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-014.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-014.htm */ + + #i { border: 2px solid; } + #i:before { display: block; content: "One"; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-014.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-014.1.scss new file mode 100644 index 0000000000..4fb8ca38ec --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-014.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-014.htm */ +.style { display: none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-015.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-015.0.scss new file mode 100644 index 0000000000..064cb0734c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-015.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-015.htm */ + + #i { display: inline; border: 2px solid; } + #i:after { display: block; content: "Three"; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016a.0.scss new file mode 100644 index 0000000000..27a0dd79bd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-016a.htm */ + + #i { border: 2px solid; } + #i:after { display: block; content: "Two"; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016a.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016a.1.scss new file mode 100644 index 0000000000..e2ddc868f4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016a.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-016a.htm */ +.style { display: none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016b.0.scss new file mode 100644 index 0000000000..7b53f1212b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-016b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-016b.htm */ + + #i { border: 2px solid; } + #i:after { display: block; content: "Two"; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.0.scss new file mode 100644 index 0000000000..fb90ff7fde --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-017.htm */ +.style { width: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.1.scss new file mode 100644 index 0000000000..7efbd77d83 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-017.htm */ +.style { border: 2px solid blue; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.2.scss new file mode 100644 index 0000000000..95aac0261c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-insert-017.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-insert-017.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001a.0.scss new file mode 100644 index 0000000000..d683f3fa54 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001a.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-001a.htm */ +.style { direction: ltr; width: 100px; border: 1px solid green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001a.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001a.1.scss new file mode 100644 index 0000000000..aae6310bf0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001a.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-001a.htm */ +.style { display: block; height: 20px; width: 80px; margin: 10px; border: 5px solid black } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.0.scss new file mode 100644 index 0000000000..4a040231ea --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-001b.htm */ +.style { direction: ltr; width: 100px; border: 1px solid green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.1.scss new file mode 100644 index 0000000000..5f99cd4c5c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-001b.htm */ +.style { direction: rtl } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.2.scss new file mode 100644 index 0000000000..bede015e4e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-001b.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-001b.htm */ +.style { display: block; height: 20px; width: 80px; margin: 10px; border: 5px solid black } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002a.0.scss new file mode 100644 index 0000000000..7c7cbd0808 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002a.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-002a.htm */ +.style { direction: rtl; width: 100px; border: 1px solid green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002a.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002a.1.scss new file mode 100644 index 0000000000..305b8ac11a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002a.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-002a.htm */ +.style { display: block; height: 20px; width: 80px; margin: 10px; border: 5px solid black } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.0.scss new file mode 100644 index 0000000000..7b8252e044 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-002b.htm */ +.style { direction: rtl; width: 100px; border: 1px solid green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.1.scss new file mode 100644 index 0000000000..11e90f792e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-002b.htm */ +.style { direction: ltr } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.2.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.2.scss new file mode 100644 index 0000000000..3416f8de01 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-margins-002b.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-margins-002b.htm */ +.style { display: block; height: 20px; width: 80px; margin: 10px; border: 5px solid black } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-001.0.scss new file mode 100644 index 0000000000..e78538e895 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-nested-001.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-002.0.scss new file mode 100644 index 0000000000..9367c041d0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-nested-002.htm */ +.style { border: 5px solid blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-002.1.scss new file mode 100644 index 0000000000..fee6eb9e60 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-nested-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-nested-002.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-percents-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-percents-001.0.scss new file mode 100644 index 0000000000..efb841d5dc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-percents-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-percents-001.htm */ +.style { height: 200px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-percents-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-percents-001.1.scss new file mode 100644 index 0000000000..57e6d10c49 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-percents-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-percents-001.htm */ +.style { display: block; height: 50%; border: 10px solid black } diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-001.0.scss new file mode 100644 index 0000000000..ebe1d5373b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-remove-001.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-002.0.scss new file mode 100644 index 0000000000..ca9c6e7a45 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-002.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-remove-002.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-003.0.scss new file mode 100644 index 0000000000..dc223e8297 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-003.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-remove-003.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-004.0.scss new file mode 100644 index 0000000000..ed1891d7f0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-004.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-remove-004.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-005.0.scss new file mode 100644 index 0000000000..c3f1c4fcc0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-005.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-remove-005.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-006.0.scss new file mode 100644 index 0000000000..2f4d5643be --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-remove-006.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-remove-006.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-whitespace-001a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-whitespace-001a.0.scss new file mode 100644 index 0000000000..a0fdf69e23 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-whitespace-001a.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-whitespace-001a.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-whitespace-001b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-whitespace-001b.0.scss new file mode 100644 index 0000000000..4c860c2a7e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/block-in-inline-whitespace-001b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/block-in-inline-whitespace-001b.htm */ + + body > span { border: 3px solid blue } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.0.scss new file mode 100644 index 0000000000..898d753e68 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-001.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.1.scss new file mode 100644 index 0000000000..7a2f6b66db --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-001.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.2.scss new file mode 100644 index 0000000000..bfd8fdb6e5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-001.htm */ +.style { border-style:none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.0.scss new file mode 100644 index 0000000000..e0dbae8b77 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-002.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.1.scss new file mode 100644 index 0000000000..a5f32321c6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-002.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.2.scss new file mode 100644 index 0000000000..49b52904b4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-002.htm */ +.style { border-width:11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-003.0.scss new file mode 100644 index 0000000000..8b018c1980 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-003.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-003.1.scss new file mode 100644 index 0000000000..c4dc834384 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-003.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.0.scss new file mode 100644 index 0000000000..1f0a0f3c56 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-004.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.1.scss new file mode 100644 index 0000000000..14810d15b6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-004.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.2.scss new file mode 100644 index 0000000000..15f89578e1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-004.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-004.htm */ +.style { border-style:none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.0.scss new file mode 100644 index 0000000000..5117efb468 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-005.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.1.scss new file mode 100644 index 0000000000..2e248a0aaa --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-005.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.2.scss new file mode 100644 index 0000000000..15ba20a79f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-cell-005.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-cell-005.htm */ +.style { border-style:none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.0.scss new file mode 100644 index 0000000000..d6af94204f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-001.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.1.scss new file mode 100644 index 0000000000..1d942d6b38 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-001.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.2.scss new file mode 100644 index 0000000000..27a43b6bd8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-001.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.0.scss new file mode 100644 index 0000000000..ae15dde154 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-002.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.1.scss new file mode 100644 index 0000000000..8ee152dc38 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-002.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.2.scss new file mode 100644 index 0000000000..c6318a3584 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-002.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.0.scss new file mode 100644 index 0000000000..0d7f407a9d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-003.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.1.scss new file mode 100644 index 0000000000..e58b8bb8df --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-003.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.2.scss new file mode 100644 index 0000000000..cadad9538f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-colgroup-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-colgroup-003.htm */ +.style { border:outset green 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.0.scss new file mode 100644 index 0000000000..ba42b5052f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-001.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.1.scss new file mode 100644 index 0000000000..262d6bbedd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-001.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.2.scss new file mode 100644 index 0000000000..d32773435c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-001.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.0.scss new file mode 100644 index 0000000000..4ca986a899 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-002.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.1.scss new file mode 100644 index 0000000000..caf207660d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-002.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.2.scss new file mode 100644 index 0000000000..f7228f354e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-002.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.0.scss new file mode 100644 index 0000000000..d5b7eae31a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-003.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.1.scss new file mode 100644 index 0000000000..4b42a2998c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-003.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.2.scss new file mode 100644 index 0000000000..a967891706 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-column-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-column-003.htm */ +.style { border:outset green 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.0.scss new file mode 100644 index 0000000000..070b886636 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-001.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.1.scss new file mode 100644 index 0000000000..0aec943a6c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-001.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.2.scss new file mode 100644 index 0000000000..1c23b85d86 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-001.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.0.scss new file mode 100644 index 0000000000..7bfdeac373 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-002.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.1.scss new file mode 100644 index 0000000000..f50de68330 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-002.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.2.scss new file mode 100644 index 0000000000..62bb238c7a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-002.htm */ +.style { border:solid green 2px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.0.scss new file mode 100644 index 0000000000..a18235986c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-003.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.1.scss new file mode 100644 index 0000000000..16f289c84f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-003.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.2.scss new file mode 100644 index 0000000000..0cef689399 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-row-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-row-003.htm */ +.style { border:outset green 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.0.scss new file mode 100644 index 0000000000..aa87c0c1d3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-001.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.1.scss new file mode 100644 index 0000000000..9d26fe3df3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-001.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.2.scss new file mode 100644 index 0000000000..7195bcef72 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-001.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.0.scss new file mode 100644 index 0000000000..be951ef050 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-002.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.1.scss new file mode 100644 index 0000000000..8fde9220db --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-002.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.2.scss new file mode 100644 index 0000000000..86f188e449 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-002.htm */ +.style { border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.0.scss new file mode 100644 index 0000000000..7a94d7c74b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-003.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.1.scss new file mode 100644 index 0000000000..2c43199f38 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-003.htm */ +.style { border-collapse:collapse } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.2.scss new file mode 100644 index 0000000000..08d7e668d6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-rowgroup-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-rowgroup-003.htm */ +.style { border:outset green 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-001.0.scss new file mode 100644 index 0000000000..98f04c7a57 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-table-001.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-001.1.scss new file mode 100644 index 0000000000..7a7cf28388 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-table-001.htm */ +.style { border-collapse:collapse; border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-002.0.scss new file mode 100644 index 0000000000..d5453532b4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-table-002.htm */ + +td { border: 10px green solid;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-002.1.scss new file mode 100644 index 0000000000..da3a1b0a1b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-table-002.htm */ +.style { border-collapse:collapse; border:solid green 11px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-003.0.scss new file mode 100644 index 0000000000..aff4d99c71 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-table-003.htm */ + +td { border: 10px green outset;} +table {margin: 30px} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-003.1.scss new file mode 100644 index 0000000000..fd48bad69d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-dynamic-table-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-dynamic-table-003.htm */ +.style { border-collapse:collapse; border:none green 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.0.scss new file mode 100644 index 0000000000..10da13d64d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-offset-001.htm */ + +td {width: 100px; text-align:center} +div {position:absolute; border:green 4px solid} + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.1.scss new file mode 100644 index 0000000000..c87fcbc76a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-offset-001.htm */ +.style { border-collapse:collapse; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.2.scss new file mode 100644 index 0000000000..340f309e2e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-offset-001.htm */ +.style { border:solid 4px orange; height:30px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.0.scss new file mode 100644 index 0000000000..d33ffa4284 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-offset-002.htm */ + +td {width: 100px; text-align:center} +caption {border:solid 4px green} + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.1.scss new file mode 100644 index 0000000000..88535218ab --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-offset-002.htm */ +.style { border-collapse:collapse; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.2.scss new file mode 100644 index 0000000000..ee3eb8c007 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/border-collapse-offset-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/border-collapse-offset-002.htm */ +.style { border:solid 4px orange; height:30px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/charset-attr-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/charset-attr-001.0.scss new file mode 100644 index 0000000000..b09d86f8f7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/charset-attr-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/charset-attr-001.htm */ + + body { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/charset-attr-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/charset-attr-001.1.scss Binary files differnew file mode 100644 index 0000000000..bfaba9dc01 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/charset-attr-001.1.scss diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-1.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-1.0.scss new file mode 100644 index 0000000000..f0a8248396 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-1.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-1.html */ +li,p { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-10.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-10.0.scss new file mode 100644 index 0000000000..d0d1a14d60 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-10.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-10.html */ +p { background-color : red } +p[title$="bar"] { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-11.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-11.0.scss new file mode 100644 index 0000000000..ca558792b0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-11.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-11.html */ +p { background-color : red } +p[title*="bar"] { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-13.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-13.0.scss new file mode 100644 index 0000000000..344a9e8e46 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-13.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-13.html */ +li { background-color : red } +.t1 { background-color : lime } +li.t2 { background-color : lime } +.t3 { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14.0.scss new file mode 100644 index 0000000000..faf4d3c7cb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14.0.scss @@ -0,0 +1,10 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-14.html */ +p { background-color : red ; border : thick solid red ; padding : 1em } +p.t1 { background-color : lime } +p.t2 { border : thick solid green } + +div { background: green; color: white; } +div.teST { background: red; color: yellow; } +div.te { background: red; color: yellow; } +div.st { background: red; color: yellow; } +div.te.st { background: red; color: yellow; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-144.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-144.0.scss new file mode 100644 index 0000000000..c669785ac7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-144.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-144.html */ +div :not(:enabled):not(:disabled) { background: lime; } +p { background : red;} diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-148.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-148.0.scss new file mode 100644 index 0000000000..a41bb1ed85 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-148.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-148.html */ + + p { background: lime; } + p:empty { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-149.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-149.0.scss new file mode 100644 index 0000000000..23eba2f553 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-149.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-149.html */ + + address:empty { background: lime; } + address { background: red; margin: 0; height: 1em; } + .text { margin: -1em 0 0 0; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-149b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-149b.0.scss new file mode 100644 index 0000000000..ae6c5ca1c7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-149b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-149b.html */ + + address:empty { background: lime; } + address { background: red; margin: 0; height: 1em; } + .text { margin: -1em 0 0 0; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14b.0.scss new file mode 100644 index 0000000000..5851edc2e3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14b.0.scss @@ -0,0 +1,10 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-14b.html */ + +p { background: green; color: white; } +.t1.fail { background: red; color: yellow; } +.fail.t1 { background: red; color: yellow; } +.t2.fail { background: red; color: yellow; } +.fail.t2 { background: red; color: yellow; } +/* Note: This is a valid test even per CSS1, since in CSS1 those rules + are invalid and should be dropped. */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14c.0.scss new file mode 100644 index 0000000000..d32fec8496 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14c.0.scss @@ -0,0 +1,9 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-14c.html */ + +p { background: red; color: yellow; } +p.t1.t2 { background: green; color: white; } +div { background: green; color: white; } +div.t1 { background: red; color: yellow; } +address { background: red; color: yellow; } +address.t5.t5 { background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14d.0.scss new file mode 100644 index 0000000000..3432db6913 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14d.0.scss @@ -0,0 +1,8 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-14d.html */ + +p { background: green; color: white; } +.t1:not(.t2) { background: red; color: yellow; } +:not(.t2).t1 { background: red; color: yellow; } +.t2:not(.t1) { background: red; color: yellow; } +:not(.t1).t2 { background: red; color: yellow; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14e.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14e.0.scss new file mode 100644 index 0000000000..979edeed91 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-14e.0.scss @@ -0,0 +1,9 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-14e.html */ + +p { background: green; color: white; } +p:not(.t1):not(.t2) { background: red; color: yellow; } +div { background: red; color: yellow; } +div:not(.t1) { background: green; color: white; } +address { background: green; color: white; } +address:not(.t5):not(.t5) { background: red; color: yellow; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-15.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-15.0.scss new file mode 100644 index 0000000000..ff1d3a2d9b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-15.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-15.html */ +li { background-color : red } +#t1 { background-color : lime } +li#t2 { background-color : lime } +li#t3 { background-color : lime } +#t4 { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-150.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-150.0.scss new file mode 100644 index 0000000000..bb9cc2cb7c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-150.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-150.html */ + + address:empty { background: lime; } + address { background: red; margin: 0; height: 1em; } + .text { margin: -1em 0 0 0; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-151.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-151.0.scss new file mode 100644 index 0000000000..ec229bdd33 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-151.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-151.html */ + + address { background: lime; margin: 0; height: 1em; } + address:empty { background: red; } + .text { margin: -1em 0 0 0; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-152.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-152.0.scss new file mode 100644 index 0000000000..bf765f8b5d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-152.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-152.html */ + + address { background: lime; margin: 0; height: 1em; } + address:empty { background: red; } + .text { margin: -1em 0 0 0; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155.0.scss new file mode 100644 index 0000000000..1f073c35b4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-155.html */ + + p { background: lime; } + .5cm { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155a.0.scss new file mode 100644 index 0000000000..9ce3a19428 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-155a.html */ + + p { background: lime; } + .\5cm { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155b.0.scss new file mode 100644 index 0000000000..83340f5351 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155b.0.scss @@ -0,0 +1,10 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-155b.html */ + + p { background: lime; } + .two\ words { background: red; } + + /* the "." and "~=" forms match on a space separated list of words. + In such a list, a word containing a space can never match, since it + would by definition be two words. */ + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155c.0.scss new file mode 100644 index 0000000000..516c8de4e0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-155c.html */ + + p { background: lime; } + .one.word { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155d.0.scss new file mode 100644 index 0000000000..6930469379 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-155d.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-155d.html */ + + .one\.word { background: lime; } + p { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156.0.scss new file mode 100644 index 0000000000..058b6b4290 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-156.html */ + + p { background: lime; } + foo & address, p { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156b.0.scss new file mode 100644 index 0000000000..033b8f59a9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-156b.html */ + + foo & address, p { background: red; } + p { background: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156c.0.scss new file mode 100644 index 0000000000..62d2a7ceb6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-156c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-156c.html */ + + foo & address, p { background: red ! important; } + p { background: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-159.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-159.0.scss new file mode 100644 index 0000000000..6f85988756 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-159.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-159.html */ + + ::selection { background: lime; } + :selection { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-15b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-15b.0.scss new file mode 100644 index 0000000000..b2fb3ac6ae --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-15b.0.scss @@ -0,0 +1,9 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-15b.html */ + +p { background: green; color: white; } +#test#fail { background: red; color: yellow; } +#fail#test { background: red; color: yellow; } +#fail { background: red; color: yellow; } +div { background: red; color: yellow; } +#pass#pass { background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-16.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-16.0.scss new file mode 100644 index 0000000000..7b909a1ac1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-16.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-16.html */ +p.test a { background-color : red } +p.test *:link { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-160.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-160.0.scss new file mode 100644 index 0000000000..45c7c74e02 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-160.0.scss @@ -0,0 +1,7 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-160.html */ + + p { background: lime; } + p:subject { background: red; } /* this is not valid CSS, and if UAs + implemented the experimental :subject pseudo-class they should have + used the :-vnd-ident syntax. */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-161.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-161.0.scss new file mode 100644 index 0000000000..c10cdd2dfd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-161.0.scss @@ -0,0 +1,26 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-161.html */ + + p { background: lime; } + p * { background: lime; } + p > * { background: lime; } + p + * { background: lime; } + p ~ * { background: lime; } + + /* let's try some pseudos that are not valid CSS but are likely to + be implemented as extensions in some UAs. These should not be + recognised, as UAs implementing such extensions should use the + :-vnd-ident syntax. */ + + :canvas { background: red; } + :viewport { background: red; } + :window { background: red; } + :menu { background: red; } + :table { background: red; } + :select { background: red; } + ::canvas { background: red; } + ::viewport { background: red; } + ::window { background: red; } + ::menu { background: red; } + ::table { background: red; } + ::select { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-166.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-166.0.scss new file mode 100644 index 0000000000..de27d9ffd2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-166.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-166.html */ + + p:first-letter { background-color: red; } + p::first-letter { background-color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-166a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-166a.0.scss new file mode 100644 index 0000000000..ed465fe93b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-166a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-166a.html */ + + p::first-letter { background-color: red; } + p:first-letter { background-color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-167.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-167.0.scss new file mode 100644 index 0000000000..5aad6a87bd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-167.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-167.html */ + + p:first-line { background-color: red; } + p::first-line { background-color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-167a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-167a.0.scss new file mode 100644 index 0000000000..109defc654 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-167a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-167a.html */ + + p::first-line { background-color: red; } + p:first-line { background-color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-168.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-168.0.scss new file mode 100644 index 0000000000..81f5c1e9b1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-168.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-168.html */ + + span:before { background-color: red; content: 'FAILED'; } + span::before { background-color: lime; content: 'PASSED'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-168a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-168a.0.scss new file mode 100644 index 0000000000..0898dd7d8c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-168a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-168a.html */ + + span::before { background-color: red; content: 'FAILED'; } + span:before { background-color: lime; content: 'PASSED'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-169.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-169.0.scss new file mode 100644 index 0000000000..69ddf7fccc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-169.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-169.html */ + + span:after { background-color: red; content: 'FAILED'; } + span::after { background-color: lime; content: 'PASSED'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-169a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-169a.0.scss new file mode 100644 index 0000000000..efb74238ec --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-169a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-169a.html */ + + span::after { background-color: red; content: 'FAILED'; } + span:after { background-color: lime; content: 'PASSED'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-17.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-17.0.scss new file mode 100644 index 0000000000..2b881ad09d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-17.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-17.html */ +p.test a { background-color : red } +p.test *:visited { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170.0.scss new file mode 100644 index 0000000000..e33d2f5b12 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-170.html */ + + span { color: red; } + span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span, span { color: green } /* 2049 */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170a.0.scss new file mode 100644 index 0000000000..7d09cee5ee --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-170a.html */ + + .span { color: red; } + .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span, .span { color: green } /* 2049 */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170b.0.scss new file mode 100644 index 0000000000..9144c18516 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-170b.html */ + + .span { color: red; } + .span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span.span { color: green } /* 2049 */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170c.0.scss new file mode 100644 index 0000000000..adcf326e76 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-170c.html */ + + p.span { color: red; } + p:not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span):not(.span) { color: green } /* 2049 */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170d.0.scss new file mode 100644 index 0000000000..1ace26ae1f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-170d.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-170d.html */ + + p { color: red; } + p:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child:first-child { color: green } /* 2049 */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175a.0.scss new file mode 100644 index 0000000000..eb61d12ff2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-175a.html */ + + p { color: green; } + .13 { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175b.0.scss new file mode 100644 index 0000000000..91066d4671 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-175b.html */ + + p { color: green; } + .\13 { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175c.0.scss new file mode 100644 index 0000000000..d7555e9fa0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-175c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-175c.html */ + + p { color: red; } + .\31 \33 { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-176.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-176.0.scss new file mode 100644 index 0000000000..474be8d9e8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-176.0.scss @@ -0,0 +1,11 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-176.html */ + +p { background: red; color: yellow; } +p:not(#other).class:not(.fail).test#id#id { background: green; color: white; } +div { background: green; color: white; } +div:not(#theid).class:not(.fail).test#theid#theid { background: red; color: yellow; } +div:not(#other).notclass:not(.fail).test#theid#theid { background: red; color: yellow; } +div:not(#other).class:not(.test).test#theid#theid { background: red; color: yellow; } +div:not(#other).class:not(.fail).nottest#theid#theid { background: red; color: yellow; } +div:not(#other).class:not(.fail).nottest#theid#other { background: red; color: yellow; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-177a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-177a.0.scss new file mode 100644 index 0000000000..29359bcba2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-177a.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-177a.html */ + + p:selection { color: yellow; background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-177b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-177b.0.scss new file mode 100644 index 0000000000..64f2c84901 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-177b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-177b.html */ + + div { color: green; } + p::first-child { color: yellow; background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-178.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-178.0.scss new file mode 100644 index 0000000000..92b765dff4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-178.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-178.html */ + + div { color: green; } + p:not(:first-line) { color: yellow; background: red; } + p:not(:after) { color: yellow; background: red; content: ' THIS TEST HAS FAILED! '; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-179.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-179.0.scss new file mode 100644 index 0000000000..ce5e3a8630 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-179.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-179.html */ + + p { color: green; } + span:first-line { background: red; color: yellow; font-size: 4em; } + span::first-line { background: red; color: yellow; font-size: 4em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-179a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-179a.0.scss new file mode 100644 index 0000000000..660e7508dc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-179a.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-179a.html */ + + p { color: green; } + p:first-line { background: red; color: yellow; font-size: 4em; } + p::first-line { background: red; color: yellow; font-size: 4em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18.0.scss new file mode 100644 index 0000000000..33067afba0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18.0.scss @@ -0,0 +1,8 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-18.html */ +p:hover { background-color : lime } +a:hover { background-color : lime } + +tr:hover { background-color : green } +td:hover { background-color : lime } + +table { border-spacing: 5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-180a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-180a.0.scss new file mode 100644 index 0000000000..a7a641bcb6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-180a.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-180a.html */ + + p { color: green; } + p:first-letter { background: red; color: yellow; font-size: 4em; } + p::first-letter { background: red; color: yellow; font-size: 4em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-181.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-181.0.scss new file mode 100644 index 0000000000..24dbd1031d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-181.0.scss @@ -0,0 +1,15 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-181.html */ + + .cs { color: green; } + .cs P { background: red; color: yellow; } + .cs .a { background: red; color: yellow; } + .cs .span1 span { background: red; color: yellow; } + .cs .span2 { color: red; } + .cs .span2 SPAN { color: green; } + .cs .span2 span { background: red; color: yellow; } + .ci { color: red; } + .ci P { background: green; color: white; } + .ci .a { background: green; color: white; } + .ci .span1 span { background: green; color: white; } + .ci .span2 SPAN { background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184a.0.scss new file mode 100644 index 0000000000..7d5c5fd2d4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-184a.html */ + +p { color: lime; } +p[class$=""] { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184b.0.scss new file mode 100644 index 0000000000..f0e5f98b15 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-184b.html */ + +p { color: lime; } +p[class^=""] { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184c.0.scss new file mode 100644 index 0000000000..892f85f7f3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-184c.html */ + +p { color: lime; } +p[class*=""] { color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184d.0.scss new file mode 100644 index 0000000000..ad721d0131 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184d.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-184d.html */ + +p { color: red; } +p:not([class$=""]) { color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184e.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184e.0.scss new file mode 100644 index 0000000000..b1ae45984c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184e.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-184e.html */ + +p { color: red; } +p:not([class^=""]) { color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184f.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184f.0.scss new file mode 100644 index 0000000000..8d461ff6d6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-184f.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-184f.html */ + +p { color: red; } +p:not([class*=""]) { color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18a.0.scss new file mode 100644 index 0000000000..ccd04a2cef --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18a.0.scss @@ -0,0 +1,12 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-18a.html */ + +p { color: navy; } + +.a a:hover { background: green; color: white; } + +.b a:hover { background: red; color: yellow; } +.b a:link { background: green; color: white; } + +.c :link { background: green; color: white; } +.c :visited:hover { background: red; color: yellow; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18b.0.scss new file mode 100644 index 0000000000..87405f66f8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-18b.html */ +div:hover > p:first-child { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18c.0.scss new file mode 100644 index 0000000000..519cbce0ee --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-18c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-18c.html */ + +:link, :visited { color: navy; text-decoration: none; } +:link:hover span { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-19.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-19.0.scss new file mode 100644 index 0000000000..8b13ef8766 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-19.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-19.html */ +a:active { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-19b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-19b.0.scss new file mode 100644 index 0000000000..c5ddec6c1d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-19b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-19b.html */ +button:active { background: green; color: white; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-2.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-2.0.scss new file mode 100644 index 0000000000..ae64542b1c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-2.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-2.html */ +address { background-color: lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-20.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-20.0.scss new file mode 100644 index 0000000000..5a2ef60ca9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-20.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-20.html */ +a:focus { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21.0.scss new file mode 100644 index 0000000000..c391cb4d6f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-21.html */ +p:target { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21b.0.scss new file mode 100644 index 0000000000..ef7b904578 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21b.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-21b.html */ +p { background-color: lime; } +p:target { background-color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21c.0.scss new file mode 100644 index 0000000000..842e11db74 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-21c.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-21c.html */ +:root { background-color: green; } +:target { background-color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-22.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-22.0.scss new file mode 100644 index 0000000000..62a0370b78 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-22.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-22.html */ +ul > li { background-color : red } +li:lang(en-GB) { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-23.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-23.0.scss new file mode 100644 index 0000000000..4415be07a9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-23.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-23.html */ +button { background-color : red } +input { background-color : red } +button:enabled { background-color : lime } +input:enabled { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-24.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-24.0.scss new file mode 100644 index 0000000000..40f518adc3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-24.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-24.html */ +button { background-color : red } +input { background-color : red } +button:disabled { background-color : lime } +input:disabled { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-25.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-25.0.scss new file mode 100644 index 0000000000..a9d194c71e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-25.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-25.html */ +input, span { background-color : red } +input:checked, input:checked + span { background-color : lime} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27.0.scss new file mode 100644 index 0000000000..6451254f09 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-27.html */ +html { background-color : red } +*:root { background-color: lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27a.0.scss new file mode 100644 index 0000000000..4482386911 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27a.0.scss @@ -0,0 +1,17 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-27a.html */ + +:root:first-child { background-color: red; } +:root:last-child { background-color: red; } +:root:only-child { background-color: red; } +:root:nth-child(1) { background-color: red; } +:root:nth-child(n) { background-color: red; } +:root:nth-last-child(1) { background-color: red; } +:root:nth-last-child(n) { background-color: red; } +:root:first-of-type { background-color: red; } +:root:last-of-type { background-color: red; } +:root:only-of-type { background-color: red; } +:root:nth-of-type(1) { background-color: red; } +:root:nth-of-type(n) { background-color: red; } +:root:nth-last-of-type(1) { background-color: red; } +:root:nth-last-of-type(n) { background-color: red; } +p { color: green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27b.0.scss new file mode 100644 index 0000000000..a21c7dbf6d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-27b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-27b.html */ +* html { background-color: red; } +* :root { background-color: red; } +p { color: green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-28.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-28.0.scss new file mode 100644 index 0000000000..3546bfc898 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-28.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-28.html */ +.red { background-color : red } +ul > li:nth-child(odd) { background-color : lime } +ol > li:nth-child(even) { background-color : lime } +table.t1 tr:nth-child(-n+4) { background-color : lime } +table.t2 td:nth-child(3n+1) { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-28b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-28b.0.scss new file mode 100644 index 0000000000..a91ad30283 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-28b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-28b.html */ +.green { background-color : lime ! important } +ul > li:nth-child(odd) { background-color : red } +ol > li:nth-child(even) { background-color : red } +table.t1 tr:nth-child(-n+4) { background-color : red } +table.t2 td:nth-child(3n+1) { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-29.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-29.0.scss new file mode 100644 index 0000000000..0860aa4956 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-29.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-29.html */ +.red { background-color : red } +ul > li:nth-last-child(odd) { background-color : green } +ol > li:nth-last-child(even) { background-color : green } +table.t1 tr:nth-last-child(-n+4) { background-color : green } +table.t2 td:nth-last-child(3n+1) { background-color : green } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-29b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-29b.0.scss new file mode 100644 index 0000000000..eb55cc8de4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-29b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-29b.html */ +.green { background-color : lime ! important } +ul > li:nth-last-child(odd) { background-color : red } +ol > li:nth-last-child(even) { background-color : red } +table.t1 tr:nth-last-child(-n+4) { background-color : red } +table.t2 td:nth-last-child(3n+1) { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-30.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-30.0.scss new file mode 100644 index 0000000000..46d21fae2a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-30.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-30.html */ +.red { background-color : red } +p:nth-of-type(3) { background-color : lime } +dl > :nth-of-type(3n+1) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-31.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-31.0.scss new file mode 100644 index 0000000000..de45ba5eb1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-31.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-31.html */ +.red { background-color : red } +p:nth-last-of-type(3) { background-color : lime } +dl > :nth-last-of-type(3n+1) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-32.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-32.0.scss new file mode 100644 index 0000000000..5fbf5c2b5e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-32.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-32.html */ +.red { background-color : red } +.t1 td:first-child { background-color : lime } +p > *:first-child { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-33.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-33.0.scss new file mode 100644 index 0000000000..507ac1b3cb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-33.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-33.html */ +.red { background-color : red } +.t1 td:last-child { background-color : lime } +p > *:last-child { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-34.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-34.0.scss new file mode 100644 index 0000000000..697d635940 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-34.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-34.html */ +.red { background-color : red } +address { margin-bottom : 1em ; margin-left : 1em } +address:first-of-type { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-35.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-35.0.scss new file mode 100644 index 0000000000..0fee4326d0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-35.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-35.html */ +.red { background-color : red } +address { margin-bottom : 1em ; margin-left : 1em } +address:last-of-type { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-36.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-36.0.scss new file mode 100644 index 0000000000..5190600df7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-36.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-36.html */ +.red { background-color : red } +p:only-child { background-color : lime } +div.testText > div > p { margin-left : 1em } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-37.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-37.0.scss new file mode 100644 index 0000000000..37d2a23b4c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-37.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-37.html */ +.red { background-color : red } +.t1 :only-of-type { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-38.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-38.0.scss new file mode 100644 index 0000000000..9a039639b1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-38.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-38.html */ +p:first-line { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39.0.scss new file mode 100644 index 0000000000..5243f7505a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-39.html */ +p:first-letter { font-size : xx-large ; background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39a.0.scss new file mode 100644 index 0000000000..af6c66bd8a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39a.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-39a.html */ +p:first-letter { color: lime; font-size: xx-large; } +p:before { color: red; content: 'T'; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39b.0.scss new file mode 100644 index 0000000000..38ff4ba000 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39b.0.scss @@ -0,0 +1,2 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-39b.html */ +p::first-letter { font-size : xx-large ; background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39c.0.scss new file mode 100644 index 0000000000..f49d085ddb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-39c.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-39c.html */ +p::first-letter { color: lime; font-size: xx-large; } + p::before { color: red; content: 'T'; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-3a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-3a.0.scss new file mode 100644 index 0000000000..a53bb65f46 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-3a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-3a.html */ +* { color : lime } +ul, p { color : red } +*.t1 { color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-4.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-4.0.scss new file mode 100644 index 0000000000..232286f470 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-4.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-4.html */ +#foo { background-color : lime } +p { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-41.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-41.0.scss new file mode 100644 index 0000000000..12049ebc09 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-41.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-41.html */ +p::before { background-color : lime ; content : "GENERATED CONTENT "} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-41a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-41a.0.scss new file mode 100644 index 0000000000..9092fb307f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-41a.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-41a.html */ +p:before { background-color : lime ; content : "GENERATED CONTENT "} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-42.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-42.0.scss new file mode 100644 index 0000000000..2c7b3c5930 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-42.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-42.html */ +p::after { background-color : lime ; content : "GENERATED CONTENT "} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-42a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-42a.0.scss new file mode 100644 index 0000000000..319f9620b6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-42a.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-42a.html */ +p:after { background-color : lime ; content : "GENERATED CONTENT "} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-43.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-43.0.scss new file mode 100644 index 0000000000..6bac1431f1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-43.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-43.html */ +.white { background-color: transparent ! important; } +.red { background-color: red; } +div.t1 p { background-color: lime; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-43b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-43b.0.scss new file mode 100644 index 0000000000..57d2e390f0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-43b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-43b.html */ +.white { background-color: transparent ! important; } +.green { background-color: lime; } +div.t1 p { background-color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44.0.scss new file mode 100644 index 0000000000..909bbca20e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-44.html */ +.white { background-color: transparent ! important; } +.red { background-color: red; } +div > p.test { background-color: lime; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44b.0.scss new file mode 100644 index 0000000000..b26c14087f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-44b.html */ +.white { background-color: transparent ! important; } +.green { background-color: lime; } +div > p.test { background-color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44c.0.scss new file mode 100644 index 0000000000..9279385479 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-44c.html */ + + .fail > div { background: red; color: yellow; } + .control { background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44d.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44d.0.scss new file mode 100644 index 0000000000..a8ed5ed793 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-44d.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-44d.html */ + + #fail > div { background: red; } + p { background: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45.0.scss new file mode 100644 index 0000000000..3de4e06318 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-45.html */ +.red { background-color : red } +div.stub > p + p { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45b.0.scss new file mode 100644 index 0000000000..02ddbde845 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-45b.html */ +.green { background-color: lime; } +.white { background-color: transparent ! important; } +div.stub > p + p { background-color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45c.0.scss new file mode 100644 index 0000000000..6ed552f04e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-45c.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-45c.html */ + + .fail + div { background: red; } + .control { background: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-46.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-46.0.scss new file mode 100644 index 0000000000..be3866cefe --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-46.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-46.html */ +.red { background-color : red } +div.stub > p ~ p { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-46b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-46b.0.scss new file mode 100644 index 0000000000..4de9c09290 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-46b.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-46b.html */ +.green { background-color : lime ! important } +div.stub > p ~ p { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-5.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-5.0.scss new file mode 100644 index 0000000000..acf0689798 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-5.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-5.html */ +p { background-color : red } +p[title] { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-54.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-54.0.scss new file mode 100644 index 0000000000..4be84ca7f0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-54.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-54.html */ +div.stub > * { color : red } +div.stub *:not([title^="si on"]) { color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-55.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-55.0.scss new file mode 100644 index 0000000000..eb3a0e6341 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-55.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-55.html */ +div.stub > * { color : red } +div.stub *:not([title$="tait"]) { color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-56.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-56.0.scss new file mode 100644 index 0000000000..e9a01bdad8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-56.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-56.html */ +div.stub > * { color : red } +div.stub *:not([title*=" on"]) { color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-59.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-59.0.scss new file mode 100644 index 0000000000..8c8d5d061c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-59.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-59.html */ +div.stub > * { color : red } +div.stub *:not(.foo) { color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-6.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-6.0.scss new file mode 100644 index 0000000000..514e4c3a8c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-6.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-6.html */ +address { background-color : red } +address[title="foo"] { background-color : lime } +span[title="a"] { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-60.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-60.0.scss new file mode 100644 index 0000000000..726b9f378b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-60.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-60.html */ +div.stub > * { color : red } +div.stub *:not(#foo) { color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-61.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-61.0.scss new file mode 100644 index 0000000000..2b346351b6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-61.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-61.html */ +div.stub > * { background-color : red } +div.stub *:not(:link) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-62.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-62.0.scss new file mode 100644 index 0000000000..4181d2eec7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-62.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-62.html */ +div.stub > * { background-color : red } +div.stub *:not(:visited) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-63.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-63.0.scss new file mode 100644 index 0000000000..24d4e99c5d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-63.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-63.html */ +div.stub * { color: lime; text-decoration: none; } +div.stub > * > *:not(:hover) { color: black } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-64.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-64.0.scss new file mode 100644 index 0000000000..480b30d221 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-64.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-64.html */ +div.stub * { color : lime } +div.stub > * > *:not(:active) { color : black } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-65.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-65.0.scss new file mode 100644 index 0000000000..30615dc8ef --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-65.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-65.html */ +a:not(:focus) { background-color: transparent; } +a { background-color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-66.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-66.0.scss new file mode 100644 index 0000000000..6532029b34 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-66.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-66.html */ +p { background-color: navy; color: white; } +p:not(:target) { background-color: white; color: black; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-66b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-66b.0.scss new file mode 100644 index 0000000000..6323784598 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-66b.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-66b.html */ +p { background-color: red; } +p:not(:target) { background-color: lime; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-68.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-68.0.scss new file mode 100644 index 0000000000..b6f16cb7a8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-68.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-68.html */ +button { background-color : red } +input { background-color : red } +button:not(:enabled) { background-color : lime } +input:not(:enabled) { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-69.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-69.0.scss new file mode 100644 index 0000000000..9f407b8406 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-69.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-69.html */ +button { background-color : red } +input { background-color : red } +button:not(:disabled) { background-color : lime } +input:not(:disabled) { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-7.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-7.0.scss new file mode 100644 index 0000000000..8f1a711e3e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-7.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-7.html */ +p { background-color : red } +p[class~="b"] { background-color : lime } +address { background-color : red } +address[title~="foo"] { background-color : lime } +span[class~="b"] { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-70.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-70.0.scss new file mode 100644 index 0000000000..23ec933cc2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-70.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-70.html */ +input, span { background-color : red } +input:not(:checked), input:not(:checked) + span { background-color : lime} diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-72.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-72.0.scss new file mode 100644 index 0000000000..ee7aae040e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-72.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-72.html */ +p:not(:root) { background-color: lime; } +div * { background-color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-72b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-72b.0.scss new file mode 100644 index 0000000000..2e52ad5595 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-72b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-72b.html */ +html:not(:root), test:not(:root) { background-color: red; } +p { background-color: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-77.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-77.0.scss new file mode 100644 index 0000000000..43036386f6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-77.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-77.html */ +.red { background-color : red } +.t1 td:not(:first-child) { background-color : lime } +p > *:not(:first-child) { background-color : lime } +table.t1 td { border : thin black solid } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-77b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-77b.0.scss new file mode 100644 index 0000000000..fd95f40ed5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-77b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-77b.html */ +.green { background-color : lime ! important } +.t1 td:not(:first-child) { background-color : red } +p > *:not(:first-child) { background-color : red } +table.t1 td { border : thin black solid } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-78.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-78.0.scss new file mode 100644 index 0000000000..4d99f1ceca --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-78.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-78.html */ +.red { background-color : red } +.t1 td:not(:last-child) { background-color : lime } +p > *:not(:last-child) { background-color : lime } +table.t1 td { border : thin black solid } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-78b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-78b.0.scss new file mode 100644 index 0000000000..8e3c173b9c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-78b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-78b.html */ +.green { background-color : lime ! important } +.t1 td:not(:last-child) { background-color : red } +p > *:not(:last-child) { background-color : red } +table.t1 td { border : thin black solid } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-79.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-79.0.scss new file mode 100644 index 0000000000..1d1ff21830 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-79.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-79.html */ +.red { background-color : red } +address { margin-bottom : 1em ; margin-left : 1em } +address:not(:first-of-type) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-7b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-7b.0.scss new file mode 100644 index 0000000000..8043e647d2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-7b.0.scss @@ -0,0 +1,9 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-7b.html */ + +p { background: lime; } +[title~="hello world"] { background: red; } +/* Section 6.3.1: Represents the att attribute whose value is a +space-separated list of words, one of which is exactly "val". If this +selector is used, the words in the value must not contain spaces +(since they are separated by spaces). */ + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-8.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-8.0.scss new file mode 100644 index 0000000000..8afa5ca99d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-8.0.scss @@ -0,0 +1,6 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-8.html */ +p { background-color : red } +p[lang|="en"] { background-color : lime } +address { background-color : red } +address[lang="fi"] { background-color : lime } +span[lang|="fr"] { background-color : red } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-80.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-80.0.scss new file mode 100644 index 0000000000..697846a18f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-80.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-80.html */ +.red { background-color : red } +address { margin-bottom : 1em ; margin-left : 1em } +address:not(:last-of-type) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-81.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-81.0.scss new file mode 100644 index 0000000000..7b6f700901 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-81.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-81.html */ +.red { background-color : red } +p:not(:only-child) { background-color : lime } +div.testText > div > p { margin-left : 1em } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-81b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-81b.0.scss new file mode 100644 index 0000000000..af6a6cb054 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-81b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-81b.html */ +.green { background-color : lime ! important } +p:not(:only-child) { background-color : lime } +div.testText > div > p { margin-left : 1em } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-82.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-82.0.scss new file mode 100644 index 0000000000..5869d3161a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-82.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-82.html */ +.red { background-color : red } +.t1 *:not(:only-of-type) { background-color : lime } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-82b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-82b.0.scss new file mode 100644 index 0000000000..c9e4c2cc94 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-82b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-82b.html */ +.green { background-color : lime ! important } +.t1 *:not(:only-of-type) { background-color : red } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-86.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-86.0.scss new file mode 100644 index 0000000000..7022b8c830 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-86.0.scss @@ -0,0 +1,4 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-86.html */ +p { color: red; } +blockquote > div p { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-87.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-87.0.scss new file mode 100644 index 0000000000..275d4274ca --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-87.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-87.html */ +p { color: red; } +blockquote + div ~ p { color: green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-87b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-87b.0.scss new file mode 100644 index 0000000000..1776b027f7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-87b.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-87b.html */ +p { color: green ! important; } +blockquote + div ~ p { color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-88.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-88.0.scss new file mode 100644 index 0000000000..57814ed7c0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-88.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-88.html */ +p { color: red; } +blockquote + div p { color: green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-88b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-88b.0.scss new file mode 100644 index 0000000000..2d0e34e3c8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-88b.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-88b.html */ +p { color: green ! important; } +blockquote + div p { color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-89.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-89.0.scss new file mode 100644 index 0000000000..d6c797e143 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-89.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-89.html */ +p { color: red; } +blockquote div > p { color: green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-9.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-9.0.scss new file mode 100644 index 0000000000..cba3eded20 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-9.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-9.html */ +p { background-color : red } +p[title^="foo"] { background-color : lime } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-90.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-90.0.scss new file mode 100644 index 0000000000..32175261e4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-90.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-90.html */ +p { color: red; } +blockquote ~ div + p { color: green; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-90b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-90b.0.scss new file mode 100644 index 0000000000..afcdbafe4d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-90b.0.scss @@ -0,0 +1,3 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-90b.html */ +p { color: green ! important; } +blockquote ~ div + p { color: red; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d1.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d1.0.scss new file mode 100644 index 0000000000..b669874e11 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d1.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-d1.html */ + + #test { background: red; display: block; padding: 1em; } + #test:not(:empty) { background: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d1b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d1b.0.scss new file mode 100644 index 0000000000..0ac92bcd18 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d1b.0.scss @@ -0,0 +1,7 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-d1b.html */ + + #test1 { background: red; display: block; padding: 1em; margin: 1em; } + #test1:empty { background: lime; } + #test2 { background: lime; display: block; padding: 1em; margin: 1em; } + #test2:empty { background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d2.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d2.0.scss new file mode 100644 index 0000000000..c3f0544bb5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d2.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-d2.html */ + + #test { background: red; display: block; padding: 1em; } + #stub ~ div div + div > div { background: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d4.0.scss b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d4.0.scss new file mode 100644 index 0000000000..dbf2bdda74 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/css3-modsel-d4.0.scss @@ -0,0 +1,5 @@ +/* Source: http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-d4.html */ + + #two:first-child { background: red; } + #three:last-child { background: lime; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-001.0.scss new file mode 100644 index 0000000000..7e94325735 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-001.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-001.0.scss new file mode 100644 index 0000000000..3e68199d28 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-dynamic-001.htm */ + + span:before { content: open-quote; } + span:after { content: close-quote; } + span { quotes: '"' '"'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-003a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-003a.0.scss new file mode 100644 index 0000000000..30c5445777 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-003a.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-dynamic-003a.htm */ + + div#x:first-letter { color: blue; float: left; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-003b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-003b.0.scss new file mode 100644 index 0000000000..37e3dee7fd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-dynamic-003b.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-dynamic-003b.htm */ + + div#x:first-letter { color: blue; float: none } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-inherit-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-inherit-001.0.scss new file mode 100644 index 0000000000..4aea22c740 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-inherit-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-inherit-001.htm */ + +div { float: left; overflow: scroll; font-size: 50px; width: 3em; line-height: 10px } +div:first-letter { float: inherit; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-inherit-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-inherit-001.1.scss new file mode 100644 index 0000000000..9bc48c3a71 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-inherit-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-inherit-001.htm */ +.style { font-size: 10px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-001.0.scss new file mode 100644 index 0000000000..7d79ae49d8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-001.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-002.0.scss new file mode 100644 index 0000000000..8ab9328de6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-002.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-003.0.scss new file mode 100644 index 0000000000..2c2b8a906f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-003.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-004.0.scss new file mode 100644 index 0000000000..b568b4430b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-004.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-004.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-005.0.scss new file mode 100644 index 0000000000..d5f9376161 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-005.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-005.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-006.0.scss new file mode 100644 index 0000000000..fc0089ccde --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-006.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-006.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-007.0.scss new file mode 100644 index 0000000000..5fbf16bc9d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-nested-007.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-nested-007.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-001.0.scss new file mode 100644 index 0000000000..ba956560c8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-quote-001.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-002.0.scss new file mode 100644 index 0000000000..a5f95536b7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-002.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-quote-002.htm */ + + div { color: black; } + div:first-letter { color: green; } + span:before { content: open-quote; } + span:after { content: close-quote; } + span { quotes: '"' '"'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-003.0.scss new file mode 100644 index 0000000000..849c55abf5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-003.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-quote-003.htm */ + + div { color: black; } + div:first-letter { color: green; } + span:before { content: open-quote "This "; } + span:after { content: close-quote; } + span { quotes: '"' '"'; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-004.0.scss new file mode 100644 index 0000000000..96706e1f1e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-004.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-quote-004.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-005.0.scss new file mode 100644 index 0000000000..15214106ba --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-005.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-quote-005.htm */ + + div { color: black; } + div:first-letter { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-006.0.scss new file mode 100644 index 0000000000..970e5b70b0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-letter-quote-006.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-letter-quote-006.htm */ + + div { color: black; } + div:first-letter { color: green; } + span:before { content: "\"This "; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-001.0.scss new file mode 100644 index 0000000000..74973ac9a1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-001.htm */ + + body { color: red } + body:first-line { color: green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-001.0.scss new file mode 100644 index 0000000000..5cec148572 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-001.htm */ + + div { color: green } + div:first-line { color: red } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-001.1.scss new file mode 100644 index 0000000000..59ddfc8476 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-001.htm */ +.style { float: left } diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-002.0.scss new file mode 100644 index 0000000000..89f8cbdeda --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-002.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-002.htm */ + + div { color: red } + div:first-line { color: green } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-002.1.scss new file mode 100644 index 0000000000..716528bfc2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-002.htm */ +.style { float: left } diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-003.0.scss new file mode 100644 index 0000000000..8b793f90aa --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-003.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-003.htm */ + + div { color: green } + div:first-line { color: red } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-003.1.scss new file mode 100644 index 0000000000..1da72d9761 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-003.htm */ +.style { float: left } diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-004.0.scss new file mode 100644 index 0000000000..cade4a2861 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-floats-004.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-floats-004.htm */ + + div { color: green } + div:first-line { color: red } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-001.0.scss new file mode 100644 index 0000000000..c5e5fe5468 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-001.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-inherit-001.htm */ + + +.a:first-line { } +.a { overflow: scroll; } +.b, .c { overflow: inherit; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-002.0.scss new file mode 100644 index 0000000000..ea1027fc24 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-002.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-inherit-002.htm */ + + div { background: green; } + div:first-line { background-color: red; } + span.one { background: inherit; } + span.two { background-color: inherit; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-003.0.scss new file mode 100644 index 0000000000..f498981952 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/first-line-inherit-003.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/first-line-inherit-003.htm */ + + div, p { background: green; } + div:first-line, p:first-line { background-color: red; } + span.one { background: inherit; } + span.two { background-color: inherit; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.0.scss new file mode 100644 index 0000000000..9358f2916e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001a.htm */ + +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.1.scss new file mode 100644 index 0000000000..d803b8ffd2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001a.htm */ +.style { width:400px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.2.scss new file mode 100644 index 0000000000..0a22209fb1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001a.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001a.htm */ +.style { text-align:right; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.0.scss new file mode 100644 index 0000000000..80fe2ff996 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001b.htm */ + +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.1.scss new file mode 100644 index 0000000000..3992160e83 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001b.htm */ +.style { width:400px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.2.scss new file mode 100644 index 0000000000..f19a8d2088 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001b.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001b.htm */ +.style { text-align:right; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.0.scss new file mode 100644 index 0000000000..19d1d26dc5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001c.htm */ + +.left { float:left; } +.right { float:right; } +.left, .right { width:50px; height:50px; background:yellow; } +p { overflow:auto; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.1.scss new file mode 100644 index 0000000000..c3143dca78 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001c.htm */ +.style { width:400px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.2.scss new file mode 100644 index 0000000000..e52a60f4ed --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-001c.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-001c.htm */ +.style { text-align:right; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.0.scss new file mode 100644 index 0000000000..4141a2ba00 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-003.htm */ +.style { width:100px; font-size:5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.1.scss new file mode 100644 index 0000000000..aecdad0621 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-003.htm */ +.style { background:blue; width:100px; height:100px; float:left; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.2.scss new file mode 100644 index 0000000000..2e7fc3e31e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-003.htm */ +.style { background:yellow; width:30px; height:30px; float:left; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.3.scss new file mode 100644 index 0000000000..bacc9de7c9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-003.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-003.htm */ +.style { background:yellow; width:30px; height:30px; float:right; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.0.scss new file mode 100644 index 0000000000..a1f23b9119 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-004.htm */ +.style { width:200px; font-size:5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.1.scss new file mode 100644 index 0000000000..be86a0b01e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-004.htm */ +.style { background:green; width:100px; height:100px; float:left; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.2.scss new file mode 100644 index 0000000000..b9c4341835 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-placement-vertical-004.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-placement-vertical-004.htm */ +.style { background:blue; width:100px; height:100px; float:left; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.0.scss new file mode 100644 index 0000000000..1f12c6fb78 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-001.htm */ +.style { float: left; width: 500px; height: 500px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.1.scss new file mode 100644 index 0000000000..155ae9bb17 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-001.htm */ +.style { float: right; width: 50px; height: 300px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.2.scss new file mode 100644 index 0000000000..03921ad64e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-001.htm */ +.style { margin-right: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.3.scss new file mode 100644 index 0000000000..82327074bf --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-001.htm */ +.style { float: left; width: 425px; height: 10px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.0.scss new file mode 100644 index 0000000000..b0659ed170 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-002.htm */ +.style { float: left; width: 500px; height: 500px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.1.scss new file mode 100644 index 0000000000..51d4aae421 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-002.htm */ +.style { float: right; width: 50px; height: 300px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.2.scss new file mode 100644 index 0000000000..b64d557e23 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-002.htm */ +.style { margin-right: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.3.scss new file mode 100644 index 0000000000..667087faba --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-left-002.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-left-002.htm */ +.style { float: left; width: 475px; height: 10px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.0.scss new file mode 100644 index 0000000000..bb6604d005 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-001.htm */ +.style { float: left; width: 500px; height: 500px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.1.scss new file mode 100644 index 0000000000..7ee24227e9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-001.htm */ +.style { float: left; width: 50px; height: 300px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.2.scss new file mode 100644 index 0000000000..1d11bdf6dc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-001.htm */ +.style { margin-left: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.3.scss new file mode 100644 index 0000000000..2ce67f6358 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-001.htm */ +.style { float: right; width: 425px; height: 10px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.0.scss new file mode 100644 index 0000000000..02936f2d05 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-002.htm */ +.style { float: left; width: 500px; height: 500px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.1.scss new file mode 100644 index 0000000000..62e70dc857 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-002.htm */ +.style { float: left; width: 50px; height: 300px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.2.scss new file mode 100644 index 0000000000..33158539ba --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-002.htm */ +.style { margin-left: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.3.scss new file mode 100644 index 0000000000..b657772275 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule3-outside-right-002.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule3-outside-right-002.htm */ +.style { float: right; width: 475px; height: 10px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.0.scss new file mode 100644 index 0000000000..a0b07a7d20 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-left-001.htm */ +.style { float: left; width: 500px; height: 500px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.1.scss new file mode 100644 index 0000000000..282d40f7de --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-left-001.htm */ +.style { float: left; width: 50px; height: 300px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.2.scss new file mode 100644 index 0000000000..ab40480544 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-left-001.htm */ +.style { margin-left: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.3.scss new file mode 100644 index 0000000000..3d1bced7d2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-left-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-left-001.htm */ +.style { float: left; width: 425px; height: 10px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.0.scss new file mode 100644 index 0000000000..808f90847a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-right-001.htm */ +.style { float: left; width: 500px; height: 500px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.1.scss new file mode 100644 index 0000000000..2591c3de52 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-right-001.htm */ +.style { float: right; width: 50px; height: 300px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.2.scss new file mode 100644 index 0000000000..2ca9103b55 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-right-001.htm */ +.style { margin-right: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.3.scss new file mode 100644 index 0000000000..a051758341 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-rule7-outside-right-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-rule7-outside-right-001.htm */ +.style { float: right; width: 425px; height: 10px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.0.scss new file mode 100644 index 0000000000..55dbbeebaa --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ + + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.1.scss new file mode 100644 index 0000000000..59d553acc3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { background: aqua } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.12.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.12.scss new file mode 100644 index 0000000000..941f9b0c43 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.12.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { float:right; background:blue; width: 100px; height: 20px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.2.scss new file mode 100644 index 0000000000..231f1d76cf --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { float:left; background:blue; width: 100px; height: 20px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.24.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.24.scss new file mode 100644 index 0000000000..5304225969 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.24.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { overflow: hidden; background: yellow } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.3.scss new file mode 100644 index 0000000000..0ffa20c60c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { float:left; background:silver; width: 100px; height: 6px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.4.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.4.scss new file mode 100644 index 0000000000..3af0c41084 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { background: yellow } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.5.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.5.scss new file mode 100644 index 0000000000..70e5ab27a3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { width: 150px; height: 10px; background: purple } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.8.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.8.scss new file mode 100644 index 0000000000..4f0231e636 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-004.8.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-004.htm */ +.style { float:right; background:silver; width: 100px; height: 6px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.0.scss new file mode 100644 index 0000000000..87b04d41d4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.0.scss @@ -0,0 +1,9 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-005.htm */ + + + body { font-size: 10px; } + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; vertical-align: top; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.1.scss new file mode 100644 index 0000000000..4ed6811ec4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-005.htm */ +.style { background: aqua } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.2.scss new file mode 100644 index 0000000000..04ba12051e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-005.htm */ +.style { float:left; background:blue; width: 200px; height: 20px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.3.scss new file mode 100644 index 0000000000..59ff5a258e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-005.htm */ +.style { background: yellow } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.5.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.5.scss new file mode 100644 index 0000000000..1f9328855c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-005.htm */ +.style { float:right; background:blue; width: 200px; height: 20px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.9.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.9.scss new file mode 100644 index 0000000000..53a68a0469 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-005.9.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-005.htm */ +.style { overflow:hidden; background: yellow; width: 50%; height: 20px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.0.scss new file mode 100644 index 0000000000..ca6d5ed844 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.0.scss @@ -0,0 +1,12 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ + + + body { font-size: 16px; } + + table { margin: 0; border-spacing: 0; } + caption, td, th { padding: 0; vertical-align: top; text-align: left; } + + table table caption { background: yellow; } + table table { background: purple; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.1.scss new file mode 100644 index 0000000000..beba9cf330 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { background: aqua } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.10.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.10.scss new file mode 100644 index 0000000000..49c74a97d9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.10.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:110px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.11.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.11.scss new file mode 100644 index 0000000000..deee635381 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.11.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:105px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.12.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.12.scss new file mode 100644 index 0000000000..fdb260729a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.12.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:100px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.13.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.13.scss new file mode 100644 index 0000000000..4522f57cb8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.13.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:95px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.131.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.131.scss new file mode 100644 index 0000000000..a274d6ee7f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.131.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { caption-side: bottom; height:30px; width: 192px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.14.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.14.scss new file mode 100644 index 0000000000..b49fd302a9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.14.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:90px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.15.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.15.scss new file mode 100644 index 0000000000..2a29f56c3f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.15.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:85px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.16.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.16.scss new file mode 100644 index 0000000000..e8f11cc823 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.16.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:80px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.17.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.17.scss new file mode 100644 index 0000000000..231f28519c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.17.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:75px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.18.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.18.scss new file mode 100644 index 0000000000..a4f78671cb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.18.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:70px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.19.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.19.scss new file mode 100644 index 0000000000..9e9e29d19c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.19.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:65px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.2.scss new file mode 100644 index 0000000000..501590ad5d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:150px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.20.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.20.scss new file mode 100644 index 0000000000..126280a6fe --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.20.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:60px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.21.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.21.scss new file mode 100644 index 0000000000..a7228173da --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.21.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:55px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.22.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.22.scss new file mode 100644 index 0000000000..0cc681c041 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.22.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:50px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.23.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.23.scss new file mode 100644 index 0000000000..f2c07e7838 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.23.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:45px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.24.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.24.scss new file mode 100644 index 0000000000..b8e2c5796e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.24.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:40px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.25.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.25.scss new file mode 100644 index 0000000000..ce05ee6888 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.25.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:35px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.26.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.26.scss new file mode 100644 index 0000000000..d5ab773c5f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.26.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:30px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.27.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.27.scss new file mode 100644 index 0000000000..3385f4ea30 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.27.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:25px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.28.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.28.scss new file mode 100644 index 0000000000..6022a36c29 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.28.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:20px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.29.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.29.scss new file mode 100644 index 0000000000..a352e1fa56 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.29.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:15px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.3.scss new file mode 100644 index 0000000000..29eb47aa2f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:145px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.30.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.30.scss new file mode 100644 index 0000000000..5bacfae2f3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.30.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:10px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.31.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.31.scss new file mode 100644 index 0000000000..0a8445e2b0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.31.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:5px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.32.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.32.scss new file mode 100644 index 0000000000..ba50d0bd65 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.32.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { caption-side: top; height:30px; width: 100px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.33.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.33.scss new file mode 100644 index 0000000000..2dc59a3264 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.33.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { height: 30px; width: 230px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.4.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.4.scss new file mode 100644 index 0000000000..97ec1f9113 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:140px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.5.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.5.scss new file mode 100644 index 0000000000..0778fc55c9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:135px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.6.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.6.scss new file mode 100644 index 0000000000..eee0117225 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.6.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:130px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.65.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.65.scss new file mode 100644 index 0000000000..7c9e6eda76 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.65.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { caption-side: top; height:30px; width: 190px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.66.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.66.scss new file mode 100644 index 0000000000..bb41e0cbaf --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.66.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { height: 30px; width: 100px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.7.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.7.scss new file mode 100644 index 0000000000..764745abb1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.7.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:125px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.8.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.8.scss new file mode 100644 index 0000000000..ae65d3d2e4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.8.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:120px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.9.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.9.scss new file mode 100644 index 0000000000..c86cc30a7c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.9.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { float:left; clear:left; background:blue; width:115px; height:1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.98.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.98.scss new file mode 100644 index 0000000000..9cd7749821 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.98.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { caption-side: bottom; height:30px; width: 100px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.99.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.99.scss new file mode 100644 index 0000000000..eabd2b81b7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-006.99.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-006.htm */ +.style { height: 30px; width: 227px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.0.scss new file mode 100644 index 0000000000..fe79ead93b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ + + + table { margin: 0; border-spacing: 0; } + td, th { padding: 0; vertical-align: top; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.1.scss new file mode 100644 index 0000000000..da32416752 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { background: aqua } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.15.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.15.scss new file mode 100644 index 0000000000..dc37b6963d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.15.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: 5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.16.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.16.scss new file mode 100644 index 0000000000..c2fed6240b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.16.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.19.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.19.scss new file mode 100644 index 0000000000..a656c57cf1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.19.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: 10px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.2.scss new file mode 100644 index 0000000000..bcd2f016b0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { float: left; height: 10px; width: 150px; background: blue } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.20.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.20.scss new file mode 100644 index 0000000000..64956d2143 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.20.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.23.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.23.scss new file mode 100644 index 0000000000..9796be893b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.23.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: -5px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.24.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.24.scss new file mode 100644 index 0000000000..7842444780 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.24.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 10px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.27.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.27.scss new file mode 100644 index 0000000000..d2e20e04cc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.27.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: 4px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.28.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.28.scss new file mode 100644 index 0000000000..74db9f2d40 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.28.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 4px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.3.scss new file mode 100644 index 0000000000..b50e1429ae --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: 6px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.31.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.31.scss new file mode 100644 index 0000000000..f09ed11cee --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.31.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: -1px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.39.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.39.scss new file mode 100644 index 0000000000..8dcb8d161c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.39.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: -4px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.4.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.4.scss new file mode 100644 index 0000000000..3a4a85219f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.40.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.40.scss new file mode 100644 index 0000000000..bfdf7db3b4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.40.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 0px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.43.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.43.scss new file mode 100644 index 0000000000..6f0581a068 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.43.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; margin-bottom: 0px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.44.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.44.scss new file mode 100644 index 0000000000..186f24937b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.44.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -4px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.48.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.48.scss new file mode 100644 index 0000000000..489890f8bd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.48.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: -1px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.7.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.7.scss new file mode 100644 index 0000000000..0ee68c91ce --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.7.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { height: 5px; background: purple; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.8.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.8.scss new file mode 100644 index 0000000000..5c131b1a4d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-007.8.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-007.htm */ +.style { overflow: hidden; width: 200px; height: 5px; background: yellow; margin-top: 6px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-outside-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-outside-001.0.scss new file mode 100644 index 0000000000..c7fdc4f3ba --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-bfc-outside-001.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-bfc-outside-001.htm */ + +#wrap {width:600px; border:1px solid;} +.a {background:lime; color:#fff; width:80%;} +.b {float:right; width:18%; background: cyan; color: #000; height:10em;} +textarea {width: 100%; height:10em;} + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.0.scss new file mode 100644 index 0000000000..f780444dc2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-001l.htm */ + + +body { width: 400px; border: medium solid; } +div { float: left; clear: left; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; margin-right: auto; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.1.scss new file mode 100644 index 0000000000..a695061dc6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-001l.htm */ +.style { width: 50px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.2.scss new file mode 100644 index 0000000000..94b3728f3d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001l.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-001l.htm */ +.style { width: 100px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.0.scss new file mode 100644 index 0000000000..c665929221 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-001r.htm */ + + +body { width: 400px; border: medium solid; } +div { float: right; clear: right; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; margin-left: auto; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.1.scss new file mode 100644 index 0000000000..2775ef585f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-001r.htm */ +.style { width: 50px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.2.scss new file mode 100644 index 0000000000..3c9ab6d376 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-001r.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-001r.htm */ +.style { width: 100px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.0.scss new file mode 100644 index 0000000000..48cf6ec53a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-002l.htm */ + + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.1.scss new file mode 100644 index 0000000000..10ffd0fc80 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-002l.htm */ +.style { float: left; width: 150px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.2.scss new file mode 100644 index 0000000000..3a572e8b03 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002l.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-002l.htm */ +.style { float: right; width: 300px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.0.scss new file mode 100644 index 0000000000..fe457370c1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-002r.htm */ + + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 200px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.1.scss new file mode 100644 index 0000000000..4e2081dba9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-002r.htm */ +.style { float: right; width: 150px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.2.scss new file mode 100644 index 0000000000..1055fac5ff --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-002r.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-002r.htm */ +.style { float: left; width: 300px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.0.scss new file mode 100644 index 0000000000..ef1a96a2bf --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-003l.htm */ + + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 100px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.1.scss new file mode 100644 index 0000000000..1c57064ba3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-003l.htm */ +.style { float: left; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.2.scss new file mode 100644 index 0000000000..2e90f18734 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003l.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-003l.htm */ +.style { float: right; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.0.scss new file mode 100644 index 0000000000..d2971cb795 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-003r.htm */ + + +body { width: 400px; border: medium solid; } +span { display: block; overflow: hidden; width: 100px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.1.scss new file mode 100644 index 0000000000..f6306c31aa --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-003r.htm */ +.style { float: right; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.2.scss new file mode 100644 index 0000000000..3b63ad756d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-bfc-003r.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-bfc-003r.htm */ +.style { float: left; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.0.scss new file mode 100644 index 0000000000..6119b6895a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-001l.htm */ + + +body { width: 400px; border: medium solid; text-align: left; } +div { float: left; clear: left; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.1.scss new file mode 100644 index 0000000000..60abfaa89f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-001l.htm */ +.style { width: 50px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.2.scss new file mode 100644 index 0000000000..bb8f7d8585 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001l.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-001l.htm */ +.style { width: 100px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.0.scss new file mode 100644 index 0000000000..3c674d4165 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-001r.htm */ + + +body { width: 400px; border: medium solid; text-align: right; } +div { float: right; clear: right; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.1.scss new file mode 100644 index 0000000000..254cceff5d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-001r.htm */ +.style { width: 50px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.2.scss new file mode 100644 index 0000000000..f9da61827d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-001r.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-001r.htm */ +.style { width: 100px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.0.scss new file mode 100644 index 0000000000..d391fc5bb6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-002l.htm */ + + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.1.scss new file mode 100644 index 0000000000..b8b4e306b2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-002l.htm */ +.style { float: left; width: 150px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.2.scss new file mode 100644 index 0000000000..4fe3554d42 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002l.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-002l.htm */ +.style { float: right; width: 300px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.0.scss new file mode 100644 index 0000000000..278a0b20d1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-002r.htm */ + + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 200px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.1.scss new file mode 100644 index 0000000000..24fc0000cb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-002r.htm */ +.style { float: right; width: 150px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.2.scss new file mode 100644 index 0000000000..5aba32ba55 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-002r.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-002r.htm */ +.style { float: left; width: 300px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.0.scss new file mode 100644 index 0000000000..5af166b155 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-003l.htm */ + + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 100px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.1.scss new file mode 100644 index 0000000000..ae6e0a84ea --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-003l.htm */ +.style { float: left; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.2.scss new file mode 100644 index 0000000000..f6a110f660 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003l.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-003l.htm */ +.style { float: right; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.0.scss new file mode 100644 index 0000000000..573684a70a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-003r.htm */ + + +body { width: 400px; border: medium solid; } +span { display: inline-block; vertical-align: top; width: 100px; height: 50px; background: aqua; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.1.scss new file mode 100644 index 0000000000..ed8f4d939a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-003r.htm */ +.style { float: right; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.2.scss new file mode 100644 index 0000000000..3156752c2e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-wrap-top-below-inline-003r.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-wrap-top-below-inline-003r.htm */ +.style { float: left; width: 250px; height: 75px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.0.scss new file mode 100644 index 0000000000..4cb8f644c2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-001.htm */ +.style { width: 500px; height: 500px; float: left; font-size: 12px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.1.scss new file mode 100644 index 0000000000..c1ed4bbe00 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-001.htm */ +.style { float: left; width: 10px; height: 30px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.2.scss new file mode 100644 index 0000000000..b3891027db --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-001.htm */ +.style { float: left; clear: left; width: 100px; height: 1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.3.scss new file mode 100644 index 0000000000..92c36c2b4b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-001.htm */ +.style { display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: blue; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.4.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.4.scss new file mode 100644 index 0000000000..7a4a377d29 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-001.htm */ +.style { display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: purple; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.5.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.5.scss new file mode 100644 index 0000000000..30b08ae999 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-001.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-001.htm */ +.style { display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: fuchsia } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.0.scss new file mode 100644 index 0000000000..c718bdcd07 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-002.htm */ +.style { width: 500px; height: 500px; float: left; font-size: 12px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.1.scss new file mode 100644 index 0000000000..fa43435f50 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-002.htm */ +.style { float: left; width: 10px; height: 30px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.2.scss new file mode 100644 index 0000000000..302c91ab56 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-002.htm */ +.style { float: left; clear: left; width: 100px; height: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.3.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.3.scss new file mode 100644 index 0000000000..d90881ad6d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-002.htm */ +.style { display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: blue; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.4.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.4.scss new file mode 100644 index 0000000000..1f403a2ed2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-002.htm */ +.style { display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: purple; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.5.scss b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.5.scss new file mode 100644 index 0000000000..901a27fe9d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/floats-zero-height-wrap-002.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/floats-zero-height-wrap-002.htm */ +.style { display:inline-block; vertical-align: bottom; height: 20px; width: 300px; background: fuchsia } diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-001.0.scss new file mode 100644 index 0000000000..f70698a920 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-001.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-001.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: CSSTest FamilyName, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-002.0.scss new file mode 100644 index 0000000000..f1cfd976b2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-002.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-002.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: csstest familyname, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-003.0.scss new file mode 100644 index 0000000000..55ae604a48 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-003.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-003.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: cssTest familyName, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-004.0.scss new file mode 100644 index 0000000000..b95f2e94bf --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-004.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-004.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: "CSSTest FamilyName", CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-005.0.scss new file mode 100644 index 0000000000..3a5f916cce --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-005.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-005.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: 'CSSTest FamilyName', CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-006.0.scss new file mode 100644 index 0000000000..312f9c8948 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-006.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-006.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: CSSTest FamilyName, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-007.0.scss new file mode 100644 index 0000000000..d6f61aa0da --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-007.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-007.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: "CSSTest FamilyName", CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-008.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-008.0.scss new file mode 100644 index 0000000000..b0f025d6f0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-008.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-008.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: 'CSSTest FamilyName', CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-009.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-009.0.scss new file mode 100644 index 0000000000..f6ed3eea3d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-009.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-009.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: CSSTest \000046amilyName, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-012.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-012.0.scss new file mode 100644 index 0000000000..ff9c919acd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-012.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-012.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: "CSSTest Family\Name", CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-013.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-013.0.scss new file mode 100644 index 0000000000..04100a1326 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-013.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-013.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: CSSTest FamilyName Bold, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-014.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-014.0.scss new file mode 100644 index 0000000000..d98252d89d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-014.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-014.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: CSSTestFamilyNameBold, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-016.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-016.0.scss new file mode 100644 index 0000000000..11566bc342 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-016.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-016.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + p { + font-family: CSSTest Weights 400; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-017.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-017.0.scss new file mode 100644 index 0000000000..ea2b2110b0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-017.0.scss @@ -0,0 +1,9 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-017.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + body { font-family: CSSTest Fallback; } + p, div { + font-family: CSSTest Unknown; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-018.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-018.0.scss new file mode 100644 index 0000000000..81e90cee9c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-018.0.scss @@ -0,0 +1,9 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-018.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + body { font-family: CSSTest Fallback; } + p, div { + font-family: "CSSTest Unknown"; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-019.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-019.0.scss new file mode 100644 index 0000000000..ad32f6351b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-019.0.scss @@ -0,0 +1,9 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-019.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + div#test { font-family: CSSTest Fallback; } + p { + font-family: CSSTest Unknown; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-020.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-020.0.scss new file mode 100644 index 0000000000..0d66b81154 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-020.0.scss @@ -0,0 +1,9 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-020.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + div#test { font-family: CSSTest Fallback; } + p { + font-family: "CSSTest Unknown"; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-021.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-021.0.scss new file mode 100644 index 0000000000..592d994b47 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-021.0.scss @@ -0,0 +1,10 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-021.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + body { font-family: "CSSTest FamilyName"; } + div { font-family: "CSSTest Unknown"; } + p { + font-family: "CSSTest" Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-022.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-022.0.scss new file mode 100644 index 0000000000..dc737140a8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-022.0.scss @@ -0,0 +1,14 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-022.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + div { font-family: "CSSTest Unknown"; } + p { + } + p#test1 { + font-family: x-large CSSTest Fallback; + } + p#test4 { + font-family: caption CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-023.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-023.0.scss new file mode 100644 index 0000000000..4c4dc9c7f3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-023.0.scss @@ -0,0 +1,20 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-023.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + div.test { font-family: CSSTest Fallback; } + p { + } + p#test1a { + font-family: "small-caps 1in CSSTest FamilyName Funky", CSSTest Fallback; + } + p#test2 { + font-family: x-large CSSTest FamilyName Funky, CSSTest Fallback; + } + p#test2a { + font-family: "x-large CSSTest FamilyName Funky", CSSTest Fallback; + } + p#test3a { + font-family: "12px CSSTest FamilyName Funky", CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-family-name-024.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-024.0.scss new file mode 100644 index 0000000000..79ac477f2c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-family-name-024.0.scss @@ -0,0 +1,26 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-024.htm */ + + body { font-size: 36px; } + span#verify { font-family: CSSTest Verify; } + div.test { font-family: CSSTest Fallback; } + p { + } + p#test1 { + font-family: caption, CSSTest Fallback; + } + p#test2 { + font-family: icon, CSSTest Fallback; + } + p#test3 { + font-family: menu, CSSTest Fallback; + } + p#test4 { + font-family: message-box, CSSTest Fallback; + } + p#test5 { + font-family: small-caption, CSSTest Fallback; + } + p#test6 { + font-family: status-bar, CSSTest Fallback; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-weight-bolder-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-weight-bolder-001.0.scss new file mode 100644 index 0000000000..e1334dbe2f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-weight-bolder-001.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-weight-bolder-001.htm */ + + span#verify { font-family: CSSTest Verify; font-weight: normal; } + div { margin-bottom: 1em; } + body { margin: 50px; } + table { + border-collapse: collapse; + } + th { + font-weight: normal; + text-align: left; + padding-right: 1em; + } + span { font-weight: bolder; } + thead th { text-align: center; padding-bottom: 1em; } + td { width: 5em; text-align: center; } + td.f1 { font-family: CSSTest Weights Full; } + td.f2 { font-family: CSSTest Weights W1479; } + td.f3 { font-family: CSSTest Weights W15; } + td.f4 { font-family: CSSTest Weights W24; } + td.f5 { font-family: CSSTest Weights W2569; } + td.f6 { font-family: CSSTest Weights W258; } + td.f7 { font-family: CSSTest Weights W3589; } + td.f8 { font-family: CSSTest Weights W47; } + th.f1 { display: table-cell; } + th.f2 { display: table-cell; } + th.f3 { display: table-cell; } + th.f4 { display: table-cell; } + th.f5 { display: table-cell; } + th.f6 { display: table-cell; } + th.f7 { display: table-cell; } + th.f8 { display: table-cell; } + + tr.w1 td { font-weight: 100; } + tr.w2 td { font-weight: 200; } + tr.w3 td { font-weight: 300; } + tr.w4 td { font-weight: 400; } + tr.w5 td { font-weight: 500; } + tr.w6 td { font-weight: 600; } + tr.w7 td { font-weight: 700; } + tr.w8 td { font-weight: 800; } + tr.w9 td { font-weight: 900; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-weight-lighter-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-weight-lighter-001.0.scss new file mode 100644 index 0000000000..1840142b38 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-weight-lighter-001.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-weight-lighter-001.htm */ + + span#verify { font-family: CSSTest Verify; font-weight: normal; } + div { margin-bottom: 1em; } + body { margin: 50px; } + table { + border-collapse: collapse; + } + th { + font-weight: normal; + text-align: left; + padding-right: 1em; + } + span { font-weight: lighter; } + thead th { text-align: center; padding-bottom: 1em; } + td { width: 5em; text-align: center; } + td.f1 { font-family: CSSTest Weights Full; } + td.f2 { font-family: CSSTest Weights W1479; } + td.f3 { font-family: CSSTest Weights W15; } + td.f4 { font-family: CSSTest Weights W24; } + td.f5 { font-family: CSSTest Weights W2569; } + td.f6 { font-family: CSSTest Weights W258; } + td.f7 { font-family: CSSTest Weights W3589; } + td.f8 { font-family: CSSTest Weights W47; } + th.f1 { display: table-cell; } + th.f2 { display: table-cell; } + th.f3 { display: table-cell; } + th.f4 { display: table-cell; } + th.f5 { display: table-cell; } + th.f6 { display: table-cell; } + th.f7 { display: table-cell; } + th.f8 { display: table-cell; } + + tr.w1 td { font-weight: 100; } + tr.w2 td { font-weight: 200; } + tr.w3 td { font-weight: 300; } + tr.w4 td { font-weight: 400; } + tr.w5 td { font-weight: 500; } + tr.w6 td { font-weight: 600; } + tr.w7 td { font-weight: 700; } + tr.w8 td { font-weight: 800; } + tr.w9 td { font-weight: 900; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/font-weight-normal-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/font-weight-normal-001.0.scss new file mode 100644 index 0000000000..29a665ee9a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/font-weight-normal-001.0.scss @@ -0,0 +1,43 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/font-weight-normal-001.htm */ + + span#verify { font-family: CSSTest Verify; font-weight: normal; } + div { margin-bottom: 1em; } + body { margin: 50px; } + table { + border-collapse: collapse; + } + th { + font-weight: normal; + text-align: left; + padding-right: 1em; + } + span { } + thead th { text-align: center; padding-bottom: 1em; } + td { width: 5em; text-align: center; } + td.f1 { font-family: CSSTest Weights Full; } + td.f2 { font-family: CSSTest Weights W1479; } + td.f3 { font-family: CSSTest Weights W15; } + td.f4 { font-family: CSSTest Weights W24; } + td.f5 { font-family: CSSTest Weights W2569; } + td.f6 { font-family: CSSTest Weights W258; } + td.f7 { font-family: CSSTest Weights W3589; } + td.f8 { font-family: CSSTest Weights W47; } + th.f1 { display: table-cell; } + th.f2 { display: table-cell; } + th.f3 { display: table-cell; } + th.f4 { display: table-cell; } + th.f5 { display: table-cell; } + th.f6 { display: table-cell; } + th.f7 { display: table-cell; } + th.f8 { display: table-cell; } + + tr.w1 td { font-weight: 100; } + tr.w2 td { font-weight: 200; } + tr.w3 td { font-weight: 300; } + tr.w4 td { font-weight: 400; } + tr.w5 td { font-weight: 500; } + tr.w6 td { font-weight: 600; } + tr.w7 td { font-weight: 700; } + tr.w8 td { font-weight: 800; } + tr.w9 td { font-weight: 900; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-000.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-000.0.scss new file mode 100644 index 0000000000..9ddf923d46 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-000.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-000.htm */ + +span { display: inline-block; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-height-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-height-001.0.scss new file mode 100644 index 0000000000..595b0fef80 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-height-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-height-001.htm */ + +div { display: inline-block; width: 10em; background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-height-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-height-002.0.scss new file mode 100644 index 0000000000..2876e73ab5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-height-002.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-height-002.htm */ + +div { display: inline-block; height: 5em; width:10em; vertical-align: baseline; background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-valign-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-valign-001.0.scss new file mode 100644 index 0000000000..5d2446d71f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-valign-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-valign-001.htm */ + +span { display: inline-block; } +span > span { display: block; visibility: hidden; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-valign-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-valign-002.0.scss new file mode 100644 index 0000000000..f262046c2b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-valign-002.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-valign-002.htm */ + +body { background: white; color: black; } +span { display: inline-block; margin: 3px 0; border: 4px solid white; border-width: 4px 0; padding: 9px 0; } +span > span { display: block; visibility: hidden; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-001a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-001a.0.scss new file mode 100644 index 0000000000..18c2f89059 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-001a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-width-001a.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-block; background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-001b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-001b.0.scss new file mode 100644 index 0000000000..438331f06c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-001b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-width-001b.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-block; background: green; color: white; width: 10em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-002a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-002a.0.scss new file mode 100644 index 0000000000..851a3e0556 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-002a.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-width-002a.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-block; background: green; color: white; } +body > div > div > div { width: 20em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-002b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-002b.0.scss new file mode 100644 index 0000000000..652628c616 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-width-002b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-width-002b.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-block; background: green; color: white; width: 20em; } +body > div > div > div { width: 20em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-001.0.scss new file mode 100644 index 0000000000..b04dd45c9a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-zorder-001.htm */ + +div { width: 2em; height: 1em; } +span { display:inline-block; vertical-align: top; width: 2em; height: 1em; background: green; } +div#after { margin-top:-1em; background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-002.0.scss new file mode 100644 index 0000000000..f888f84439 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-002.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-zorder-002.htm */ + +div { width: 2em; height: 1em; } +span { display:inline-block; vertical-align: top; width: 2em; height: 1em; } +span span { display: block; background: green; } +div#after { margin-top: -1em; background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-003.0.scss new file mode 100644 index 0000000000..902c10615b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-003.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-zorder-003.htm */ + +div { height: 1em; } +div#test span { display:inline-block; vertical-align: top; height: 1em; background: red; color: red; } +div#after { margin-top:-1em; } +div#after span { display: inline; vertical-align: top; background: green; color: green; border-bottom: 0.25em solid green; border-top: 0.25em solid green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-004.0.scss new file mode 100644 index 0000000000..2a326680b7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-004.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-zorder-004.htm */ + +div#test span { display:inline-block; vertical-align: top; background: green; color: green; border-bottom: 0.25em solid green; border-top: 0.25em solid green; } +div#before { height: 1em; margin-bottom:-1em; } +div#before span { display: inline; vertical-align: top; background: red; color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-005.0.scss new file mode 100644 index 0000000000..7831203024 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-block-zorder-005.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-block-zorder-005.htm */ + +div#test > span { display:inline-block; vertical-align: top; } +div#test > span > span { display: block; background: green; color: green; border-bottom: 0.25em solid green; border-top: 0.25em solid green; } +div#before { height: 1em; margin-bottom:-1em; } +div#before > span { display: inline; vertical-align: top; background: red; color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-002a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-002a.0.scss new file mode 100644 index 0000000000..bbb79e3952 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-002a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-002a.htm */ + +span { display: inline-table; } +span > span { display: block; visibility: hidden; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-002b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-002b.0.scss new file mode 100644 index 0000000000..085e0301ae --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-002b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-002b.htm */ + +span > span { display: table-cell; } +span > span > span { display: block; visibility: hidden; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-003.0.scss new file mode 100644 index 0000000000..ced4d93ae8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-003.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-003.htm */ + +span { display: inline-table; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-height-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-height-001.0.scss new file mode 100644 index 0000000000..76cf9d68e4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-height-001.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-height-001.htm */ + +div { display: inline-table; width: 10em; background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-height-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-height-002.0.scss new file mode 100644 index 0000000000..ee38aae8ea --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-height-002.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-height-002.htm */ + +div { display: inline-table; height: 5em; vertical-align: baseline; background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-valign-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-valign-001.0.scss new file mode 100644 index 0000000000..73e683bbcd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-valign-001.0.scss @@ -0,0 +1,15 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-valign-001.htm */ + +span#table { display: inline-table; } +span#rowgroup { display: table-row-group; } +span#row { display: table-row; } +span#cell { display: table-cell; } +span#table, span#rowgroup, span#row, span#cell { + border: 4px solid white; + margin: 3px 0; + border-width: 4px 0; + padding: 9px 0; + border-spacing: 0 5px; +} +span#block { display: block; visibility: hidden; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-001a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-001a.0.scss new file mode 100644 index 0000000000..78e2c1ecab --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-001a.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-width-001a.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-table; background: green; color: white; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-001b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-001b.0.scss new file mode 100644 index 0000000000..3a7ba0f225 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-001b.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-width-001b.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-table; background: green; color: white; width: 10em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-002a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-002a.0.scss new file mode 100644 index 0000000000..686714f14a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-002a.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-width-002a.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-table; background: green; color: white; } +body > div > div > div { width: 20em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-002b.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-002b.0.scss new file mode 100644 index 0000000000..c363def1ac --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-width-002b.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-width-002b.htm */ + +body > div { width: 10em; } +body > div > div { display: inline-table; background: green; color: white; width: 20em; } +body > div > div > div { width: 20em; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-001.0.scss new file mode 100644 index 0000000000..79c11c95e5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-zorder-001.htm */ + +div { width: 2em; height: 2em; } +span { display:inline-table; vertical-align: top; width: 2em; height: 2em; background: green; } +div#after { margin-top:-2em; background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-002.0.scss new file mode 100644 index 0000000000..6e208ec410 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-002.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-zorder-002.htm */ + +div { width: 2em; height: 2em; } +span { display:inline-table; vertical-align: top; width: 2em; height: 2em; } +span span { display: block; background: green; } +div#after { margin-top: -2em; background: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-003.0.scss new file mode 100644 index 0000000000..8722af2fb2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-003.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-zorder-003.htm */ + +div { height: 1em; } +div#test > span { display:inline-table; vertical-align: top; height: 1em; background: red; color: red; } +div#after { margin-top:-1em; } +div#after > span { display: inline; vertical-align: top; background: green; color: green; border-bottom: 0.25em solid green; border-top: 0.25em solid green; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-004.0.scss new file mode 100644 index 0000000000..344d56ff21 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-004.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-zorder-004.htm */ + +div#test > span { display:inline-table; vertical-align: top; background: green; color: green; border-bottom: 0.25em solid green; border-top: 0.25em solid green; } +div#before { height: 1em; margin-bottom:-1em; } +div#before > span { display: inline; vertical-align: top; background: red; color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-005.0.scss new file mode 100644 index 0000000000..de883783f6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/inline-table-zorder-005.0.scss @@ -0,0 +1,7 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/inline-table-zorder-005.htm */ + +div#test > span { display:inline-table; vertical-align: top; } +div#test > span > span { display: block; background: green; color: green; border-bottom: 0.25em solid green; border-top: 0.25em solid green; } +div#before { height: 1em; margin-bottom:-1em; } +div#before > span { display: inline; vertical-align: top; background: red; color: red; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/quotes-035.0.scss b/theme-compiler/tests/resources/w3ctests/scss/quotes-035.0.scss new file mode 100644 index 0000000000..7e8809a736 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/quotes-035.0.scss @@ -0,0 +1,29 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/quotes-035.htm */ + + + .party1 * { display: inline; } + .party1 .a { quotes: "Isn" "'" + "t" "FAIL!" + "FAIL!" " i"; } + .party1 .b { quotes: "" "FAIL!!" + " wonderful" "!!!" + " to " " work" + "see " " [FAIL to]" + "C" "quotes" + "S" " "; } + .party1 .c { quotes: none; } + .party1 .d { quotes: "FAIL!" "FAIL!" + "FAIL!" "FAIL!" + "" ""; } + .test { margin-left: 2em; } + .test .no-open:before { content: no-open-quote; } + .test .open:before { content: open-quote; } + .test .triple-open:before { content: open-quote open-quote open-quote; } + .test .no-close:after { content: no-close-quote; } + .test .triple-no-close:after { content: no-close-quote no-close-quote no-close-quote; } + .test .close:after { content: close-quote; } + .test .triple-close:after { content: close-quote close-quote close-quote; } + .test .no-close-open:before { content: no-close-quote open-quote; } + + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/quotes-035a.0.scss b/theme-compiler/tests/resources/w3ctests/scss/quotes-035a.0.scss new file mode 100644 index 0000000000..e4e3d17658 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/quotes-035a.0.scss @@ -0,0 +1,31 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/quotes-035a.htm */ + + + .party1 * { display: inline; } + .party1 .a { quotes: "Isn" "'" + "t" "FAIL!" + "FAIL!" " i"; } + .party1 .b { quotes: "" "FAIL!!" + " wonderful" "!!!" + " to " " work" + "see " " [FAIL to]" + "C" "quotes" + "S" " " + "S" " "; } + .party1 .c { quotes: none; } + .party1 .d { quotes: "FAIL!" "FAIL!" + "FAIL!" "FAIL!" + "" "" + "" ""; } + .test { margin-left: 2em; } + .test .no-open:before { content: no-open-quote; } + .test .open:before { content: open-quote; } + .test .triple-open:before { content: open-quote open-quote open-quote; } + .test .no-close:after { content: no-close-quote; } + .test .triple-no-close:after { content: no-close-quote no-close-quote no-close-quote; } + .test .close:after { content: close-quote; } + .test .triple-close:after { content: close-quote close-quote close-quote; } + .test .no-close-open:before { content: no-close-quote open-quote; } + + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/quotes-036.0.scss b/theme-compiler/tests/resources/w3ctests/scss/quotes-036.0.scss new file mode 100644 index 0000000000..2d2927c254 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/quotes-036.0.scss @@ -0,0 +1,35 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/quotes-036.htm */ + + + .party1 * { display: inline; } + .party1 .a { quotes: "Isn" "'" + "t" "FAIL!" + "FAIL!" " i"; } + .party1 .b { quotes: "" "FAIL!!" + " wonderful" "!!!" + " to " " work" + "see " " [FAIL to]" + "C" "quotes" + "S" " "; } + .party1 .c { quotes: none; } + .party1 .d { quotes: "FAIL!" "FAIL!" + "FAIL!" "FAIL!" + "" ""; } + .test { margin-left: 2em; } + .test .no-open:before { content: no-open-quote; } + .test .open:before { content: open-quote; } + .test .triple-open:before { content: open-quote open-quote open-quote; } + .test .no-close:after { content: no-close-quote; } + .test .triple-no-close:after { content: no-close-quote no-close-quote no-close-quote; } + .test .close:after { content: close-quote; } + .test .triple-close:after { content: close-quote close-quote close-quote; } + .test .no-close-open:before { content: no-close-quote open-quote; } + + /* hr br */ + .test hr, .test br { display: inline; margin: 0; padding: 0; + height: auto; width: auto; border: none; color: inherit; + background: transparent; } + .test br:before { content: "" } + .test br:after { content: "" } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/ref-green-box-100x100.0.scss b/theme-compiler/tests/resources/w3ctests/scss/ref-green-box-100x100.0.scss new file mode 100644 index 0000000000..6ee83f95d6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/ref-green-box-100x100.0.scss @@ -0,0 +1,8 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/support/ref-green-box-100x100.htm */ + + div { + width: 100px; + height: 100px; + background: green; + } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-cell-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-cell-001.0.scss new file mode 100644 index 0000000000..c03a4049a6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-cell-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bc-cell-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 8px 6px; /* collapsed */ + padding: 3px 7px 8px 6px; /* ignored */ + border-collapse: collapse; + } + + td { + border: transparent solid; + border-width: 2px 0 4px 2px; /* collapsed */ + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color td.t { background-color: aqua; } + + table.imagetl td.t, table.imagebr td.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl td.t { background-position: top left; /* default */ } + table.imagebr td.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-colgroup-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-colgroup-001.0.scss new file mode 100644 index 0000000000..d0ce72d0e0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-colgroup-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bc-colgroup-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 8px 6px; /* collapsed */ + padding: 3px 7px 8px 6px; /* ignored */ + border-collapse: collapse; + } + + td { + border: transparent solid; + border-width: 2px 0 4px 2px; /* collapsed */ + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color colgroup.t { background-color: aqua; } + + table.imagetl colgroup.t, table.imagebr colgroup.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl colgroup.t { background-position: top left; /* default */ } + table.imagebr colgroup.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-column-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-column-001.0.scss new file mode 100644 index 0000000000..c3d2bd0503 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-column-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bc-column-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 8px 6px; /* collapsed */ + padding: 3px 7px 8px 6px; /* ignored */ + border-collapse: collapse; + } + + td { + border: transparent solid; + border-width: 2px 0 4px 2px; /* collapsed */ + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color col.t { background-color: aqua; } + + table.imagetl col.t, table.imagebr col.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl col.t { background-position: top left; /* default */ } + table.imagebr col.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-row-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-row-001.0.scss new file mode 100644 index 0000000000..1a7049fba8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-row-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bc-row-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 8px 6px; /* collapsed */ + padding: 3px 7px 8px 6px; /* ignored */ + border-collapse: collapse; + } + + td { + border: transparent solid; + border-width: 2px 0 4px 2px; /* collapsed */ + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color tr.t { background-color: aqua; } + + table.imagetl tr.t, table.imagebr tr.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl tr.t { background-position: top left; /* default */ } + table.imagebr tr.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-rowgroup-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-rowgroup-001.0.scss new file mode 100644 index 0000000000..69c10cca9f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-rowgroup-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bc-rowgroup-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 8px 6px; /* collapsed */ + padding: 3px 7px 8px 6px; /* ignored */ + border-collapse: collapse; + } + + td { + border: transparent solid; + border-width: 2px 0 4px 2px; /* collapsed */ + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color tbody.t { background-color: aqua; } + + table.imagetl tbody.t, table.imagebr tbody.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl tbody.t { background-position: top left; /* default */ } + table.imagebr tbody.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-table-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-table-001.0.scss new file mode 100644 index 0000000000..b6a8f27ab2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bc-table-001.0.scss @@ -0,0 +1,33 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bc-table-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 8px 6px; /* collapsed */ + padding: 3px 7px 8px 6px; /* ignored */ + border-collapse: collapse; + } + + td { + border: transparent solid; + border-width: 2px 0 4px 2px; /* collapsed */ + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color { background-color: aqua; } + + table.imagetl, table.imagebr { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl { background-position: top left; /* default */ } + table.imagebr { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-cell-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-cell-001.0.scss new file mode 100644 index 0000000000..02289c80e2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-cell-001.0.scss @@ -0,0 +1,34 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bs-cell-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 7px 3px; + padding: 3px 7px 8px 6px; + border-collapse: separate; + border-spacing: 2px 3px; + } + + td { + border: transparent solid; + border-width: 2px 1px 4px 3px; + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color td.t { background-color: aqua; } + + table.imagetl td.t, table.imagebr td.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl td.t { background-position: top left; /* default */ } + table.imagebr td.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-colgroup-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-colgroup-001.0.scss new file mode 100644 index 0000000000..dae2af72ae --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-colgroup-001.0.scss @@ -0,0 +1,34 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bs-colgroup-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 7px 3px; + padding: 3px 7px 8px 6px; + border-collapse: separate; + border-spacing: 2px 3px; + } + + td { + border: transparent solid; + border-width: 2px 1px 4px 3px; + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color colgroup.t { background-color: aqua; } + + table.imagetl colgroup.t, table.imagebr colgroup.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl colgroup.t { background-position: top left; /* default */ } + table.imagebr colgroup.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-column-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-column-001.0.scss new file mode 100644 index 0000000000..8289f3a4bb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-column-001.0.scss @@ -0,0 +1,34 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bs-column-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 7px 3px; + padding: 3px 7px 8px 6px; + border-collapse: separate; + border-spacing: 2px 3px; + } + + td { + border: transparent solid; + border-width: 2px 1px 4px 3px; + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color col.t { background-color: aqua; } + + table.imagetl col.t, table.imagebr col.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl col.t { background-position: top left; /* default */ } + table.imagebr col.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-row-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-row-001.0.scss new file mode 100644 index 0000000000..f2ec27e38b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-row-001.0.scss @@ -0,0 +1,34 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bs-row-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 7px 3px; + padding: 3px 7px 8px 6px; + border-collapse: separate; + border-spacing: 2px 3px; + } + + td { + border: transparent solid; + border-width: 2px 1px 4px 3px; + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color tr.t { background-color: aqua; } + + table.imagetl tr.t, table.imagebr tr.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl tr.t { background-position: top left; /* default */ } + table.imagebr tr.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-rowgroup-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-rowgroup-001.0.scss new file mode 100644 index 0000000000..cb5b8f79a6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-rowgroup-001.0.scss @@ -0,0 +1,34 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bs-rowgroup-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 7px 3px; + padding: 3px 7px 8px 6px; + border-collapse: separate; + border-spacing: 2px 3px; + } + + td { + border: transparent solid; + border-width: 2px 1px 4px 3px; + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color tbody.t { background-color: aqua; } + + table.imagetl tbody.t, table.imagebr tbody.t { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl tbody.t { background-position: top left; /* default */ } + table.imagebr tbody.t { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-table-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-table-001.0.scss new file mode 100644 index 0000000000..6d1eabb6a8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-backgrounds-bs-table-001.0.scss @@ -0,0 +1,34 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-backgrounds-bs-table-001.htm */ + + + html, body { margin: 0; padding: 0; border: 0; font-size: 16px; } + body { padding: 15px; } + + table { + margin: 0 3px 2px 4px; /* zero top to work around collapsing bug */ + border: transparent solid; + border-width: 4px 2px 7px 3px; + padding: 3px 7px 8px 6px; + border-collapse: separate; + border-spacing: 2px 3px; + } + + td { + border: transparent solid; + border-width: 2px 1px 4px 3px; + padding: 1px 2px 4px 3px; + empty-cells: show; + } + + div { height: 10px; width: 50px; } + + table.color { background-color: aqua; } + + table.imagetl, table.imagebr { + background-image: url(support/repeatable-diagonal-gradient-with-ticks.png); + } + + table.imagetl { background-position: top left; /* default */ } + table.imagebr { background-position: bottom right; /* default */ } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.0.scss new file mode 100644 index 0000000000..bc5733aedd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-in-inline-001.htm */ +.style { display: table-row } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.1.scss new file mode 100644 index 0000000000..a4d01762bd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-in-inline-001.htm */ +.style { display: block } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.2.scss new file mode 100644 index 0000000000..fe13eb4cbb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-in-inline-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-in-inline-001.htm */ +.style { display: table-cell } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.0.scss new file mode 100644 index 0000000000..15d24294d1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-001.htm */ + + +td { vertical-align: baseline; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.1.scss new file mode 100644 index 0000000000..c93d980b57 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-001.htm */ +.style { padding-top: 40px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.2.scss new file mode 100644 index 0000000000..8c98e302cc --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-001.htm */ +.style { padding-top: 20px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.3.scss new file mode 100644 index 0000000000..90b0e303b2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-001.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-001.htm */ +.style { padding-top: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.0.scss new file mode 100644 index 0000000000..9e8fc17d73 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-002.htm */ + + +td { vertical-align: baseline; padding-top: 0; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.1.scss new file mode 100644 index 0000000000..c8a265b2e4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-002.htm */ +.style { padding-top: 40px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.2.scss new file mode 100644 index 0000000000..84c4a43819 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-002.htm */ +.style { padding-top: 20px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.3.scss new file mode 100644 index 0000000000..b212fc065f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-002.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-002.htm */ +.style { padding-top: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.0.scss new file mode 100644 index 0000000000..b623b103e4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-003.htm */ + + +td { vertical-align: baseline; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.1.scss new file mode 100644 index 0000000000..646c3603f7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-003.htm */ +.style { padding-top: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.2.scss new file mode 100644 index 0000000000..c461bdba34 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-003.htm */ +.style { padding-top: 40px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.3.scss new file mode 100644 index 0000000000..3b0a262d34 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-003.htm */ +.style { padding-top: 12px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.4.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.4.scss new file mode 100644 index 0000000000..055905d9d7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-003.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-003.htm */ +.style { padding-top: 3px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.0.scss new file mode 100644 index 0000000000..3563cde096 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-004.htm */ + + +td { vertical-align: baseline; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.1.scss new file mode 100644 index 0000000000..eac995c41d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-004.htm */ +.style { padding-top: 12px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.2.scss new file mode 100644 index 0000000000..b2745143e2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-004.htm */ +.style { padding-top: 3px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.3.scss new file mode 100644 index 0000000000..15214ad16a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-004.htm */ +.style { padding-top: 40px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.4.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.4.scss new file mode 100644 index 0000000000..4b93164a1b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-004.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-004.htm */ +.style { padding-top: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.0.scss new file mode 100644 index 0000000000..49e4923cc8 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ + + +td { vertical-align: baseline; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.1.scss new file mode 100644 index 0000000000..7896c6342c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ +.style { padding-top: 0; height: 80px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.2.scss new file mode 100644 index 0000000000..e000d2e340 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ +.style { padding-top: 40px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.3.scss new file mode 100644 index 0000000000..0a30e0d376 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ +.style { padding-top: 12px; height: 120px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.4.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.4.scss new file mode 100644 index 0000000000..c4152587ea --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ +.style { padding-top: 3px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.5.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.5.scss new file mode 100644 index 0000000000..ec44e94e6d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ +.style { padding-top: 40px; height: 160px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.6.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.6.scss new file mode 100644 index 0000000000..3a3990256c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-005.6.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-005.htm */ +.style { padding-top: 0 } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.0.scss new file mode 100644 index 0000000000..3f56772677 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ + + +td { vertical-align: baseline; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.1.scss new file mode 100644 index 0000000000..4b20736354 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ +.style { padding-top: 0; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.2.scss new file mode 100644 index 0000000000..9f71b57dd9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ +.style { padding-top: 40px; height: 80px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.3.scss new file mode 100644 index 0000000000..dd8cd111f5 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ +.style { padding-top: 12px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.4.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.4.scss new file mode 100644 index 0000000000..90ef71d106 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ +.style { padding-top: 3px; height: 120px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.5.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.5.scss new file mode 100644 index 0000000000..6d33486f7c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ +.style { padding-top: 40px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.6.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.6.scss new file mode 100644 index 0000000000..0bec2dee1a --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-006.6.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-006.htm */ +.style { padding-top: 0; height: 160px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.0.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.0.scss new file mode 100644 index 0000000000..6c11f1b90f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.0.scss @@ -0,0 +1,6 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-007.htm */ + + +td { vertical-align: baseline; } + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.1.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.1.scss new file mode 100644 index 0000000000..4863e1df5b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-007.htm */ +.style { padding-top: 0; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.2.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.2.scss new file mode 100644 index 0000000000..d32301afb9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-007.htm */ +.style { padding-top: 40px; height: 80px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.3.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.3.scss new file mode 100644 index 0000000000..b25a964d73 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-007.htm */ +.style { padding-top: 12px; height: 160px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.4.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.4.scss new file mode 100644 index 0000000000..98808066f1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-007.htm */ +.style { padding-top: 3px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.5.scss b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.5.scss new file mode 100644 index 0000000000..8a366d4df2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/table-vertical-align-baseline-007.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/table-vertical-align-baseline-007.htm */ +.style { padding-top: 40px; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-113.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-113.0.scss new file mode 100644 index 0000000000..01e37d208c --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-113.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-113.htm */ + +p { text-indent: 100px } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-114.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-114.0.scss new file mode 100644 index 0000000000..ec19eb2816 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-114.0.scss @@ -0,0 +1,4 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-114.htm */ + +p { text-indent: 0px } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-115.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-115.0.scss new file mode 100644 index 0000000000..569f033276 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-115.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-115.htm */ + +p { text-indent: 100px } +span { background: yellow } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.0.scss new file mode 100644 index 0000000000..6ed93593e9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.0.scss @@ -0,0 +1,17 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-001.htm */ + + +body { font-size: 12px; width: 1px; } + +body > div, body > pre { + float: left; clear: left; margin: 1px; height: 2em; + border: medium solid; +} + +span { + display: inline-block; + height: 1em; + width: 1em; +} + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.1.scss new file mode 100644 index 0000000000..c71814945e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-001.htm */ +.style { text-indent: 3em; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.11.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.11.scss new file mode 100644 index 0000000000..d43af6804b --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.11.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-001.htm */ +.style { width: 6em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.4.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.4.scss new file mode 100644 index 0000000000..aecf9b104d --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-001.htm */ +.style { text-indent: 3em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.5.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.5.scss new file mode 100644 index 0000000000..4d3f04cdf4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-001.htm */ +.style { width: 1em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.8.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.8.scss new file mode 100644 index 0000000000..11f2a1b4c7 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-001.8.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-001.htm */ +.style { width: 2em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.0.scss new file mode 100644 index 0000000000..7dcafd1001 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.0.scss @@ -0,0 +1,17 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-002.htm */ + + +body { font-size: 12px; } + +body > div, body > pre { + float: left; clear: left; margin: 1px; height: 2em; + border: medium solid; +} + +span { + display: inline-block; + height: 1em; + width: 1em; +} + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.1.scss new file mode 100644 index 0000000000..fb9ad27680 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-002.htm */ +.style { text-indent: 3em; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.11.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.11.scss new file mode 100644 index 0000000000..9783ca14ac --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.11.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-002.htm */ +.style { width: 6em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.4.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.4.scss new file mode 100644 index 0000000000..dc20dd4b85 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-002.htm */ +.style { text-indent: 3em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.5.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.5.scss new file mode 100644 index 0000000000..41cee98d11 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-002.htm */ +.style { width: 1em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.8.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.8.scss new file mode 100644 index 0000000000..49161e2910 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-002.8.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-002.htm */ +.style { width: 2em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.0.scss new file mode 100644 index 0000000000..98f79df5fd --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.0.scss @@ -0,0 +1,17 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ + + +body { font-size: 12px; } + +body > div, body > pre { + float: left; clear: left; margin: 1px; height: 2em; + border: medium solid; +} + +span { + display: inline-block; + height: 1em; + width: 1em; +} + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.1.scss new file mode 100644 index 0000000000..ef4f538864 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { width: 1px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.11.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.11.scss new file mode 100644 index 0000000000..29d824d66e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.11.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { width: 3em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.17.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.17.scss new file mode 100644 index 0000000000..ce29a677f1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.17.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { width: 4em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.2.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.2.scss new file mode 100644 index 0000000000..d9169cf13e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { text-indent: -3em; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.25.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.25.scss new file mode 100644 index 0000000000..575d7393f2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.25.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { text-indent: -3em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.3.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.3.scss new file mode 100644 index 0000000000..44021e266f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.3.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { width: 1em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.5.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.5.scss new file mode 100644 index 0000000000..0b02a652f9 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-003.5.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-003.htm */ +.style { width: 5em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.0.scss new file mode 100644 index 0000000000..4fcfac5be6 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.0.scss @@ -0,0 +1,17 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ + + +body { font-size: 12px; } + +body > div, body > pre { + float: left; clear: left; margin: 1px; height: 2em; + border: medium solid; +} + +span { + display: inline-block; + height: 1em; + width: 1em; +} + + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.1.scss new file mode 100644 index 0000000000..a8cd2367c3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ +.style { text-indent: -3em; } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.10.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.10.scss new file mode 100644 index 0000000000..549eca8142 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.10.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ +.style { width: 3em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.16.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.16.scss new file mode 100644 index 0000000000..d97bdc5805 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.16.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ +.style { width: 4em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.2.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.2.scss new file mode 100644 index 0000000000..645265fcee --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.2.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ +.style { width: 1em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.24.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.24.scss new file mode 100644 index 0000000000..a43261231e --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.24.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ +.style { text-indent: -3em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.4.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.4.scss new file mode 100644 index 0000000000..60d30f9cdb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-intrinsic-004.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-intrinsic-004.htm */ +.style { width: 5em } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-percent-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-percent-001.0.scss new file mode 100644 index 0000000000..2204bedfe4 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-percent-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-percent-001.htm */ + +div { width: 500px; } +p { width: 300px; text-indent: 10%; } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-indent-wrap-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-indent-wrap-001.0.scss new file mode 100644 index 0000000000..fc5dab0d52 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-indent-wrap-001.0.scss @@ -0,0 +1,5 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-indent-wrap-001.htm */ + +p { text-indent: 100px } +span { background: yellow } + diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-001.0.scss new file mode 100644 index 0000000000..515fa762c3 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-001.htm */ +.style { letter-spacing:2px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-001.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-001.1.scss new file mode 100644 index 0000000000..69ff275066 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-001.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-001.htm */ +.style { text-transform:capitalize } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-002.0.scss new file mode 100644 index 0000000000..4d744e17b1 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-002.htm */ +.style { letter-spacing:2px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-002.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-002.1.scss new file mode 100644 index 0000000000..c6bb7e4bef --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-002.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-002.htm */ +.style { text-transform:capitalize } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.0.scss new file mode 100644 index 0000000000..0ba48a86c0 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-003.htm */ +.style { letter-spacing:2px } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.1.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.1.scss new file mode 100644 index 0000000000..e1cb8d6745 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.1.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-003.htm */ +.style { text-transform:capitalize } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.4.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.4.scss new file mode 100644 index 0000000000..a0d1d9a606 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.4.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-003.htm */ +.style { text-transform:none } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.7.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.7.scss new file mode 100644 index 0000000000..438a1e4be2 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-capitalize-003.7.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-capitalize-003.htm */ +.style { white-space:nowrap } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-lowercase-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-lowercase-001.0.scss new file mode 100644 index 0000000000..fe6e97e39f --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-lowercase-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-lowercase-001.htm */ +.style { text-transform:lowercase } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-uppercase-001.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-uppercase-001.0.scss new file mode 100644 index 0000000000..7dc1c293cb --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-uppercase-001.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-uppercase-001.htm */ +.style { text-transform:uppercase } diff --git a/theme-compiler/tests/resources/w3ctests/scss/text-transform-uppercase-002.0.scss b/theme-compiler/tests/resources/w3ctests/scss/text-transform-uppercase-002.0.scss new file mode 100644 index 0000000000..c18eff8824 --- /dev/null +++ b/theme-compiler/tests/resources/w3ctests/scss/text-transform-uppercase-002.0.scss @@ -0,0 +1,2 @@ +/* Source: http://test.csswg.org/suites/css2.1/20110323/html4/text-transform-uppercase-002.htm */ +.style { text-transform:uppercase } diff --git a/theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java b/theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java index d867e6ccd0..ff92b636ed 100644 --- a/theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java +++ b/theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java @@ -30,6 +30,8 @@ import com.vaadin.sass.internal.ScssStylesheet; public abstract class AbstractTestBase { + public static final String CR = "\r"; + protected ScssStylesheet stylesheet; protected String originalScss; protected String parsedScss; @@ -69,17 +71,21 @@ public abstract class AbstractTestBase { public void testParser(String file) throws CSSException, IOException, URISyntaxException { originalScss = getFileContent(file); + originalScss = originalScss.replaceAll(CR, ""); ScssStylesheet sheet = getStyleSheet(file); - parsedScss = sheet.toString(); + parsedScss = sheet.printState(); + parsedScss = parsedScss.replace(CR, ""); Assert.assertEquals("Original CSS and parsed CSS do not match", originalScss, parsedScss); } public void testCompiler(String scss, String css) throws Exception { comparisonCss = getFileContent(css); + comparisonCss = comparisonCss.replaceAll(CR, ""); ScssStylesheet sheet = getStyleSheet(scss); sheet.compile(); - parsedScss = sheet.toString(); + parsedScss = sheet.printState(); + parsedScss = parsedScss.replaceAll(CR, ""); Assert.assertEquals("Original CSS and parsed CSS do not match", comparisonCss, parsedScss); } diff --git a/theme-compiler/tests/src/com/vaadin/sass/resolvers/VaadinResolverTest.java b/theme-compiler/tests/src/com/vaadin/sass/resolvers/VaadinResolverTest.java index 59b49888c2..0183142747 100644 --- a/theme-compiler/tests/src/com/vaadin/sass/resolvers/VaadinResolverTest.java +++ b/theme-compiler/tests/src/com/vaadin/sass/resolvers/VaadinResolverTest.java @@ -40,16 +40,26 @@ import java.lang.reflect.Method; import org.junit.Assert; import org.junit.Test; -import com.vaadin.sass.internal.resolver.VaadinResolver; +import com.vaadin.sass.internal.resolver.AbstractResolver; +import com.vaadin.sass.internal.resolver.ClassloaderResolver; +import com.vaadin.sass.internal.resolver.FilesystemResolver; public class VaadinResolverTest { @Test - public void testPathNormalization() throws Exception { + public void testFilesystemResolverPathNormalization() throws Exception { + testPathNormalization(new FilesystemResolver()); + } + + @Test + public void testClassloaderResolverPathNormalization() throws Exception { + testPathNormalization(new ClassloaderResolver()); + } - VaadinResolver resolver = new VaadinResolver(); + public void testPathNormalization(AbstractResolver resolver) + throws Exception { - Method normalizeMethod = VaadinResolver.class.getDeclaredMethod( + Method normalizeMethod = AbstractResolver.class.getDeclaredMethod( "normalize", String.class); normalizeMethod.setAccessible(true); diff --git a/theme-compiler/tests/src/com/vaadin/sass/testcases/css/Media.java b/theme-compiler/tests/src/com/vaadin/sass/testcases/css/Media.java index 1c84bf8c49..b7ca325aa7 100644 --- a/theme-compiler/tests/src/com/vaadin/sass/testcases/css/Media.java +++ b/theme-compiler/tests/src/com/vaadin/sass/testcases/css/Media.java @@ -33,4 +33,5 @@ public class Media extends AbstractTestBase { IOException { testParser(css); } + } diff --git a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/AbstractDirectoryScanningSassTests.java b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/AbstractDirectoryScanningSassTests.java index 21edde0c17..b9b80a7588 100644 --- a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/AbstractDirectoryScanningSassTests.java +++ b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/AbstractDirectoryScanningSassTests.java @@ -28,8 +28,13 @@ import java.util.List; import org.apache.commons.io.IOUtils; import org.junit.Assert; +import org.w3c.css.sac.CSSException; +import org.w3c.css.sac.CSSParseException; import com.vaadin.sass.internal.ScssStylesheet; +import com.vaadin.sass.internal.handler.SCSSDocumentHandler; +import com.vaadin.sass.internal.handler.SCSSDocumentHandlerImpl; +import com.vaadin.sass.internal.handler.SCSSErrorHandler; import com.vaadin.sass.testcases.scss.SassTestRunner.FactoryTest; public abstract class AbstractDirectoryScanningSassTests { @@ -78,19 +83,38 @@ public abstract class AbstractDirectoryScanningSassTests { @FactoryTest public void compareScssWithCss(String scssResourceName) throws Exception { - String referenceCss; File scssFile = getSassLangResourceFile(scssResourceName); - File cssFile = getCssFile(scssFile); - referenceCss = IOUtils.toString(new FileInputStream(cssFile)); - ScssStylesheet scssStylesheet = ScssStylesheet.get(scssFile - .getCanonicalPath()); + + SCSSDocumentHandler documentHandler = new SCSSDocumentHandlerImpl(); + SCSSErrorHandler errorHandler = new SCSSErrorHandler() { + @Override + public void error(CSSParseException arg0) throws CSSException { + super.error(arg0); + Assert.fail(arg0.getMessage()); + } + + @Override + public void fatalError(CSSParseException arg0) throws CSSException { + super.error(arg0); + Assert.fail(arg0.getMessage()); + } + }; + + ScssStylesheet scssStylesheet = ScssStylesheet.get( + scssFile.getCanonicalPath(), null, documentHandler, + errorHandler); scssStylesheet.compile(); - String parsedCss = scssStylesheet.toString(); + String parsedCss = scssStylesheet.printState(); + + if (getCssFile(scssFile) != null) { + String referenceCss = IOUtils.toString(new FileInputStream( + getCssFile(scssFile))); + String normalizedReference = normalize(referenceCss); + String normalizedParsed = normalize(parsedCss); - String normalizedReference = normalize(referenceCss); - String normalizedParsed = normalize(parsedCss); - Assert.assertEquals("Original CSS and parsed CSS do not match for " - + scssResourceName, normalizedReference, normalizedParsed); + Assert.assertEquals("Original CSS and parsed CSS do not match for " + + scssResourceName, normalizedReference, normalizedParsed); + } } private String normalize(String css) { @@ -120,7 +144,7 @@ public abstract class AbstractDirectoryScanningSassTests { return new File(res.toURI()); } - private File getCssFile(File scssFile) throws IOException { + protected File getCssFile(File scssFile) throws IOException { return new File(scssFile.getCanonicalPath().replace("scss", "css")); } } diff --git a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java new file mode 100644 index 0000000000..02415dbe15 --- /dev/null +++ b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.sass.testcases.scss; + +import java.io.File; +import java.io.IOException; + +import junit.framework.Assert; + +import org.junit.Test; +import org.w3c.css.sac.CSSException; + +import com.vaadin.sass.AbstractTestBase; +import com.vaadin.sass.internal.ScssStylesheet; +import com.vaadin.sass.internal.handler.SCSSDocumentHandler; +import com.vaadin.sass.internal.handler.SCSSDocumentHandlerImpl; +import com.vaadin.sass.internal.parser.Parser; +import com.vaadin.sass.internal.resolver.FilesystemResolver; +import com.vaadin.sass.internal.tree.ImportNode; + +public class CompassImports extends AbstractTestBase { + + String scssOtherDirectory = "/scss/compass-test/compass-import.scss"; + String scssSameDirectory = "/scss/compass-test2/compass-import2.scss"; + String css = "/css/compass-import.css"; + + String compassPath = "/scss/compass-test2"; + + @Test + public void testParser() throws CSSException, IOException { + Parser parser = new Parser(); + SCSSDocumentHandler handler = new SCSSDocumentHandlerImpl(); + parser.setDocumentHandler(handler); + parser.parseStyleSheet(getClass().getResource(scssOtherDirectory) + .getPath()); + ScssStylesheet root = handler.getStyleSheet(); + ImportNode importVariableNode = (ImportNode) root.getChildren().get(0); + Assert.assertEquals("compass", importVariableNode.getUri()); + Assert.assertFalse(importVariableNode.isPureCssImport()); + } + + @Test + public void testCompiler() throws Exception { + testCompiler(scssSameDirectory, css, null); + } + + @Test + public void testCompilerWithCustomPath() throws Exception { + File rootPath = new File(getClass().getResource(compassPath).toURI()); + + testCompiler(scssOtherDirectory, css, rootPath.getPath()); + } + + public void testCompiler(String scss, String css, String additionalPath) + throws Exception { + comparisonCss = getFileContent(css); + comparisonCss = comparisonCss.replaceAll(CR, ""); + ScssStylesheet sheet = getStyleSheet(scss); + Assert.assertNotNull(sheet); + sheet.addResolver(new FilesystemResolver(additionalPath)); + + sheet.compile(); + parsedScss = sheet.printState(); + parsedScss = parsedScss.replaceAll(CR, ""); + Assert.assertEquals("Original CSS and parsed CSS do not match", + comparisonCss, parsedScss); + } +} diff --git a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/Functions.java b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/Functions.java index 5c41494ac6..bd214986c0 100644 --- a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/Functions.java +++ b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/Functions.java @@ -41,9 +41,9 @@ public class Functions extends AbstractTestBase { parser.setDocumentHandler(handler); parser.parseStyleSheet(getClass().getResource(scss).getPath()); ScssStylesheet root = handler.getStyleSheet(); - Assert.assertEquals(3, root.getChildren().size()); - BlockNode blockNode = (BlockNode) root.getChildren().get(2); - Assert.assertEquals(14, blockNode.getChildren().size()); + Assert.assertEquals(6, root.getChildren().size()); + BlockNode blockNode = (BlockNode) root.getChildren().get(5); + Assert.assertEquals(17, blockNode.getChildren().size()); } @Test diff --git a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/W3ConformanceTests.java b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/W3ConformanceTests.java new file mode 100644 index 0000000000..8dbc6345d6 --- /dev/null +++ b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/W3ConformanceTests.java @@ -0,0 +1,236 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.sass.testcases.scss; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.junit.runner.RunWith; + +import com.vaadin.sass.testcases.scss.SassTestRunner.TestFactory; + +@RunWith(SassTestRunner.class) +public class W3ConformanceTests extends AbstractDirectoryScanningSassTests { + + @Override + protected URL getResourceURL(String path) { + return getResourceURLInternal(path); + } + + private static URL getResourceURLInternal(String path) { + return AutomaticSassTests.class.getResource("/w3ctests" + path); + } + + @TestFactory + public static Collection<String> getScssResourceNames() + throws URISyntaxException, IOException { + return getScssResourceNames(getResourceURLInternal("")); + } + + @Override + protected File getCssFile(File scssFile) throws IOException { + /* + * We should really compare the result of unparse(parse(css)) to css, + * but the comparator routine is currently too primitive. + */ + // return scssFile; + + // no comparison step, just parse, in this test + return null; + } + + /* + * Download W3C conformance tests for CSS 2.1 and CSS 3 (selectors), + * extracts all CSS (style tags, inline styles, and linked stylesheets), + * then tries to parse them. Since each CSS is valid SCSS, the parser should + * accept them. As these are browser tests, some are intentionally + * malformed, and must be excluded from the test suite. + */ + + public static void main(String[] args) throws Exception { + if (args.length < 1) { + System.err.println("Target directory not provided"); + return; + } + File targetDir = new File(args[0]); + for (URI url : CSS21()) { + extractCSS(url, targetDir); + } + for (URI url : CSS3Selectors()) { + extractCSS(url, targetDir); + } + + } + + public static Collection<URI> CSS21() throws Exception { + /* + * Tests explicitly excluded are listed below---case by case motivation + * required! + */ + final String[] excludelist = new String[] { + // Unsupported character encoding UTF-16 + "http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-utf16-be-002.htm", + "http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-utf16-be-003.htm", + "http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-utf16-le-002.htm", + "http://test.csswg.org/suites/css2.1/20110323/html4/at-charset-utf16-le-003.htm", + + // Font family name contains (Asian?) cryptoglyphs + "http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-010.htm", + "http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-011.htm", + "http://test.csswg.org/suites/css2.1/20110323/html4/font-family-name-015.htm", + + // Contains syntactically illegal CSS + "http://test.csswg.org/suites/css2.1/20110323/html4/uri-013.htm", + + // Missing semicolon on line 29 + "http://test.csswg.org/suites/css2.1/20110323/html4/z-index-020.htm", }; + + // Note: W3C test reference files also not included! + return scrapeIndexForTests( + "http://test.csswg.org/suites/css2.1/20110323/html4/reftest-toc.html", + ".*[0-9][0-9][0-9][a-z]?\\.htm", Integer.MAX_VALUE, + new LinkedHashSet<URI>() { + { + for (String s : excludelist) { + add(new URI(s)); + } + } + }); + } + + public static Collection<URI> CSS3Selectors() throws Exception { + /* + * Tests explicitly excluded are listed below---case by case motivation + * required! + */ + final String[] excludelist = new String[] { + + // Probable bug/limitation (filed as #12834) + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-73.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-73b.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-74.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-74b.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-75.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-75b.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-76.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-76b.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-83.html", + + // Invalid CSS, although sass-lang compiler accepts (see #12835) + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-154.html", + + // Invalid CSS? sass-lang compiler fails + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-157.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-158.html", + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/css3-modsel-183.html", }; + + return scrapeIndexForTests( + "http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/html/tests/", + "css3-.*\\.html", Integer.MAX_VALUE, new LinkedHashSet<URI>() { + { + for (String s : excludelist) { + add(new URI(s)); + } + } + }); + } + + /* + * Loads up to maxTest tests, excluding any URL in excludeUrls. + */ + protected static Collection<URI> scrapeIndexForTests(String url, + String regexp, int maxTests, Collection<URI> excludeUrls) + throws Exception { + + URI baseUrl = new URI(url); + Document doc = Jsoup.connect(url).timeout(10000).get(); + Elements elems = doc.select(String.format("a[href~=%s]", regexp)); + LinkedHashSet<URI> tests = new LinkedHashSet<URI>(); + for (Element e : elems) { + URI testUrl = new URI(e.attr("href")); + if (!testUrl.isAbsolute()) { + testUrl = baseUrl.resolve(testUrl); + } + if (tests.size() < maxTests) { + if (!excludeUrls.contains(testUrl)) { + tests.add(testUrl); + } + } else { + break; + } + } + + return tests; + } + + public static void extractCSS(final URI url, File targetdir) + throws Exception { + /* + * For each test URL: 1) extract <style> tag contents 2) extract from + * <link rel="stylesheet"> files 3) extract inline style attributes from + * all elements and wrap the result in .style {} + */ + + Document doc = Jsoup.connect(url.toString()).timeout(20000).get(); + + List<String> tests = new ArrayList<String>(); + + for (Element e : doc.select("style[type=text/css]")) { + tests.add(e.data()); + } + + for (Element e : doc + .select("link[rel=stylesheet][href][type=text/css]")) { + URI cssUri = new URI(e.attr("href")); + if (!cssUri.isAbsolute()) { + cssUri = url.resolve(cssUri); + } + String encoding = doc.outputSettings().charset().name(); + tests.add(IOUtils.toString(cssUri, encoding)); + } + + for (Element e : doc.select("*[style]")) { + tests.add(String.format(".style { %s }", e.attr("style"))); + } + + for (final String test : tests) { + targetdir.mkdirs(); + String logfile = String.format("%s.%d.scss", + FilenameUtils.getBaseName(url.toString()), + tests.indexOf(test)); + PrintStream dataLogger = new PrintStream(new File(targetdir, + logfile)); + + dataLogger.println("/* Source: " + url + " */"); + dataLogger.println(test); + + } + } +} diff --git a/theme-compiler/tests/src/com/vaadin/sass/tree/ImportNodeTest.java b/theme-compiler/tests/src/com/vaadin/sass/tree/ImportNodeTest.java index 68c886b407..a7cf442966 100644 --- a/theme-compiler/tests/src/com/vaadin/sass/tree/ImportNodeTest.java +++ b/theme-compiler/tests/src/com/vaadin/sass/tree/ImportNodeTest.java @@ -56,22 +56,22 @@ public class ImportNodeTest { } @Test - public void testToStringWhenIsURL() { + public void testSerializeWhenIsURL() { ImportNode node = new ImportNode("test", null, true); - Assert.assertEquals("@import url(test);", node.toString()); + Assert.assertEquals("@import url(test);", node.printState()); } @Test - public void testToStringWhenIsNotURL() { + public void testSerializeWhenIsNotURL() { ImportNode node = new ImportNode("test", null, false); - Assert.assertEquals("@import \"test\";", node.toString()); + Assert.assertEquals("@import \"test\";", node.printState()); } @Test - public void testToStringWithMediaQueries() { + public void testSerializeWithMediaQueries() { SACMediaListImpl ml = new SACMediaListImpl(); ml.add("screen"); ImportNode node = new ImportNode("test", ml, true); - Assert.assertEquals("@import url(test) screen;", node.toString()); + Assert.assertEquals("@import url(test) screen;", node.printState()); } } diff --git a/uitest/ivy.xml b/uitest/ivy.xml index 91c049b551..03b57a30e5 100644 --- a/uitest/ivy.xml +++ b/uitest/ivy.xml @@ -84,6 +84,9 @@ conf="build,ide -> default" /> <dependency org="com.vaadin" name="vaadin-testbench" rev="3.1.3" conf="build-provided,ide -> default" /> + <!-- This should be removed once tests have been updated to use lang3 --> + <dependency org="commons-lang" name="commons-lang" + rev="2.6" conf="build,ide -> default" /> </dependencies> </ivy-module> diff --git a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java index a8d639cbc8..20e187c187 100644 --- a/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java +++ b/uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java @@ -217,7 +217,6 @@ public class DevelopmentServerLauncher { Socket accept = serverSocket.accept(); // First stop listening to the port serverSocket.close(); - final Thread stopThread = Thread.currentThread(); // Start a thread that kills the JVM if // server.stop() doesn't have any effect diff --git a/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.html b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.html new file mode 100644 index 0000000000..33fc46f060 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.html @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.application.DetachOldUIOnReload?restartApplication</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> + <td>This is UI 0</td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.application.DetachOldUIOnReload</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::PID_SLog_row_0</td> + <td>1. UI 0 has been detached</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> + <td>This is UI 1</td> +</tr> +<tr> + <td>clickAndWait</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::PID_SLog_row_0</td> + <td>2. UI 1 has been detached</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> + <td>This is UI 2</td> +</tr> +<tr> + <td>open</td> + <td>/</td> + <td></td> +</tr> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.application.DetachOldUIOnReload</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::PID_SLog_row_0</td> + <td>3. UI 2 has been detached</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> + <td>This is UI 3</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java new file mode 100644 index 0000000000..154c84b4f5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.application; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; + +public class DetachOldUIOnReload extends AbstractTestUIWithLog { + private static final String PERSISTENT_MESSAGES_ATTRIBUTE = DetachOldUIOnReload.class + .getName() + ".sessionMessages"; + + @Override + protected void setup(VaadinRequest request) { + addComponent(new Label("This is UI " + getUIId())); + addComponent(new Button("Reload page", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + getPage().reload(); + } + })); + addComponent(new Button("Read log messages from session", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + for (String message : getSessionMessages(false)) { + log(message); + } + } + })); + } + + private List<String> getSessionMessages(boolean storeIfNeeded) { + List<String> messages = (List<String>) getSession().getAttribute( + PERSISTENT_MESSAGES_ATTRIBUTE); + if (messages == null) { + messages = new ArrayList<String>(); + if (storeIfNeeded) { + getSession().setAttribute(PERSISTENT_MESSAGES_ATTRIBUTE, + messages); + } + } + return messages; + } + + private void logToSession(String message) { + getSessionMessages(true).add(message); + } + + @Override + public void detach() { + super.detach(); + logToSession("UI " + getUIId() + " has been detached"); + } + + @Override + protected String getTestDescription() { + return "Tests that the previous UI gets cleaned immediately when refreshing."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(10338); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionTooltip.html b/uitest/src/com/vaadin/tests/application/RefreshStatePreserveTitle.html index 4f574a92c7..f366054f45 100644 --- a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionTooltip.html +++ b/uitest/src/com/vaadin/tests/application/RefreshStatePreserveTitle.html @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> +<link rel="selenium.base" href="http://localhost:8888/run/com.vaadin.tests.application.RefreshStatePreserveTitle?restartApplication" /> <title>New Test</title> </head> <body> @@ -13,19 +13,22 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.applicationcontext.CloseSession?restartApplication&debug</td> + <td>/run/com.vaadin.tests.application.RefreshStatePreserveTitle?restartApplication</td> <td></td> </tr> -<!-- Show tooltip for the Events caption --> <tr> - <td>showTooltip</td> - <td>//div[@id='gwt-uid-4']/span</td> + <td>assertTitle</td> + <td>TEST</td> <td></td> </tr> -<!-- Verify that there's no error notification --> <tr> - <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestsapplicationcontextCloseSession::Root/VNotification[0]</td> + <td>open</td> + <td>/run/com.vaadin.tests.application.RefreshStatePreserveTitle</td> + <td></td> +</tr> +<tr> + <td>assertTitle</td> + <td>TEST</td> <td></td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/application/RefreshStatePreserveTitle.java b/uitest/src/com/vaadin/tests/application/RefreshStatePreserveTitle.java new file mode 100644 index 0000000000..88b3a9b9f4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/RefreshStatePreserveTitle.java @@ -0,0 +1,30 @@ +package com.vaadin.tests.application; + +import com.vaadin.annotations.PreserveOnRefresh; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.util.Log; +import com.vaadin.ui.Label; + +@PreserveOnRefresh +public class RefreshStatePreserveTitle extends AbstractTestUI { + + private Log log = new Log(5); + + @Override + protected void setup(VaadinRequest request) { + getPage().setTitle("TEST"); + addComponent(new Label( + "Refresh the page and observe that window title 'TEST' is lost.")); + } + + @Override + protected String getTestDescription() { + return "Refreshing the browser window should preserve the window title"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(11054); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.html b/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.html index f20967c8de..e7d437eeca 100644 --- a/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.html +++ b/uitest/src/com/vaadin/tests/application/TerminalErrorNotification.html @@ -28,7 +28,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationTerminalErrorNotification::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestsapplicationTerminalErrorNotification::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>Got an exception: You asked for it</td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/application/VaadinSessionAttribute.html b/uitest/src/com/vaadin/tests/application/VaadinSessionAttribute.html index e03027f308..150ab3ff3d 100644 --- a/uitest/src/com/vaadin/tests/application/VaadinSessionAttribute.html +++ b/uitest/src/com/vaadin/tests/application/VaadinSessionAttribute.html @@ -23,7 +23,7 @@ </tr> <tr> <td>assertText</td> - <td>//body/div[2]</td> + <td>//body/div[2]//h1</td> <td>42 & 84</td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/application/calculator/Calc.java b/uitest/src/com/vaadin/tests/application/calculator/Calc.java new file mode 100644 index 0000000000..7911556f4e --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/calculator/Calc.java @@ -0,0 +1,268 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.application.calculator; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.ColumnHeaderMode; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +@SuppressWarnings("serial") +public class Calc extends AbstractTestUI { + + private class Log extends VerticalLayout { + + private Table table; + private Button addCommentButton; + private int line = 0; + + public Log() { + super(); + + table = new Table(); + table.setSizeFull(); + + setWidth("200px"); + setHeight("100%"); + + table.setColumnHeaderMode(ColumnHeaderMode.HIDDEN); + table.addContainerProperty("Operation", String.class, ""); + + addComponent(table); + + addCommentButton = new Button("Add Comment"); + addCommentButton.setWidth("100%"); + + addCommentButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + + final Window w = new Window("Add comment"); + VerticalLayout vl = new VerticalLayout(); + vl.setMargin(true); + + final TextField tf = new TextField(); + tf.setSizeFull(); + vl.addComponent(tf); + + HorizontalLayout hl = new HorizontalLayout(); + + Button okButton = new Button("OK"); + okButton.setWidth("100%"); + okButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + addRow("[ " + tf.getValue() + " ]"); + tf.setValue(""); + w.close(); + removeWindow(w); + } + }); + + Button cancelButton = new Button("Cancel"); + cancelButton.setWidth("100%"); + cancelButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + tf.setValue(""); + w.close(); + removeWindow(w); + } + }); + + hl.addComponent(cancelButton); + hl.addComponent(okButton); + hl.setSpacing(true); + hl.setWidth("100%"); + + vl.addComponent(hl); + vl.setSpacing(true); + + w.setContent(vl); + addWindow(w); + } + }); + + addComponent(addCommentButton); + + setExpandRatio(table, 1); + setSpacing(true); + } + + public void addRow(String row) { + Integer id = ++line; + table.addItem(new Object[] { row }, id); + table.setCurrentPageFirstItemIndex(line + 1); + } + + } + + // All variables are automatically stored in the session. + private Double current = 0.0; + private double stored = 0.0; + private char lastOperationRequested = 'C'; + private VerticalLayout topLayout = new VerticalLayout(); + + // User interface components + private final TextField display = new TextField(); + + private final Log log = new Log(); + + // Calculator "business logic" implemented here to keep the example + // minimal + private double calculate(char requestedOperation) { + if ('0' <= requestedOperation && requestedOperation <= '9') { + if (current == null) { + current = 0.0; + } + current = current * 10 + + Double.parseDouble("" + requestedOperation); + return current; + } + + if (current == null) { + current = stored; + } + switch (lastOperationRequested) { + case '+': + stored += current; + break; + case '-': + stored -= current; + break; + case '/': + stored /= current; + break; + case '*': + stored *= current; + break; + default: + stored = current; + break; + } + + switch (requestedOperation) { + case '+': + log.addRow(current + " +"); + break; + case '-': + log.addRow(current + " -"); + break; + case '/': + log.addRow(current + " /"); + break; + case '*': + log.addRow(current + " x"); + break; + case '=': + log.addRow(current + " ="); + log.addRow("------------"); + log.addRow("" + stored); + break; + } + + lastOperationRequested = requestedOperation; + current = null; + if (requestedOperation == 'C') { + log.addRow("0.0"); + stored = 0.0; + } + return stored; + } + + @Override + protected void setup(VaadinRequest request) { + setContent(topLayout); + + // Create the main layout for our application (4 columns, 5 rows) + final GridLayout layout = new GridLayout(4, 5); + + topLayout.setMargin(true); + topLayout.setSpacing(true); + Label title = new Label("Calculator"); + topLayout.addComponent(title); + topLayout.addComponent(log); + + HorizontalLayout horizontalLayout = new HorizontalLayout(); + horizontalLayout.setSpacing(true); + horizontalLayout.addComponent(layout); + horizontalLayout.addComponent(log); + topLayout.addComponent(horizontalLayout); + + // Create a result label that over all 4 columns in the first row + layout.setSpacing(true); + layout.addComponent(display, 0, 0, 3, 0); + layout.setComponentAlignment(display, Alignment.MIDDLE_RIGHT); + display.setSizeFull(); + display.setId("display"); + display.setValue("0.0"); + + // The operations for the calculator in the order they appear on the + // screen (left to right, top to bottom) + String[] operations = new String[] { "7", "8", "9", "/", "4", "5", "6", + "*", "1", "2", "3", "-", "0", "=", "C", "+" }; + + for (String caption : operations) { + + // Create a button and use this application for event handling + Button button = new Button(caption); + button.setWidth("40px"); + button.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + // Get the button that was clicked + Button button = event.getButton(); + + // Get the requested operation from the button caption + char requestedOperation = button.getCaption().charAt(0); + + // Calculate the new value + double newValue = calculate(requestedOperation); + + // Update the result label with the new value + display.setValue("" + newValue); + } + }); + button.setId("button_" + caption); + + // Add the button to our main layout + layout.addComponent(button); + } + + } + + @Override + protected String getTestDescription() { + return "Provide test application for generic testing purposes"; + } + + @Override + protected Integer getTicketNumber() { + return 12444; + } + +} diff --git a/uitest/src/com/vaadin/tests/gwtadapter/componentlocator/TestDetachedNotPresent.html b/uitest/src/com/vaadin/tests/componentlocator/TestDetachedNotPresent.html index 18129a72e2..18129a72e2 100644 --- a/uitest/src/com/vaadin/tests/gwtadapter/componentlocator/TestDetachedNotPresent.html +++ b/uitest/src/com/vaadin/tests/componentlocator/TestDetachedNotPresent.html diff --git a/uitest/src/com/vaadin/tests/components/AbstractTestUI.java b/uitest/src/com/vaadin/tests/components/AbstractTestUI.java index 6213993257..5c7076c07e 100644 --- a/uitest/src/com/vaadin/tests/components/AbstractTestUI.java +++ b/uitest/src/com/vaadin/tests/components/AbstractTestUI.java @@ -113,27 +113,27 @@ public abstract class AbstractTestUI extends UI { protected void setTransport(VaadinRequest request) { String transport = request.getParameter("transport"); PushConfiguration config = getPushConfiguration(); - PushMode mode = config.getPushMode(); if ("xhr".equals(transport)) { config.setPushMode(PushMode.DISABLED); } else if ("websocket".equals(transport)) { - if (!mode.isEnabled()) { - config.setPushMode(PushMode.AUTOMATIC); - } - config.setTransport(Transport.WEBSOCKET); - // Ensure no fallback is used - getPushConfiguration().setParameter( - PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + enablePush(Transport.WEBSOCKET); } else if ("streaming".equals(transport)) { - if (!mode.isEnabled()) { - config.setPushMode(PushMode.AUTOMATIC); - } - config.setTransport(Transport.STREAMING); - // Ensure no fallback is used - getPushConfiguration().setParameter( - PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + enablePush(Transport.STREAMING); + } else if ("long-polling".equals(transport)) { + enablePush(Transport.LONG_POLLING); + } + } + + protected void enablePush(Transport transport) { + PushConfiguration config = getPushConfiguration(); + if (!config.getPushMode().isEnabled()) { + config.setPushMode(PushMode.AUTOMATIC); } + config.setTransport(transport); + // Ensure no fallback is used + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); } private VerticalLayout layout; diff --git a/uitest/src/com/vaadin/tests/components/ErrorMessages.html b/uitest/src/com/vaadin/tests/components/ErrorMessages.html index 5379ff59e0..2b7032ea79 100644 --- a/uitest/src/com/vaadin/tests/components/ErrorMessages.html +++ b/uitest/src/com/vaadin/tests/components/ErrorMessages.html @@ -3,17 +3,17 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://artur-laptop.office.itmill.com:8888/" /> -<title>New Test</title> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>ErrorMessages</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> +<tr><td rowspan="1" colspan="3">ErrorMessages</td></tr> </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.ErrorMessages</td> + <td>/run/com.vaadin.tests.components.ErrorMessages?restartApplication</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/SaneErrors.java b/uitest/src/com/vaadin/tests/components/SaneErrors.java new file mode 100644 index 0000000000..b82c1dd18b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/SaneErrors.java @@ -0,0 +1,86 @@ +package com.vaadin.tests.components; + +import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.ItemClickEvent.ItemClickListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.RowHeaderMode; +import com.vaadin.ui.VerticalLayout; + +public class SaneErrors extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Button b = new Button("Show me my NPE!"); + b.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + throwError(); + } + + }); + + /* + * Errors from "legacy variable changes" + */ + final Table table = new Table(); + table.addItem("Show me my NPE!"); + table.setRowHeaderMode(RowHeaderMode.ID); + table.addItemClickListener(new ItemClickListener() { + @Override + public void itemClick(ItemClickEvent event) { + throwError(); + } + }); + + final VerticalLayout content = new VerticalLayout(b, table); + + /** + * Button that shows reported exception for TB integration test + */ + Button button = new Button("Collect exceptions", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + reportException(b, content); + reportException(table, content); + } + + private void reportException(final AbstractComponent b, + final VerticalLayout content) { + String message = b.getErrorMessage().getFormattedHtmlMessage(); + message = message.replaceAll(".", "."); + message = message.substring(message.indexOf("h2>") + 3, + message.indexOf(" ")); + Label label = new Label(message); + content.addComponent(label); + } + }); + content.addComponent(button); + + setContent(content); + + } + + private void throwError() { + Object o = null; + o.getClass(); + } + + @Override + protected String getTestDescription() { + return "Vaadin should by default report exceptions relevant for the developer."; + } + + @Override + protected Integer getTicketNumber() { + return 11599; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java b/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java new file mode 100644 index 0000000000..6cf49151b3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components; + +import java.util.Collections; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class SaneErrorsTest extends MultiBrowserTest { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() + */ + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + return Collections.singletonList(DesiredCapabilities.firefox()); + } + + @Test + public void test() { + openTestURL(); + List<WebElement> elements = getDriver().findElements( + By.xpath("//*[text() = 'Show me my NPE!']")); + for (WebElement webElement : elements) { + webElement.click(); + } + + getDriver().findElement(By.xpath("//*[text() = 'Collect exceptions']")) + .click(); + + List<WebElement> errorMessages = getDriver().findElements( + By.className("v-label")); + for (WebElement webElement : errorMessages) { + String text = webElement.getText(); + Assert.assertEquals("java.lang.NullPointerException", text); + } + } + +} diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonsAndIcons.java b/uitest/src/com/vaadin/tests/components/button/ButtonsAndIcons.java index 4ab18e994a..64f690dbf5 100644 --- a/uitest/src/com/vaadin/tests/components/button/ButtonsAndIcons.java +++ b/uitest/src/com/vaadin/tests/components/button/ButtonsAndIcons.java @@ -27,7 +27,7 @@ public class ButtonsAndIcons extends TestBase { b = new Button("Only text"); addComponent(b); - b = new Button(null); + b = new Button((String) null); b.setIcon(new ThemeResource("../runo/icons/16/ok.png")); addComponent(b); diff --git a/uitest/src/com/vaadin/tests/components/button/ButtonsWaiAria.java b/uitest/src/com/vaadin/tests/components/button/ButtonsWaiAria.java index 1208b8be3b..24dc942171 100644 --- a/uitest/src/com/vaadin/tests/components/button/ButtonsWaiAria.java +++ b/uitest/src/com/vaadin/tests/components/button/ButtonsWaiAria.java @@ -22,6 +22,7 @@ public class ButtonsWaiAria extends ComponentTestCase<Button> { l = createButton("Icon Button, empty alt", nat); l.setIcon(ICON_16_USER_PNG_CACHEABLE); + l.setDescription("Empty alt text"); addTestComponent(l); l = createButton("Icon Button with alt", nat); @@ -31,6 +32,10 @@ public class ButtonsWaiAria extends ComponentTestCase<Button> { l = createButton("Tooltip Button", nat); l.setDescription("Tooltip"); addTestComponent(l); + + l = createButton("Another tooltip", nat); + l.setDescription("Another"); + addTestComponent(l); } private Button createButton(String text, boolean nativeButton) { diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarWeeklyViewNewEvents.html b/uitest/src/com/vaadin/tests/components/calendar/CalendarWeeklyViewNewEvents.html index fd51a0daad..6add1deba5 100644 --- a/uitest/src/com/vaadin/tests/components/calendar/CalendarWeeklyViewNewEvents.html +++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarWeeklyViewNewEvents.html @@ -313,7 +313,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>8,9</td> </tr> <!--Edit previously created events and change properties--> @@ -438,7 +438,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,8</td> </tr> <tr> @@ -558,7 +558,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>7,8</td> </tr> <tr> @@ -583,7 +583,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentscalendarCalendarTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>12,10</td> </tr> <!--Go to monthly view and assert inserted events--> diff --git a/uitest/src/com/vaadin/tests/components/calendar/TestHideTimeAndSeparator.java b/uitest/src/com/vaadin/tests/components/calendar/TestHideTimeAndSeparator.java index b8b55048f9..60e8720d44 100644 --- a/uitest/src/com/vaadin/tests/components/calendar/TestHideTimeAndSeparator.java +++ b/uitest/src/com/vaadin/tests/components/calendar/TestHideTimeAndSeparator.java @@ -21,7 +21,8 @@ public class TestHideTimeAndSeparator extends AbstractTestUI { private final String caption; private final boolean hideTime; - public GenericEvent(Date start, Date end, String caption, boolean hideTime) { + public GenericEvent(Date start, Date end, String caption, + boolean hideTime) { this.start = start; this.end = end; this.caption = caption; @@ -60,10 +61,16 @@ public class TestHideTimeAndSeparator extends AbstractTestUI { } - CalendarEvent shortEventHidden = new GenericEvent(makeDate(2013, 1, 2, 8, 0), makeDate(2013, 1, 2, 8, 30), "Short event", true); - CalendarEvent longEventHidden = new GenericEvent(makeDate(2013, 1, 2, 10, 0), makeDate(2013, 1, 2, 12, 0), "Long event", true); - CalendarEvent shortEvent = new GenericEvent(makeDate(2013, 1, 3, 8, 0), makeDate(2013, 1, 3, 8, 30), "Short event", false); - CalendarEvent longEvent = new GenericEvent(makeDate(2013, 1, 3, 10, 0), makeDate(2013, 1, 3, 12, 0), "Long event", false); + CalendarEvent shortEventHidden = new GenericEvent( + makeDate(2013, 1, 2, 8, 0), makeDate(2013, 1, 2, 8, 30), + "Short event", true); + CalendarEvent longEventHidden = new GenericEvent( + makeDate(2013, 1, 2, 10, 0), makeDate(2013, 1, 2, 12, 0), + "Long event", true); + CalendarEvent shortEvent = new GenericEvent(makeDate(2013, 1, 3, 8, 0), + makeDate(2013, 1, 3, 8, 30), "Short event", false); + CalendarEvent longEvent = new GenericEvent(makeDate(2013, 1, 3, 10, 0), + makeDate(2013, 1, 3, 12, 0), "Long event", false); @Override protected void setup(VaadinRequest request) { @@ -100,6 +107,7 @@ public class TestHideTimeAndSeparator extends AbstractTestUI { juc.set(year, month, day, hour, minute); return juc.getTime(); } + private Date makeDate(int year, int month, int day) { java.util.Calendar juc = java.util.Calendar.getInstance(); juc.set(year, month, day); diff --git a/uitest/src/com/vaadin/tests/components/customfield/CustomFieldSize.java b/uitest/src/com/vaadin/tests/components/customfield/CustomFieldSize.java new file mode 100644 index 0000000000..a3e19513b0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customfield/CustomFieldSize.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.customfield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Component; +import com.vaadin.ui.CustomField; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class CustomFieldSize extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setWidth("50px"); + + layout.addComponent(new TextField()); + + layout.addComponent(new CustomField<String>() { + + @Override + protected Component initContent() { + return new TextField(); + } + + @Override + public Class<? extends String> getType() { + return String.class; + } + + }); + } + + @Override + protected String getTestDescription() { + return "Any part of a TextField wrapped in a CustomField should not be cut off even when the dimensions of the TextField exceed those of the CustomField"; + } + + @Override + protected Integer getTicketNumber() { + return 12482; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/customfield/CustomFieldSizeTest.java b/uitest/src/com/vaadin/tests/components/customfield/CustomFieldSizeTest.java new file mode 100644 index 0000000000..c47ec0b792 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customfield/CustomFieldSizeTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.customfield; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class CustomFieldSizeTest extends MultiBrowserTest { + + @Test + public void checkScreenshot() throws IOException { + openTestURL(); + compareScreen("size"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperTooltips.html b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperTooltips.html index 03ec163e40..3c91c8b24f 100644 --- a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperTooltips.html +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropWrapperTooltips.html @@ -18,7 +18,7 @@ </tr> <tr> <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragAndDropWrapperTooltips::PID_Swrapper3</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragAndDropWrapperTooltips::PID_Swrapper3/VLabel[0]</td> <td>0,0</td> </tr> <tr> @@ -26,9 +26,10 @@ <td></td> <td>tooltip-initial</td> </tr> +<!--Drag Block 4 between Block 1 and Block 2--> <tr> <td>drag</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragAndDropWrapperTooltips::PID_Swrapper4</td> + <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragAndDropWrapperTooltips::PID_Swrapper4/VLabel[0]</td> <td>30,41</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/embedded/EmbeddedClickListenerRelativeCoordinates.html b/uitest/src/com/vaadin/tests/components/embedded/EmbeddedClickListenerRelativeCoordinates.html index 2dcd1b5071..ae81cfe61c 100644 --- a/uitest/src/com/vaadin/tests/components/embedded/EmbeddedClickListenerRelativeCoordinates.html +++ b/uitest/src/com/vaadin/tests/components/embedded/EmbeddedClickListenerRelativeCoordinates.html @@ -23,7 +23,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>41, 22</td> </tr> <tr> @@ -33,7 +33,7 @@ </tr> <tr> <td>waitForElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td></td> </tr> <tr> @@ -43,7 +43,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsembeddedEmbeddedClickListenerRelativeCoordinates::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>0, 0</td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/components/form/FormTooltips.html b/uitest/src/com/vaadin/tests/components/form/FormTooltips.html index ee693fd4be..5e412c3aad 100644 --- a/uitest/src/com/vaadin/tests/components/form/FormTooltips.html +++ b/uitest/src/com/vaadin/tests/components/form/FormTooltips.html @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8070" /> +<link rel="selenium.base" href="http://localhost:8888" /> <title>FormTooltips</title> </head> <body> @@ -38,10 +38,15 @@ <td></td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>-1000</td> +</tr> <!--first name caption tooltip--> <tr> <td>showTooltip</td> @@ -64,10 +69,15 @@ <td></td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>-1000</td> +</tr> <!--Form should not have a description tooltip--> <tr> <td>showTooltip</td> @@ -80,9 +90,9 @@ <td></td> </tr> <tr> - <td>assertElementNotPresent</td> + <td>assertElementPositionLeft</td> <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]</td> - <td></td> + <td>-1000</td> </tr> <!--Form error message should not have a tooltip--> <tr> @@ -96,9 +106,9 @@ <td></td> </tr> <tr> - <td>assertElementNotPresent</td> + <td>assertElementPositionLeft</td> <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]</td> - <td></td> + <td>-1000</td> </tr> <!--last name should have no tooltip--> <tr> @@ -112,9 +122,9 @@ <td></td> </tr> <tr> - <td>assertElementNotPresent</td> + <td>assertElementPositionLeft</td> <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td></td> + <td>-1000</td> </tr> <!--last name caption should have no tooltip--> <tr> @@ -128,9 +138,9 @@ <td></td> </tr> <tr> - <td>assertElementNotPresent</td> + <td>assertElementPositionLeft</td> <td>vaadin=runcomvaadintestscomponentsformFormTooltips::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td></td> + <td>-1000</td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonIconAndText.java b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonIconAndText.java new file mode 100644 index 0000000000..fdeed316ba --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonIconAndText.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.nativebutton; + +import com.vaadin.server.ThemeResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.NativeButton; + +public class NativeButtonIconAndText extends AbstractTestUI implements + ClickListener { + + static final String UPDATED_ALTERNATE_TEXT = "Now has alternate text"; + static final String INITIAL_ALTERNATE_TEXT = "Initial alternate text"; + static final String BUTTON_TEXT = "buttonText"; + static final String BUTTON_TEXT_ICON = "buttonTextIcon"; + static final String BUTTON_TEXT_ICON_ALT = "buttonTextIconAlt"; + static final String NATIVE_BUTTON_TEXT = "nativeButtonText"; + static final String NATIVE_BUTTON_TEXT_ICON = "nativeButtonTextIcon"; + static final String NATIVE_BUTTON_TEXT_ICON_ALT = "nativeButtonTextIconAlt"; + + @Override + protected void setup(VaadinRequest request) { + Button buttonText = new Button("Only text"); + + Button buttonTextIcon = new Button("Text icon"); + buttonTextIcon.setIcon(new ThemeResource("../runo/icons/64/ok.png")); + + Button buttonTextIconAlt = new Button("Text icon alt"); + buttonTextIconAlt.setIcon(new ThemeResource( + "../runo/icons/64/cancel.png")); + buttonTextIconAlt.setIconAlternateText(INITIAL_ALTERNATE_TEXT); + + buttonText.addClickListener(this); + buttonTextIcon.addClickListener(this); + buttonTextIconAlt.addClickListener(this); + + buttonText.setId(BUTTON_TEXT); + buttonTextIcon.setId(BUTTON_TEXT_ICON); + buttonTextIconAlt.setId(BUTTON_TEXT_ICON_ALT); + + addComponent(buttonText); + addComponent(buttonTextIcon); + addComponent(buttonTextIconAlt); + + NativeButton nativeButtonText = new NativeButton("Only text"); + + NativeButton nativeButtonTextIcon = new NativeButton("Text icon"); + nativeButtonTextIcon.setIcon(new ThemeResource( + "../runo/icons/64/ok.png")); + + NativeButton nativeButtonTextIconAlt = new NativeButton("Text icon alt"); + nativeButtonTextIconAlt.setIcon(new ThemeResource( + "../runo/icons/64/cancel.png")); + nativeButtonTextIconAlt.setIconAlternateText(INITIAL_ALTERNATE_TEXT); + + nativeButtonText.addClickListener(this); + nativeButtonTextIcon.addClickListener(this); + nativeButtonTextIconAlt.addClickListener(this); + + nativeButtonText.setId(NATIVE_BUTTON_TEXT); + nativeButtonTextIcon.setId(NATIVE_BUTTON_TEXT_ICON); + nativeButtonTextIconAlt.setId(NATIVE_BUTTON_TEXT_ICON_ALT); + + addComponent(nativeButtonText); + addComponent(nativeButtonTextIcon); + addComponent(nativeButtonTextIconAlt); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Click the buttons to toggle icon alternate text"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 12780; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.Button.ClickListener#buttonClick(com.vaadin.ui.Button. + * ClickEvent) + */ + @Override + public void buttonClick(ClickEvent event) { + Button b = event.getButton(); + String was = b.getIconAlternateText(); + if (was == null || was.isEmpty()) { + b.setIconAlternateText(UPDATED_ALTERNATE_TEXT); + } else { + b.setIconAlternateText(null); + } + + } + +} diff --git a/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonIconAndTextTest.java b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonIconAndTextTest.java new file mode 100644 index 0000000000..2cb294de77 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/nativebutton/NativeButtonIconAndTextTest.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.nativebutton; + +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.BUTTON_TEXT; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.BUTTON_TEXT_ICON; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.BUTTON_TEXT_ICON_ALT; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.INITIAL_ALTERNATE_TEXT; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.NATIVE_BUTTON_TEXT; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.NATIVE_BUTTON_TEXT_ICON; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.NATIVE_BUTTON_TEXT_ICON_ALT; +import static com.vaadin.tests.components.nativebutton.NativeButtonIconAndText.UPDATED_ALTERNATE_TEXT; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class NativeButtonIconAndTextTest extends MultiBrowserTest { + + @Test + public void testNativeButtonIconAltText() { + openTestURL(); + assertAltText(BUTTON_TEXT, ""); + assertAltText(BUTTON_TEXT_ICON, ""); + assertAltText(BUTTON_TEXT_ICON_ALT, INITIAL_ALTERNATE_TEXT); + assertAltText(NATIVE_BUTTON_TEXT, ""); + assertAltText(NATIVE_BUTTON_TEXT_ICON, ""); + assertAltText(NATIVE_BUTTON_TEXT_ICON_ALT, INITIAL_ALTERNATE_TEXT); + + clickElements(BUTTON_TEXT, BUTTON_TEXT_ICON, BUTTON_TEXT_ICON_ALT, + NATIVE_BUTTON_TEXT, NATIVE_BUTTON_TEXT_ICON, + NATIVE_BUTTON_TEXT_ICON_ALT); + + // Button without icon - should not get alt text + assertAltText(BUTTON_TEXT, ""); + assertAltText(BUTTON_TEXT_ICON, UPDATED_ALTERNATE_TEXT); + assertAltText(BUTTON_TEXT_ICON_ALT, ""); + // Button without icon - should not get alt text + assertAltText(NATIVE_BUTTON_TEXT, ""); + assertAltText(NATIVE_BUTTON_TEXT_ICON, UPDATED_ALTERNATE_TEXT); + assertAltText(NATIVE_BUTTON_TEXT_ICON_ALT, ""); + + } + + private void clickElements(String... ids) { + for (String id : ids) { + vaadinElementById(id).click(); + } + } + + /** + * If the button identified by 'buttonId' has an icon, asserts that the + * alternate text of the icon matches 'expected'. "" and null are considered + * equivalent. + * + * @param buttonId + * the id of the button who possibly contains an icon + * @param expected + * the expected alternate text, cannot be null + */ + private void assertAltText(String buttonId, String expected) { + WebElement button = vaadinElementById(buttonId); + List<WebElement> imgList = button.findElements(By.xpath(".//img")); + if (imgList.isEmpty()) { + return; + } + WebElement img = imgList.get(0); + String alt = img.getAttribute("alt"); + if (alt == null) { + alt = ""; + } + + Assert.assertEquals(expected, alt); + + } +} diff --git a/uitest/src/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html b/uitest/src/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html index 1ab75e1176..c9d9e186bc 100644 --- a/uitest/src/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html +++ b/uitest/src/com/vaadin/tests/components/notification/CloseErrorNotificationWithEscape.html @@ -28,12 +28,12 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotifications::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotifications::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>Hello world</td> </tr> <tr> <td>keyDown</td> - <td>vaadin=runcomvaadintestscomponentsnotificationNotifications::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotifications::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>\27</td> </tr> <!-- Fade delay is 400 ms by default - VNotification --> diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html new file mode 100644 index 0000000000..fb00953e48 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.html @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>NotificationsWaiAria</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">NotificationsWaiAria</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.notification.NotificationsWaiAria?restartApplication</td> + <td></td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td> + <td>Prefix:</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td> + <td>- press ESC to close</td> +</tr> +<tr> + <td>select</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VNativeSelect[0]/domChild[0]</td> + <td>label=ALERT</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> + <td></td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]@role</td> + <td>alert</td> +</tr> +<tr> + <td>assertText</td> + <td>xpath=//div[@class='v-Notification humanized v-Notification-humanized']//span[@class='v-assistive-device-only'][1]</td> + <td>Prefix:</td> +</tr> +<tr> + <td>assertText</td> + <td>xpath=//div[@class='v-Notification humanized v-Notification-humanized']//span[@class='v-assistive-device-only'][2]</td> + <td>- press ESC to close</td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>select</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VNativeSelect[0]/domChild[0]</td> + <td>label=STATUS</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertAttribute</td> + <td>xpath=/html/body/div[2]/div@role</td> + <td>status</td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTextField[0]</td> + <td></td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VTextField[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestscomponentsnotificationNotificationsWaiAria::Root/VNotification[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td></td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java new file mode 100644 index 0000000000..27af49a397 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAria.java @@ -0,0 +1,116 @@ +package com.vaadin.tests.components.notification; + +import com.vaadin.data.Item; +import com.vaadin.server.Page; +import com.vaadin.shared.ui.ui.NotificationConfigurationBean.Role; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Notification.Type; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; + +public class NotificationsWaiAria extends TestBase { + + private static final String CAPTION = "CAPTION"; + private static final String ROLE = "ROLE"; + + private TextField prefix; + private TextField postfix; + private NativeSelect role; + + private TextArea tf; + private ComboBox type; + + @SuppressWarnings("deprecation") + @Override + protected void setup() { + prefix = new TextField("Prefix", "Info"); + addComponent(prefix); + + postfix = new TextField("Postfix", + " - closes automatically after 10 seconds"); + addComponent(postfix); + + role = new NativeSelect("Role"); + role.addItem(Role.ALERT); + role.addItem(Role.STATUS); + role.setValue(role.getItemIds().iterator().next()); + addComponent(role); + + tf = new TextArea("Text", "Hello world"); + tf.setRows(10); + addComponent(tf); + type = new ComboBox(); + type.setNullSelectionAllowed(false); + type.addContainerProperty(CAPTION, String.class, ""); + + type.setItemCaptionPropertyId(CAPTION); + + Item item = type.addItem(Notification.TYPE_HUMANIZED_MESSAGE); + item.getItemProperty(CAPTION).setValue("Humanized"); + + item = type.addItem(Notification.TYPE_ERROR_MESSAGE); + item.getItemProperty(CAPTION).setValue("Error"); + + item = type.addItem(Notification.TYPE_WARNING_MESSAGE); + item.getItemProperty(CAPTION).setValue("Warning"); + + item = type.addItem(Notification.TYPE_TRAY_NOTIFICATION); + item.getItemProperty(CAPTION).setValue("Tray"); + + item = type.addItem(Notification.Type.ASSISTIVE_NOTIFICATION); + item.getItemProperty(CAPTION).setValue("Assistive"); + + type.setValue(type.getItemIds().iterator().next()); + addComponent(type); + + Button showNotification = new Button("Show notification", + new SettingHandler()); + addComponent(showNotification); + + Button showDefaultNotification = new Button("Default notification", + new DefaultHandler()); + addComponent(showDefaultNotification); + } + + @Override + protected String getDescription() { + return "Generic test case for notifications"; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + + private class SettingHandler implements ClickListener { + @Override + public void buttonClick(ClickEvent event) { + Type typeValue = (Type) type.getValue(); + + Notification n = new Notification(tf.getValue(), typeValue); + n.setHtmlContentAllowed(true); + n.setAssistivePrefixForType(typeValue, prefix.getValue()); + n.setAssistivePostfixForType(typeValue, postfix.getValue()); + n.setAssistiveRoleForType(typeValue, (Role) role.getValue()); + + n.show(Page.getCurrent()); + } + } + + private class DefaultHandler implements ClickListener { + @Override + public void buttonClick(ClickEvent event) { + Notification n = new Notification(tf.getValue(), + (Type) type.getValue()); + n.setHtmlContentAllowed(true); + n.show(Page.getCurrent()); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupParentDisabled.html b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupParentDisabled.html index 80d10a05ca..db5a268ecd 100644 --- a/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupParentDisabled.html +++ b/uitest/src/com/vaadin/tests/components/optiongroup/OptionGroupParentDisabled.html @@ -1,4 +1,4 @@ -?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHover.java b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHover.java new file mode 100644 index 0000000000..e9b022eac2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHover.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.orderedlayout; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.VerticalLayout; + +/** + * Test hovering over nested layout caption + * + * @author Vaadin Ltd + */ +public class NestedLayoutCaptionHover extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout test = new VerticalLayout(); + test.setCaption("inner layout"); + addComponent(new VerticalLayout(new VerticalLayout(new VerticalLayout( + test)))); + } + + @Override + protected String getTestDescription() { + return "Hovering over nested layout caption should not freeze the browser"; + } + + @Override + protected Integer getTicketNumber() { + return 12469; + } +} diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHoverTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHoverTest.java new file mode 100644 index 0000000000..24a27f343a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHoverTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.orderedlayout; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.HasInputDevices; +import org.openqa.selenium.interactions.internal.Coordinates; +import org.openqa.selenium.internal.Locatable; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests hovering over caption in nested layout + */ +public class NestedLayoutCaptionHoverTest extends MultiBrowserTest { + + @Test + public void testTooltipInNestedLayout() throws Exception { + openTestURL(); + + WebElement caption = getDriver().findElement( + By.className("v-captiontext")); + + assertEquals("inner layout", caption.getText()); + + // Hover over the caption + Coordinates coords = ((Locatable) caption).getCoordinates(); + ((HasInputDevices) getDriver()).getMouse().mouseMove(coords); + sleep(1000); + + String selector = "Root/VNotification[0]"; + try { + // Verify that there's no error notification + vaadinElement(selector); + fail("No error notification should be found"); + } catch (NoSuchElementException e) { + // Exception caught. Verify it's the right one. + assertTrue(e.getMessage().contains(selector)); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/page/PageTitle.java b/uitest/src/com/vaadin/tests/components/page/PageTitle.java new file mode 100644 index 0000000000..38dcd4673c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/page/PageTitle.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.page; + +import com.vaadin.annotations.Title; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; + +@Title("bar") +public class PageTitle extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + String title = request.getParameter("title"); + if (title != null) { + getPage().setTitle(title); + } + + } + + @Override + protected String getTestDescription() { + return "Sets the title according to a given ?title parameter. By default the ApplicationServletRunner will set the title to the fully qualified class name"; + } + + @Override + protected Integer getTicketNumber() { + return 13430; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/page/PageTitleTest.java b/uitest/src/com/vaadin/tests/components/page/PageTitleTest.java new file mode 100644 index 0000000000..039f52be73 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/page/PageTitleTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.page; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class PageTitleTest extends MultiBrowserTest { + + @Test + public void nullTitle() { + driver.get(getTestUrl()); + Assert.assertEquals(PageTitle.class.getName(), driver.getTitle()); + } + + @Test + public void fooTitle() { + driver.get(getTestUrl() + "?title=foo"); + Assert.assertEquals("foo", driver.getTitle()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/slider/SliderTooltip.html b/uitest/src/com/vaadin/tests/components/slider/SliderTooltip.html index 4e8296050f..806e7d1b44 100644 --- a/uitest/src/com/vaadin/tests/components/slider/SliderTooltip.html +++ b/uitest/src/com/vaadin/tests/components/slider/SliderTooltip.html @@ -3,13 +3,13 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://arturwin.office.itmill.com:9999/" /> -<title>New Test</title> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>SliderTooltip</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> +<tr><td rowspan="1" colspan="3">SliderTooltip</td></tr> </thead><tbody> <tr> <td>open</td> @@ -57,9 +57,14 @@ <td>40,16</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>pause</td> <td></td> + <td>1000</td> +</tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runcomvaadintestscomponentssliderSliderTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> + <td>-1000</td> </tr> </tbody></table> diff --git a/uitest/src/com/vaadin/tests/components/table/DoublesInTable.java b/uitest/src/com/vaadin/tests/components/table/DoublesInTable.java index 355cd43d37..4cf2506eeb 100644 --- a/uitest/src/com/vaadin/tests/components/table/DoublesInTable.java +++ b/uitest/src/com/vaadin/tests/components/table/DoublesInTable.java @@ -9,7 +9,7 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.data.util.converter.Converter; -import com.vaadin.data.util.converter.StringToNumberConverter; +import com.vaadin.data.util.converter.StringToDoubleConverter; import com.vaadin.tests.components.TestBase; import com.vaadin.tests.data.bean.Address; import com.vaadin.tests.data.bean.Country; @@ -276,7 +276,7 @@ public class DoublesInTable extends TestBase { }); - t.setConverter("rent", new StringToNumberConverter() { + t.setConverter("rent", new StringToDoubleConverter() { @Override protected NumberFormat getFormat(Locale locale) { return NumberFormat.getCurrencyInstance(locale); diff --git a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java index 664b36fa75..2e27675b25 100644 --- a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java +++ b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java @@ -21,7 +21,7 @@ import static com.vaadin.tests.components.table.SelectAllRows.TABLE; import static com.vaadin.tests.components.table.SelectAllRows.TOTAL_NUMBER_OF_ROWS; import static org.junit.Assert.assertEquals; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import org.junit.Test; @@ -38,11 +38,19 @@ public class SelectAllRowsTest extends MultiBrowserTest { private final static String TABLE_ROW = "v-table-row"; @Override + protected DesiredCapabilities getDesiredCapabilities() { + DesiredCapabilities cap = super.getDesiredCapabilities(); + cap.setCapability("requireWindowFocus", true); + return cap; + } + + @Override public List<DesiredCapabilities> getBrowsersToTest() { - // Pressing Shift modifier key does not work with TestBench and IE - // (#8621) - return Arrays.asList(Browser.FIREFOX.getDesiredCapabilities(), - Browser.CHROME.getDesiredCapabilities()); + // Pressing Shift modifier key does not work with Firefox + ArrayList<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( + super.getBrowsersToTest()); + browsers.remove(Browser.FIREFOX.getDesiredCapabilities()); + return browsers; } @Test @@ -66,15 +74,14 @@ public class SelectAllRowsTest extends MultiBrowserTest { private void selectAllRowsInTable() { clickFirstRow(); scrollTableToBottom(); - new Actions(getDriver()).keyDown(Keys.SHIFT).perform(); - clickLastRow(); - new Actions(getDriver()).keyUp(Keys.SHIFT).perform(); + new Actions(getDriver()).keyDown(Keys.SHIFT).click(getLastRow()) + .keyUp(Keys.SHIFT).perform(); } - private void clickLastRow() { + private WebElement getLastRow() { List<WebElement> rows = allVisibleTableRows(); WebElement lastRow = rows.get(rows.size() - 1); - lastRow.click(); + return lastRow; } private void clickFirstRow() { diff --git a/uitest/src/com/vaadin/tests/components/table/TableDragColumnFloatingElementStyles.html b/uitest/src/com/vaadin/tests/components/table/TableDragColumnFloatingElementStyles.html new file mode 100644 index 0000000000..e225091b5f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableDragColumnFloatingElementStyles.html @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>TableDragColumn</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TableDragColumn</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.table.Tables?restartApplication</td> + <td></td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>51,6</td> +</tr> +<tr> + <td>mouseMoveAt</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[3]</td> + <td>70,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>1 basic ghost element</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>10,10</td> +</tr> +<!--Add style name "red-border-1px" to table--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item0</td> + <td>24,7</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item1</td> + <td>18,10</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item4</td> + <td>19,8</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item2</td> + <td>75,7</td> +</tr> +<!-- Drag and drop column 1 to the left of column 4 --> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>51,6</td> +</tr> +<tr> + <td>mouseMoveAt</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[3]</td> + <td>70,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>2 themed ghost element should have red borders</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>10,10</td> +</tr> +<!--Add style name "red-border-1px" to table--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_Smenu#item0</td> + <td>24,7</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[0]/VMenuBar[0]#item1</td> + <td>18,10</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[1]/VMenuBar[0]#item4</td> + <td>19,8</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstableTables::Root/VOverlay[2]/VMenuBar[0]#item3</td> + <td>164,10</td> +</tr> +<tr> + <td>drag</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>51,6</td> +</tr> +<tr> + <td>mouseMoveAt</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[3]</td> + <td>70,10</td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>3 themed ghost element should have 2px blue borders</td> +</tr> +<tr> + <td>drop</td> + <td>vaadin=runcomvaadintestscomponentstableTables::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>10,10</td> +</tr> +</tbody></table> +</body> +</html>
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html index eb3efc28fd..2df9fb678c 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html +++ b/uitest/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.html @@ -3,13 +3,13 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://arturwin.office.itmill.com:8888/" /> -<title>New Test</title> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>TableItemDescriptionGeneratorTest</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> +<tr><td rowspan="1" colspan="3">TableItemDescriptionGeneratorTest</td></tr> </thead><tbody> <tr> <td>open</td> @@ -39,10 +39,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Button tooltip--> <tr> <td>mouseMoveAt</td> @@ -65,10 +70,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--TextField tooltip--> <tr> <td>mouseMoveAt</td> @@ -91,10 +101,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Cell and row tooltips--> <tr> <td>mouseClick</td> @@ -123,10 +138,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Button tooltip--> <tr> <td>mouseMoveAt</td> @@ -149,10 +169,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--TextField tooltip--> <tr> <td>mouseMoveAt</td> @@ -175,10 +200,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Row and Component tooltips--> <tr> <td>mouseClick</td> @@ -212,10 +242,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Button tooltip--> <tr> <td>mouseMoveAt</td> @@ -238,10 +273,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--TextField tooltip--> <tr> <td>mouseMoveAt</td> @@ -264,10 +304,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Row tooltips--> <tr> <td>mouseClick</td> @@ -296,10 +341,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--Button tooltip--> <tr> <td>mouseMoveAt</td> @@ -322,10 +372,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> <!--TextField tooltip--> <tr> <td>mouseMoveAt</td> @@ -348,10 +403,15 @@ <td>22,7</td> </tr> <tr> - <td>waitForElementNotPresent</td> - <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>pause</td> + <td>1000</td> <td></td> </tr> +<tr> + <td>assertElementPositionLeft</td> + <td>vaadin=runTableItemDescriptionGeneratorTest::Root/VTooltip[0]</td> + <td>-1000</td> +</tr> </tbody></table> </body> diff --git a/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java new file mode 100644 index 0000000000..ab0198f39c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java @@ -0,0 +1,281 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.components.table; + +import java.util.ArrayList; +import java.util.Collection; + +import org.json.JSONObject; + +import com.vaadin.annotations.Push; +import com.vaadin.server.ClientConnector; +import com.vaadin.server.StreamVariable; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.ConnectorTracker; +import com.vaadin.ui.Table; + +@Push +public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI { + + public static final String SUCCESS_CAPTION = "Success!"; + public static final String BUTTON_ID = "blinkbutton"; + public static final String FAILURE_CAPTION = "Test failed"; + + private class WrappedConnectorTracker extends ConnectorTracker { + private ConnectorTracker tracker; + + private boolean initialDirtyHasBeenCalled = false; + + public WrappedConnectorTracker(ConnectorTracker tracker) { + super(TableRemovedQuicklySendsInvalidRpcCalls.this); + this.tracker = tracker; + } + + @Override + public void markAllConnectorsDirty() { + tracker.markAllConnectorsDirty(); + if (initialDirtyHasBeenCalled) { + button.setCaption(FAILURE_CAPTION); + } + initialDirtyHasBeenCalled = true; + } + + // DELEGATED METHODS BELOW: + + @Override + public void registerConnector(ClientConnector connector) { + tracker.registerConnector(connector); + } + + @Override + public void unregisterConnector(ClientConnector connector) { + tracker.unregisterConnector(connector); + } + + @Override + public boolean isClientSideInitialized(ClientConnector connector) { + return tracker.isClientSideInitialized(connector); + } + + @Override + public void markClientSideInitialized(ClientConnector connector) { + tracker.markClientSideInitialized(connector); + } + + @Override + public void markAllClientSidesUninitialized() { + tracker.markAllClientSidesUninitialized(); + } + + @Override + public ClientConnector getConnector(String connectorId) { + return tracker.getConnector(connectorId); + } + + @Override + public void cleanConnectorMap() { + tracker.cleanConnectorMap(); + } + + @Override + public void markDirty(ClientConnector connector) { + tracker.markDirty(connector); + } + + @Override + public void markClean(ClientConnector connector) { + tracker.markClean(connector); + } + + @Override + public void markAllConnectorsClean() { + tracker.markAllConnectorsClean(); + } + + @Override + public Collection<ClientConnector> getDirtyConnectors() { + return tracker.getDirtyConnectors(); + } + + @Override + public boolean hasDirtyConnectors() { + return tracker.hasDirtyConnectors(); + } + + @Override + public ArrayList<ClientConnector> getDirtyVisibleConnectors() { + return tracker.getDirtyVisibleConnectors(); + } + + @Override + public JSONObject getDiffState(ClientConnector connector) { + return tracker.getDiffState(connector); + } + + @Override + public void setDiffState(ClientConnector connector, JSONObject diffState) { + tracker.setDiffState(connector, diffState); + } + + @Override + public boolean isDirty(ClientConnector connector) { + return tracker.isDirty(connector); + } + + @Override + public boolean isWritingResponse() { + return tracker.isWritingResponse(); + } + + @Override + public void setWritingResponse(boolean writingResponse) { + tracker.setWritingResponse(writingResponse); + } + + @Override + public StreamVariable getStreamVariable(String connectorId, + String variableName) { + return tracker.getStreamVariable(connectorId, variableName); + } + + @Override + public void addStreamVariable(String connectorId, String variableName, + StreamVariable variable) { + tracker.addStreamVariable(connectorId, variableName, variable); + } + + @Override + public void cleanStreamVariable(String connectorId, String variableName) { + tracker.cleanStreamVariable(connectorId, variableName); + } + + @Override + public String getSeckey(StreamVariable variable) { + return tracker.getSeckey(variable); + } + + @Override + public boolean connectorWasPresentAsRequestWasSent(String connectorId, + long lastSyncIdSeenByClient) { + return tracker.connectorWasPresentAsRequestWasSent(connectorId, + lastSyncIdSeenByClient); + } + + @Override + public int getCurrentSyncId() { + return tracker.getCurrentSyncId(); + } + + @Override + public void cleanConcurrentlyRemovedConnectorIds( + int lastSyncIdSeenByClient) { + tracker.cleanConcurrentlyRemovedConnectorIds(lastSyncIdSeenByClient); + } + + @Override + public boolean equals(Object obj) { + return tracker.equals(obj); + } + + @Override + public int hashCode() { + return tracker.hashCode(); + } + + @Override + public String toString() { + return tracker.toString(); + } + } + + private Button button; + private WrappedConnectorTracker wrappedTracker = null; + + @Override + protected void setup(VaadinRequest request) { + button = new Button("Blink a table", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + blinkTable(); + } + }); + button.setId(BUTTON_ID); + addComponent(button); + } + + @Override + public ConnectorTracker getConnectorTracker() { + if (wrappedTracker == null) { + wrappedTracker = new WrappedConnectorTracker( + super.getConnectorTracker()); + } + return wrappedTracker; + } + + private void blinkTable() { + final Table table = new Table(); + table.setPageLength(5); + table.addContainerProperty(new Object(), String.class, null); + + for (int i = 0; i < 50; i++) { + table.addItem(new Object[] { "Row" }, new Object()); + } + + System.out.println("adding component"); + addComponent(table); + + new Thread() { + @Override + public void run() { + getSession().lock(); + try { + Thread.sleep(500); + access(new Runnable() { + @Override + public void run() { + System.out.println("removing component"); + removeComponent(table); + button.setCaption(SUCCESS_CAPTION); + } + }); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + getSession().unlock(); + } + } + }.start(); + } + + @Override + protected String getTestDescription() { + return "Adding and subsequently quickly removing a table " + + "should not leave any pending RPC calls waiting " + + "in a Timer. Issue can be reproduced by " + + "1) pressing the button 2) checking the server " + + "log for any error messages starting with " + + "\"RPC call to...\" ."; + } + + @Override + protected Integer getTicketNumber() { + return 12337; + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCallsTest.java b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCallsTest.java new file mode 100644 index 0000000000..68c8dc9884 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCallsTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TableRemovedQuicklySendsInvalidRpcCallsTest extends + MultiBrowserTest { + + private static final String BUTTON_ID = TableRemovedQuicklySendsInvalidRpcCalls.BUTTON_ID; + private static final String FAILURE_CAPTION = TableRemovedQuicklySendsInvalidRpcCalls.FAILURE_CAPTION; + private static final String SUCCESS_CAPTION = TableRemovedQuicklySendsInvalidRpcCalls.SUCCESS_CAPTION; + + @Test + public void test() throws Exception { + setDebug(true); + openTestURL(); + + assertFalse("Test started with the error present.", button().getText() + .equals(FAILURE_CAPTION)); + assertFalse("Test jumped the gun.", + button().getText().equals(SUCCESS_CAPTION)); + + button().click(); + Thread.sleep(5000); + + assertFalse("Test failed after trying to trigger the error.", button() + .getText().equals(FAILURE_CAPTION)); + assertTrue("Test didn't end up in correct success state.", button() + .getText().equals(SUCCESS_CAPTION)); + } + + private WebElement button() { + return vaadinElementById(BUTTON_ID); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.html b/uitest/src/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.html index bab6c8dc16..e24f4ddca4 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.html +++ b/uitest/src/com/vaadin/tests/components/table/TableShouldNotEatValueChanges.html @@ -33,7 +33,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableShouldNotEatValueChanges::Root/VNotification[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableShouldNotEatValueChanges::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>TF Value on the server:fooo</td> </tr> <tr> @@ -63,7 +63,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableShouldNotEatValueChanges::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableShouldNotEatValueChanges::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>TF Value on the server:baar</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/table/TableWithBrokenGeneratorAndContainer.html b/uitest/src/com/vaadin/tests/components/table/TableWithBrokenGeneratorAndContainer.html index c2481e6be6..441324bb6a 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableWithBrokenGeneratorAndContainer.html +++ b/uitest/src/com/vaadin/tests/components/table/TableWithBrokenGeneratorAndContainer.html @@ -3,7 +3,6 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:9999/" /> <title>TableWithBrokenGeneratorAndContainer</title> </head> <body> @@ -163,7 +162,7 @@ <!--error notification--> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentstableTableWithBrokenGeneratorAndContainer::Root/VNotification[0]/HTML[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentstableTableWithBrokenGeneratorAndContainer::Root/VNotification[0]/HTML[0]/domChild[1]</td> <td>Problem updating table. Please try again later</td> </tr> <!--table should be empty--> diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html index 4b2ad890c3..825988173a 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigation.html @@ -33,6 +33,16 @@ <tr> <td>assertText</td> <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VLabel[0]</td> + <td>Tab 1</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[1]/ChildComponentContainer[0]/VLabel[0]</td> <td>Tab 2</td> </tr> <tr> @@ -58,6 +68,16 @@ <tr> <td>assertText</td> <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[3]/ChildComponentContainer[0]/VLabel[0]</td> + <td>Tab 2</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[3]/ChildComponentContainer[0]/VLabel[0]</td> <td>Tab 5</td> </tr> <tr> @@ -83,6 +103,16 @@ <tr> <td>assertText</td> <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[4]/ChildComponentContainer[0]/VLabel[0]</td> + <td>Tab 5</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[4]/ChildComponentContainer[0]/VLabel[0]</td> <td>Tab 6</td> </tr> <tr> @@ -143,6 +173,16 @@ <tr> <td>assertText</td> <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[8]/ChildComponentContainer[0]/VLabel[0]</td> + <td>Tab 9</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[10]</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[8]/ChildComponentContainer[0]/VLabel[0]</td> <td>Tab 12</td> </tr> <tr> @@ -178,6 +218,16 @@ <tr> <td>assertText</td> <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> + <td>Tab 5</td> +</tr> +<tr> + <td>pressSpecialKey</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>space</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runTabKeyboardNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTabsheet[0]/VTabsheetPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> <td>Tab 1</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigationWaiAria.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigationWaiAria.java new file mode 100644 index 0000000000..e394594176 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabKeyboardNavigationWaiAria.java @@ -0,0 +1,86 @@ +package com.vaadin.tests.components.tabsheet; + +import java.util.ArrayList; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Component; +import com.vaadin.ui.Layout; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.TabSheet.Tab; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +public class TabKeyboardNavigationWaiAria extends AbstractTestUI { + + int index = 1; + ArrayList<Component> tabs = new ArrayList<Component>(); + TabSheet ts = new TabSheet(); + + @Override + protected void setup(VaadinRequest request) { + ts.setWidth("500px"); + ts.setHeight("500px"); + + for (int i = 0; i < 5; ++i) { + addTab(); + } + + Button addTab = new Button("Add a tab", new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + addTab(); + } + }); + Button focus = new Button("Focus tabsheet", new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + ts.focus(); + } + }); + + addComponent(addTab); + addComponent(focus); + + addComponent(ts); + } + + @Override + protected String getTestDescription() { + return "The tab bar should be focusable and arrow keys should change focus for tabs. Space key selects a focused tab. The del key should close a tab if closable."; + } + + @Override + protected Integer getTicketNumber() { + return 11827; + } + + private Tab addTab() { + Layout content = new VerticalLayout(); + tabs.add(content); + + TextField field = new TextField("Tab " + index + " label"); + content.addComponent(field); + + Tab tab = ts.addTab(content, "Tab " + index, null); + + if (index == 2) { + tab.setClosable(true); + tab.setDescription("Tab 2 Tooltip"); + } + + if (index == 4) { + tab.setEnabled(false); + } + + if (index == 5) { + tab.setDefaultFocusComponent(field); + } + + index++; + return tab; + } +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java new file mode 100644 index 0000000000..81648c1b52 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.tabsheet; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class TabSheetFocusedTabTest extends MultiBrowserTest { + + @Override + protected Class<?> getUIClass() { + return TabsheetScrolling.class; + } + + @Test + public void clickingChangesFocusedTab() throws Exception { + openTestURL(); + + getTab(1).click(); + + assertTrue(isFocused(getTab(1))); + + new Actions(getDriver()).sendKeys(Keys.RIGHT).perform(); + + assertFalse(isFocused(getTab(1))); + assertTrue(isFocused(getTab(3))); + + getTab(5).click(); + + assertFalse(isFocused(getTab(3))); + assertTrue(isFocused(getTab(5))); + + getTab(1).click(); + + assertFalse(isFocused(getTab(5))); + assertTrue(isFocused(getTab(1))); + } + + private WebElement getTab(int index) { + return getDriver() + .findElement( + By.xpath("(//table[contains(@class, 'v-tabsheet-tabs')])[1]/tbody/tr/td[" + + (index + 1) + "]/div")); + } + + private boolean isFocused(WebElement tab) { + return tab.getAttribute("class").contains("v-tabsheet-tabitem-focus"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.html b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.html index 425da11af4..6876497a1f 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.html +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.html @@ -21,6 +21,16 @@ <td></td> <td></td> </tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetIcons::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]@alt</td> + <td>iconalt1</td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetIcons::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VTabsheet[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]@alt</td> + <td>iconalt3</td> +</tr> </tbody></table> </body> diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.java index 5d814ec48f..ccdc4ecb38 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetIcons.java @@ -46,6 +46,8 @@ public class TabSheetIcons extends TestBase { for (Component c : tab) { tabsheet.addTab(c); + tabsheet.getTab(c).setIconAltText( + "iconalt" + tabsheet.getComponentCount()); } return tabsheet; diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetTest.java index 6c39cdab73..56836037b7 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetTest.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetTest.java @@ -26,7 +26,7 @@ public class TabSheetTest<T extends TabSheet> extends @Override public void execute(T c, Integer value, Object data) { - c.getTab(value).setIcon((Resource) data); + c.getTab(value).setIcon((Resource) data, "tabicon"); } }; diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetWithTabIds.html b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetWithTabIds.html new file mode 100644 index 0000000000..64e85f55e3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetWithTabIds.html @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>TabSheetWithTabIds</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">TabSheetWithTabIds</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.tabsheet.TabSheetWithTabIds</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>tab1</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>tab2</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>tab3</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetWithTabIds::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>tab1</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>tab2</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>tab3</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstabsheetTabSheetWithTabIds::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>tab1</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>tab2</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>tab3</td> + <td></td> +</tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetWithTabIds.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetWithTabIds.java new file mode 100644 index 0000000000..ae5adea45e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetWithTabIds.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +/** + * + */ +package com.vaadin.tests.components.tabsheet; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.TabSheet.Tab; + +public class TabSheetWithTabIds extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + TabSheet tabSheet = new TabSheet(); + + final Tab tab1 = tabSheet.addTab(new Label("Label 1"), "Tab 1", null); + + final Tab tab2 = tabSheet.addTab(new Label("Label 2"), "Tab 2", null); + + final Tab tab3 = tabSheet.addTab(new Label("Label 3"), "Tab 3", null); + + addComponent(tabSheet); + + Button b = new Button("Set ids", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tab1.setId("tab1"); + tab2.setId("tab2"); + tab3.setId("tab3"); + } + }); + addComponent(b); + + Button b2 = new Button("Clear ids", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tab1.setId(null); + tab2.setId(null); + tab3.setId(null); + } + }); + addComponent(b2); + } + + @Override + protected String getTestDescription() { + return "Add support for setId to TabSheet.Tab"; + } + + @Override + protected Integer getTicketNumber() { + return 12064; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.java index 1670963b9b..b55f1057b5 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.java @@ -33,6 +33,7 @@ public class TabsheetScrollingTest extends MultiBrowserTest { for (int i = 0; i < 10; i++) { sendKey(Keys.ARROW_RIGHT); } + sendKey(Keys.SPACE); Assert.assertEquals("Hide this tab (21)", getHideButtonText()); } diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetTooltip.html b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetTooltip.html index d133ab9937..38ff6ab8ca 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetTooltip.html +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetTooltip.html @@ -13,7 +13,7 @@ </thead><tbody> <tr> <td>open</td> - <td>/run/com.vaadin.tests.components.tabsheet.TabsheetTooltip</td> + <td>/run/com.vaadin.tests.components.tabsheet.TabsheetTooltip?restartApplication</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediate.java b/uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediate.java new file mode 100644 index 0000000000..26716846fc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediate.java @@ -0,0 +1,147 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.textfield; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.TextField; + +/** + * Test to verify fields become implicitly "immediate" when adding value change + * listener to them. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class AutomaticImmediate extends AbstractTestUIWithLog { + + /** + * + */ + static final String BUTTON = "button"; + /** + * + */ + static final String EXPLICIT_FALSE = "explicit-false"; + /** + * + */ + static final String FIELD = "field"; + /** + * + */ + static final String LISTENER_TOGGLE = "listener-toggle"; + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + + final TextField textField = new TextField() { + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.AbstractField#fireValueChange(boolean) + */ + @Override + protected void fireValueChange(boolean repaintIsNotNeeded) { + log("fireValueChange"); + super.fireValueChange(repaintIsNotNeeded); + } + }; + textField.setId(FIELD); + + final ValueChangeListener listener = new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + log("Value changed: " + event.getProperty().getValue()); + } + }; + + final CheckBox checkBox = new CheckBox("Toggle listener"); + checkBox.addValueChangeListener(new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + if (checkBox.getValue()) { + textField.addValueChangeListener(listener); + } else { + textField.removeValueChangeListener(listener); + } + } + }); + checkBox.setId(LISTENER_TOGGLE); + + Button b = new Button( + "setImmediate(false), sets explicitly false and causes server roundtrip", + new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + textField.setImmediate(false); + } + }); + b.setId(EXPLICIT_FALSE); + + Button b2 = new Button("Hit server, causes server roundtrip", + new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + } + }); + b2.setId(BUTTON); + + addComponent(textField); + addComponent(checkBox); + addComponent(b); + addComponent(b2); + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Field should be immediate automatically if it has value change listener"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 8029; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediateTest.java b/uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediateTest.java new file mode 100644 index 0000000000..4b522a1f37 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediateTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.textfield; + +import org.apache.commons.lang.RandomStringUtils; +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class AutomaticImmediateTest extends MultiBrowserTest { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.tb3.AbstractTB3Test#getUIClass() + */ + @Override + protected Class<?> getUIClass() { + return AutomaticImmediate.class; + } + + @Test + public void test() { + openTestURL(); + + WebElement field = getDriver().findElement( + By.id(AutomaticImmediate.FIELD)); + + WebElement toggle = getDriver().findElement( + By.xpath("//input[@type = 'checkbox']")); + + WebElement explicitFalseButton = getDriver().findElement( + By.id(AutomaticImmediate.EXPLICIT_FALSE)); + + WebElement hitServerButton = getDriver().findElement( + By.id(AutomaticImmediate.BUTTON)); + + String string = getRandomString(); + field.sendKeys(string + Keys.ENTER); + + // Non immediate, just the initial server side valuechange + assertLastLog("1. fireValueChange"); + + hitServerButton.click(); + + // No value change, but value sent to server + assertLastLog("2. fireValueChange"); + + // listener on -> immediate on + toggle.click(); + + string = getRandomString(); + String delSequence = "" + Keys.BACK_SPACE + Keys.BACK_SPACE; + field.sendKeys(delSequence + string + Keys.ENTER); + assertLastLog("4. Value changed: " + string); + + // listener off -> immediate off + String lastvalue = string; + toggle.click(); + string = getRandomString(); + field.sendKeys(delSequence + string + Keys.ENTER); + // No new value change should happen... + assertLastLog("4. Value changed: " + lastvalue); + hitServerButton.click(); + // ... but server should receive value with roundtrip + assertLastLog("5. fireValueChange"); + + // explicitly non immediate, but with listener + explicitFalseButton.click(); + toggle.click(); + + string = getRandomString(); + field.sendKeys(delSequence + string + Keys.ENTER); + // non immediate, no change... + assertLastLog("5. fireValueChange"); + // ... until server round trip + hitServerButton.click(); + assertLastLog("7. Value changed: " + string); + + } + + private String getRandomString() { + String string = RandomStringUtils.randomAlphanumeric(2); + return string; + } + + private void assertLastLog(String string) { + String text = getDriver().findElement(By.id("Log_row_0")).getText(); + Assert.assertEquals(string, text); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/textfield/BigDecimalTextField.html b/uitest/src/com/vaadin/tests/components/textfield/BigDecimalTextField.html new file mode 100644 index 0000000000..2428e8b4bb --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/BigDecimalTextField.html @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.textfield.BigDecimalTextField?restartApplication</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>15,2</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::PID_SLog_row_0</td> + <td>1. Commit ok. Property value: 15.2</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>70,12</td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>130</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::</td> + <td>160,327</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::PID_SLog_row_0</td> + <td>2. Commit ok. Property value: 130</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>75,16</td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>130abc</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::</td> + <td>96,280</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::PID_SLog_row_0</td> + <td>3. Commit failed: Commit failed</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> + <td>v-errorindicator</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>71,12</td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[1]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[0]</td> + <td>130,130</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::</td> + <td>118,280</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::/VVerticalLayout[0]/Slot[3]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<!--The converter automatically removes trailing zeros--> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestscomponentstextfieldBigDecimalTextField::PID_SLog_row_0</td> + <td>4. Commit ok. Property value: 130.13</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/textfield/BigDecimalTextField.java b/uitest/src/com/vaadin/tests/components/textfield/BigDecimalTextField.java new file mode 100644 index 0000000000..18d8679c2f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/textfield/BigDecimalTextField.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.textfield; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Locale; + +import com.vaadin.data.fieldgroup.FieldGroup; +import com.vaadin.data.util.BeanItem; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +/** + * @since 7.2 + * @author Vaadin Ltd + */ +public class BigDecimalTextField extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + final VerticalLayout layout = new VerticalLayout(); + layout.setMargin(true); + setLocale(new Locale("fi", "FI")); + + BeanBigDecimal beanBigDecimal = new BeanBigDecimal(); + BeanItem<BeanBigDecimal> beanItem = new BeanItem<BeanBigDecimal>( + beanBigDecimal); + + FormLayout formLayout = new FormLayout(); + TextField textField = new TextField("BigDecimal field"); + textField.setImmediate(true); + textField.setValue("12"); + formLayout.addComponent(textField); + + final FieldGroup fieldGroup = new FieldGroup(beanItem); + fieldGroup.bind(textField, "decimal"); + + Button setValue = new Button("Set value to 15,2", new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + ((TextField) fieldGroup.getField("decimal")).setValue("15,2"); + } + }); + + Button button = new Button("Commit"); + button.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + try { + fieldGroup.commit(); + log("Commit ok. Property value: " + + fieldGroup.getItemDataSource() + .getItemProperty("decimal").getValue()); + } catch (FieldGroup.CommitException e) { + log("Commit failed: " + e.getMessage()); + } + } + }); + + layout.addComponent(formLayout); + layout.addComponent(setValue); + layout.addComponent(button); + + setContent(layout); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Tests that BigDecimals work correctly with TextFields"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 9997; + } + + public static class BeanBigDecimal implements Serializable { + BigDecimal decimal; + + public BeanBigDecimal() { + + } + + public BigDecimal getDecimal() { + return decimal; + } + + public void setDecimal(BigDecimal decimal) { + this.decimal = decimal; + } + } + +} diff --git a/uitest/src/com/vaadin/tests/components/tree/SimpleTree.java b/uitest/src/com/vaadin/tests/components/tree/SimpleTree.java index 2fd3f05dbb..06b8af1ec6 100644 --- a/uitest/src/com/vaadin/tests/components/tree/SimpleTree.java +++ b/uitest/src/com/vaadin/tests/components/tree/SimpleTree.java @@ -8,6 +8,8 @@ import com.vaadin.event.Action; import com.vaadin.server.ThemeResource; import com.vaadin.tests.components.TestBase; import com.vaadin.ui.AbstractSelect; +import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; +import com.vaadin.ui.Component; import com.vaadin.ui.Tree; public class SimpleTree extends TestBase implements Action.Handler { @@ -53,6 +55,17 @@ public class SimpleTree extends TestBase implements Action.Handler { tree.setItemIcon(9, notCachedFolderIconLargeOther, "First Choice"); tree.setItemIcon(11, notCachedFolderIconLarge); + tree.setItemDescriptionGenerator(new ItemDescriptionGenerator() { + @Override + public String generateDescription(Component source, Object itemId, + Object propertyId) { + if ((Integer) itemId == 3) { + return "tree item tooltip"; + } + return ""; + } + }); + // Expand whole tree for (Object id : tree.rootItemIds()) { tree.expandItemsRecursively(id); diff --git a/uitest/src/com/vaadin/tests/components/ui/MultiFileUploadTest.java b/uitest/src/com/vaadin/tests/components/ui/MultiFileUploadTest.java new file mode 100644 index 0000000000..8f3e08335f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/MultiFileUploadTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import java.io.IOException; +import java.io.OutputStream; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Upload; +import com.vaadin.ui.Upload.ChangeEvent; +import com.vaadin.ui.Upload.ChangeListener; +import com.vaadin.ui.Upload.FailedEvent; +import com.vaadin.ui.Upload.FailedListener; +import com.vaadin.ui.Upload.Receiver; +import com.vaadin.ui.Upload.SucceededEvent; +import com.vaadin.ui.Upload.SucceededListener; +import com.vaadin.ui.VerticalLayout; + +public class MultiFileUploadTest extends AbstractTestUIWithLog { + + private ChangeListener changeListener = new ChangeListener() { + + @Override + public void filenameChanged(ChangeEvent event) { + if (event.getFilename().equals("")) { + removeUpload(event.getSource()); + } else { + addUpload(); + } + + } + }; + private VerticalLayout uploadsLayout = new VerticalLayout(); + + @Override + protected void setup(VaadinRequest request) { + getPage().getStyles().add( + ".v-upload-hidden-button .v-button {display:none};"); + addUpload(); + addComponent(uploadsLayout); + addComponent(new Button("Upload files", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + for (Upload u : getUploads()) { + u.submitUpload(); + } + } + })); + } + + protected Iterable<Upload> getUploads() { + return (Iterable) uploadsLayout; + } + + protected void removeUpload(Upload source) { + uploadsLayout.removeComponent(source); + + } + + protected void addUpload() { + Upload upload = createUpload(); + upload.addSucceededListener(new SucceededListener() { + + @Override + public void uploadSucceeded(SucceededEvent event) { + log("Upload of " + event.getFilename() + " complete"); + uploadsLayout.removeComponent(event.getUpload()); + } + }); + + upload.addFailedListener(new FailedListener() { + @Override + public void uploadFailed(FailedEvent event) { + log("Upload of " + event.getFilename() + " FAILED"); + } + }); + + upload.setReceiver(new Receiver() { + @Override + public OutputStream receiveUpload(String filename, String mimeType) { + return new OutputStream() { + @Override + public void write(int arg0) throws IOException { + + } + }; + } + }); + upload.setStyleName("hidden-button"); + uploadsLayout.addComponent(upload); + + } + + private Upload createUpload() { + Upload upload = new Upload(); + upload.addChangeListener(changeListener); + return upload; + } + + @Override + protected String getTestDescription() { + return "Tests that an Upload change event can be used to create a multiple file upload component"; + } + + @Override + protected Integer getTicketNumber() { + return 13222; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/PollListenerTest.html b/uitest/src/com/vaadin/tests/components/ui/PollListenerTest.html new file mode 100644 index 0000000000..ac39d1f03c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/PollListenerTest.html @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="http://localhost:8888/" /> +<title>PollListenerTest</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">PollListenerTest</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.ui.PollListenerTest?restartApplication</td> + <td></td> +</tr> +<tr> + <td>pause</td> + <td>5000</td> + <td></td> +</tr> +<tr> + <td>verifyTextPresent</td> + <td>PollEvent received</td> + <td></td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/ui/PollListenerTest.java b/uitest/src/com/vaadin/tests/components/ui/PollListenerTest.java new file mode 100644 index 0000000000..0e5ddaab87 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/PollListenerTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.components.ui; + +import com.vaadin.event.UIEvents.PollEvent; +import com.vaadin.event.UIEvents.PollListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; + +public class PollListenerTest extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Label statusLabel = new Label("Default Label"); + addComponent(statusLabel); + + setPollInterval(2000); + addPollListener(new PollListener() { + @Override + public void poll(PollEvent event) { + setPollInterval(-1); + statusLabel.setValue(event.getClass().getSimpleName() + + " received"); + removePollListener(this); + } + }); + } + + @Override + protected String getTestDescription() { + return "Polling should fire a PollEvent on the server-side"; + } + + @Override + protected Integer getTicketNumber() { + return 12466; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TooltipConfiguration.html b/uitest/src/com/vaadin/tests/components/ui/TooltipConfiguration.html index e41cf5e176..338e4a2c5b 100644 --- a/uitest/src/com/vaadin/tests/components/ui/TooltipConfiguration.html +++ b/uitest/src/com/vaadin/tests/components/ui/TooltipConfiguration.html @@ -4,12 +4,12 @@ <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="selenium.base" href="http://localhost:8888/" /> -<title>New Test</title> +<title>TooltipConfiguration</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> +<tr><td rowspan="1" colspan="3">TooltipConfiguration</td></tr> </thead><tbody> <tr> <td>open</td> @@ -43,9 +43,9 @@ <td></td> </tr> <tr> - <td>assertElementNotPresent</td> + <td>assertElementPositionLeft</td> <td>vaadin=runcomvaadintestscomponentsuiTooltipConfiguration::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td></td> + <td>-1000</td> </tr> <!--Long close delay--> <tr> @@ -140,6 +140,7 @@ <td>vaadin=runcomvaadintestscomponentsuiTooltipConfiguration::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> <td>100</td> </tr> + </tbody></table> </body> </html> diff --git a/uitest/src/com/vaadin/tests/components/ui/UIAccess.java b/uitest/src/com/vaadin/tests/components/ui/UIAccess.java deleted file mode 100644 index d036827159..0000000000 --- a/uitest/src/com/vaadin/tests/components/ui/UIAccess.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.vaadin.tests.components.ui; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.locks.ReentrantLock; - -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinService; -import com.vaadin.server.VaadinSession; -import com.vaadin.shared.communication.PushMode; -import com.vaadin.tests.components.AbstractTestUIWithLog; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.UI; -import com.vaadin.util.CurrentInstance; - -public class UIAccess extends AbstractTestUIWithLog { - - private volatile boolean checkCurrentInstancesBeforeResponse = false; - - private Future<Void> checkFromBeforeClientResponse; - - private class CurrentInstanceTestType { - private String value; - - public CurrentInstanceTestType(String value) { - this.value = value; - } - - @Override - public String toString() { - return value; - } - } - - @Override - protected void setup(VaadinRequest request) { - addComponent(new Button("Access from UI thread", - new Button.ClickListener() { - - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - // Ensure beforeClientResponse is invoked - markAsDirty(); - checkFromBeforeClientResponse = access(new Runnable() { - @Override - public void run() { - log("Access from UI thread is run"); - } - }); - log("Access from UI thread future is done? " - + checkFromBeforeClientResponse.isDone()); - } - })); - addComponent(new Button("Access from background thread", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - final CountDownLatch latch = new CountDownLatch(1); - - new Thread() { - @Override - public void run() { - final boolean threadHasCurrentResponse = VaadinService - .getCurrentResponse() != null; - // session is locked by request thread at this - // point - final Future<Void> initialFuture = access(new Runnable() { - @Override - public void run() { - log("Initial background message"); - log("Thread has current response? " - + threadHasCurrentResponse); - } - }); - - // Let request thread continue - latch.countDown(); - - // Wait until thread can be locked - while (!getSession().getLockInstance() - .tryLock()) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - try { - log("Thread got lock, inital future done? " - + initialFuture.isDone()); - setPollInterval(-1); - } finally { - getSession().unlock(); - } - } - }.start(); - - // Wait for thread to do initialize before continuing - try { - latch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - setPollInterval(3000); - } - })); - addComponent(new Button("Access throwing exception", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - final Future<Void> firstFuture = access(new Runnable() { - @Override - public void run() { - log("Throwing exception in access"); - throw new RuntimeException( - "Catch me if you can"); - } - }); - access(new Runnable() { - @Override - public void run() { - log("firstFuture is done? " - + firstFuture.isDone()); - try { - firstFuture.get(); - log("Should not get here"); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - log("Got exception from firstFuture: " - + e.getMessage()); - } - } - }); - } - })); - addComponent(new Button("Cancel future before started", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - Future<Void> future = access(new Runnable() { - @Override - public void run() { - log("Should not get here"); - } - }); - future.cancel(false); - log("future was cancled, should not start"); - } - })); - addComponent(new Button("Cancel running future", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - final ReentrantLock interruptLock = new ReentrantLock(); - - final Future<Void> future = access(new Runnable() { - @Override - public void run() { - log("Waiting for thread to start"); - while (!interruptLock.isLocked()) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - log("Premature interruption"); - throw new RuntimeException(e); - } - } - - log("Thread started, waiting for interruption"); - try { - interruptLock.lockInterruptibly(); - } catch (InterruptedException e) { - log("I was interrupted"); - } - } - }); - - new Thread() { - @Override - public void run() { - interruptLock.lock(); - // Wait until UI thread has started waiting for - // the lock - while (!interruptLock.hasQueuedThreads()) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - future.cancel(true); - } - }.start(); - } - })); - addComponent(new Button("CurrentInstance accessSynchronously values", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - // accessSynchronously should maintain values - CurrentInstance.set(CurrentInstanceTestType.class, - new CurrentInstanceTestType( - "Set before accessSynchronosly")); - accessSynchronously(new Runnable() { - @Override - public void run() { - log.log("accessSynchronously has request? " - + (VaadinService.getCurrentRequest() != null)); - log.log("Test value in accessSynchronously: " - + CurrentInstance - .get(CurrentInstanceTestType.class)); - CurrentInstance.set( - CurrentInstanceTestType.class, - new CurrentInstanceTestType( - "Set in accessSynchronosly")); - } - }); - log.log("has request after accessSynchronously? " - + (VaadinService.getCurrentRequest() != null)); - log("Test value after accessSynchornously: " - + CurrentInstance - .get(CurrentInstanceTestType.class)); - } - })); - addComponent(new Button("CurrentInstance access values", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - // accessSynchronously should maintain values - CurrentInstance - .setInheritable(CurrentInstanceTestType.class, - new CurrentInstanceTestType( - "Set before access")); - access(new Runnable() { - @Override - public void run() { - log.log("access has request? " - + (VaadinService.getCurrentRequest() != null)); - log.log("Test value in access: " - + CurrentInstance - .get(CurrentInstanceTestType.class)); - CurrentInstance.setInheritable( - CurrentInstanceTestType.class, - new CurrentInstanceTestType( - "Set in access")); - } - }); - CurrentInstance.setInheritable( - CurrentInstanceTestType.class, - new CurrentInstanceTestType( - "Set before run pending")); - - getSession().getService().runPendingAccessTasks( - getSession()); - - log.log("has request after access? " - + (VaadinService.getCurrentRequest() != null)); - log("Test value after access: " - + CurrentInstance - .get(CurrentInstanceTestType.class)); - } - })); - - addComponent(new Button("CurrentInstance when pushing", - new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - log.clear(); - if (getPushConfiguration().getPushMode() != PushMode.AUTOMATIC) { - log("Can only test with automatic push enabled"); - return; - } - - final VaadinSession session = getSession(); - new Thread() { - @Override - public void run() { - // Pretend this isn't a Vaadin thread - CurrentInstance.clearAll(); - - /* - * Get explicit lock to ensure the (implicit) - * push does not happen during normal request - * handling. - */ - session.lock(); - try { - access(new Runnable() { - @Override - public void run() { - checkCurrentInstancesBeforeResponse = true; - // Trigger beforeClientResponse - markAsDirty(); - } - }); - } finally { - session.unlock(); - } - } - }.start(); - } - })); - } - - @Override - public void beforeClientResponse(boolean initial) { - if (checkFromBeforeClientResponse != null) { - log("beforeClientResponse future is done? " - + checkFromBeforeClientResponse.isDone()); - checkFromBeforeClientResponse = null; - } - if (checkCurrentInstancesBeforeResponse) { - UI currentUI = UI.getCurrent(); - VaadinSession currentSession = VaadinSession.getCurrent(); - - log("Current UI matches in beforeResponse? " + (currentUI == this)); - log("Current session matches in beforeResponse? " - + (currentSession == getSession())); - checkCurrentInstancesBeforeResponse = false; - } - } - - @Override - protected String getTestDescription() { - return "Test for various ways of using UI.access"; - } - - @Override - protected Integer getTicketNumber() { - return Integer.valueOf(11897); - } - -} diff --git a/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html b/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html index b5326e4660..acbe30c5d2 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html +++ b/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html @@ -43,7 +43,7 @@ </tr> <tr> <td>assertText</td> - <td>//div[@id='runcomvaadintestscomponentsuitestUIScrollTest-1797389287-overlays']/div</td> + <td>//div[@id='runcomvaadintestscomponentsuitestUIScrollTest-1797389287-overlays']//h1</td> <td>Scrolled to 1020 px</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/uitest/base_theme_test.html b/uitest/src/com/vaadin/tests/components/uitest/base_theme_test.html index 614ae7bcda..cdbcf8bacc 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/base_theme_test.html +++ b/uitest/src/com/vaadin/tests/components/uitest/base_theme_test.html @@ -289,7 +289,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,8</td> </tr> <tr> @@ -304,7 +304,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,6</td> </tr> <tr> @@ -319,7 +319,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>8,5</td> </tr> <tr> @@ -334,7 +334,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,6</td> </tr> <tr> @@ -349,7 +349,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>10,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/uitest/chameleon_theme_test.html b/uitest/src/com/vaadin/tests/components/uitest/chameleon_theme_test.html index 7d9ffc65b8..d5d70a62d2 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/chameleon_theme_test.html +++ b/uitest/src/com/vaadin/tests/components/uitest/chameleon_theme_test.html @@ -289,7 +289,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,8</td> </tr> <tr> @@ -304,7 +304,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,6</td> </tr> <tr> @@ -319,7 +319,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>8,5</td> </tr> <tr> @@ -334,7 +334,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,6</td> </tr> <tr> @@ -349,7 +349,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>10,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/uitest/liferay_theme_test.html b/uitest/src/com/vaadin/tests/components/uitest/liferay_theme_test.html index d0ee96c7ef..783784e993 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/liferay_theme_test.html +++ b/uitest/src/com/vaadin/tests/components/uitest/liferay_theme_test.html @@ -289,7 +289,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,8</td> </tr> <tr> @@ -304,7 +304,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,6</td> </tr> <tr> @@ -319,7 +319,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>8,5</td> </tr> <tr> @@ -334,7 +334,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,6</td> </tr> <tr> @@ -349,7 +349,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>10,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/uitest/reindeer_theme_test.html b/uitest/src/com/vaadin/tests/components/uitest/reindeer_theme_test.html index a330f5bf61..175def94d3 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/reindeer_theme_test.html +++ b/uitest/src/com/vaadin/tests/components/uitest/reindeer_theme_test.html @@ -289,7 +289,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,8</td> </tr> <tr> @@ -304,7 +304,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,6</td> </tr> <tr> @@ -319,7 +319,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>8,5</td> </tr> <tr> @@ -334,7 +334,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,6</td> </tr> <tr> @@ -349,7 +349,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>10,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/uitest/runo_theme_test.html b/uitest/src/com/vaadin/tests/components/uitest/runo_theme_test.html index 61ba58a0e6..0db6614a9c 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/runo_theme_test.html +++ b/uitest/src/com/vaadin/tests/components/uitest/runo_theme_test.html @@ -289,7 +289,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,8</td> </tr> <tr> @@ -304,7 +304,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,6</td> </tr> <tr> @@ -319,7 +319,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>8,5</td> </tr> <tr> @@ -334,7 +334,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>9,6</td> </tr> <tr> @@ -349,7 +349,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runThemeTestUI::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>10,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/window/CloseSubWindow.html b/uitest/src/com/vaadin/tests/components/window/CloseSubWindow.html index ac81dfdefb..ae77628bff 100644 --- a/uitest/src/com/vaadin/tests/components/window/CloseSubWindow.html +++ b/uitest/src/com/vaadin/tests/components/window/CloseSubWindow.html @@ -40,7 +40,7 @@ <!--Click close in title bar--> <tr> <td>click</td> - <td>vaadin=runcomvaadintestscomponentswindowCloseSubWindow::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentswindowCloseSubWindow::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td></td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/window/ExtraWindowShownWaiAria.html b/uitest/src/com/vaadin/tests/components/window/ExtraWindowShownWaiAria.html new file mode 100644 index 0000000000..f5f89d13ef --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/ExtraWindowShownWaiAria.html @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>ExtraWindowShownWaiAria</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">ExtraWindowShownWaiAria</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.window.ExtraWindowShownWaiAria?restartApplication</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementPresent</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/</td> + <td></td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/@role</td> + <td>dialog</td> +</tr> +<tr> + <td>storeAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]@id</td> + <td>headerid</td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/@aria-labelledby</td> + <td>${headerid}</td> +</tr> +<tr> + <td>storeAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/FocusableScrollPanel[0]/VCssLayout[0]/VLabel[0]@id</td> + <td>descriptionid</td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/@aria-describedby</td> + <td>${descriptionid}</td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]@role</td> + <td>button</td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]@role</td> + <td>button</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/FocusableScrollPanel[0]/VCssLayout[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[3]/VCheckBox[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>storeAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/FocusableScrollPanel[0]/VCssLayout[0]/VLabel[0]@id</td> + <td>descriptionid</td> +</tr> +<tr> + <td>storeAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/FocusableScrollPanel[0]/VCssLayout[0]/VLabel[1]@id</td> + <td>description2id</td> +</tr> +<tr> + <td>assertAttribute</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/@aria-describedby</td> + <td>${descriptionid} ${description2id}</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/FocusableScrollPanel[0]/VCssLayout[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertElementNotPresent</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VWindow[0]/</td> + <td></td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[6]/VTextField[0]</td> + <td>Important</td> +</tr> +<tr> + <td>type</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[7]/VTextField[0]</td> + <td> - do ASAP</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentswindowExtraWindowShownWaiAria::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>xpath=//div[@class='v-window-header']/span[@class='v-assistive-device-only'][1]</td> + <td>Important</td> +</tr> +<tr> + <td>assertText</td> + <td>xpath=//div[@class='v-window-header']/span[@class='v-assistive-device-only'][2]</td> + <td>- do ASAP</td> +</tr> +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/window/ExtraWindowShownWaiAria.java b/uitest/src/com/vaadin/tests/components/window/ExtraWindowShownWaiAria.java new file mode 100644 index 0000000000..39989926e7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/ExtraWindowShownWaiAria.java @@ -0,0 +1,172 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.server.ThemeResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.window.WindowState.WindowRole; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; +import com.vaadin.ui.Window; + +public class ExtraWindowShownWaiAria extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final CheckBox modal = new CheckBox("Modal dialog"); + modal.setTabIndex(7); + final CheckBox additionalDescription = new CheckBox( + "Additional Description"); + final CheckBox tabStop = new CheckBox( + "Prevent leaving window with Tab key"); + final CheckBox tabOrder = new CheckBox("Change Taborder"); + final TextField prefix = new TextField("Prefix: "); + final TextField postfix = new TextField("Postfix: "); + + final TextField topTabStopMessage = new TextField( + "Top Tab Stop Message"); + final TextField bottomTabStopMessage = new TextField( + "Bottom Tab Stop Message"); + + Button simple = new Button("Open Alert Dialog", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + CssLayout layout = new CssLayout(); + + final Window w = new Window("Sub window", layout); + w.center(); + w.setModal(modal.getValue()); + w.setAssistiveRole(WindowRole.ALERTDIALOG); + w.setAssistivePrefix(prefix.getValue()); + w.setAssistivePostfix(postfix.getValue()); + + Label description1 = new Label("Simple alert dialog."); + layout.addComponent(description1); + + if (!additionalDescription.getValue()) { + w.setAssistiveDescription(description1); + } else { + Label description2 = new Label( + "Please select what to do!"); + layout.addComponent(description2); + + w.setAssistiveDescription(description1, + description2); + } + + w.setTabStopEnabled(tabStop.getValue()); + w.setTabStopTopAssistiveText(topTabStopMessage + .getValue()); + w.setTabStopBottomAssistiveText(bottomTabStopMessage + .getValue()); + + Button close = new Button("Close", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + w.close(); + } + }); + layout.addComponent(close); + Button iconButton = new Button("A button with icon"); + iconButton.setIcon(new ThemeResource( + "../runo/icons/16/ok.png")); + layout.addComponent(iconButton); + + event.getButton().getUI().addWindow(w); + iconButton.focus(); + + if (tabOrder.getValue()) { + close.setTabIndex(5); + } + } + + }); + getLayout().addComponent(simple); + + Button complex = new Button("Open Entry Dialog", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + FormLayout form = new FormLayout(); + + final Window w = new Window("Form Window", form); + w.center(); + w.setModal(modal.getValue()); + w.setAssistivePrefix(prefix.getValue()); + w.setAssistivePostfix(postfix.getValue()); + + Label description1 = new Label( + "Please fill in your data"); + form.addComponent(description1); + + if (!additionalDescription.getValue()) { + w.setAssistiveDescription(description1); + } else { + Label description2 = new Label( + "and press the button save."); + form.addComponent(description2); + + w.setAssistiveDescription(description1, + description2); + } + + w.setTabStopEnabled(tabStop.getValue()); + w.setTabStopTopAssistiveText(topTabStopMessage + .getValue()); + w.setTabStopBottomAssistiveText(bottomTabStopMessage + .getValue()); + + TextField name = new TextField("Name:"); + form.addComponent(name); + + form.addComponent(new TextField("Address")); + + Button saveButton = new Button("Save", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + w.close(); + } + }); + form.addComponent(saveButton); + + event.getButton().getUI().addWindow(w); + name.focus(); + + if (tabOrder.getValue()) { + name.setTabIndex(5); + } + } + }); + getLayout().addComponent(complex); + + getLayout().addComponent(modal); + getLayout().addComponent(additionalDescription); + getLayout().addComponent(tabStop); + getLayout().addComponent(tabOrder); + + getLayout().addComponent(prefix); + getLayout().addComponent(postfix); + + getLayout().addComponent(topTabStopMessage); + getLayout().addComponent(bottomTabStopMessage); + + } + + @Override + protected String getTestDescription() { + return "Test for WAI-ARIA implementation"; + } + + @Override + protected Integer getTicketNumber() { + return 11821; + } +} diff --git a/uitest/src/com/vaadin/tests/components/window/SubWindowOrder.html b/uitest/src/com/vaadin/tests/components/window/SubWindowOrder.html index 8374a90b52..6fd99caa19 100644 --- a/uitest/src/com/vaadin/tests/components/window/SubWindowOrder.html +++ b/uitest/src/com/vaadin/tests/components/window/SubWindowOrder.html @@ -90,7 +90,7 @@ <!--Close window 4, which is the topmost window--> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowSubWindowOrder::/VWindow[3]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentswindowSubWindowOrder::/VWindow[3]/domChild[0]/domChild[0]/domChild[3]</td> <td>11,15</td> </tr> <tr> @@ -101,7 +101,7 @@ <!--Close Dialog 3 (topmost)--> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowSubWindowOrder::/VWindow[2]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentswindowSubWindowOrder::/VWindow[2]/domChild[0]/domChild[0]/domChild[3]</td> <td>6,8</td> </tr> <!--Make Dialog 5 (topmost) non-modal--> @@ -139,7 +139,7 @@ <!--Close dialog 5--> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowSubWindowOrder::/VWindow[2]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentswindowSubWindowOrder::/VWindow[2]/domChild[0]/domChild[0]/domChild[3]</td> <td>10,5</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html deleted file mode 100644 index 63e371e379..0000000000 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>TooltipInWindow</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">TooltipInWindow</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.window.TooltipInWindow?restartApplication</td> - <td></td> -</tr> -<!--Show tooltip in Root--> -<tr> - <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::/VVerticalLayout[0]/VVerticalLayout[0]/VTextField[0]</td> - <td>5,5</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>My tooltip</td> -</tr> -<!--Hide the tooltip--> -<tr> - <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::/VVerticalLayout[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]</td> - <td></td> -</tr> -<!--Show tooltip in Window--> -<tr> - <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/VTextField[0]</td> - <td>5,5</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td>My tooltip</td> -</tr> -<!-- Hide tooltip in Window --> -<tr> - <td>showTooltip</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]</td> - <td>0,0</td> -</tr> -<tr> - <td>pause</td> - <td>1000</td> - <td></td> -</tr> -<tr> - <td>assertElementNotPresent</td> - <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td> - <td></td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java index d3c7a616cd..02ec0c047b 100644 --- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java +++ b/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java @@ -31,15 +31,16 @@ public class TooltipInWindow extends AbstractTestUI { Window window = new Window("Window", layout); layout.setSizeUndefined(); window.center(); - layout.addComponent(createTextField()); + layout.addComponent(createTextField("tf1")); addWindow(window); - addComponent(createTextField()); + addComponent(createTextField("tf2")); } - private TextField createTextField() { + private TextField createTextField(String id) { TextField tf = new TextField("TextField with a tooltip"); tf.setDescription("My tooltip"); + tf.setId(id); return tf; } diff --git a/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java new file mode 100644 index 0000000000..0e11041e3b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.window; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.HasInputDevices; +import org.openqa.selenium.interactions.Mouse; +import org.openqa.selenium.interactions.internal.Coordinates; +import org.openqa.selenium.internal.Locatable; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class TooltipInWindowTest extends MultiBrowserTest { + + @Test + public void testTooltipsInSubWindow() throws Exception { + openTestURL(); + + WebElement textfield = vaadinElementById("tf1"); + Coordinates textfieldCoordinates = ((Locatable) textfield) + .getCoordinates(); + + Mouse mouse = ((HasInputDevices) getDriver()).getMouse(); + + // Show tooltip + mouse.mouseMove(textfieldCoordinates, 10, 10); + sleep(1000); + + ensureVisibleTooltipPositionedCorrectly(); + assertEquals("My tooltip", getTooltipElement().getText()); + + // Hide tooltip + mouse.mouseMove(textfieldCoordinates, -100, -100); + sleep(1000); + + ensureHiddenTooltipPositionedCorrectly(); + assertEquals("", getTooltipElement().getText()); + + // Show tooltip again + mouse.mouseMove(textfieldCoordinates, 10, 10); + sleep(1000); + + ensureVisibleTooltipPositionedCorrectly(); + assertEquals("My tooltip", getTooltipElement().getText()); + + // Hide tooltip + mouse.mouseMove(textfieldCoordinates, -100, -100); + sleep(1000); + + ensureHiddenTooltipPositionedCorrectly(); + assertEquals("", getTooltipElement().getText()); + } + + private WebElement getTooltipElement() { + return getDriver().findElement(By.className("v-tooltip-text")); + } + + private WebElement getTooltipContainerElement() { + return getDriver().findElement(By.className("v-tooltip")); + } + + private void ensureVisibleTooltipPositionedCorrectly() { + WebElement textfield = vaadinElementById("tf1"); + int tooltipX = getTooltipContainerElement().getLocation().getX(); + int textfieldX = textfield.getLocation().getX(); + assertGreaterOrEqual("Tooltip should be positioned on the textfield (" + + tooltipX + " < " + textfieldX + ")", tooltipX, textfieldX); + } + + private void ensureHiddenTooltipPositionedCorrectly() { + int tooltipX = getTooltipContainerElement().getLocation().getX(); + assertLessThanOrEqual( + "Tooltip should be positioned outside of viewport (was at " + + tooltipX + ")", tooltipX, -1000); + } +} diff --git a/uitest/src/com/vaadin/tests/components/window/WindowCaptionTest.html b/uitest/src/com/vaadin/tests/components/window/WindowCaptionTest.html index a9a6fd621e..85ab67e4f6 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowCaptionTest.html +++ b/uitest/src/com/vaadin/tests/components/window/WindowCaptionTest.html @@ -3,7 +3,6 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://arturwin.office.itmill.com:8888/" /> <title>New Test</title> </head> <body> @@ -18,7 +17,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowTest::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowTest::PID_StestComponent/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td>Short</td> </tr> <tr> @@ -43,7 +42,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowTest::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowTest::PID_StestComponent/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td>This is a semi-long text that might wrap.</td> </tr> <tr> @@ -68,7 +67,7 @@ </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowTest::PID_StestComponent/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowTest::PID_StestComponent/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td></td> </tr> diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html b/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html index dcdfa05687..a27963a066 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html +++ b/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html @@ -3,7 +3,6 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8888/run/" /> <title>WindowMaximizeRestoreTest</title> </head> <body> @@ -19,59 +18,59 @@ <!--Test maximize-restore button--> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-maximizebox</td> </tr> <tr> <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td>Window 1</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>7,8</td> </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-restorebox</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>9,7</td> </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-maximizebox</td> </tr> <!--test double click on header--> <tr> <td>doubleClickAt</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td></td> </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-restorebox</td> </tr> <tr> <td>doubleClickAt</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td></td> </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-maximizebox</td> </tr> <!--Resizable = false should hide max-restore button--> <tr> <td>assertVisible</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td></td> </tr> <tr> @@ -81,7 +80,7 @@ </tr> <tr> <td>assertNotVisible</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td></td> </tr> <!--Test server side max-restore--> @@ -92,7 +91,7 @@ </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-restorebox</td> </tr> <tr> @@ -102,28 +101,28 @@ </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-maximizebox</td> </tr> <!--test double click on header doesn't work--> <tr> <td>doubleClickAt</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td></td> </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-maximizebox</td> </tr> <tr> <td>doubleClickAt</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td></td> </tr> <tr> <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>v-window-maximizebox</td> </tr> <tr> @@ -149,7 +148,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>10,8</td> </tr> <tr> @@ -175,7 +174,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[2]</td> <td>6,11</td> </tr> <tr> @@ -185,7 +184,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[3]</td> <td>7,5</td> </tr> <tr> @@ -210,12 +209,12 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[2]</td> <td>6,11</td> </tr> <tr> <td>doubleClickAt</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td>113,10</td> </tr> <tr> @@ -226,27 +225,27 @@ <!--Test that size and position is preserved when maximizing and restoring--> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>8,4</td> </tr> <tr> <td>dragAndDrop</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]/domChild[0]</td> <td>-200,-200</td> </tr> <tr> <td>dragAndDrop</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[4]/domChild[0]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[5]/domChild[0]</td> <td>+100,+100</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>6,5</td> </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> <td>5,8</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/components/window/WindowWithInvalidCloseListener.html b/uitest/src/com/vaadin/tests/components/window/WindowWithInvalidCloseListener.html index fa63e5e1e6..3ea1f8f732 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowWithInvalidCloseListener.html +++ b/uitest/src/com/vaadin/tests/components/window/WindowWithInvalidCloseListener.html @@ -18,7 +18,7 @@ </tr> <tr> <td>mouseClick</td> - <td>vaadin=runcomvaadintestscomponentswindowWindowWithInvalidCloseListener::/VWindow[0]/domChild[0]/domChild[0]/domChild[2]</td> + <td>vaadin=runcomvaadintestscomponentswindowWindowWithInvalidCloseListener::/VWindow[0]/domChild[0]/domChild[0]/domChild[3]</td> <td>6,7</td> </tr> <tr> diff --git a/uitest/src/com/vaadin/tests/fieldgroup/CommitHandlerFailures.html b/uitest/src/com/vaadin/tests/fieldgroup/CommitHandlerFailures.html index f0fe883d57..aaaa0a6625 100644 --- a/uitest/src/com/vaadin/tests/fieldgroup/CommitHandlerFailures.html +++ b/uitest/src/com/vaadin/tests/fieldgroup/CommitHandlerFailures.html @@ -1,220 +1,215 @@ -package com.vaadin.tests.fieldgroup; +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.fieldgroup.BasicPersonForm?restartApplication</td> + <td></td> +</tr> +<!--assert we are starting with what we think we are starting with--> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VTextField[0]</td> + <td>John</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> + <td>Doe</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> + <td>john@doe.com</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> + <td>64</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> + <td>v-selected</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]</td> + <td>v-selected</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VTextField[0]</td> + <td>NAAAAAH</td> +</tr> +<!--Make changes to fields--> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> + <td>Doeve</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VTextField[0]</td> + <td>Mike</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> + <td>me@me.com</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> + <td>12</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td> + <td>31,10</td> +</tr> +<!--show bean values--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>1. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> +<!--pre commit fails--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]</td> + <td>35,6</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>2. Commit failed: Commit failed</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>3. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> +<!--post commit fails--> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]</td> + <td>10,7</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VCheckBox[0]/domChild[0]</td> + <td>9,7</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>4. Commit failed: Commit failed</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>5. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> +<!--discard and ensure old values are returned as all commits have failed--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[9]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VTextField[0]</td> + <td>John</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> + <td>Doe</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> + <td>john@doe.com</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> + <td>64</td> +</tr> +<tr> + <td>assertCSSClass</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> + <td>v-selected</td> +</tr> +<tr> + <td>assertNotCSSClass</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]</td> + <td>v-selected</td> +</tr> +<tr> + <td>assertValue</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VTextField[0]</td> + <td>NAAAAAH</td> +</tr> +<!--show bean values--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>7. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> -public class CommitHandlerFailures_html { - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head profile="http://selenium-ide.openqa.org/profiles/test-case"> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <link rel="selenium.base" href="" /> - <title>New Test</title> - </head> - <body> - <table cellpadding="1" cellspacing="1" border="1"> - <thead> - <tr><td rowspan="1" colspan="3">New Test</td></tr> - </thead><tbody> - <tr> - <td>open</td> - <td>/run/com.vaadin.tests.fieldgroup.BasicPersonForm?restartApplication</td> - <td></td> - </tr> - <!--assert we are starting with what we think we are starting with--> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VTextField[0]</td> - <td>John</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> - <td>Doe</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> - <td>john@doe.com</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> - <td>64</td> - </tr> - <tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>v-selected</td> - </tr> - <tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]</td> - <td>v-selected</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VTextField[0]</td> - <td>NAAAAAH</td> - </tr> - <!--Make changes to fields--> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> - <td>Doeve</td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VTextField[0]</td> - <td>Mike</td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> - <td>me@me.com</td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> - <td>12</td> - </tr> - <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]</td> - <td>31,10</td> - </tr> - <!--show bean values--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>1. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - <!--pre commit fails--> - <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]</td> - <td>35,6</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> - <td>0,0</td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>2. Commit failed: Commit failed</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>3. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - <!--post commit fails--> - <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VCheckBox[0]/domChild[0]</td> - <td>10,7</td> - </tr> - <tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VPanel[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VCheckBox[0]/domChild[0]</td> - <td>9,7</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> - <td>0,0</td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>4. Commit failed: Commit failed</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>5. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - <!--discard and ensure old values are returned as all commits have failed--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[9]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VTextField[0]</td> - <td>John</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> - <td>Doe</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VTextField[0]</td> - <td>john@doe.com</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> - <td>64</td> - </tr> - <tr> - <td>assertCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]</td> - <td>v-selected</td> - </tr> - <tr> - <td>assertNotCSSClass</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VScrollTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]</td> - <td>v-selected</td> - </tr> - <tr> - <td>assertValue</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VTextField[0]</td> - <td>NAAAAAH</td> - </tr> - <!--show bean values--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>7. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - - </tbody></table> - </body> - </html> - -} +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/fieldgroup/CommitWithValidationOrConversionError.html b/uitest/src/com/vaadin/tests/fieldgroup/CommitWithValidationOrConversionError.html index e32633513b..8681c6485e 100644 --- a/uitest/src/com/vaadin/tests/fieldgroup/CommitWithValidationOrConversionError.html +++ b/uitest/src/com/vaadin/tests/fieldgroup/CommitWithValidationOrConversionError.html @@ -1,150 +1,148 @@ - <?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> - <head profile="http://selenium-ide.openqa.org/profiles/test-case"> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <link rel="selenium.base" href="" /> - <title>New Test</title> - </head> - <body> - <table cellpadding="1" cellspacing="1" border="1"> - <thead> - <tr><td rowspan="1" colspan="3">New Test</td></tr> - </thead><tbody> - <tr> - <td>open</td> - <td>/run/com.vaadin.tests.fieldgroup.BasicPersonForm?restartApplication</td> - <td></td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> - <td>Doev</td> - </tr> - <!--commit with invalid field must fail--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> - <td>0,0</td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>1. Commit failed: Commit failed</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>2. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> - <td>64,2</td> - </tr> - <!--commit with 2 fails--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> - <td>0,0</td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>3. Commit failed: Commit failed</td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> - <td>Doever</td> - </tr> - <!--1 error fixed, still 1 conversion error--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> - <td>0,0</td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>4. Commit failed: Commit failed</td> - </tr> - <tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> - <td>123</td> - </tr> - <!--all fields ok, commit should be ok--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>closeNotification</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> - <td>0,0</td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>5. Commit succesful</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>6. Person [firstName=John, lastName=Doever, email=john@doe.com, age=123, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - <!--discard should now have no effect--> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[9]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>7. Discarded changes</td> - </tr> - <tr> - <td>click</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]</td> - <td></td> - </tr> - <tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> - <td>8. Person [firstName=John, lastName=Doever, email=john@doe.com, age=123, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> - </tr> - - </tbody></table> - </body> - </html> - -} +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head profile="http://selenium-ide.openqa.org/profiles/test-case"> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> +<link rel="selenium.base" href="" /> +<title>New Test</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">New Test</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.fieldgroup.BasicPersonForm?restartApplication</td> + <td></td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> + <td>Doev</td> +</tr> +<!--commit with invalid field must fail--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>1. Commit failed: Commit failed</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>2. Person [firstName=John, lastName=Doe, email=john@doe.com, age=64, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> + <td>64,2</td> +</tr> +<!--commit with 2 fails--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>3. Commit failed: Commit failed</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTextArea[0]</td> + <td>Doever</td> +</tr> +<!--1 error fixed, still 1 conversion error--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>4. Commit failed: Commit failed</td> +</tr> +<tr> + <td>enterCharacter</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> + <td>123</td> +</tr> +<!--all fields ok, commit should be ok--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[8]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>closeNotification</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VNotification[0]</td> + <td>0,0</td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>5. Commit succesful</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>6. Person [firstName=John, lastName=Doever, email=john@doe.com, age=123, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> +<!--discard should now have no effect--> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[9]/VButton[0]/domChild[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>7. Discarded changes</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[10]/VButton[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>assertText</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::PID_SLog_row_0</td> + <td>8. Person [firstName=John, lastName=Doever, email=john@doe.com, age=123, sex=Male, address=Address [streetAddress=John street, postalCode=11223, city=John's town, country=USA], deceased=false, salary=null, salaryDouble=null, rent=null]</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java b/uitest/src/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java index 4f83f5d0fd..2c202af02b 100644 --- a/uitest/src/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java +++ b/uitest/src/com/vaadin/tests/fieldgroup/FieldBinderWithBeanValidation.java @@ -7,7 +7,6 @@ import com.vaadin.data.util.BeanItem; import com.vaadin.tests.components.TestBase; import com.vaadin.tests.data.bean.Address; import com.vaadin.tests.data.bean.Country; -import com.vaadin.tests.data.bean.Person; import com.vaadin.tests.data.bean.PersonWithBeanValidationAnnotations; import com.vaadin.tests.data.bean.Sex; import com.vaadin.tests.util.Log; @@ -90,8 +89,10 @@ public class FieldBinderWithBeanValidation extends TestBase { p)); } - public static Person getPerson(FieldGroup binder) { - return ((BeanItem<Person>) binder.getItemDataSource()).getBean(); + public static PersonWithBeanValidationAnnotations getPerson( + FieldGroup binder) { + return ((BeanItem<PersonWithBeanValidationAnnotations>) binder + .getItemDataSource()).getBean(); } @Override diff --git a/uitest/src/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html b/uitest/src/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html index 57b267530c..48d48ede80 100644 --- a/uitest/src/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html +++ b/uitest/src/com/vaadin/tests/fieldgroup/IntegerRangeValidator.html @@ -4,12 +4,12 @@ <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="selenium.base" href="" /> -<title>New Test</title> +<title>IntegerRangeValidator</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> +<tr><td rowspan="1" colspan="3">IntegerRangeValidator</td></tr> </thead><tbody> <tr> <td>open</td> @@ -82,12 +82,7 @@ </tr> <tr> <td>showTooltip</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td> - <td></td> -</tr> -<tr> - <td>waitForElementPresent</td> - <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::Root/VTooltip[0]</td> + <td>vaadin=runcomvaadintestsfieldgroupBasicPersonForm::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VTextField[0]</td> <td></td> </tr> <tr> @@ -98,4 +93,3 @@ </tbody></table> </body> </html> - diff --git a/uitest/src/com/vaadin/tests/fonticon/FontIcons.java b/uitest/src/com/vaadin/tests/fonticon/FontIcons.java new file mode 100644 index 0000000000..5511acf3bf --- /dev/null +++ b/uitest/src/com/vaadin/tests/fonticon/FontIcons.java @@ -0,0 +1,226 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.fonticon; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.server.FontAwesome; +import com.vaadin.server.FontIcon; +import com.vaadin.server.Page; +import com.vaadin.server.Resource; +import com.vaadin.server.ThemeResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.Position; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.AbstractSelect; +import com.vaadin.ui.Accordion; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; +import com.vaadin.ui.DateField; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Link; +import com.vaadin.ui.ListSelect; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.Notification; +import com.vaadin.ui.OptionGroup; +import com.vaadin.ui.Panel; +import com.vaadin.ui.Slider; +import com.vaadin.ui.TabSheet; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.Align; +import com.vaadin.ui.Table.RowHeaderMode; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; +import com.vaadin.ui.Tree; +import com.vaadin.ui.TwinColSelect; +import com.vaadin.ui.Upload; +import com.vaadin.ui.VerticalLayout; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class FontIcons extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + buildUI(FontAwesome.ANDROID); + } + + private void buildUI(final Resource icon) { + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setMargin(true); + + layout.setIcon(icon); + + layout.addComponent(new Button("Switch icon type", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + buildUI(icon instanceof FontIcon ? new ThemeResource( + "../runo/icons/16/user.png") + : FontAwesome.ANDROID); + } + })); + + Handler actionHandler = new Handler() { + Action[] actions = { new Action("Do it!", icon) }; + + @Override + public void handleAction(Action action, Object sender, Object target) { + + } + + @Override + public Action[] getActions(Object target, Object sender) { + return actions; + } + }; + + // Notification + Notification n = new Notification("Hey there!"); + n.setIcon(icon); + n.setPosition(Position.BOTTOM_CENTER); + n.setDelayMsec(-1); + n.show(Page.getCurrent()); + + // grid of compoents + GridLayout gl = new GridLayout(4, 5); + gl.setSpacing(true); + layout.addComponent(gl); + + // Basic components, caption icon only + Class<?>[] components = { Button.class, CheckBox.class, + DateField.class, NativeButton.class, Link.class, Label.class, + Panel.class, Slider.class, TextArea.class, TextField.class, + Upload.class }; + for (Class<?> clazz : components) { + Component c; + try { + c = (Component) clazz.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + continue; + } + c.setCaption(clazz.getSimpleName()); + c.setIcon(icon); + gl.addComponent(c); + } + + // TabSheet, caption + tab icons + TabSheet tabs = new TabSheet(); + tabs.setCaption("TabSheet"); + tabs.setIcon(icon); + tabs.addStyleName("myTabs"); + tabs.addTab(new Label("Content 1"), "Tab 1", icon); + tabs.addTab(new Label("Content 2"), "Tab 2", icon); + tabs.setWidth("150px"); + gl.addComponent(tabs); + + // Accordion, caption + tab icons + Accordion acc = new Accordion(); + acc.setCaption("Accordion"); + acc.setIcon(icon); + acc.addTab(new Label(), "Section 1", icon); + acc.addTab(new Label(), "Section 2", icon); + gl.addComponent(acc); + + // Table, caption + column + row + action icons + Table tbl = new Table("Table"); + tbl.setRowHeaderMode(RowHeaderMode.ICON_ONLY); + tbl.setIcon(icon); + tbl.addContainerProperty("Column 1", String.class, "Row", "Column 1", + icon, Align.LEFT); + tbl.addContainerProperty("Column 2", String.class, "Row", "Column 2", + icon, Align.LEFT); + tbl.setItemIcon(tbl.addItem(), icon); + tbl.setItemIcon(tbl.addItem(), icon); + tbl.setItemIcon(tbl.addItem(), icon); + tbl.setPageLength(3); + gl.addComponent(tbl); + tbl.addActionHandler(actionHandler); + + // Selects, caption + item icons + Class<?>[] selects = { ComboBox.class, NativeSelect.class, + ListSelect.class, TwinColSelect.class, OptionGroup.class }; + for (Class<?> clazz : selects) { + AbstractSelect sel; + try { + sel = (AbstractSelect) clazz.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + continue; + } + sel.setCaption(clazz.getSimpleName()); + sel.setIcon(icon); + sel.addItem("One"); + sel.setItemIcon("One", icon); + sel.addItem("Two"); + sel.setItemIcon("Two", icon); + gl.addComponent(sel); + } + + // MenuBar, caption + item + sub-item icons + MenuBar menu = new MenuBar(); + menu.setIcon(icon); + menu.setCaption("MenuBar"); + MenuItem mi = menu.addItem("File", icon, null); + MenuItem smi = mi.addItem("Item", icon, null); + smi = mi.addItem("Item", icon, null); + smi = smi.addItem("Item", icon, null); + gl.addComponent(menu); + + // Tree, caption + item + subitem + action icons + Tree tree = new Tree("Tree"); + tree.addItem("Root"); + tree.setItemIcon("Root", icon); + tree.addItem("Leaf"); + tree.setItemIcon("Leaf", icon); + tree.setParent("Leaf", "Root"); + tree.expandItemsRecursively("Root"); + tree.addActionHandler(actionHandler); + gl.addComponent(tree); + + // All of FontAwesome + String allIcons = ""; + for (FontIcon ic : FontAwesome.values()) { + allIcons += ic.getHtml() + " "; + } + layout.addComponent(new Label(allIcons, ContentMode.HTML)); + } + + @Override + protected String getTestDescription() { + return "Font icons should show up in all the right places"; + } + + @Override + protected Integer getTicketNumber() { + return 13152; + } + +} diff --git a/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java b/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java new file mode 100644 index 0000000000..af54b73ae3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.fonticon; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class FontIconsTest extends MultiBrowserTest { + + @Test + public void checkScreenshot() throws IOException { + openTestURL(); + compareScreen("all"); + } +} diff --git a/uitest/src/com/vaadin/tests/integration/JSPIntegrationTest.java b/uitest/src/com/vaadin/tests/integration/JSPIntegrationTest.java new file mode 100644 index 0000000000..c5d6a65d87 --- /dev/null +++ b/uitest/src/com/vaadin/tests/integration/JSPIntegrationTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.integration; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.PrivateTB3Configuration; + +public class JSPIntegrationTest extends PrivateTB3Configuration { + + final String appRunnerTestUrl = getBaseURL() + "/run/Buttons"; + final String jspUrl = getBaseURL() + "/statictestfiles/vaadinsessions.jsp"; + final String integrationUrl = getBaseURL() + "/integration"; + + @Test + public void listVaadinSessions() { + + assertUICount(0); + + // Open a new UI + getDriver().get(integrationUrl); + assertUICount(1); + + // Open a new UI + getDriver().get(integrationUrl); + + // Should now have two UIs for the same service with different uiIds + List<UIData> twoUIs = getUIs(); + assertEquals(2, twoUIs.size()); + assertNotEquals(twoUIs.get(0).uiId, twoUIs.get(1).uiId); + assertEquals(twoUIs.get(0).serviceName, twoUIs.get(1).serviceName); + + getDriver().get(appRunnerTestUrl); + // Should now have two services with 2 + 1 UIs + List<UIData> threeUIs = getUIs(); + assertEquals(3, threeUIs.size()); + Set<String> serviceNames = new HashSet<String>(); + Set<Integer> uiIds = new HashSet<Integer>(); + for (UIData uiData : threeUIs) { + serviceNames.add(uiData.serviceName); + uiIds.add(uiData.uiId); + } + assertGreaterOrEqual( + "There should be at least two unique service names", + serviceNames.size(), 2); + assertGreaterOrEqual("There should be at least two unique ui ids", + uiIds.size(), 2); + } + + private static class UIData { + private String serviceName; + private int uiId; + } + + private List<UIData> getUIs() { + List<UIData> uis = new ArrayList<UIData>(); + + getDriver().get(jspUrl); + List<WebElement> rows = getDriver().findElements( + By.xpath("//tr[@class='uirow']")); + for (WebElement row : rows) { + UIData data = new UIData(); + List<WebElement> tds = row.findElements(By.xpath("./td")); + + data.serviceName = tds.get(0).getText(); + data.uiId = Integer.parseInt(tds.get(2).getText()); + + uis.add(data); + } + + return uis; + } + + private void assertUICount(int i) { + assertEquals(i, getUIs().size()); + } +} diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationLongPollingUI.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationLongPollingUI.java new file mode 100644 index 0000000000..f96000f1ce --- /dev/null +++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationLongPollingUI.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.integration; + +import com.vaadin.annotations.Push; +import com.vaadin.shared.ui.ui.Transport; + +/** + * Server test which uses long polling + * + * @since 7.1 + * @author Vaadin Ltd + */ +@Push(transport = Transport.LONG_POLLING) +public class ServletIntegrationLongPollingUI extends ServletIntegrationUI { + +} diff --git a/uitest/src/com/vaadin/tests/integration/ServletIntegrationLongPollingUITest.java b/uitest/src/com/vaadin/tests/integration/ServletIntegrationLongPollingUITest.java new file mode 100644 index 0000000000..70ca890b31 --- /dev/null +++ b/uitest/src/com/vaadin/tests/integration/ServletIntegrationLongPollingUITest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.integration; + +public class ServletIntegrationLongPollingUITest extends + AbstractServletIntegrationTest { + // Uses the test method declared in the super class +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/minitutorials/v7a1/FormatTableValue.java b/uitest/src/com/vaadin/tests/minitutorials/v7a1/FormatTableValue.java index be2768a5f7..8485bba499 100644 --- a/uitest/src/com/vaadin/tests/minitutorials/v7a1/FormatTableValue.java +++ b/uitest/src/com/vaadin/tests/minitutorials/v7a1/FormatTableValue.java @@ -3,7 +3,7 @@ package com.vaadin.tests.minitutorials.v7a1; import java.text.NumberFormat; import java.util.Locale; -import com.vaadin.data.util.converter.StringToNumberConverter; +import com.vaadin.data.util.converter.StringToDoubleConverter; import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.ui.Table; @@ -30,14 +30,14 @@ public class FormatTableValue extends AbstractTestUI { table.getItem(itemId).getItemProperty(DEFAULT_PROPERTY) .setValue(3.1415); - table.setConverter(PERCENT_PROPERTY, new StringToNumberConverter() { + table.setConverter(PERCENT_PROPERTY, new StringToDoubleConverter() { @Override protected NumberFormat getFormat(Locale locale) { return NumberFormat.getPercentInstance(locale); } }); - table.setConverter(CURRENCY_PROPERTY, new StringToNumberConverter() { + table.setConverter(CURRENCY_PROPERTY, new StringToDoubleConverter() { @Override protected NumberFormat getFormat(Locale locale) { return NumberFormat.getCurrencyInstance(locale); diff --git a/uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java b/uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java new file mode 100644 index 0000000000..bbb7895f20 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.LONG_POLLING) +public class BasicPushLongPolling extends BasicPush { + + @Override + public void init(VaadinRequest request) { + super.init(request); + // Don't use fallback so we can easier detect if long polling fails + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java b/uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java new file mode 100644 index 0000000000..b526a11d38 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java @@ -0,0 +1,19 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +public class BasicPushLongPollingTest extends BasicPushTest { +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeLongPolling.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeLongPolling.java new file mode 100644 index 0000000000..7c0899c481 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeLongPolling.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.LONG_POLLING) +public class ExtremelyLongPushTimeLongPolling extends ExtremelyLongPushTime { + + @Override + public void init(VaadinRequest request) { + super.init(request); + // Don't use fallback so we can easier detect failures + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } +} diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeLongPollingTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeLongPollingTest.java new file mode 100644 index 0000000000..eb28634dfa --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeLongPollingTest.java @@ -0,0 +1,21 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +public class ExtremelyLongPushTimeLongPollingTest extends + ExtremelyLongPushTimeTest { + +} diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelLongPollingTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelLongPollingTest.java new file mode 100644 index 0000000000..5a90c4333d --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelLongPollingTest.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +public class IdlePushChannelLongPollingTest extends IdlePushChannelTest { + @Override + protected Class<?> getUIClass() { + return BasicPushLongPolling.class; + } +} diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java index a8ea9d0010..d7ffb47bbc 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java @@ -93,6 +93,38 @@ public class PushConfigurationTest extends WebsocketTest { } + @Test + public void testLongPolling() throws InterruptedException { + setDebug(true); + openTestURL(); + verifyPushDisabled(); + new Select(getTransportSelect()).selectByVisibleText("LONG_POLLING"); + new Select(getPushModeSelect()).selectByVisibleText("AUTOMATIC"); + Assert.assertTrue(vaadinElement( + "/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[0]/VVerticalLayout[0]/Slot[5]/VLabel[0]/domChild[0]") + .getText() + .matches( + "^[\\s\\S]*fallbackTransport: streaming[\\s\\S]*transport: long-polling[\\s\\S]*$")); + int counter = getServerCounter(); + final int waitCounter = counter + 2; + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + return (getServerCounter() >= waitCounter); + } + }); + + // Use debug console to verify we used the correct transport type + Assert.assertTrue(driver.getPageSource().contains( + "Push connection established using long-polling")); + Assert.assertFalse(driver.getPageSource().contains( + "Push connection established using streaming")); + + new Select(getPushModeSelect()).selectByVisibleText("DISABLED"); + + } + /** * Verifies that push is currently not enabled. * diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java new file mode 100644 index 0000000000..52a647115a --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +import com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.shared.ui.ui.UIState.PushConfigurationState; + +@Push(transport = Transport.LONG_POLLING) +public class PushLargeDataLongPolling extends PushLargeData { + + @Override + protected void setup(VaadinRequest request) { + super.setup(request); + getPushConfiguration().setParameter( + PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none"); + } +} diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java new file mode 100644 index 0000000000..534c5287bb --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class PushLargeDataLongPollingTest extends MultiBrowserTest { + + @Test + public void testLongPollingLargeData() throws Exception { + openTestURL(); + + // Without this there is a large chance that we will wait for all pushes + // to complete before moving on + testBench(driver).disableWaitForVaadin(); + + push(); + // Push complete. Browser will reconnect now as > 10MB has been sent + // Push again to ensure push still works + push(); + + } + + private void push() throws InterruptedException { + // Wait for startButton to be present + waitForElementToBePresent(vaadinLocatorById("startButton")); + + String logRow0Id = "Log_row_0"; + By logRow0 = vaadinLocatorById(logRow0Id); + + vaadinElementById("startButton").click(); + // Wait for push to start + waitUntil(ExpectedConditions.textToBePresentInElement(logRow0, + "Package ")); + + // Wait for until push should be done + sleep(PushLargeData.DEFAULT_DURATION_MS); + + // Wait until push is actually done + waitUntil(ExpectedConditions.textToBePresentInElement(logRow0, + "Push complete")); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java b/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java new file mode 100644 index 0000000000..6d0c0c53b0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/ReconnectLongPollingTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +public class ReconnectLongPollingTest extends ReconnectTest { + + @Override + protected Class<?> getUIClass() { + return BasicPushLongPolling.class; + } + +} diff --git a/uitest/src/com/vaadin/tests/push/StreamingReconnectTest.java b/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java index 24dfdd8ba1..ebacf5be37 100755 --- a/uitest/src/com/vaadin/tests/push/StreamingReconnectTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectStreamingTest.java @@ -15,7 +15,7 @@ */ package com.vaadin.tests.push; -public class StreamingReconnectTest extends PushReconnectTest { +public class ReconnectStreamingTest extends ReconnectTest { @Override protected Class<?> getUIClass() { diff --git a/uitest/src/com/vaadin/tests/push/PushReconnectTest.java b/uitest/src/com/vaadin/tests/push/ReconnectTest.java index 76a0b547da..69b2ccf22b 100644 --- a/uitest/src/com/vaadin/tests/push/PushReconnectTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectTest.java @@ -23,7 +23,7 @@ import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.tests.tb3.MultiBrowserTestWithProxy; -public abstract class PushReconnectTest extends MultiBrowserTestWithProxy { +public abstract class ReconnectTest extends MultiBrowserTestWithProxy { @Test public void testShortDisconnect() throws Exception { @@ -152,7 +152,7 @@ public abstract class PushReconnectTest extends MultiBrowserTestWithProxy { @Override public Boolean apply(WebDriver input) { - return BasicPushTest.getServerCounter(PushReconnectTest.this) > counter; + return BasicPushTest.getServerCounter(ReconnectTest.this) > counter; } }, 30); } diff --git a/uitest/src/com/vaadin/tests/push/WebsocketReconnectTest.java b/uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java index 075a18c0e7..57fe0a040d 100644 --- a/uitest/src/com/vaadin/tests/push/WebsocketReconnectTest.java +++ b/uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java @@ -21,7 +21,7 @@ import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.tests.tb3.WebsocketTest; -public class WebsocketReconnectTest extends PushReconnectTest { +public class ReconnectWebsocketTest extends ReconnectTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { diff --git a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java index f904675b5e..2fc868d4ed 100644 --- a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java +++ b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java @@ -24,7 +24,7 @@ public class TrackMessageSizeUITest extends MultiBrowserTest { @Test public void runTests() { openTestURL(); - Assert.assertEquals("1. All tests run", - vaadinElementById("Log_row_0").getText()); + Assert.assertEquals("1. All tests run", vaadinElementById("Log_row_0") + .getText()); } }
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/serialization/GenericWidgetHandling.java b/uitest/src/com/vaadin/tests/serialization/GenericWidgetHandling.java new file mode 100644 index 0000000000..dca96a46ea --- /dev/null +++ b/uitest/src/com/vaadin/tests/serialization/GenericWidgetHandling.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.serialization; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.server.GenericWidgetComponent; + +@Widgetset(TestingWidgetSet.NAME) +public class GenericWidgetHandling extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final GenericWidgetComponent component = new GenericWidgetComponent(); + component.setId("label"); + component.setGenericText("The generic text is strong in this one"); + addComponent(component); + } + + @Override + protected String getTestDescription() { + return "Tests that a connector works even if its widget is of a generic type"; + } + + @Override + protected Integer getTicketNumber() { + // Also 12900 if someone happens to care + return Integer.valueOf(12873); + } + +} diff --git a/uitest/src/com/vaadin/tests/serialization/GenericWidgetHandlingTest.java b/uitest/src/com/vaadin/tests/serialization/GenericWidgetHandlingTest.java new file mode 100644 index 0000000000..a6ff0c4459 --- /dev/null +++ b/uitest/src/com/vaadin/tests/serialization/GenericWidgetHandlingTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.serialization; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GenericWidgetHandlingTest extends MultiBrowserTest { + + @Test + public void testWidgetInit() { + openTestURL(); + WebElement label = vaadinElementById("label"); + + Assert.assertEquals("The generic text is strong in this one", + label.getText()); + } + +} diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTest.html b/uitest/src/com/vaadin/tests/serialization/SerializerTest.html deleted file mode 100644 index 63219de5c2..0000000000 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTest.html +++ /dev/null @@ -1,116 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8888/" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.serialization.SerializerTest?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[18]</td> - <td>sendBeanSubclass: 43</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[17]</td> - <td>sendBoolean: false, false, [false, false, true, false, true, true]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[16]</td> - <td>sendByte: 5, -12, [3, 1, 2]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[15]</td> - <td>sendChar: Å, ∫, [a, b, c, d]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[14]</td> - <td>sendInt: 2, 5, [2147483647, 0]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[13]</td> - <td>sendLong: -57841235865, 577431841358, [57, 0]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[12]</td> - <td>sendFloat: 1.0000001, 3.14159, [-12.0, 0.0, 57.0]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[11]</td> - <td>sendDouble: 0.423310825130748, 5.859874482048838, [2.0, 1.7976931348623157E308, 4.9E-324]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[10]</td> - <td>sendString: Taegghiiiinnrsssstt‡</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[9]</td> - <td>sendConnector: com.vaadin.tests.widgetset.server.SerializerTestExtension</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[8]</td> - <td>sendBean: ComplexTestBean [innerBean1=SimpleTestBean(1), innerBean2=SimpleTestBean(3), innerBeanCollection=[SimpleTestBean(6), SimpleTestBean(0)], privimite=6], SimpleTestBean(0), [SimpleTestBean(7)]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[7]</td> - <td>sendNull: null, Not null</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[6]</td> - <td>sendNestedArray: [[7, 5]], [[SimpleTestBean(2)], [SimpleTestBean(4)]]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[5]</td> - <td>sendList: [-234, 5, 8], class com.vaadin.tests.widgetset.server.SerializerTestExtension, class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(-568), SimpleTestBean(234)]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[4]</td> - <td>sendArrayList: [[2], [2]], [[2, 1], [2, 3]], [[SimpleTestBean(7)]]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[3]</td> - <td>sendSet: [-12, -7, -4], class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(2), SimpleTestBean(3)]</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[2]</td> - <td>sendMap: {a=SimpleTestBean(1)}, [com.vaadin.tests.widgetset.server.SerializerTestExtension=SimpleTestBean(4)], [2=com.vaadin.tests.widgetset.server.SerializerTestExtension], {SimpleTestBean(4)=SimpleTestBean(-4), SimpleTestBean(-5)=SimpleTestBean(5)}</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[1]</td> - <td>sendWrappedGenerics: {[SimpleTestBean(1)]={1=[SimpleTestBean(42)]}}</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsserializationSerializerTest::/VVerticalLayout[0]/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]</td> - <td>sendEnum: PREFORMATTED, [HTML, RAW], [PREFORMATTED, XML]</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java index 0561f73b21..d4849ce667 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java @@ -16,15 +16,19 @@ package com.vaadin.tests.serialization; +import java.text.DateFormat; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TimeZone; import com.vaadin.annotations.Widgetset; import com.vaadin.server.VaadinRequest; @@ -137,6 +141,8 @@ public class SerializerTest extends AbstractTestUI { ContentMode.PREFORMATTED, ContentMode.XML }, Arrays.asList(ContentMode.HTML, ContentMode.RAW)); + rpc.sendDate(new Date(1)); + rpc.sendDate(new Date(2013 - 1900, 5 - 1, 31, 11, 12, 13)); testExtension.registerRpc(new SerializerTestRpc() { @Override public void sendBoolean(boolean value, Boolean boxedValue, @@ -316,6 +322,15 @@ public class SerializerTest extends AbstractTestUI { log.log("sendBeanSubclass: " + bean.getValue()); } + @Override + public void sendDate(Date date) { + DateFormat format = DateFormat.getDateTimeInstance( + DateFormat.LONG, DateFormat.FULL, + new Locale("en", "fi")); + format.setTimeZone(TimeZone.getTimeZone("UTC")); + log.log("sendDate: " + format.format(date)); + } + }); } diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java new file mode 100644 index 0000000000..d093a30ea7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.serialization; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class SerializerTestTest extends MultiBrowserTest { + + @Test + public void testSerialization() { + openTestURL(); + int logRow = 0; + + Assert.assertEquals("sendDate: May 31, 2013 8:12:13 AM UTC", + getLogRow(logRow++)); + Assert.assertEquals("sendDate: January 1, 1970 12:00:00 AM UTC", + getLogRow(logRow++)); + Assert.assertEquals( + "sendEnum: PREFORMATTED, [HTML, RAW], [PREFORMATTED, XML]", + getLogRow(logRow++)); + Assert.assertEquals( + "sendWrappedGenerics: {[SimpleTestBean(1)]={1=[SimpleTestBean(42)]}}", + getLogRow(logRow++)); + Assert.assertEquals( + "sendMap: {a=SimpleTestBean(1)}, [com.vaadin.tests.widgetset.server.SerializerTestExtension=SimpleTestBean(4)], [2=com.vaadin.tests.widgetset.server.SerializerTestExtension], {SimpleTestBean(4)=SimpleTestBean(-4), SimpleTestBean(-5)=SimpleTestBean(5)}", + getLogRow(logRow++)); + Assert.assertEquals( + "sendSet: [-12, -7, -4], class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(2), SimpleTestBean(3)]", + getLogRow(logRow++)); + Assert.assertEquals( + "sendArrayList: [[2], [2]], [[2, 1], [2, 3]], [[SimpleTestBean(7)]]", + getLogRow(logRow++)); + Assert.assertEquals( + "sendList: [-234, 5, 8], class com.vaadin.tests.widgetset.server.SerializerTestExtension, class com.vaadin.tests.serialization.SerializerTest, [SimpleTestBean(-568), SimpleTestBean(234)]", + getLogRow(logRow++)); + Assert.assertEquals( + "sendNestedArray: [[7, 5]], [[SimpleTestBean(2)], [SimpleTestBean(4)]]", + getLogRow(logRow++)); + Assert.assertEquals("sendNull: null, Not null", getLogRow(logRow++)); + Assert.assertEquals( + "sendBean: ComplexTestBean [innerBean1=SimpleTestBean(1), innerBean2=SimpleTestBean(3), innerBeanCollection=[SimpleTestBean(6), SimpleTestBean(0)], privimite=6], SimpleTestBean(0), [SimpleTestBean(7)]", + getLogRow(logRow++)); + Assert.assertEquals( + "sendConnector: com.vaadin.tests.widgetset.server.SerializerTestExtension", + getLogRow(logRow++)); + Assert.assertEquals("sendString: Taegghiiiinnrsssstt‡", + getLogRow(logRow++)); + Assert.assertEquals( + "sendDouble: 0.423310825130748, 5.859874482048838, [2.0, 1.7976931348623157E308, 4.9E-324]", + getLogRow(logRow++)); + Assert.assertEquals( + "sendFloat: 1.0000001, 3.14159, [-12.0, 0.0, 57.0]", + getLogRow(logRow++)); + Assert.assertEquals("sendLong: -57841235865, 577431841358, [57, 0]", + getLogRow(logRow++)); + Assert.assertEquals("sendInt: 2, 5, [2147483647, 0]", + getLogRow(logRow++)); + Assert.assertEquals("sendChar: Å, ∫, [a, b, c, d]", getLogRow(logRow++)); + Assert.assertEquals("sendByte: 5, -12, [3, 1, 2]", getLogRow(logRow++)); + Assert.assertEquals( + "sendBoolean: false, false, [false, false, true, false, true, true]", + getLogRow(logRow++)); + Assert.assertEquals("sendBeanSubclass: 43", getLogRow(logRow++)); + } +} diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java index 400a2fe429..a00ff7ab4d 100644 --- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java +++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java @@ -125,7 +125,8 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { || nwInterface.isVirtual()) { continue; } - Enumeration<InetAddress> addresses = nwInterface.getInetAddresses(); + Enumeration<InetAddress> addresses = nwInterface + .getInetAddresses(); while (addresses.hasMoreElements()) { InetAddress address = addresses.nextElement(); if (address.isLoopbackAddress()) { diff --git a/uitest/src/com/vaadin/tests/util/TestUtils.java b/uitest/src/com/vaadin/tests/util/TestUtils.java index 5c6315a23a..dcd28c3413 100644 --- a/uitest/src/com/vaadin/tests/util/TestUtils.java +++ b/uitest/src/com/vaadin/tests/util/TestUtils.java @@ -99,22 +99,13 @@ public class TestUtils { "YE", "ZAMBIA", "ZM", "ZIMBABWE", "ZW" }; /** - * Crossbrowser hack to dynamically add css current window. Can be used to - * keep tests css in source files. + * Injects css into the current window. Can be used to keep tests css in + * source files. * * @param cssString */ public static void injectCSS(UI w, String cssString) { - String script = "if ('\\v'=='v') /* ie only */ {\n" - + " document.createStyleSheet().cssText = '" - + cssString - + "';\n" - + " } else {var tag = document.createElement('style'); tag.type = 'text/css';" - + " document.getElementsByTagName('head')[0].appendChild(tag);tag[ (typeof " - + "document.body.style.WebkitAppearance=='string') /* webkit only */ ? 'innerText' " - + ": 'innerHTML'] = '" + cssString + "';}"; - - w.getPage().getJavaScript().execute(script); + w.getPage().getStyles().add(cssString); } public static void installPerformanceReporting(TextArea targetTextArea) { diff --git a/uitest/src/com/vaadin/tests/widgetset/client/GenericWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/GenericWidget.java new file mode 100644 index 0000000000..bf191d1e87 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/GenericWidget.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client; + +import com.google.gwt.user.client.ui.Label; + +public class GenericWidget<T> extends Label { + public void setGenericText(T value) { + setText(String.valueOf(value)); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/GenericWidgetConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/GenericWidgetConnector.java new file mode 100644 index 0000000000..a05bedfa27 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/GenericWidgetConnector.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client; + +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.GenericWidgetComponent; + +@Connect(GenericWidgetComponent.class) +public class GenericWidgetConnector extends AbstractComponentConnector { + @Override + public GenericWidget<String> getWidget() { + return (GenericWidget<String>) super.getWidget(); + } + + @Override + public GenericWidgetState getState() { + return (GenericWidgetState) super.getState(); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/GenericWidgetState.java b/uitest/src/com/vaadin/tests/widgetset/client/GenericWidgetState.java new file mode 100644 index 0000000000..79dce8de9f --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/GenericWidgetState.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client; + +import com.vaadin.shared.AbstractComponentState; +import com.vaadin.shared.annotations.DelegateToWidget; + +public class GenericWidgetState extends AbstractComponentState { + @DelegateToWidget + public String genericText; +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java index 0f6ad577ed..01ec6cc4bb 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java @@ -19,6 +19,7 @@ package com.vaadin.tests.widgetset.client; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -251,6 +252,11 @@ public class SerializerTestConnector extends AbstractExtensionConnector { } }); } + + @Override + public void sendDate(Date date) { + rpc.sendDate(date); + } }); } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java index 4bda067242..fb5b6a1980 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java @@ -16,6 +16,7 @@ package com.vaadin.tests.widgetset.client; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -79,4 +80,5 @@ public interface SerializerTestRpc extends ServerRpc, ClientRpc { public void sendBeanSubclass(SimpleTestBean bean); + public void sendDate(Date date); } diff --git a/uitest/src/com/vaadin/tests/widgetset/server/GenericWidgetComponent.java b/uitest/src/com/vaadin/tests/widgetset/server/GenericWidgetComponent.java new file mode 100644 index 0000000000..2be59ee96b --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/GenericWidgetComponent.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.tests.widgetset.client.GenericWidgetState; +import com.vaadin.ui.AbstractComponent; + +public class GenericWidgetComponent extends AbstractComponent { + + @Override + protected GenericWidgetState getState() { + return (GenericWidgetState) super.getState(); + } + + public void setGenericText(String genericText) { + getState().genericText = genericText; + } +} |