summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2014-02-12 15:49:31 +0200
committerLeif Åstrand <leif@vaadin.com>2014-02-12 15:49:49 +0200
commit42f2387165471d08bbd24d4c3ae4a271d2cda4c5 (patch)
tree4418a7610edf326d308f65ee0d79d4d09c341a93
parent50381a619458017d69b044435a22fae457a5d4c1 (diff)
parent40e07d0172532ebf5750b8c2aab5ec892e42cdab (diff)
downloadvaadin-framework-42f2387165471d08bbd24d4c3ae4a271d2cda4c5.tar.gz
vaadin-framework-42f2387165471d08bbd24d4c3ae4a271d2cda4c5.zip
Merge remote-tracking branch 'origin/master' into grid
Change-Id: I8f1f412eeb450688bba58b715eba6db9e4ae43ae
-rw-r--r--WebContent/VAADIN/themes/base/base.scss5
-rw-r--r--WebContent/VAADIN/themes/base/common/common.scss4
-rw-r--r--WebContent/VAADIN/themes/base/debug/debug.scss8
-rw-r--r--WebContent/VAADIN/themes/chameleon/components/textfield/textfield.scss7
-rw-r--r--WebContent/WEB-INF/web.xml15
-rw-r--r--WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html69
-rw-r--r--WebContent/statictestfiles/vaadinsessions.jsp54
-rw-r--r--all/build.xml3
-rw-r--r--all/javadoc.css236
-rw-r--r--build.xml1
-rw-r--r--buildhelpers/src/com/vaadin/buildhelpers/FetchReleaseNotesTickets.java1
-rw-r--r--client-compiler/ivy.xml45
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java288
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ConnectorBundle.java100
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/metadata/FieldProperty.java19
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/metadata/MethodProperty.java78
-rw-r--r--client-compiler/src/com/vaadin/server/widgetsetutils/metadata/Property.java24
-rwxr-xr-xclient/src/com/vaadin/DefaultWidgetSet.gwt.xml4
-rw-r--r--client/src/com/vaadin/Vaadin.gwt.xml1
-rw-r--r--client/src/com/vaadin/client/ApplicationConfiguration.java27
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java139
-rw-r--r--client/src/com/vaadin/client/ComponentLocator.java700
-rw-r--r--client/src/com/vaadin/client/ConnectorMap.java2
-rw-r--r--client/src/com/vaadin/client/Profiler.java4
-rw-r--r--client/src/com/vaadin/client/SimpleTree.java8
-rw-r--r--client/src/com/vaadin/client/Util.java3
-rw-r--r--client/src/com/vaadin/client/communication/AtmospherePushConnection.java12
-rw-r--r--client/src/com/vaadin/client/communication/Date_Serializer.java44
-rw-r--r--client/src/com/vaadin/client/communication/Heartbeat.java171
-rw-r--r--client/src/com/vaadin/client/communication/JSONSerializer.java7
-rw-r--r--client/src/com/vaadin/client/componentlocator/ComponentLocator.java220
-rw-r--r--client/src/com/vaadin/client/componentlocator/LegacyLocatorStrategy.java719
-rw-r--r--client/src/com/vaadin/client/componentlocator/LocatorStrategy.java122
-rw-r--r--client/src/com/vaadin/client/componentlocator/LocatorUtil.java76
-rw-r--r--client/src/com/vaadin/client/componentlocator/SelectorPredicate.java228
-rw-r--r--client/src/com/vaadin/client/componentlocator/VaadinFinderLocatorStrategy.java748
-rw-r--r--client/src/com/vaadin/client/debug/internal/AnalyzeLayoutsPanel.java267
-rw-r--r--client/src/com/vaadin/client/debug/internal/ConnectorInfoPanel.java107
-rw-r--r--client/src/com/vaadin/client/debug/internal/HierarchyPanel.java178
-rw-r--r--client/src/com/vaadin/client/debug/internal/HierarchySection.java474
-rw-r--r--client/src/com/vaadin/client/debug/internal/Highlight.java58
-rw-r--r--client/src/com/vaadin/client/debug/internal/Icon.java2
-rw-r--r--client/src/com/vaadin/client/debug/internal/OptimizedWidgetsetPanel.java137
-rw-r--r--client/src/com/vaadin/client/debug/internal/SelectConnectorListener.java37
-rw-r--r--client/src/com/vaadin/client/debug/internal/SelectorPath.java238
-rw-r--r--client/src/com/vaadin/client/debug/internal/TestBenchSection.java281
-rw-r--r--client/src/com/vaadin/client/metadata/ConnectorBundleLoader.java8
-rw-r--r--client/src/com/vaadin/client/metadata/Property.java8
-rw-r--r--client/src/com/vaadin/client/metadata/TypeDataStore.java183
-rw-r--r--client/src/com/vaadin/client/ui/SubPartAware.java4
-rw-r--r--client/src/com/vaadin/client/ui/UnknownComponentConnector.java6
-rw-r--r--client/src/com/vaadin/client/ui/VAccordion.java1
-rw-r--r--client/src/com/vaadin/client/ui/VCalendarPanel.java11
-rw-r--r--client/src/com/vaadin/client/ui/VFilterSelect.java4
-rw-r--r--client/src/com/vaadin/client/ui/VLabel.java8
-rw-r--r--client/src/com/vaadin/client/ui/VOverlay.java4
-rw-r--r--client/src/com/vaadin/client/ui/VPanel.java1
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java164
-rw-r--r--client/src/com/vaadin/client/ui/VTabsheet.java51
-rw-r--r--client/src/com/vaadin/client/ui/VTreeTable.java2
-rw-r--r--client/src/com/vaadin/client/ui/VUpload.java7
-rw-r--r--client/src/com/vaadin/client/ui/VWindow.java7
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java8
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/DayToolbar.java2
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/MonthGrid.java1
-rw-r--r--client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java1
-rw-r--r--client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java52
-rw-r--r--client/src/com/vaadin/client/ui/dd/VIsOverId.java3
-rw-r--r--client/src/com/vaadin/client/ui/dd/VItemIdIs.java2
-rw-r--r--client/src/com/vaadin/client/ui/label/LabelConnector.java6
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/Slot.java51
-rw-r--r--client/src/com/vaadin/client/ui/table/TableConnector.java6
-rw-r--r--client/src/com/vaadin/client/ui/tree/TreeConnector.java20
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java2
-rw-r--r--client/src/com/vaadin/client/ui/upload/UploadConnector.java14
-rw-r--r--common.xml6
-rw-r--r--eclipse/Development Server (vaadin).launch7
-rw-r--r--publish.xml32
-rw-r--r--push/build.xml2
-rw-r--r--push/ivy.xml4
-rw-r--r--server/src/com/vaadin/data/Buffered.java58
-rw-r--r--server/src/com/vaadin/data/fieldgroup/FieldGroup.java6
-rw-r--r--server/src/com/vaadin/data/util/filter/Between.java4
-rw-r--r--server/src/com/vaadin/data/util/filter/Compare.java3
-rw-r--r--server/src/com/vaadin/data/util/filter/IsNull.java4
-rw-r--r--server/src/com/vaadin/data/util/filter/Like.java4
-rw-r--r--server/src/com/vaadin/data/util/filter/SimpleStringFilter.java3
-rw-r--r--server/src/com/vaadin/event/EventRouter.java39
-rw-r--r--server/src/com/vaadin/server/Constants.java2
-rw-r--r--server/src/com/vaadin/server/JsonCodec.java15
-rw-r--r--server/src/com/vaadin/server/LegacyCommunicationManager.java2
-rw-r--r--server/src/com/vaadin/server/VaadinPortlet.java1
-rw-r--r--server/src/com/vaadin/server/VaadinService.java15
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java29
-rw-r--r--server/src/com/vaadin/server/communication/AtmospherePushConnection.java146
-rw-r--r--server/src/com/vaadin/server/communication/DateSerializer.java42
-rw-r--r--server/src/com/vaadin/server/communication/JSONSerializer.java72
-rw-r--r--server/src/com/vaadin/server/communication/PushConnection.java14
-rw-r--r--server/src/com/vaadin/server/communication/PushHandler.java52
-rw-r--r--server/src/com/vaadin/server/communication/PushRequestHandler.java14
-rw-r--r--server/src/com/vaadin/server/communication/ServerRpcHandler.java4
-rw-r--r--server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java75
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java30
-rw-r--r--server/src/com/vaadin/ui/AbstractField.java21
-rw-r--r--server/src/com/vaadin/ui/AbstractSelect.java31
-rw-r--r--server/src/com/vaadin/ui/Calendar.java4
-rw-r--r--server/src/com/vaadin/ui/ComboBox.java2
-rw-r--r--server/src/com/vaadin/ui/FormLayout.java19
-rw-r--r--server/src/com/vaadin/ui/Label.java4
-rw-r--r--server/src/com/vaadin/ui/PushConfiguration.java42
-rw-r--r--server/src/com/vaadin/ui/Table.java1
-rw-r--r--server/src/com/vaadin/ui/UI.java83
-rw-r--r--server/src/com/vaadin/ui/Upload.java14
-rw-r--r--server/tests/src/com/vaadin/data/util/TestIndexedContainer.java2
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/SQLContainerTest.java5
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/TicketTests.java1
-rw-r--r--server/tests/src/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java44
-rw-r--r--server/tests/src/com/vaadin/tests/event/EventRouterTest.java111
-rw-r--r--server/tests/src/com/vaadin/tests/server/TestClassesSerializable.java3
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java15
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/abstractselect/TestVarargsItemAddition.java26
-rw-r--r--shared/src/com/vaadin/shared/communication/PushConstants.java5
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/Transport.java6
-rw-r--r--shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java26
-rw-r--r--theme-compiler/build.xml4
-rw-r--r--theme-compiler/src/com/vaadin/sass/CustomConsoleHandler.java52
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java17
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluator.java7
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/expression/exception/ArithmeticException.java20
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandler.java6
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandlerImpl.java43
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/handler/SCSSErrorHandler.java36
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/LexicalUnitImpl.java87
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/LocatorImpl.java29
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java15052
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj249
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java2
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/SCSSLexicalUnit.java2
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/AbsFunctionGenerator.java39
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/CeilFunctionGenerator.java39
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/DarkenFunctionGenerator.java38
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/DefaultFunctionGenerator.java45
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/FloorFunctionGenerator.java40
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/LightenFunctionGenerator.java38
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/RoundFunctionGenerator.java39
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/parser/function/SCSSFunctionGenerator.java54
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/selector/SelectorUtil.java13
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/tree/BlockNode.java5
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/tree/ExtendNode.java5
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/tree/MixinNode.java5
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java15
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/tree/controldirective/IfElseDefNode.java6
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/util/DeepCopy.java12
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java8
-rw-r--r--theme-compiler/src/com/vaadin/sass/internal/visitor/VariableNodeHandler.java10
-rw-r--r--theme-compiler/src/logging.properties2
-rw-r--r--theme-compiler/tests/resources/automatic/css/media.css11
-rw-r--r--theme-compiler/tests/resources/automatic/css/variable-defaults-with-null.css5
-rw-r--r--theme-compiler/tests/resources/automatic/scss/media.scss21
-rw-r--r--theme-compiler/tests/resources/automatic/scss/variable-defaults-with-null.scss19
-rw-r--r--theme-compiler/tests/resources/sasslang/css/106-test_pseudoclass_remains_at_end_of_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/106-test_pseudoclass_remains_at_end_of_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/107-test_pseudoelement_goes_lefter_than_not.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/107-test_pseudoelement_goes_lefter_than_not.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/108-test_pseudoelement_goes_lefter_than_pseudoclass.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/108-test_pseudoelement_goes_lefter_than_pseudoclass.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/109-test_pseudoelement_remains_at_end_of_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/109-test_pseudoelement_remains_at_end_of_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/110-test_redundant_selector_elimination.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/110-test_redundant_selector_elimination.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/112-test_target_with_child.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/112-test_target_with_child.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/2-test_basic.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/2-test_basic.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/33-test_extend_redundancy_elimination_never_eliminates_base_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/33-test_extend_redundancy_elimination_never_eliminates_base_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/333-test_empty_content.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/333-test_empty_content.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/350-test_interpolation.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/350-test_interpolation.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/368-test_mixins_with_args.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/368-test_mixins_with_args.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/369-test_mixins_with_empty_args.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/369-test_mixins_with_empty_args.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/390-test_parent_selector_with_parent_and_subject.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/390-test_parent_selector_with_parent_and_subject.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/420-test_warn_directive.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/420-test_warn_directive.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/55-test_long_extendee.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/55-test_long_extendee.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/63-test_multiple_extendees.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/63-test_multiple_extendees.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/65-test_multiple_extends_with_multiple_extenders_and_single_target.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/65-test_multiple_extends_with_multiple_extenders_and_single_target.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/66-test_multiple_extends_with_single_extender_and_single_target.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/66-test_multiple_extends_with_single_extender_and_single_target.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/67-test_multiple_targets.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/67-test_multiple_targets.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/7-test_combinator_unification_angle_sibling.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/7-test_combinator_unification_angle_sibling.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/70-test_nested_extender.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/70-test_nested_extender.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/80-test_nested_extender_merges_with_same_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/80-test_nested_extender_merges_with_same_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/81-test_nested_extender_runs_unification.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/81-test_nested_extender_runs_unification.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/85-test_nested_extender_with_child_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/85-test_nested_extender_with_child_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/86-test_nested_extender_with_child_selector_merges_with_same_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/86-test_nested_extender_with_child_selector_merges_with_same_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/90-test_nested_extender_with_sibling_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/90-test_nested_extender_with_sibling_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/91-test_nested_selector_with_child_selector_hack_extendee.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/91-test_nested_selector_with_child_selector_hack_extendee.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/96-test_nested_target.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/96-test_nested_target.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/css/98-test_not_remains_at_end_of_selector.css (renamed from theme-compiler/tests/resources/sasslangbroken/css/98-test_not_remains_at_end_of_selector.css)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/106-test_pseudoclass_remains_at_end_of_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/106-test_pseudoclass_remains_at_end_of_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/107-test_pseudoelement_goes_lefter_than_not.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/107-test_pseudoelement_goes_lefter_than_not.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/108-test_pseudoelement_goes_lefter_than_pseudoclass.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/108-test_pseudoelement_goes_lefter_than_pseudoclass.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/109-test_pseudoelement_remains_at_end_of_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/109-test_pseudoelement_remains_at_end_of_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/110-test_redundant_selector_elimination.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/110-test_redundant_selector_elimination.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/112-test_target_with_child.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/112-test_target_with_child.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/2-test_basic.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/2-test_basic.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/33-test_extend_redundancy_elimination_never_eliminates_base_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/33-test_extend_redundancy_elimination_never_eliminates_base_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/333-test_empty_content.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/333-test_empty_content.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/350-test_interpolation.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/350-test_interpolation.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/368-test_mixins_with_args.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/368-test_mixins_with_args.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/369-test_mixins_with_empty_args.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/369-test_mixins_with_empty_args.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/390-test_parent_selector_with_parent_and_subject.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/390-test_parent_selector_with_parent_and_subject.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/420-test_warn_directive.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/420-test_warn_directive.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/55-test_long_extendee.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/55-test_long_extendee.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/63-test_multiple_extendees.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/63-test_multiple_extendees.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/65-test_multiple_extends_with_multiple_extenders_and_single_target.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/65-test_multiple_extends_with_multiple_extenders_and_single_target.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/66-test_multiple_extends_with_single_extender_and_single_target.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/66-test_multiple_extends_with_single_extender_and_single_target.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/67-test_multiple_targets.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/67-test_multiple_targets.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/7-test_combinator_unification_angle_sibling.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/7-test_combinator_unification_angle_sibling.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/70-test_nested_extender.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/70-test_nested_extender.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/80-test_nested_extender_merges_with_same_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/80-test_nested_extender_merges_with_same_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/81-test_nested_extender_runs_unification.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/81-test_nested_extender_runs_unification.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/85-test_nested_extender_with_child_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/85-test_nested_extender_with_child_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/86-test_nested_extender_with_child_selector_merges_with_same_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/86-test_nested_extender_with_child_selector_merges_with_same_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/90-test_nested_extender_with_sibling_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/90-test_nested_extender_with_sibling_selector.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/91-test_nested_selector_with_child_selector_hack_extendee.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/91-test_nested_selector_with_child_selector_hack_extendee.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/96-test_nested_target.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/96-test_nested_target.scss)0
-rw-r--r--theme-compiler/tests/resources/sasslang/scss/98-test_not_remains_at_end_of_selector.scss (renamed from theme-compiler/tests/resources/sasslangbroken/scss/98-test_not_remains_at_end_of_selector.scss)0
-rw-r--r--theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java6
-rw-r--r--theme-compiler/tests/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java12
-rw-r--r--theme-compiler/tests/src/com/vaadin/sass/testcases/css/Media.java1
-rw-r--r--theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java2
-rw-r--r--uitest/ivy.xml5
-rw-r--r--uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java2
-rw-r--r--uitest/src/com/vaadin/launcher/DevelopmentServerLauncher.java1
-rw-r--r--uitest/src/com/vaadin/tests/application/calculator/Calc.java268
-rw-r--r--uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html26
-rw-r--r--uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java49
-rw-r--r--uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java39
-rw-r--r--uitest/src/com/vaadin/tests/componentlocator/TestDetachedNotPresent.html (renamed from uitest/src/com/vaadin/tests/gwtadapter/componentlocator/TestDetachedNotPresent.html)0
-rw-r--r--uitest/src/com/vaadin/tests/components/AbstractTestUI.java34
-rw-r--r--uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java47
-rw-r--r--uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html27
-rw-r--r--uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java42
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java114
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java83
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHover.java46
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHoverTest.java54
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionTooltip.html33
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java63
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java100
-rw-r--r--uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html47
-rw-r--r--uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java75
-rw-r--r--uitest/src/com/vaadin/tests/components/table/ExpandingContainer.java429
-rw-r--r--uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceCondition.java67
-rw-r--r--uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceConditionTest.java90
-rw-r--r--uitest/src/com/vaadin/tests/components/table/SelectAllRows.java83
-rw-r--r--uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java105
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java226
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCallsTest.java55
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java71
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.java61
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediate.java147
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/AutomaticImmediateTest.java109
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogs.java65
-rw-r--r--uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogsTest.java16
-rw-r--r--uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java53
-rw-r--r--uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java69
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetset.java (renamed from uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.java)6
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.java41
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetset.java (renamed from uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset2.java)6
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java42
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html36
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java74
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java85
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/UIAccess.java361
-rw-r--r--uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java83
-rw-r--r--uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java56
-rw-r--r--uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpened.java58
-rw-r--r--uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpenedTest.java47
-rw-r--r--uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java3
-rw-r--r--uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html86
-rw-r--r--uitest/src/com/vaadin/tests/components/window/TooltipInWindow.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/window/TooltipInWindowTest.java98
-rw-r--r--uitest/src/com/vaadin/tests/integration/JSPIntegrationTest.java100
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushLongPolling.java34
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushLongPollingTest.java19
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushTest.java2
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java50
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java33
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.java21
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java67
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java34
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java31
-rw-r--r--uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java23
-rw-r--r--uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java37
-rw-r--r--uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java35
-rw-r--r--uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java25
-rw-r--r--uitest/src/com/vaadin/tests/push/PushFromInit.java53
-rw-r--r--uitest/src/com/vaadin/tests/push/PushFromInitTest.java28
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeData.java12
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataLongPolling.java32
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java61
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java4
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java4
-rw-r--r--uitest/src/com/vaadin/tests/push/TogglePushTest.java4
-rw-r--r--uitest/src/com/vaadin/tests/serialization/SerializerTest.html116
-rw-r--r--uitest/src/com/vaadin/tests/serialization/SerializerTest.java15
-rw-r--r--uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java81
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java60
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java28
-rw-r--r--uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java18
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassConnector.java36
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassWidget.java33
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java6
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java2
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClass.java47
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassComponent.java29
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassTest.java35
315 files changed, 18152 insertions, 10807 deletions
diff --git a/WebContent/VAADIN/themes/base/base.scss b/WebContent/VAADIN/themes/base/base.scss
index 54e0916da1..0e19c8a339 100644
--- a/WebContent/VAADIN/themes/base/base.scss
+++ b/WebContent/VAADIN/themes/base/base.scss
@@ -55,6 +55,11 @@
margin: 0;
overflow: hidden;
}
+
+.v-modal-window-open {
+ overflow: hidden;
+}
+
$font-size: 16px;
$line-height: normal;
@mixin base {
diff --git a/WebContent/VAADIN/themes/base/common/common.scss b/WebContent/VAADIN/themes/base/common/common.scss
index 07e244a76f..5cae1b26ce 100644
--- a/WebContent/VAADIN/themes/base/common/common.scss
+++ b/WebContent/VAADIN/themes/base/common/common.scss
@@ -227,6 +227,10 @@ input::-ms-clear {
font-size: 0;
line-height: normal;
}
+/* Set font-size in order to make Firefox scrolling better #11353 */
+.v-ff & .v-scrollable {
+ font-size: $font-size;
+}
.v-ios.v-webkit & .v-scrollable {
-webkit-overflow-scrolling: touch;
}
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/chameleon/components/textfield/textfield.scss b/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.scss
index 7c5c72c1df..4554672da4 100644
--- a/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.scss
+++ b/WebContent/VAADIN/themes/chameleon/components/textfield/textfield.scss
@@ -20,7 +20,10 @@ textarea.v-textarea,
input.#{$primaryStyleName}[type="text"],
textarea.v-textarea,
.v-filterselect {
- padding: .2em;
+ padding-bottom: .1em;
+ padding-top: .1em;
+ padding-left: .2em;
+ padding-right: .2em;
}
input.#{$primaryStyleName}[type="text"] {
@@ -29,7 +32,7 @@ input.#{$primaryStyleName}[type="text"] {
input.v-widget.#{$primaryStyleName}[type="text"],
.v-filterselect {
- height: 1.6em;
+ height: 1.7em;
}
&.v-app input.#{$primaryStyleName},
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml
index 8a917966a1..f98b7c78d1 100644
--- a/WebContent/WEB-INF/web.xml
+++ b/WebContent/WEB-INF/web.xml
@@ -77,6 +77,16 @@
</servlet>
<servlet>
+ <!--
+ This servlet is a separate instance for the sole purpose of
+ testing #12446 (com.vaadin.tests.components.ui.TimeoutRedirectResetsOnActivity)
+ because it modifies the VaadinService timeout parameters
+ -->
+ <servlet-name>VaadinApplicationRunnerWithTimeoutRedirect</servlet-name>
+ <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
+ </servlet>
+
+ <servlet>
<servlet-name>VaadinApplicationRunnerWithPush</servlet-name>
<servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class>
<init-param>
@@ -117,6 +127,11 @@
</servlet-mapping>
<servlet-mapping>
+ <servlet-name>VaadinApplicationRunnerWithTimeoutRedirect</servlet-name>
+ <url-pattern>/12446/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
<servlet-name>VaadinApplicationRunnerWithPush</servlet-name>
<url-pattern>/run-push/*</url-pattern>
</servlet-mapping>
diff --git a/WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html b/WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html
new file mode 100644
index 0000000000..7547816006
--- /dev/null
+++ b/WebContent/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html
@@ -0,0 +1,69 @@
+<!doctype>
+<html><head>
+ <style>
+ #spacer {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ }
+ #scrollable {
+ background: white;
+ border: 1px solid black;
+ overflow: auto;
+ position: relative;
+ width: 250px;
+ }
+ #container {
+ position:relative;
+ display:inline-block;
+ width:100%;
+ height:130px;
+ }
+ #margin {
+ position: absolute;
+ width: 200px;
+ top: 12px;
+ margin-right: 12px;
+ left: 12px;
+ height: 110px;
+ }
+ </style>
+ </head>
+ <body>
+ <div>
+ Starting point: No horizontal scrollbar<br/>
+ Expected: Get back to starting point after clicking through steps (do 1, do 2, cancel 1, cancel 2)<br/>
+ Actual: Scrollbars after doing the steps<br/><br/>
+ </div>
+<button id="step1" onclick="step1();">Step 1 - Enlarge container</button>
+<button id="step2" onclick="step2();">Step 2 - Move child</button>
+<button id="step3" onclick="step3();">Step 3 - Reduce container</button>
+<button id="step4" onclick="step4();">Step 4 - Return child</button>
+<div id="scrollable">
+<div id="container">
+<div id="margin" style="">
+<div id="spacer" style="height: 100px; width: 100%;">
+</div>
+</div>
+</div>
+</div>
+
+<script>
+function step1() {
+ document.getElementById("container").style.width="110%";
+}
+function step2() {
+ document.getElementById("margin").style.left="200px";
+}
+function step3() {
+ document.getElementById("container").style.width="100%";
+}
+function step4() {
+ document.getElementById("margin").style.left="12px";
+}
+
+</script>
+
+
+</body>
+</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/all/build.xml b/all/build.xml
index 1b48721ecd..36a9499dea 100644
--- a/all/build.xml
+++ b/all/build.xml
@@ -43,7 +43,8 @@
<property name="javadoc.dir" location="${result.dir}/javadoc" />
<property name="title" value="Vaadin ${vaadin.version} API" />
- <javadoc maxmemory="1024m" destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="${title}" encoding="utf-8">
+ <javadoc maxmemory="1024m" destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="${title}" encoding="utf-8"
+ stylesheetfile="javadoc.css">
<packageset dir="${javadoc.temp.dir}">
<!-- TODO Javadoc throws ClassCastException if this is included
(#9660) -->
diff --git a/all/javadoc.css b/all/javadoc.css
new file mode 100644
index 0000000000..ffa7288ad4
--- /dev/null
+++ b/all/javadoc.css
@@ -0,0 +1,236 @@
+@charset "UTF-8";
+
+/*
+ * stylesheet for Vaadin Javadoc when compiled with Java 6
+ */
+body {
+ background-color: rgb(244, 244, 240);
+ color: rgb(70, 68, 64);
+ font-size: 16px;
+ font-family: Helvetica, Arial, sans-serif;
+ font-weight: lighter;
+ line-height: 18px;
+ margin: 10px 14px;
+}
+
+body[onload] {
+ background-color: rgb(255, 255, 255);
+ margin: 8px 23px;
+}
+
+a:link,a:visited {
+ color: rgb(0, 180, 240);
+ text-decoration: none;
+}
+
+b {
+ font-weight: bolder;
+}
+
+code,pre {
+ font-family: Courier, monospace;
+}
+
+dt {
+ font-size: 12px;
+ color: rgb(120, 119, 109);
+ text-transform: uppercase;
+}
+
+dd>dl>dt {
+ font-size: 13px;
+ text-transform: none;
+}
+
+h2+dl>dt {
+ text-transform: none;
+}
+
+dt>pre,pre>dt {
+ text-transform: initial;
+}
+
+dd {
+ font-size: 14px;
+ margin-left: 2.5em;
+}
+
+dd:first-child {
+ font-size: 13px;
+}
+
+dd>dl>dd {
+ font-size: 12px;
+}
+
+h1 {
+ font-size: 32px
+}
+
+h2 {
+ font-size: 24px;
+}
+
+h3 {
+ font-size: 16px;
+}
+
+h1,h2,h3 {
+ line-height: 30px;
+}
+
+hr {
+ border: 1px solid rgb(233, 233, 225);
+}
+
+pre,h2+ul {
+ font-size: 12px;
+}
+
+table {
+ border: none;
+ border-collapse: collapse;
+}
+
+td {
+ padding: 0;
+}
+
+th {
+ padding: 0 1ch;
+}
+
+.TableHeadingColor,.TableSubHeadingColor {
+ line-height: 30px;
+}
+
+.TableHeadingColor>th,.TableHeadingColor>th>font>b,.TableSubHeadingColor>th,.TableSubHeadingColor>th>b
+ {
+ font-weight: inherit;
+}
+
+.TableHeadingColor>th>font {
+ font-size: 18px;
+}
+
+.TableSubHeadingColor {
+ font-size: 14px;
+}
+
+.TableHeadingColor,.TableSubHeadingColor {
+ background: rgb(233, 233, 225);
+}
+
+.TableRowColor {
+ background: #FFFFFF;
+}
+
+.TableRowColor:nth-child(odd) {
+ background-color: rgb(244, 244, 240);
+}
+
+.TableRowColor>td {
+ font-size: 12px;
+ border: none;
+ padding: 1ex 1ch
+}
+
+.TableRowColor>td>font {
+ font-size: 11px;
+}
+
+.TableHeadingColor,.TableRowColor,.TableSubHeadingColor>th {
+ border: none;
+ border-color: transparent;
+}
+
+table[border="1"] {
+ border: 2px solid rgb(233, 233, 225);
+}
+
+.FrameTitleFont {
+ font-size: 18px;
+ font-family: Helvetica, Arial, sans-serif;
+ font-weight: bolder;
+ line-height: 30px;
+}
+
+.FrameHeadingFont {
+ font-size: 12px;
+ font-family: Helvetica, Arial, sans-serif;
+ font-weight: bold;
+ color: rgb(120, 119, 109);
+ text-transform: uppercase;
+ display: inline-block;
+ margin-bottom: 4px;
+}
+
+td>.FrameHeadingFont {
+ margin-top: 12px;
+}
+
+.FrameItemFont {
+ font-size: 90%;
+ font-family: Helvetica, Arial, sans-serif;
+}
+
+.NavBarCell1 {
+ background-color: rgb(245, 245, 241);
+ border: 2px solid rgb(245, 245, 241);
+}
+
+.NavBarCell1+td[rowspan="3"] {
+ display: none;
+}
+
+.NavBarCell1,.NavBarCell1Rev {
+ font-size: 0;
+}
+
+.NavBarCell1>*,.NavBarCell1Rev>* {
+ font-size: 14px;
+}
+
+.NavBarCell1 .NavBarCell1,.NavBarCell1 .NavBarCell1Rev {
+ padding: 3px 8px;
+ line-height: 1;
+ vertical-align: baseline;
+}
+
+.NavBarCell1Rev {
+ background-color: rgb(0, 180, 240);
+ border-radius: 3px;
+}
+
+.NavBarFont1 {
+ font-family: Helvetica, Arial, sans-serif;
+ color: rgb(70, 68, 64);
+}
+
+.NavBarFont1Rev {
+ font-family: Helvetica, Arial, sans-serif;
+ color: rgb(255, 255, 255);
+}
+
+.NavBarCell2 {
+ font-family: Helvetica, Arial, sans-serif;
+ background-color: #FFFFFF;
+ padding-top: 6px;
+}
+
+.NavBarCell2:first-child {
+ color: transparent;
+}
+
+.NavBarCell2>font,.NavBarCell3>font {
+ font-size: 11px;
+}
+
+.NavBarCell2>font>a>b {
+ font-weight: normal;
+}
+
+.NavBarCell3 {
+ font-family: Helvetica, Arial, sans-serif;
+ background-color: #FFFFFF;
+} \ No newline at end of file
diff --git a/build.xml b/build.xml
index bef7f7a2f3..d2e905b611 100644
--- a/build.xml
+++ b/build.xml
@@ -19,6 +19,7 @@
<fileset dir="." includes="**/build.xml">
<exclude name="build.xml" />
<exclude name="build/**" />
+ <exclude name="bin/**" />
<exclude name="buildhelpers/**" />
</fileset>
</ivy:buildlist>
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/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 cbdd3e89aa..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 void setNeedsSuperclass(JClassType typeAsClass) {
+ if (!isNeedsSuperClass(typeAsClass)) {
+ needsSuperClass.add(typeAsClass);
}
}
- private boolean isNeedsGetter(Property property) {
- if (needsGetter.contains(property)) {
+ private boolean isNeedsSuperClass(JClassType typeAsClass) {
+ if (needsSuperClass.contains(typeAsClass)) {
return true;
} else {
return previousBundle != null
- && previousBundle.isNeedsGetter(property);
+ && previousBundle.isNeedsSuperClass(typeAsClass);
}
}
- public Set<Property> getNeedsGetter() {
- return Collections.unmodifiableSet(needsGetter);
+ public Set<JClassType> getNeedsSuperclass() {
+ return Collections.unmodifiableSet(needsSuperClass);
}
- private void setNeedsType(Property property) {
- if (!isNeedsType(property)) {
- needsType.add(property);
+ private void setNeedsProperty(Property property) {
+ if (!isNeedsProperty(property)) {
+ needsProperty.add(property);
}
}
- public Set<Property> getNeedsType() {
- return Collections.unmodifiableSet(needsType);
- }
-
- private boolean isNeedsType(Property property) {
- if (needsType.contains(property)) {
+ private boolean isNeedsProperty(Property property) {
+ if (needsProperty.contains(property)) {
return true;
} else {
return previousBundle != null
- && previousBundle.isNeedsType(property);
+ && previousBundle.isNeedsProperty(property);
}
}
- public void setNeedsSetter(Property property) {
- if (!isNeedsSetter(property)) {
- needsSetter.add(property);
- }
- }
-
- private boolean isNeedsSetter(Property property) {
- if (needsSetter.contains(property)) {
- return true;
- } else {
- return previousBundle != null
- && previousBundle.isNeedsSetter(property);
- }
- }
-
- public Set<Property> getNeedsSetter() {
- return Collections.unmodifiableSet(needsSetter);
- }
-
- private void setNeedsPropertyList(JClassType type) {
- if (!isNeedsPropertyList(type)) {
- needsPropertyList.add(type);
- }
- }
-
- private boolean isNeedsPropertyList(JClassType type) {
- if (needsPropertyList.contains(type)) {
- return true;
- } else {
- return previousBundle != null
- && previousBundle.isNeedsPropertyList(type);
- }
- }
-
- public Set<JClassType> getNeedsPropertyListing() {
- return Collections.unmodifiableSet(needsPropertyList);
+ public Set<Property> getNeedsProperty() {
+ return Collections.unmodifiableSet(needsProperty);
}
public Collection<Property> getProperties(JClassType type) {
@@ -430,11 +392,11 @@ public class ConnectorBundle {
}
private static boolean isClientRpc(JClassType type) {
- return isType(type, ClientRpc.class);
+ return isInterfaceType(type, ClientRpc.class);
}
private static boolean isServerRpc(JClassType type) {
- return isType(type, ServerRpc.class);
+ return isInterfaceType(type, ServerRpc.class);
}
public static boolean isConnectedConnector(JClassType type) {
@@ -451,6 +413,10 @@ public class ConnectorBundle {
return isConnected(type) && isType(type, ComponentConnector.class);
}
+ private static boolean isInterfaceType(JClassType type, Class<?> class1) {
+ return type.isInterface() != null && isType(type, class1);
+ }
+
private static boolean isType(JClassType type, Class<?> class1) {
try {
return type.getOracle().getType(class1.getName())
@@ -619,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 da41543894..b84d8a376f 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
@@ -65,16 +65,17 @@ 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;
@@ -363,7 +364,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
@@ -428,6 +429,8 @@ public class ApplicationConnection {
private VLoadingIndicator loadingIndicator;
+ private Heartbeat heartbeat = GWT.create(Heartbeat.class);
+
public static class MultiStepDuration extends Duration {
private int previousStep = elapsedMillis();
@@ -490,7 +493,7 @@ public class ApplicationConnection {
getLoadingIndicator().show();
- scheduleHeartbeat();
+ heartbeat.init(this);
Window.addWindowClosingHandler(new ClosingHandler() {
@Override
@@ -547,38 +550,47 @@ public class ApplicationConnection {
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()
@@ -1460,6 +1472,9 @@ public class ApplicationConnection {
if (meta.containsKey("timedRedirect")) {
final ValueMap timedRedirect = meta
.getValueMap("timedRedirect");
+ if (redirectTimer != null) {
+ redirectTimer.cancel();
+ }
redirectTimer = new Timer() {
@Override
public void run() {
@@ -3311,20 +3326,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();
}
/**
@@ -3333,51 +3339,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..ef7ccc3b65 100644
--- a/client/src/com/vaadin/client/ComponentLocator.java
+++ b/client/src/com/vaadin/client/ComponentLocator.java
@@ -15,706 +15,20 @@
*/
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.
+ *
+ * @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/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 8972670232..edbb40e86c 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) {
@@ -866,7 +867,7 @@ public class Util {
element = (Element) element.getParentElement();
}
}
- if (eventListener != null) {
+ if (eventListener instanceof Widget) {
/*
* Then find the first widget of type class1 from widget
* hierarchy
diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
index c9b9e46cd5..9eb2b881bb 100644
--- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
+++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java
@@ -344,6 +344,14 @@ public class AtmospherePushConnection implements PushConnection {
state = State.CONNECT_PENDING;
}
+ protected void onClientTimeout(AtmosphereResponse response) {
+ state = State.DISCONNECTED;
+ errorHandler
+ .onError(
+ "Client unexpectedly disconnected. Ensure client timeout is disabled.",
+ -1);
+ }
+
protected void onReconnect(JavaScriptObject request,
final AtmosphereResponse response) {
if (state == State.CONNECTED) {
@@ -438,6 +446,7 @@ public class AtmospherePushConnection implements PushConnection {
fallbackTransport: 'streaming',
contentType: 'application/json; charset=UTF-8',
reconnectInterval: 5000,
+ timeout: -1,
maxReconnectOnClose: 10000000,
trackMessageLength: true,
enableProtocol: false,
@@ -472,6 +481,9 @@ public class AtmospherePushConnection implements PushConnection {
config.onReconnect = $entry(function(request, response) {
self.@com.vaadin.client.communication.AtmospherePushConnection::onReconnect(*)(request, response);
});
+ config.onClientTimeout = $entry(function(request) {
+ self.@com.vaadin.client.communication.AtmospherePushConnection::onClientTimeout(*)(request);
+ });
return $wnd.jQueryVaadin.atmosphere.subscribe(config);
}-*/;
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/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..9ef6d833e2 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("&#xf0c9;"), //
OPTIMIZE("&#xf0d0;"), //
HIERARCHY("&#xf0e8;"), //
+ // TODO create more appropriate icon
+ SELECTOR("&#x2263;"), //
MENU("&#xf013;"), //
NETWORK("&#xf0ec;"), //
ANALYZE("&#xf0f0;"), //
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..b8732e134e
--- /dev/null
+++ b/client/src/com/vaadin/client/debug/internal/SelectorPath.java
@@ -0,0 +1,238 @@
+/*
+ * 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 (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();
+ }
+ }
+ if (index > 0) {
+ elementQueryString = ".get(" + index + ");";
+ } else {
+ elementQueryString = ".first();";
+ }
+ for (int i = 1; i < fragments.length; ++i) {
+ if (fragments[i].isEmpty()) {
+ // Recursive search has occasional empty fragments
+ continue;
+ }
+
+ // Get Element.class -name
+ String queryFragment = "";
+ String elementClass = getComponentName(fragments[i])
+ + "Element.class";
+ for (SelectorPredicate p : SelectorPredicate
+ .extractPredicates(fragments[i])) {
+ // Add in predicates like .caption and .id
+ queryFragment += "." + p.getName() + "(\"" + p.getValue()
+ + "\")";
+ }
+ if (i == fragments.length - 1) {
+ // Last element in path.
+ queryFragment = "$(" + elementClass + ")" + queryFragment;
+ } else {
+ // If followed by an empty fragment search is recursive
+ boolean recursive = fragments[i + 1].isEmpty();
+ if (recursive) {
+ queryFragment = ".in(" + elementClass + ")" + queryFragment;
+ } else {
+ queryFragment = ".childOf(" + elementClass + ")"
+ + queryFragment;
+ }
+ }
+ elementQueryString = queryFragment + elementQueryString;
+ }
+
+ if (!tmpPath.startsWith("//")) {
+ elementQueryString = "$" + elementQueryString;
+ }
+
+ // Return full Java variable assignment and eQuery
+ return generateJavaVariable(fragments[fragments.length - 1])
+ + elementQueryString;
+ }
+
+ /**
+ * @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[] frags = path.split("/");
+ String name = getComponentName(frags[frags.length - 1]).substring(1);
+
+ 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..5be75f2003
--- /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.WARNING,
+ "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/Property.java b/client/src/com/vaadin/client/metadata/Property.java
index 2e0ea49c88..64fbb79ca1 100644
--- a/client/src/com/vaadin/client/metadata/Property.java
+++ b/client/src/com/vaadin/client/metadata/Property.java
@@ -30,11 +30,11 @@ public class Property {
}
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 +50,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
diff --git a/client/src/com/vaadin/client/metadata/TypeDataStore.java b/client/src/com/vaadin/client/metadata/TypeDataStore.java
index aa37d75dc8..a3939b7994 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,6 +66,22 @@ 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);
}
@@ -101,19 +114,10 @@ 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) {
@@ -227,51 +231,31 @@ 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) {
@@ -288,6 +272,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/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/UnknownComponentConnector.java b/client/src/com/vaadin/client/ui/UnknownComponentConnector.java
index ca461eb640..b9b0388d9a 100644
--- a/client/src/com/vaadin/client/ui/UnknownComponentConnector.java
+++ b/client/src/com/vaadin/client/ui/UnknownComponentConnector.java
@@ -16,6 +16,8 @@
package com.vaadin.client.ui;
+import com.google.gwt.core.client.GWT;
+
public class UnknownComponentConnector extends AbstractComponentConnector {
@Override
@@ -31,7 +33,9 @@ public class UnknownComponentConnector extends AbstractComponentConnector {
public void setServerSideClassName(String serverClassName) {
getWidget()
.setCaption(
- "Widgetset does not contain implementation for "
+ "Widgetset '"
+ + GWT.getModuleName()
+ + "' does not contain implementation for "
+ serverClassName
+ ". Check its component connector's @Connect mapping, widgetsets "
+ "GWT module description file and re-compile your"
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 96678fd133..b043cd0ab7 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);
}
@@ -1795,10 +1791,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();
@@ -1833,10 +1827,6 @@ public class VCalendarPanel extends FocusableFlexTable implements
}
- private int getMilliseconds() {
- return DateTimeService.getMilliseconds(value);
- }
-
private DateTimeService getDateTimeService() {
if (dateTimeService == null) {
dateTimeService = new DateTimeService();
@@ -2034,7 +2024,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 7efb5b8867..9bace9141c 100644
--- a/client/src/com/vaadin/client/ui/VFilterSelect.java
+++ b/client/src/com/vaadin/client/ui/VFilterSelect.java
@@ -1988,6 +1988,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
return tb.getElement();
} else if ("button".equals(subPart)) {
return popupOpener.getElement();
+ } else if ("popup".equals(subPart) && suggestionPopup.isAttached()) {
+ return suggestionPopup.getElement();
}
return null;
}
@@ -1998,6 +2000,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
return "textbox";
} else if (popupOpener.getElement().isOrHasChild(subElement)) {
return "button";
+ } else if (suggestionPopup.getElement().isOrHasChild(subElement)) {
+ return "popup";
}
return 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/VOverlay.java b/client/src/com/vaadin/client/ui/VOverlay.java
index 9f84c16020..545af2ce83 100644
--- a/client/src/com/vaadin/client/ui/VOverlay.java
+++ b/client/src/com/vaadin/client/ui/VOverlay.java
@@ -241,10 +241,10 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
private void removeShadowIfPresent() {
if (isShadowAttached()) {
- shadow.removeFromParent();
-
// Remove event listener from the shadow
unsinkShadowEvents();
+
+ shadow.removeFromParent();
}
}
diff --git a/client/src/com/vaadin/client/ui/VPanel.java b/client/src/com/vaadin/client/ui/VPanel.java
index 6b02f079d1..ffeacade46 100644
--- a/client/src/com/vaadin/client/ui/VPanel.java
+++ b/client/src/com/vaadin/client/ui/VPanel.java
@@ -170,7 +170,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 8bd875690b..bbf06bfec1 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;
@@ -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";
@@ -991,6 +993,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (scrollBody != null) {
scrollBody.removeFromParent();
}
+
+ // Without this call the scroll position is messed up in IE even after
+ // the lazy scroller has set the scroll position to the first visible
+ // item
+ scrollBodyPanel.getScrollPosition();
+
scrollBody = createScrollBody();
scrollBody.renderInitialRows(rowData, uidl.getIntAttribute("firstrow"),
@@ -1054,6 +1062,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (uidl.hasVariable("selected")) {
final Set<String> selectedKeys = uidl
.getStringArrayVariableAsSet("selected");
+ removeUnselectedRowKeys(selectedKeys);
+
if (scrollBody != null) {
Iterator<Widget> iterator = scrollBody.iterator();
while (iterator.hasNext()) {
@@ -1096,6 +1106,16 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return keyboardSelectionOverRowFetchInProgress;
}
+ private void removeUnselectedRowKeys(final Set<String> selectedKeys) {
+ List<String> unselectedKeys = new ArrayList<String>(0);
+ for (String key : selectedRowKeys) {
+ if (!selectedKeys.contains(key)) {
+ unselectedKeys.add(key);
+ }
+ }
+ selectedRowKeys.removeAll(unselectedKeys);
+ }
+
/** For internal use only. May be removed or replaced in the future. */
public void updateSortingProperties(UIDL uidl) {
oldSortColumn = sortColumn;
@@ -1121,7 +1141,28 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
+ private boolean lazyScrollerIsActive;
+
+ private void disableLazyScroller() {
+ lazyScrollerIsActive = false;
+ scrollBodyPanel.getElement().getStyle().clearOverflowX();
+ scrollBodyPanel.getElement().getStyle().clearOverflowY();
+ }
+
+ private void enableLazyScroller() {
+ Scheduler.get().scheduleDeferred(lazyScroller);
+ lazyScrollerIsActive = true;
+ // prevent scrolling to jump in IE11
+ scrollBodyPanel.getElement().getStyle().setOverflowX(Overflow.HIDDEN);
+ scrollBodyPanel.getElement().getStyle().setOverflowY(Overflow.HIDDEN);
+ }
+
+ private boolean isLazyScrollerActive() {
+ return lazyScrollerIsActive;
+ }
+
private ScheduledCommand lazyScroller = new ScheduledCommand() {
+
@Override
public void execute() {
if (firstvisible > 0) {
@@ -1134,6 +1175,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.setScrollPosition(measureRowHeightOffset(firstvisible));
}
}
+ disableLazyScroller();
}
};
@@ -1152,7 +1194,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Only scroll if the first visible changes from the server side.
// Else we might unintentionally scroll even when the scroll
// position has not changed.
- Scheduler.get().scheduleDeferred(lazyScroller);
+ enableLazyScroller();
}
}
@@ -2172,7 +2214,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
isNewBody = false;
if (firstvisible > 0) {
- Scheduler.get().scheduleDeferred(lazyScroller);
+ enableLazyScroller();
}
if (enabled) {
@@ -5056,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 this.firstRendered + relIx;
+ }
+ return -1;
+ }
+
public class VScrollTableRow extends Panel implements ActionOwner {
private static final int TOUCHSCROLL_TIMEOUT = 100;
@@ -6037,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) {
/*
@@ -6884,6 +6939,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void onScroll(ScrollEvent event) {
+ // Do not handle scroll events while there is scroll initiated from
+ // server side which is not yet executed (#11454)
+ if (isLazyScrollerActive()) {
+ return;
+ }
+
scrollLeft = scrollBodyPanel.getElement().getScrollLeft();
scrollTop = scrollBodyPanel.getScrollPosition();
/*
@@ -6932,8 +6993,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
firstRowInViewPort = calcFirstRowInViewPort();
- if (firstRowInViewPort > totalRows - pageLength) {
- firstRowInViewPort = totalRows - pageLength;
+ int maxFirstRow = totalRows - pageLength;
+ if (firstRowInViewPort > maxFirstRow && maxFirstRow >= 0) {
+ firstRowInViewPort = maxFirstRow;
}
int postLimit = (int) (firstRowInViewPort + (pageLength - 1) + pageLength
@@ -7764,4 +7826,94 @@ 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 9ad518b85b..82eb9e7694 100644
--- a/client/src/com/vaadin/client/ui/VTabsheet.java
+++ b/client/src/com/vaadin/client/ui/VTabsheet.java
@@ -135,7 +135,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
SelectedValue.FALSE);
div = DOM.createDiv();
- focusImpl.setTabIndex(td, -1);
+ setTabulatorIndex(-1);
setStyleName(div, DIV_CLASSNAME);
DOM.appendChild(td, div);
@@ -213,7 +213,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
}
public void setTabulatorIndex(int tabIndex) {
- focusImpl.setTabIndex(td, tabIndex);
+ getElement().setTabIndex(tabIndex);
}
public boolean isClosable() {
@@ -313,11 +313,9 @@ 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());
@@ -488,6 +486,9 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
int index = getWidgetIndex(caption.getParent());
+ navigateTab(getTabsheet().focusedTabIndex, index);
+ getTabsheet().focusedTabIndex = index;
+ getTabsheet().focusedTab = getTab(index);
getTabsheet().focus();
getTabsheet().loadTabSheet(index);
}
@@ -702,15 +703,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
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);
- focusedTab.focus();
- }
-
activeTabIndex = tabIndex;
- focusedTabIndex = tabIndex;
addStyleDependentName("loading");
// Hide the current contents so a loading indicator can be shown
@@ -722,6 +715,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
client.updateVariable(id, "selected", tabKeys.get(tabIndex)
.toString(), true);
waitingForResponse = true;
+
+ tb.getTab(tabIndex).focus(); // move keyboard focus to active tab
}
}
@@ -952,6 +947,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
if (tab == null) {
tab = tb.addTab();
}
+ if (selected) {
+ tb.selectTab(index);
+ renderContent(tabUidl.getChildUIDL(0));
+ }
tab.updateFromUIDL(tabUidl);
tab.setEnabledOnServer((!disabledTabKeys.contains(tabKeys.get(index))));
tab.setHiddenOnServer(hidden);
@@ -968,11 +967,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
* and tabs won't be too narrow in certain browsers
*/
tab.recalculateCaptionWidth();
-
- if (selected) {
- renderContent(tabUidl.getChildUIDL(0));
- tb.selectTab(index);
- }
}
/**
@@ -1089,16 +1083,18 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
SCROLLER_CLASSNAME + (scrolled ? "Prev" : "Prev-disabled"));
DOM.setElementProperty(scrollerNext, "className",
SCROLLER_CLASSNAME + (clipped ? "Next" : "Next-disabled"));
+
+ // the active tab should be focusable if and only if it is visible
+ boolean isActiveTabVisible = scrollerIndex <= activeTabIndex
+ && !isClipped(tb.selected);
+ tb.selected.setTabulatorIndex(isActiveTabVisible ? tabulatorIndex
+ : -1);
+
} else {
DOM.setStyleAttribute(scroller, "display", "none");
}
if (BrowserInfo.get().isSafari()) {
- // fix tab height for safari, bugs sometimes if tabs contain icons
- String property = tabs.getStyle().getProperty("height");
- if (property == null || property.equals("")) {
- tabs.getStyle().setPropertyPx("height", tb.getOffsetHeight());
- }
/*
* another hack for webkits. tabscroller sometimes drops without
* "shaking it" reproducable in
@@ -1194,7 +1190,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
public void onBlur(BlurEvent event) {
getApplicationConnection().getVTooltip().hideTooltip();
- if (focusedTab != null && event.getSource() instanceof Tab) {
+ if (focusedTab != null && focusedTab == event.getSource()) {
focusedTab.removeAssistiveDescription();
focusedTab = null;
if (client.hasEventListeners(this, EventId.BLUR)) {
@@ -1300,13 +1296,10 @@ public class VTabsheet extends VTabsheetBase implements Focusable,
}
if (isScrolledTabs()) {
- // Scroll until the new active tab is visible
- int newScrollerIndex = scrollerIndex;
- while (tb.getTab(focusedTabIndex).getAbsoluteLeft() < getAbsoluteLeft()
- && newScrollerIndex != -1) {
- newScrollerIndex = tb.scrollLeft(newScrollerIndex);
+ // Scroll until the new focused tab is visible
+ while (!tb.getTab(focusedTabIndex).isVisible()) {
+ scrollerIndex = tb.scrollLeft(scrollerIndex);
}
- scrollerIndex = newScrollerIndex;
updateTabScroller();
}
}
diff --git a/client/src/com/vaadin/client/ui/VTreeTable.java b/client/src/com/vaadin/client/ui/VTreeTable.java
index 097b9c7ab2..54c9c2d30c 100644
--- a/client/src/com/vaadin/client/ui/VTreeTable.java
+++ b/client/src/com/vaadin/client/ui/VTreeTable.java
@@ -131,7 +131,7 @@ public class VTreeTable extends VScrollTable {
private int indentWidth = -1;
private int maxIndent = 0;
- VTreeTableScrollBody() {
+ protected VTreeTableScrollBody() {
super();
}
diff --git a/client/src/com/vaadin/client/ui/VUpload.java b/client/src/com/vaadin/client/ui/VUpload.java
index c08d75e9b7..8e55387d39 100644
--- a/client/src/com/vaadin/client/ui/VUpload.java
+++ b/client/src/com/vaadin/client/ui/VUpload.java
@@ -295,10 +295,13 @@ public class VUpload extends SimplePanel {
/** For internal use only. May be removed or replaced in the future. */
public void submit() {
- if (fu.getFilename().length() == 0 || submitted || !enabled) {
- VConsole.log("Submit cancelled (disabled, no file or already submitted)");
+ if (submitted || !enabled) {
+ VConsole.log("Submit cancelled (disabled or already submitted)");
return;
}
+ if (fu.getFilename().length() == 0) {
+ VConsole.log("Submitting empty selection (no file)");
+ }
// flush possibly pending variable changes, so they will be handled
// before upload
client.sendPendingVariableChanges();
diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java
index 964adfe303..705787d6c8 100644
--- a/client/src/com/vaadin/client/ui/VWindow.java
+++ b/client/src/com/vaadin/client/ui/VWindow.java
@@ -27,6 +27,7 @@ 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;
@@ -83,6 +84,8 @@ public class VWindow extends VWindowOverlay implements
public static final String CLASSNAME = "v-window";
+ private static final String MODAL_WINDOW_OPEN_CLASSNAME = "v-modal-window-open";
+
private static final int STACKING_OFFSET_PIXELS = 15;
public static final int Z_INDEX = 10000;
@@ -725,10 +728,14 @@ public class VWindow extends VWindowOverlay implements
getOverlayContainer().appendChild(getModalityCurtain());
}
+ Document.get().getBody().addClassName(MODAL_WINDOW_OPEN_CLASSNAME);
}
private void hideModalityCurtain() {
+ Document.get().getBody().removeClassName(MODAL_WINDOW_OPEN_CLASSNAME);
+
modalityCurtain.removeFromParent();
+
if (BrowserInfo.get().isIE()) {
// IE leaks memory in certain cases unless we release the reference
// (#9197)
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/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
index f91ff9e2b9..8dec26cf90 100644
--- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
+++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java
@@ -37,6 +37,10 @@ import com.vaadin.ui.ComboBox;
public class ComboBoxConnector extends AbstractFieldConnector implements
Paintable, SimpleManagedLayout {
+ // oldSuggestionTextMatchTheOldSelection is used to detect when it's safe to
+ // update textbox text by a changed item caption.
+ private boolean oldSuggestionTextMatchTheOldSelection;
+
/*
* (non-Javadoc)
*
@@ -117,7 +121,10 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
boolean suggestionsChanged = !getWidget().initDone
|| !newSuggestions.equals(getWidget().currentSuggestions);
+ oldSuggestionTextMatchTheOldSelection = false;
+
if (suggestionsChanged) {
+ oldSuggestionTextMatchTheOldSelection = isWidgetsCurrentSelectionTextInTextBox();
getWidget().currentSuggestions.clear();
if (!getWidget().waitingForFilteringResponse) {
@@ -212,29 +219,38 @@ public class ComboBoxConnector extends AbstractFieldConnector implements
// some item selected
for (FilterSelectSuggestion suggestion : getWidget().currentSuggestions) {
String suggestionKey = suggestion.getOptionKey();
- if (suggestionKey.equals(selectedKey)) {
- if (!getWidget().waitingForFilteringResponse
- || getWidget().popupOpenerClicked) {
- if (!suggestionKey.equals(getWidget().selectedOptionKey)
- || suggestion.getReplacementString().equals(
- getWidget().tb.getText())) {
- // Update text field if we've got a new
- // selection
- // Also update if we've got the same text to
- // retain old text selection behavior
- getWidget().setPromptingOff(
- suggestion.getReplacementString());
- getWidget().selectedOptionKey = suggestionKey;
- }
+ if (!suggestionKey.equals(selectedKey)) {
+ continue;
+ }
+ if (!getWidget().waitingForFilteringResponse
+ || getWidget().popupOpenerClicked) {
+ if (!suggestionKey.equals(getWidget().selectedOptionKey)
+ || suggestion.getReplacementString().equals(
+ getWidget().tb.getText())
+ || oldSuggestionTextMatchTheOldSelection) {
+ // Update text field if we've got a new
+ // selection
+ // Also update if we've got the same text to
+ // retain old text selection behavior
+ // OR if selected item caption is changed.
+ getWidget().setPromptingOff(
+ suggestion.getReplacementString());
+ getWidget().selectedOptionKey = suggestionKey;
}
- getWidget().currentSuggestion = suggestion;
- getWidget().setSelectedItemIcon(suggestion.getIconUri());
- // only a single item can be selected
- break;
}
+ getWidget().currentSuggestion = suggestion;
+ getWidget().setSelectedItemIcon(suggestion.getIconUri());
+ // only a single item can be selected
+ break;
}
}
+ private boolean isWidgetsCurrentSelectionTextInTextBox() {
+ return getWidget().currentSuggestion != null
+ && getWidget().currentSuggestion.getReplacementString().equals(
+ getWidget().tb.getText());
+ }
+
private void resetSelection() {
if (!getWidget().waitingForFilteringResponse
|| getWidget().popupOpenerClicked) {
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/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/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
index 49b3661431..37a97f3399 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
@@ -19,9 +19,11 @@ package com.vaadin.client.ui.orderedlayout;
import java.util.List;
import com.google.gwt.aria.client.Roles;
+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;
@@ -456,6 +458,9 @@ public final class Slot extends SimplePanel {
// Caption wrappers
Widget widget = getWidget();
+ final Element focusedElement = Util.getFocusedElement();
+ // By default focus will not be lost
+ boolean focusLost = false;
if (captionText != null || iconUrl != null || error != null || required) {
if (caption == null) {
caption = DOM.createDiv();
@@ -466,6 +471,10 @@ public final class Slot extends SimplePanel {
orphan(widget);
captionWrap.appendChild(widget.getElement());
adopt(widget);
+
+ // Made changes to DOM. Focus can be lost if it was in the
+ // widget.
+ focusLost = widget.getElement().isOrHasChild(focusedElement);
}
} else if (caption != null) {
orphan(widget);
@@ -474,6 +483,9 @@ public final class Slot extends SimplePanel {
captionWrap.removeFromParent();
caption = null;
captionWrap = null;
+
+ // Made changes to DOM. Focus can be lost if it was in the widget.
+ focusLost = widget.getElement().isOrHasChild(focusedElement);
}
// Caption text
@@ -560,6 +572,45 @@ public final class Slot extends SimplePanel {
setCaptionPosition(CaptionPosition.RIGHT);
}
}
+
+ if (focusLost) {
+ // Find out what element is currently focused.
+ Element currentFocus = Util.getFocusedElement();
+ if (currentFocus != null
+ && currentFocus.equals(Document.get().getBody())) {
+ // Focus has moved to BodyElement and should be moved back to
+ // original location. This happened because of adding or
+ // removing the captionWrap
+ focusedElement.focus();
+ } else if (currentFocus != focusedElement) {
+ // Focus is either moved somewhere else on purpose or IE has
+ // lost it. Investigate further.
+ Timer focusTimer = new Timer() {
+
+ @Override
+ public void run() {
+ if (Util.getFocusedElement() == null) {
+ // This should never become an infinite loop and
+ // even if it does it will be stopped once something
+ // is done with the browser.
+ schedule(25);
+ } else if (Util.getFocusedElement().equals(
+ Document.get().getBody())) {
+ // Focus found it's way to BodyElement. Now it can
+ // be restored
+ focusedElement.focus();
+ }
+ }
+ };
+ if (BrowserInfo.get().isIE8()) {
+ // IE8 can't fix the focus immediately. It will fail.
+ focusTimer.schedule(25);
+ } else {
+ // Newer IE versions can handle things immediately.
+ focusTimer.run();
+ }
+ }
+ }
}
/**
diff --git a/client/src/com/vaadin/client/ui/table/TableConnector.java b/client/src/com/vaadin/client/ui/table/TableConnector.java
index eacd5bc77a..d2c700ab06 100644
--- a/client/src/com/vaadin/client/ui/table/TableConnector.java
+++ b/client/src/com/vaadin/client/ui/table/TableConnector.java
@@ -142,9 +142,6 @@ public class TableConnector extends AbstractHasComponentsConnector implements
getWidget().updateSortingProperties(uidl);
- boolean keyboardSelectionOverRowFetchInProgress = getWidget()
- .selectSelectedRows(uidl);
-
getWidget().updateActionMap(uidl);
getWidget().updateColumnProperties(uidl);
@@ -216,6 +213,9 @@ public class TableConnector extends AbstractHasComponentsConnector implements
}
}
+ boolean keyboardSelectionOverRowFetchInProgress = getWidget()
+ .selectSelectedRows(uidl);
+
// If a row had an open context menu before the update, and after the
// update there's a row with the same key as that row, restore the
// context menu. See #8526.
diff --git a/client/src/com/vaadin/client/ui/tree/TreeConnector.java b/client/src/com/vaadin/client/ui/tree/TreeConnector.java
index 6f89137918..61207ffa53 100644
--- a/client/src/com/vaadin/client/ui/tree/TreeConnector.java
+++ b/client/src/com/vaadin/client/ui/tree/TreeConnector.java
@@ -18,6 +18,7 @@ package com.vaadin.client.ui.tree;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.dom.client.Element;
@@ -141,9 +142,24 @@ public class TreeConnector extends AbstractComponentConnector implements
getWidget().lastSelection = getWidget().getNodeByKey(
getWidget().lastSelection.key);
}
+
if (getWidget().focusedNode != null) {
- getWidget().setFocusedNode(
- getWidget().getNodeByKey(getWidget().focusedNode.key));
+
+ Set<String> selectedIds = getWidget().selectedIds;
+
+ // If the focused node is not between the selected nodes, we need to
+ // refresh the focused node to prevent an undesired scroll. #12618.
+ if (!selectedIds.isEmpty()
+ && !selectedIds.contains(getWidget().focusedNode.key)) {
+ String keySelectedId = selectedIds.iterator().next();
+
+ TreeNode nodeToSelect = getWidget().getNodeByKey(keySelectedId);
+
+ getWidget().setFocusedNode(nodeToSelect);
+ } else {
+ getWidget().setFocusedNode(
+ getWidget().getNodeByKey(getWidget().focusedNode.key));
+ }
}
if (getWidget().lastSelection == null
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index d0f3c8603f..17a23baad5 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;
@@ -192,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;
diff --git a/client/src/com/vaadin/client/ui/upload/UploadConnector.java b/client/src/com/vaadin/client/ui/upload/UploadConnector.java
index 937ff438ac..989a913adc 100644
--- a/client/src/com/vaadin/client/ui/upload/UploadConnector.java
+++ b/client/src/com/vaadin/client/ui/upload/UploadConnector.java
@@ -22,12 +22,22 @@ import com.vaadin.client.UIDL;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.client.ui.VUpload;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.upload.UploadClientRpc;
import com.vaadin.ui.Upload;
@Connect(Upload.class)
public class UploadConnector extends AbstractComponentConnector implements
Paintable {
+ public UploadConnector() {
+ registerRpc(UploadClientRpc.class, new UploadClientRpc() {
+ @Override
+ public void submitUpload() {
+ getWidget().submit();
+ }
+ });
+ }
+
@Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
if (!isRealUpdate(uidl)) {
@@ -37,10 +47,6 @@ public class UploadConnector extends AbstractComponentConnector implements
getWidget().t.schedule(400);
return;
}
- if (uidl.hasAttribute("forceSubmit")) {
- getWidget().submit();
- return;
- }
getWidget().setImmediate(getState().immediate);
getWidget().client = client;
getWidget().paintableId = uidl.getId();
diff --git a/common.xml b/common.xml
index a1c086c57a..a49c25c6be 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" />
@@ -184,7 +185,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" />
@@ -277,6 +278,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="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;vaadin&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=vaadin&amp;amp;ivyXmlPath=uitest%2Fivy.xml&amp;amp;confs=jetty-run&quot; path=&quot;3&quot; type=&quot;4&quot;/&gt;&#10;"/>
+<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;vaadin&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
+</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 abeec2a8b0..0db99e815c 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.vaadin1" />
+ <property name="atmosphere.runtime.version" value="2.0.3.vaadin1" />
<property name="jquery.version" value="1.9.0" />
<path id="classpath.compile.custom" />
diff --git a/push/ivy.xml b/push/ivy.xml
index 2be47512fe..b28c5c69d9 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.vaadin1">
+ <!ENTITY atmosphere.runtime.version "2.0.3.vaadin1">
- <!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/server/src/com/vaadin/data/Buffered.java b/server/src/com/vaadin/data/Buffered.java
index 0d6722f71f..c4c79ae13f 100644
--- a/server/src/com/vaadin/data/Buffered.java
+++ b/server/src/com/vaadin/data/Buffered.java
@@ -23,29 +23,20 @@ import com.vaadin.data.Validator.InvalidValueException;
/**
* <p>
* Defines the interface to commit and discard changes to an object, supporting
- * read-through and write-through modes.
- * </p>
+ * buffering.
*
* <p>
- * <i>Read-through mode</i> means that the value read from the buffered object
- * is constantly up to date with the data source. <i>Write-through</i> mode
- * means that all changes to the object are immediately updated to the data
- * source.
- * </p>
+ * In <i>buffered</i> mode the initial value is read from the data source and
+ * then buffered. Any subsequential writes or reads will be done on the buffered
+ * value. Calling {@link #commit()} will write the buffered value to the data
+ * source while calling {@link #discard()} while discard the buffered value and
+ * re-read the value from the data source.
*
* <p>
- * Since these modes are independent, their combinations may result in some
- * behaviour that may sound surprising.
- * </p>
- *
- * <p>
- * For example, if a <code>Buffered</code> object is in read-through mode but
- * not in write-through mode, the result is an object whose value is updated
- * directly from the data source only if it's not locally modified. If the value
- * is locally modified, retrieving the value from the object would result in a
- * value that is different than the one stored in the data source, even though
- * the object is in read-through mode.
- * </p>
+ * In <i>non-buffered</i> mode the value is always read directly from the data
+ * source. Any write is done directly to the data source with no buffering in
+ * between. Reads are also done directly from the data source. Calling
+ * {@link #commit()} or {@link #discard()} in this mode is efficiently a no-op.
*
* @author Vaadin Ltd.
* @since 3.0
@@ -77,25 +68,15 @@ public interface Buffered extends Serializable {
public void discard() throws SourceException;
/**
- * Sets the object's buffered mode to the specified status.
+ * Sets the buffered mode to the specified status.
* <p>
- * When the object is in buffered mode, an internal buffer will be used to
- * store changes until {@link #commit()} is called. Calling
- * {@link #discard()} will revert the internal buffer to the value of the
- * data source.
- * </p>
+ * When in buffered mode, an internal buffer will be used to store changes
+ * until {@link #commit()} is called. Calling {@link #discard()} will revert
+ * the internal buffer to the value of the data source.
* <p>
- * This is an easier way to use {@link #setReadThrough(boolean)} and
- * {@link #setWriteThrough(boolean)} and not as error prone. Changing
- * buffered mode will change both the read through and write through state
- * of the object.
- * </p>
- * <p>
- * Mixing calls to {@link #setBuffered(boolean)}/{@link #isBuffered()} and
- * {@link #setReadThrough(boolean)}/{@link #isReadThrough()} or
- * {@link #setWriteThrough(boolean)}/{@link #isWriteThrough()} is generally
- * a bad idea.
- * </p>
+ * When in non-buffered mode both read and write operations will be done
+ * directly on the data source. In this mode the {@link #commit()} and
+ * {@link #discard()} methods serve no purpose.
*
* @param buffered
* true if buffered mode should be turned on, false otherwise
@@ -104,10 +85,7 @@ public interface Buffered extends Serializable {
public void setBuffered(boolean buffered);
/**
- * Checks the buffered mode of this Object.
- * <p>
- * This method only returns true if both read and write buffering is used.
- * </p>
+ * Checks the buffered mode
*
* @return true if buffered mode is on, false otherwise
* @since 7.0
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/filter/Between.java b/server/src/com/vaadin/data/util/filter/Between.java
index 8209f7b0a2..a76821981a 100644
--- a/server/src/com/vaadin/data/util/filter/Between.java
+++ b/server/src/com/vaadin/data/util/filter/Between.java
@@ -67,6 +67,10 @@ public class Between implements Filter {
@Override
public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
// Only objects of the same class can be equal
if (!getClass().equals(obj.getClass())) {
return false;
diff --git a/server/src/com/vaadin/data/util/filter/Compare.java b/server/src/com/vaadin/data/util/filter/Compare.java
index f9f19c6602..ac167673bd 100644
--- a/server/src/com/vaadin/data/util/filter/Compare.java
+++ b/server/src/com/vaadin/data/util/filter/Compare.java
@@ -307,6 +307,9 @@ public abstract class Compare implements Filter {
@Override
public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
// Only objects of the same class can be equal
if (!getClass().equals(obj.getClass())) {
diff --git a/server/src/com/vaadin/data/util/filter/IsNull.java b/server/src/com/vaadin/data/util/filter/IsNull.java
index 5c5bdfc0b1..6907a016a1 100644
--- a/server/src/com/vaadin/data/util/filter/IsNull.java
+++ b/server/src/com/vaadin/data/util/filter/IsNull.java
@@ -62,6 +62,10 @@ public final class IsNull implements Filter {
@Override
public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
// Only objects of the same class can be equal
if (!getClass().equals(obj.getClass())) {
return false;
diff --git a/server/src/com/vaadin/data/util/filter/Like.java b/server/src/com/vaadin/data/util/filter/Like.java
index 4c15564105..dc2e18363a 100644
--- a/server/src/com/vaadin/data/util/filter/Like.java
+++ b/server/src/com/vaadin/data/util/filter/Like.java
@@ -84,6 +84,10 @@ public class Like implements Filter {
@Override
public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
// Only objects of the same class can be equal
if (!getClass().equals(obj.getClass())) {
return false;
diff --git a/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java b/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java
index bc58999445..a214e69846 100644
--- a/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java
+++ b/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java
@@ -82,6 +82,9 @@ public final class SimpleStringFilter implements Filter {
@Override
public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
// Only ones of the objects of the same class can be equal
if (!(obj instanceof SimpleStringFilter)) {
diff --git a/server/src/com/vaadin/event/EventRouter.java b/server/src/com/vaadin/event/EventRouter.java
index 73bfa33881..fdc543143b 100644
--- a/server/src/com/vaadin/event/EventRouter.java
+++ b/server/src/com/vaadin/event/EventRouter.java
@@ -23,6 +23,10 @@ import java.util.EventObject;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.logging.Logger;
+
+import com.vaadin.server.ErrorEvent;
+import com.vaadin.server.ErrorHandler;
/**
* <code>EventRouter</code> class implementing the inheritable event listening
@@ -154,6 +158,25 @@ public class EventRouter implements MethodEventSource {
* the Event to be sent to all listeners.
*/
public void fireEvent(EventObject event) {
+ fireEvent(event, null);
+ }
+
+ /**
+ * Sends an event to all registered listeners. The listeners will decide if
+ * the activation method should be called or not.
+ * <p>
+ * If an error handler is set, the processing of other listeners will
+ * continue after the error handler method call unless the error handler
+ * itself throws an exception.
+ *
+ * @param event
+ * the Event to be sent to all listeners.
+ * @param errorHandler
+ * error handler to use to handle any exceptions thrown by
+ * listeners or null to let the exception propagate to the
+ * caller, preventing further listener calls
+ */
+ public void fireEvent(EventObject event, ErrorHandler errorHandler) {
// It is not necessary to send any events if there are no listeners
if (listenerList != null) {
@@ -164,7 +187,16 @@ public class EventRouter implements MethodEventSource {
// will filter out unwanted events.
final Object[] listeners = listenerList.toArray();
for (int i = 0; i < listeners.length; i++) {
- ((ListenerMethod) listeners[i]).receiveEvent(event);
+ ListenerMethod listenerMethod = (ListenerMethod) listeners[i];
+ if (null != errorHandler) {
+ try {
+ listenerMethod.receiveEvent(event);
+ } catch (Exception e) {
+ errorHandler.error(new ErrorEvent(e));
+ }
+ } else {
+ listenerMethod.receiveEvent(event);
+ }
}
}
@@ -208,4 +240,9 @@ public class EventRouter implements MethodEventSource {
}
return listeners;
}
+
+ private Logger getLogger() {
+ return Logger.getLogger(EventRouter.class.getName());
+ }
+
}
diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java
index b0841da314..a39c39fa72 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.vaadin1";
+ static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.0.3.vaadin1";
static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
+ "=================================================================\n"
diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java
index d533ed99f3..129307e5c1 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);
@@ -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
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/VaadinPortlet.java b/server/src/com/vaadin/server/VaadinPortlet.java
index a41f301219..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)) {
diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java
index aff0124d16..b457436b8f 100644
--- a/server/src/com/vaadin/server/VaadinService.java
+++ b/server/src/com/vaadin/server/VaadinService.java
@@ -420,6 +420,9 @@ public abstract class VaadinService implements Serializable {
/**
* Adds a listener that gets notified when a Vaadin service session that has
* been initialized for this service is destroyed.
+ * <p>
+ * The session being destroyed is locked and its UIs have been removed when
+ * the listeners are called.
*
* @see #addSessionInitListener(SessionInitListener)
*
@@ -461,8 +464,11 @@ public abstract class VaadinService implements Serializable {
}
});
}
+ // for now, use the session error handler; in the future, could
+ // have an API for using some other handler for session init and
+ // destroy listeners
eventRouter.fireEvent(new SessionDestroyEvent(
- VaadinService.this, session));
+ VaadinService.this, session), session.getErrorHandler());
}
});
}
@@ -776,7 +782,12 @@ public abstract class VaadinService implements Serializable {
private void onVaadinSessionStarted(VaadinRequest request,
VaadinSession session) throws ServiceException {
- eventRouter.fireEvent(new SessionInitEvent(this, session, request));
+ // for now, use the session error handler; in the future, could have an
+ // API for using some other handler for session init and destroy
+ // listeners
+
+ eventRouter.fireEvent(new SessionInitEvent(this, session, request),
+ session.getErrorHandler());
ServletPortletHelper.checkUiProviders(session, this);
}
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index f34721944a..265d18b859 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;
@@ -423,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
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/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 74595322a0..f3869a76f8 100644
--- a/server/src/com/vaadin/server/communication/PushRequestHandler.java
+++ b/server/src/com/vaadin/server/communication/PushRequestHandler.java
@@ -18,6 +18,7 @@ package com.vaadin.server.communication;
import java.io.IOException;
+import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import org.atmosphere.client.TrackMessageSizeInterceptor;
@@ -58,11 +59,22 @@ public class PushRequestHandler implements RequestHandler,
public PushRequestHandler(VaadinServletService service)
throws ServiceException {
+ final ServletConfig config = service.getServlet().getServletConfig();
+
atmosphere = new AtmosphereFramework() {
@Override
protected void analytics() {
// Overridden to disable version number check
}
+
+ @Override
+ public AtmosphereFramework addInitParameter(String name,
+ String value) {
+ if (config.getInitParameter(name) == null) {
+ super.addInitParameter(name, value);
+ }
+ return this;
+ }
};
service.addServiceDestroyListener(new ServiceDestroyListener() {
@@ -93,7 +105,7 @@ public class PushRequestHandler implements RequestHandler,
"false");
try {
- atmosphere.init(service.getServlet().getServletConfig());
+ atmosphere.init(config);
// Ensure the client-side knows how to split the message stream
// into individual messages when using certain transports
diff --git a/server/src/com/vaadin/server/communication/ServerRpcHandler.java b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
index 432a9ea893..ce9cec5e2a 100644
--- a/server/src/com/vaadin/server/communication/ServerRpcHandler.java
+++ b/server/src/com/vaadin/server/communication/ServerRpcHandler.java
@@ -68,7 +68,7 @@ public class ServerRpcHandler implements Serializable {
* @since 7.2
* @author Vaadin Ltd
*/
- public static class RpcRequest {
+ public static class RpcRequest implements Serializable {
private final String csrfToken;
private final JSONArray invocations;
@@ -439,7 +439,7 @@ public class ServerRpcHandler implements Serializable {
"Ignoring RPC call to " + interfaceName + "." + methodName
+ " in connector " + connector.getClass().getName()
+ "(" + connectorId
- + ") as no RPC implementation is regsitered");
+ + ") as no RPC implementation is registered");
return null;
}
diff --git a/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java b/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
index cc04e50b3c..3ad76794de 100644
--- a/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
+++ b/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java
@@ -32,8 +32,6 @@ import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
-import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* Utility class to collect widgetset related information from classpath.
@@ -111,6 +109,15 @@ public class ClassPathExplorer {
*/
private static Map<String, URL> classpathLocations = getClasspathLocations(rawClasspathEntries);
+ private static boolean debug = false;
+
+ static {
+ String debugProperty = System.getProperty("debug");
+ if (debugProperty != null && !debugProperty.equals("")) {
+ debug = true;
+ }
+ }
+
/**
* No instantiation from outside, callable methods are static.
*/
@@ -163,9 +170,8 @@ public class ClassPathExplorer {
sb.append("\n");
}
- final Logger logger = getLogger();
- logger.info(sb.toString());
- logger.info("Search took " + (end - start) + "ms");
+ log(sb.toString());
+ log("Search took " + (end - start) + "ms");
return new LocationInfo(widgetsets, themes);
}
@@ -226,8 +232,7 @@ public class ClassPathExplorer {
} catch (MalformedURLException e) {
// should never happen as based on an existing URL,
// only changing end of file name/path part
- getLogger().log(Level.SEVERE,
- "Error locating the widgetset " + classname, e);
+ error("Error locating the widgetset " + classname, e);
}
}
}
@@ -276,7 +281,7 @@ public class ClassPathExplorer {
}
}
} catch (IOException e) {
- getLogger().log(Level.WARNING, "Error parsing jar file", e);
+ error("Error parsing jar file", e);
}
}
@@ -304,7 +309,7 @@ public class ClassPathExplorer {
classpath = classpath.substring(0, classpath.length() - 1);
}
- getLogger().log(Level.FINE, "Classpath: {0}", classpath);
+ debug("Classpath: " + classpath);
String[] split = classpath.split(pathSep);
for (int i = 0; i < split.length; i++) {
@@ -338,9 +343,8 @@ public class ClassPathExplorer {
include(null, file, locations);
}
long end = System.currentTimeMillis();
- Logger logger = getLogger();
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("getClassPathLocations took " + (end - start) + "ms");
+ if (debug) {
+ debug("getClassPathLocations took " + (end - start) + "ms");
}
return locations;
}
@@ -379,7 +383,8 @@ public class ClassPathExplorer {
url = new URL("jar:" + url.toExternalForm() + "!/");
JarURLConnection conn = (JarURLConnection) url
.openConnection();
- getLogger().fine(url.toString());
+ debug(url.toString());
+
JarFile jarFile = conn.getJarFile();
Manifest manifest = jarFile.getManifest();
if (manifest != null) {
@@ -393,11 +398,13 @@ public class ClassPathExplorer {
}
}
} catch (MalformedURLException e) {
- getLogger().log(Level.FINEST, "Failed to inspect JAR file",
- e);
+ if (debug) {
+ error("Failed to inspect JAR file", e);
+ }
} catch (IOException e) {
- getLogger().log(Level.FINEST, "Failed to inspect JAR file",
- e);
+ if (debug) {
+ error("Failed to inspect JAR file", e);
+ }
}
return false;
@@ -489,14 +496,12 @@ public class ClassPathExplorer {
*/
public static URL getDefaultSourceDirectory() {
- final Logger logger = getLogger();
-
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("classpathLocations values:");
+ if (debug) {
+ debug("classpathLocations values:");
ArrayList<String> locations = new ArrayList<String>(
classpathLocations.keySet());
for (String location : locations) {
- logger.fine(String.valueOf(classpathLocations.get(location)));
+ debug(String.valueOf(classpathLocations.get(location)));
}
}
@@ -510,11 +515,15 @@ public class ClassPathExplorer {
try {
return new URL("file://" + directory.getCanonicalPath());
} catch (MalformedURLException e) {
- logger.log(Level.FINEST, "Ignoring exception", e);
// ignore: continue to the next classpath entry
+ if (debug) {
+ e.printStackTrace();
+ }
} catch (IOException e) {
- logger.log(Level.FINEST, "Ignoring exception", e);
// ignore: continue to the next classpath entry
+ if (debug) {
+ e.printStackTrace();
+ }
}
}
}
@@ -525,14 +534,24 @@ public class ClassPathExplorer {
* Test method for helper tool
*/
public static void main(String[] args) {
- getLogger().info(
- "Searching for available widgetsets and stylesheets...");
+ log("Searching for available widgetsets and stylesheets...");
ClassPathExplorer.getAvailableWidgetSetsAndStylesheets();
}
- private static final Logger getLogger() {
- return Logger.getLogger(ClassPathExplorer.class.getName());
+ private static void log(String message) {
+ System.out.println(message);
+ }
+
+ private static void error(String message, Exception e) {
+ System.err.println(message);
+ e.printStackTrace();
+ }
+
+ private static void debug(String message) {
+ if (debug) {
+ System.out.println(message);
+ }
}
}
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 6a52d6b849..300e130c4e 100644
--- a/server/src/com/vaadin/ui/AbstractField.java
+++ b/server/src/com/vaadin/ui/AbstractField.java
@@ -783,15 +783,16 @@ public abstract class AbstractField<T> extends AbstractComponent implements
ConversionException e) {
String conversionError = getConversionError();
- if (dataSourceType != null) {
- conversionError = conversionError.replace("{0}",
- dataSourceType.getSimpleName());
- }
- if (e != null) {
- conversionError = conversionError.replace("{1}",
- e.getLocalizedMessage());
+ if (conversionError != null) {
+ if (dataSourceType != null) {
+ conversionError = conversionError.replace("{0}",
+ dataSourceType.getSimpleName());
+ }
+ if (e != null) {
+ conversionError = conversionError.replace("{1}",
+ e.getLocalizedMessage());
+ }
}
-
return conversionError;
}
@@ -1085,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();
}
/**
@@ -1106,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/Calendar.java b/server/src/com/vaadin/ui/Calendar.java
index 9ccc8ea2d9..b0999451c3 100644
--- a/server/src/com/vaadin/ui/Calendar.java
+++ b/server/src/com/vaadin/ui/Calendar.java
@@ -1824,7 +1824,7 @@ public class Calendar extends AbstractComponent implements
try {
Date start = formatter.parse(startDate);
for (Action.Handler ah : actionHandlers) {
- ah.handleAction(action, this, start);
+ ah.handleAction(action, Calendar.this, start);
}
} catch (ParseException e) {
@@ -1842,7 +1842,7 @@ public class Calendar extends AbstractComponent implements
DateConstants.ACTION_DATE_FORMAT_PATTERN);
formatter.setTimeZone(getTimeZone());
for (Action.Handler ah : actionHandlers) {
- ah.handleAction(action, this, events.get(eventIndex));
+ ah.handleAction(action, Calendar.this, events.get(eventIndex));
}
}
}
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/FormLayout.java b/server/src/com/vaadin/ui/FormLayout.java
index 9d5e637068..9dc0b24cad 100644
--- a/server/src/com/vaadin/ui/FormLayout.java
+++ b/server/src/com/vaadin/ui/FormLayout.java
@@ -52,4 +52,23 @@ public class FormLayout extends AbstractOrderedLayout {
addComponents(children);
}
+ /**
+ * @deprecated This method currently has no effect as expand ratios are not
+ * implemented in FormLayout
+ */
+ @Override
+ @Deprecated
+ public void setExpandRatio(Component component, float ratio) {
+ super.setExpandRatio(component, ratio);
+ }
+
+ /**
+ * @deprecated This method currently has no effect as expand ratios are not
+ * implemented in FormLayout
+ */
+ @Override
+ @Deprecated
+ public float getExpandRatio(Component component) {
+ return super.getExpandRatio(component);
+ }
}
diff --git a/server/src/com/vaadin/ui/Label.java b/server/src/com/vaadin/ui/Label.java
index d7cee2a80d..3aa83de420 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
*/
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/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 a292e6b829..e688c06061 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -55,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;
@@ -422,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;
@@ -550,8 +552,6 @@ 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);
@@ -1368,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
@@ -1385,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();
- }
}
/**
diff --git a/server/src/com/vaadin/ui/Upload.java b/server/src/com/vaadin/ui/Upload.java
index 08cabf979a..98f5d2ded9 100644
--- a/server/src/com/vaadin/ui/Upload.java
+++ b/server/src/com/vaadin/ui/Upload.java
@@ -28,6 +28,7 @@ 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.ui.upload.UploadClientRpc;
/**
* Component for uploading files from client to server.
@@ -107,11 +108,6 @@ public class Upload extends AbstractComponent implements Component.Focusable,
private int nextid;
/**
- * Flag to indicate that submitting file has been requested.
- */
- private boolean forceSubmit;
-
- /**
* Creates a new instance of Upload.
*
* The receiver must be set before performing an upload.
@@ -157,11 +153,6 @@ public class Upload extends AbstractComponent implements Component.Focusable,
notStarted = false;
return;
}
- if (forceSubmit) {
- target.addAttribute("forceSubmit", true);
- forceSubmit = true;
- return;
- }
// The field should be focused
if (focus) {
target.addAttribute("focus", true);
@@ -1011,12 +1002,11 @@ public class Upload extends AbstractComponent implements Component.Focusable,
*/
public void submitUpload() {
markAsDirty();
- forceSubmit = true;
+ getRpcProxy(UploadClientRpc.class).submitUpload();
}
@Override
public void markAsDirty() {
- forceSubmit = false;
super.markAsDirty();
}
diff --git a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
index 5c78965092..5da0bdc8a2 100644
--- a/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
+++ b/server/tests/src/com/vaadin/data/util/TestIndexedContainer.java
@@ -306,7 +306,7 @@ public class TestIndexedContainer extends AbstractInMemoryContainerTest {
Capture<ItemAddEvent> capturedEvent = captureAddEvent(addListener);
EasyMock.replay(addListener);
- Object itemId = container.addItemAt(1);
+ container.addItemAt(1);
assertEquals(1, capturedEvent.getValue().getFirstIndex());
}
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/data/util/sqlcontainer/filters/CompareTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java
new file mode 100644
index 0000000000..c8faa71e66
--- /dev/null
+++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/CompareTest.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.data.util.sqlcontainer.filters;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.data.util.filter.Compare;
+
+public class CompareTest {
+
+ @Test
+ public void testEquals() {
+ Compare c1 = new Compare.Equal("prop1", "val1");
+ Compare c2 = new Compare.Equal("prop1", "val1");
+ Assert.assertTrue(c1.equals(c2));
+ }
+
+ @Test
+ public void testDifferentTypeEquals() {
+ Compare c1 = new Compare.Equal("prop1", "val1");
+ Compare c2 = new Compare.Greater("prop1", "val1");
+ Assert.assertFalse(c1.equals(c2));
+ }
+
+ @Test
+ public void testEqualsNull() {
+ Compare c1 = new Compare.Equal("prop1", "val1");
+ Assert.assertFalse(c1.equals(null));
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/event/EventRouterTest.java b/server/tests/src/com/vaadin/tests/event/EventRouterTest.java
new file mode 100644
index 0000000000..dbbeaf778e
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/event/EventRouterTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.event;
+
+import java.lang.reflect.Method;
+
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.vaadin.event.EventRouter;
+import com.vaadin.server.ErrorEvent;
+import com.vaadin.server.ErrorHandler;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Component.Listener;
+import com.vaadin.util.ReflectTools;
+
+/**
+ * Test EventRouter and related error handling.
+ */
+public class EventRouterTest {
+
+ private static final Method COMPONENT_EVENT_METHOD = ReflectTools
+ .findMethod(Component.Listener.class, "componentEvent",
+ Component.Event.class);
+
+ private EventRouter router;
+ private Component component;
+ private ErrorHandler errorHandler;
+ private Listener listener;
+
+ @Before
+ public void createMocks() {
+ router = new EventRouter();
+ component = EasyMock.createNiceMock(Component.class);
+ errorHandler = EasyMock.createMock(ErrorHandler.class);
+ listener = EasyMock.createMock(Component.Listener.class);
+ router.addListener(Component.Event.class, listener,
+ COMPONENT_EVENT_METHOD);
+ }
+
+ @Test
+ public void fireEvent_noException_eventReceived() {
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+
+ EasyMock.replay(component, listener, errorHandler);
+ router.fireEvent(new Component.Event(component), errorHandler);
+ EasyMock.verify(listener, errorHandler);
+ }
+
+ @Test
+ public void fireEvent_exceptionFromListenerAndNoHandler_exceptionPropagated() {
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+ EasyMock.expectLastCall().andThrow(
+ new RuntimeException("listener failed"));
+
+ EasyMock.replay(component, listener);
+ try {
+ router.fireEvent(new Component.Event(component));
+ Assert.fail("Did not receive expected exception from listener");
+ } catch (RuntimeException e) {
+ // e is a ListenerMethod@MethodException
+ Assert.assertEquals("listener failed", e.getCause().getMessage());
+ }
+ EasyMock.verify(listener);
+ }
+
+ @Test
+ public void fireEvent_exceptionFromListener_errorHandlerCalled() {
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+ EasyMock.expectLastCall().andThrow(
+ new RuntimeException("listener failed"));
+ errorHandler.error(EasyMock.<ErrorEvent> anyObject());
+
+ EasyMock.replay(component, listener, errorHandler);
+ router.fireEvent(new Component.Event(component), errorHandler);
+ EasyMock.verify(listener, errorHandler);
+ }
+
+ @Test
+ public void fireEvent_multipleListenersAndException_errorHandlerCalled() {
+ Listener listener2 = EasyMock.createMock(Component.Listener.class);
+ router.addListener(Component.Event.class, listener2,
+ COMPONENT_EVENT_METHOD);
+
+ listener.componentEvent(EasyMock.<Component.Event> anyObject());
+ EasyMock.expectLastCall().andThrow(
+ new RuntimeException("listener failed"));
+ errorHandler.error(EasyMock.<ErrorEvent> anyObject());
+ // second listener should be called despite an error in the first
+ listener2.componentEvent(EasyMock.<Component.Event> anyObject());
+
+ EasyMock.replay(component, listener, listener2, errorHandler);
+ router.fireEvent(new Component.Event(component), errorHandler);
+ EasyMock.verify(listener, listener2, errorHandler);
+ }
+}
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/AbsFieldValueConversionError.java b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java
index ad762f8931..887f1b8ff3 100644
--- a/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractfield/AbsFieldValueConversionError.java
@@ -54,6 +54,21 @@ public class AbsFieldValueConversionError extends TestCase {
}
+ public void testNullConversionMessages() {
+ TextField tf = new TextField();
+ tf.setConverter(new StringToIntegerConverter());
+ tf.setPropertyDataSource(new MethodProperty<String>(paulaBean, "age"));
+ tf.setConversionError(null);
+ tf.setValue("abc");
+ try {
+ tf.validate();
+ fail();
+ } catch (InvalidValueException e) {
+ Assert.assertEquals(null, e.getMessage());
+ }
+
+ }
+
public void testDefaultConversionErrorMessage() {
TextField tf = new TextField();
tf.setConverter(new StringToIntegerConverter());
diff --git a/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestVarargsItemAddition.java b/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestVarargsItemAddition.java
new file mode 100644
index 0000000000..5575b8fd3d
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/abstractselect/TestVarargsItemAddition.java
@@ -0,0 +1,26 @@
+package com.vaadin.tests.server.component.abstractselect;
+
+import java.util.Collection;
+
+import junit.framework.TestCase;
+
+import org.junit.Assert;
+
+import com.vaadin.ui.OptionGroup;
+
+public class TestVarargsItemAddition extends TestCase {
+
+ public void itemAddition() throws Exception {
+
+ OptionGroup optionGroup = new OptionGroup();
+
+ optionGroup.addItems("foo", "bar", "car");
+
+ Collection<?> itemIds = optionGroup.getItemIds();
+ Assert.assertEquals(3, itemIds.size());
+ Assert.assertTrue(itemIds.contains("foo"));
+ Assert.assertTrue(itemIds.contains("bar"));
+ Assert.assertTrue(itemIds.contains("car"));
+
+ }
+}
diff --git a/shared/src/com/vaadin/shared/communication/PushConstants.java b/shared/src/com/vaadin/shared/communication/PushConstants.java
index f16cbb7390..4b4f247e5f 100644
--- a/shared/src/com/vaadin/shared/communication/PushConstants.java
+++ b/shared/src/com/vaadin/shared/communication/PushConstants.java
@@ -27,8 +27,11 @@ public class PushConstants implements Serializable {
/**
* The size, in <b>bytes</b>, of the receiving buffer used by some servers.
+ * <p>
+ * Should not be set to a value equal to or greater than 32768 due to a
+ * Jetty 9.1 issue (see #13087)
*/
- public static final int WEBSOCKET_BUFFER_SIZE = 65536;
+ public static final int WEBSOCKET_BUFFER_SIZE = 16384;
/**
* The maximum size, in <b>characters</b>, of a websocket message fragment.
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/upload/UploadClientRpc.java b/shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java
new file mode 100644
index 0000000000..1757ddb001
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/upload/UploadClientRpc.java
@@ -0,0 +1,26 @@
+/*
+ * 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.ClientRpc;
+
+public interface UploadClientRpc extends ClientRpc {
+
+ /**
+ * Forces the upload the send selected file to the server.
+ */
+ void submitUpload();
+}
diff --git a/theme-compiler/build.xml b/theme-compiler/build.xml
index 03d0531a68..aed0f91fbb 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/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/internal/ScssStylesheet.java b/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java
index ed6b98f5ac..63f59cdfab 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/ScssStylesheet.java
@@ -24,11 +24,13 @@ 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;
@@ -457,4 +459,19 @@ public class ScssStylesheet extends Node {
public void setCharset(String charset) {
this.charset = charset;
}
+
+ 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/expression/ArithmeticExpressionEvaluator.java b/theme-compiler/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluator.java
index 7dbd8ae1a0..552b464941 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluator.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluator.java
@@ -99,7 +99,8 @@ public class ArithmeticExpressionEvaluator {
continue inputTermLoop;
}
}
- throw new ArithmeticException();
+ throw new ArithmeticException("Illegal arithmetic expression",
+ term);
}
if (current.getLexicalUnitType() == SCSSLexicalUnit.SCSS_OPERATOR_LEFT_PAREN) {
operators.push(Parentheses.LEFT);
@@ -115,7 +116,7 @@ public class ArithmeticExpressionEvaluator {
while (!operators.isEmpty()) {
Object operator = operators.pop();
if (operator == Parentheses.LEFT) {
- throw new ArithmeticException("Unexpected \"(\" found");
+ throw new ArithmeticException("Unexpected \"(\" found", term);
}
createNewOperand((BinaryOperator) operator, operands);
}
@@ -123,7 +124,7 @@ public class ArithmeticExpressionEvaluator {
if (!operands.isEmpty()) {
LexicalUnitImpl operand = (LexicalUnitImpl) operands.peek();
throw new ArithmeticException("Unexpected operand "
- + operand.toString() + " found");
+ + operand.toString() + " found", term);
}
return expression;
}
diff --git a/theme-compiler/src/com/vaadin/sass/internal/expression/exception/ArithmeticException.java b/theme-compiler/src/com/vaadin/sass/internal/expression/exception/ArithmeticException.java
index 13b6f0e936..f9ab90fc32 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/expression/exception/ArithmeticException.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/expression/exception/ArithmeticException.java
@@ -15,12 +15,28 @@
*/
package com.vaadin.sass.internal.expression.exception;
+import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+
public class ArithmeticException extends RuntimeException {
public ArithmeticException(String errorMsg) {
super(errorMsg);
}
- public ArithmeticException() {
- super("Illegal arithmetic expression");
+ public ArithmeticException(String error, LexicalUnitImpl term) {
+ super(buildMessage(error, term));
+ }
+
+ private static String buildMessage(String message, LexicalUnitImpl term) {
+ StringBuilder builder = new StringBuilder(message);
+
+ builder.append(": \"");
+ builder.append(term.toString());
+ builder.append("\" [");
+ builder.append(term.getLineNumber());
+ builder.append(",");
+ builder.append(term.getColumnNumber());
+ builder.append("]");
+
+ return builder.toString();
}
}
diff --git a/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandler.java b/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandler.java
index e6916e5070..3bf6c056c4 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandler.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/handler/SCSSDocumentHandler.java
@@ -51,8 +51,6 @@ public interface SCSSDocumentHandler extends DocumentHandler {
void endNestedProperties(String name);
- void includeDirective(String name, List<LexicalUnitImpl> args);
-
void importStyle(String uri, SACMediaList media, boolean isURL);
void property(String name, LexicalUnitImpl value, boolean important,
@@ -99,8 +97,8 @@ public interface SCSSDocumentHandler extends DocumentHandler {
void contentDirective();
- void startIncludeContentBlock(String name, List<LexicalUnitImpl> args);
+ void startInclude(String name, List<LexicalUnitImpl> args);
- void endIncludeContentBlock();
+ void endInclude();
}
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 99f00e3889..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
@@ -245,12 +247,6 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler {
}
@Override
- public void includeDirective(String name, List<LexicalUnitImpl> args) {
- MixinNode node = new MixinNode(name, args);
- nodeStack.peek().appendChild(node);
- }
-
- @Override
public void importStyle(String uri, SACMediaList media, boolean isURL) {
ImportNode node = new ImportNode(uri, media, isURL);
nodeStack.peek().appendChild(node);
@@ -375,7 +371,7 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler {
}
@Override
- public void startIncludeContentBlock(String name, List<LexicalUnitImpl> args) {
+ public void startInclude(String name, List<LexicalUnitImpl> args) {
MixinNode node = new MixinNode(name, args);
nodeStack.peek().appendChild(node);
nodeStack.push(node);
@@ -383,7 +379,20 @@ public class SCSSDocumentHandlerImpl implements SCSSDocumentHandler {
}
@Override
- public void endIncludeContentBlock() {
+ 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 0d48da34e4..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,7 +15,8 @@
*/
package com.vaadin.sass.internal.handler;
-import java.io.PrintStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.CSSParseException;
@@ -23,38 +24,33 @@ import org.w3c.css.sac.ErrorHandler;
public class SCSSErrorHandler implements ErrorHandler {
- private PrintStream errorStream;
-
- public SCSSErrorHandler(PrintStream errorStream) {
- this.errorStream = errorStream;
- }
-
public SCSSErrorHandler() {
- this(System.out);
}
@Override
public void error(CSSParseException arg0) throws CSSException {
- errorStream.println("Error when parsing file \n" + arg0.getURI()
- + " on line " + arg0.getLineNumber() + ", column "
- + arg0.getColumnNumber());
- errorStream.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 {
- errorStream.println("FATAL Error when parsing file \n" + arg0.getURI()
- + " on line " + arg0.getLineNumber() + ", column "
- + arg0.getColumnNumber());
- errorStream.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 {
- errorStream.println("Warning when parsing file \n" + arg0.getURI()
- + " on line " + arg0.getLineNumber() + ", column "
- + arg0.getColumnNumber());
- errorStream.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 cfd428e094..96f841de0b 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,22 @@
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.util.DeepCopy;
/**
@@ -247,6 +258,9 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit,
case SCSS_VARIABLE:
text = "$" + s;
break;
+ case SCSS_NULL:
+ text = "";
+ break;
case LexicalUnit.SAC_OPERATOR_COMMA:
text = ",";
break;
@@ -322,30 +336,7 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit,
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() + ")";
- }
+ text = serializeFunction(funcName);
break;
case LexicalUnit.SAC_IDENT:
text = getStringValue();
@@ -492,6 +483,11 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit,
return new LexicalUnitImpl(line, column, previous, SCSS_VARIABLE, name);
}
+ public static LexicalUnitImpl createNull(int line, int column,
+ LexicalUnitImpl previous) {
+ return new LexicalUnitImpl(line, column, previous, SCSS_NULL, "null");
+ }
+
public static LexicalUnitImpl createNumber(int line, int column,
LexicalUnitImpl previous, float v) {
int i = (int) v;
@@ -731,13 +727,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.
@@ -777,4 +766,38 @@ public class LexicalUnitImpl implements LexicalUnit, SCSSLexicalUnit,
}
}
+
+ private String serializeFunction(String funcName) {
+ return getSerializer(funcName).printState(this);
+ }
+
+ private static SCSSFunctionGenerator getSerializer(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());
+ return list;
+ }
+
+ private static final Map<String, SCSSFunctionGenerator> SERIALIZERS = new HashMap<String, SCSSFunctionGenerator>();
+
+ private static final SCSSFunctionGenerator DEFAULT_SERIALIZER = new DefaultFunctionGenerator();
+
+ 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 53d1ee78ca..e68b24355b 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
@@ -16,38 +16,41 @@
/* Generated By:JavaCC: Do not edit this line. Parser.java */
package com.vaadin.sass.internal.parser;
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URL;
+import java.io.*;
+import java.net.*;
import java.util.ArrayList;
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.CSSException;
-import org.w3c.css.sac.CSSParseException;
import org.w3c.css.sac.ConditionFactory;
+import org.w3c.css.sac.Condition;
+import org.w3c.css.sac.SelectorFactory;
+import org.w3c.css.sac.SelectorList;
+import org.w3c.css.sac.Selector;
+import org.w3c.css.sac.SimpleSelector;
import org.w3c.css.sac.DocumentHandler;
-import org.w3c.css.sac.ErrorHandler;
import org.w3c.css.sac.InputSource;
-import org.w3c.css.sac.LexicalUnit;
+import org.w3c.css.sac.ErrorHandler;
+import org.w3c.css.sac.CSSException;
+import org.w3c.css.sac.CSSParseException;
import org.w3c.css.sac.Locator;
-import org.w3c.css.sac.SelectorFactory;
-import org.w3c.css.sac.SelectorList;
-import org.w3c.flute.parser.selectors.ConditionFactoryImpl;
+import org.w3c.css.sac.LexicalUnit;
+
import org.w3c.flute.parser.selectors.SelectorFactoryImpl;
+import org.w3c.flute.parser.selectors.ConditionFactoryImpl;
+
import org.w3c.flute.util.Encoding;
-import com.vaadin.sass.internal.handler.SCSSDocumentHandlerImpl;
-import com.vaadin.sass.internal.tree.Node;
-import com.vaadin.sass.internal.tree.VariableNode;
+import com.vaadin.sass.internal.handler.*;
+
+import com.vaadin.sass.internal.tree.*;
/**
* A CSS2 parser
- *
+ *
* @author Philippe Le H�garet
* @version $Revision: 1.15 $
*/
@@ -78,32 +81,27 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
/**
* @@TODO
- * @exception CSSException
- * Not yet implemented
+ * @exception CSSException Not yet implemented
*/
- @Override
public void setLocale(Locale locale) throws CSSException {
throw new CSSException(CSSException.SAC_NOT_SUPPORTED_ERR);
}
- public InputSource getInputSource() {
+ public InputSource getInputSource(){
return source;
}
/**
* Set the document handler for this parser
*/
- @Override
public void setDocumentHandler(DocumentHandler handler) {
- documentHandler = (SCSSDocumentHandlerImpl) handler;
+ this.documentHandler = (SCSSDocumentHandlerImpl) handler;
}
- @Override
public void setSelectorFactory(SelectorFactory selectorFactory) {
this.selectorFactory = selectorFactory;
}
- @Override
public void setConditionFactory(ConditionFactory conditionFactory) {
this.conditionFactory = conditionFactory;
}
@@ -111,24 +109,19 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
/**
* Set the error handler for this parser
*/
- @Override
public void setErrorHandler(ErrorHandler error) {
- errorHandler = error;
+ this.errorHandler = error;
}
/**
* Main parse methods
- *
- * @param source
- * the source of the style sheet.
- * @exception IOException
- * the source can't be parsed.
- * @exception CSSException
- * the source is not CSS valid.
+ *
+ * @param source the source of the style sheet.
+ * @exception IOException the source can't be parsed.
+ * @exception CSSException the source is not CSS valid.
*/
- @Override
- public void parseStyleSheet(InputSource source) throws CSSException,
- IOException {
+ public void parseStyleSheet(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
if (selectorFactory == null) {
@@ -143,34 +136,26 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
/**
* Convenient method for URIs.
- *
- * @param systemId
- * the fully resolved URI of the style sheet.
- * @exception IOException
- * the source can't be parsed.
- * @exception CSSException
- * the source is not CSS valid.
+ *
+ * @param systemId the fully resolved URI of the style sheet.
+ * @exception IOException the source can't be parsed.
+ * @exception CSSException the source is not CSS valid.
*/
- @Override
- public void parseStyleSheet(String systemId) throws CSSException,
- IOException {
+ public void parseStyleSheet(String systemId)
+ throws CSSException, IOException {
parseStyleSheet(new InputSource(systemId));
}
/**
- * This method parses only one rule (style rule or at-rule, except
- * @charset).
- *
- * @param source
- * the source of the rule.
- * @exception IOException
- * the source can't be parsed.
- * @exception CSSException
- * the source is not CSS valid.
+ * This method parses only one rule (style rule or at-rule, except @charset).
+ *
+ * @param source the source of the rule.
+ * @exception IOException the source can't be parsed.
+ * @exception CSSException the source is not CSS valid.
*/
// TODO required by original parser but not used by Vaadin?
- @Override
- public void parseRule(InputSource source) throws CSSException, IOException {
+ public void parseRule(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
@@ -186,17 +171,13 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
/**
* This method parses a style declaration (including the surrounding curly
* braces).
- *
- * @param source
- * the source of the style declaration.
- * @exception IOException
- * the source can't be parsed.
- * @exception CSSException
- * the source is not CSS valid.
+ *
+ * @param source the source of the style declaration.
+ * @exception IOException the source can't be parsed.
+ * @exception CSSException the source is not CSS valid.
*/
- @Override
- public void parseStyleDeclaration(InputSource source) throws CSSException,
- IOException {
+ public void parseStyleDeclaration(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
@@ -211,10 +192,8 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
/**
* This methods returns "http://www.w3.org/TR/REC-CSS2".
- *
* @return the string "http://www.w3.org/TR/REC-CSS2".
*/
- @Override
public String getParserVersion() {
return "http://www.w3.org/TR/REC-CSS2";
}
@@ -222,8 +201,8 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
/**
* Parse methods used by DOM Level 2 implementation.
*/
- public void parseImportRule(InputSource source) throws CSSException,
- IOException {
+ public void parseImportRule(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
@@ -236,8 +215,8 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
_parseImportRule();
}
- public void parseMediaRule(InputSource source) throws CSSException,
- IOException {
+ public void parseMediaRule(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
@@ -250,16 +229,14 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
_parseMediaRule();
}
- @Override
- public SelectorList parseSelectors(InputSource source) throws CSSException,
- IOException {
+ public SelectorList parseSelectors(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
return null;
}
- @Override
public LexicalUnit parsePropertyValue(InputSource source)
throws CSSException, IOException {
this.source = source;
@@ -268,9 +245,8 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
return expr();
}
- @Override
- public boolean parsePriority(InputSource source) throws CSSException,
- IOException {
+ public boolean parsePriority(InputSource source)
+ throws CSSException, IOException {
this.source = source;
ReInit(getCharStreamWithLurk(source));
@@ -278,8 +254,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
/**
- * Convert the source into a Reader. Used only by DOM Level 2 parser
- * methods.
+ * Convert the source into a Reader. Used only by DOM Level 2 parser methods.
*/
private Reader getReader(InputSource source) throws IOException {
if (source.getCharacterStream() != null) {
@@ -291,7 +266,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
return new InputStreamReader(source.getByteStream(), "ASCII");
} else {
return new InputStreamReader(source.getByteStream(),
- source.getEncoding());
+ source.getEncoding());
}
} else {
// systemId
@@ -301,10 +276,11 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
/**
- * Convert the source into a CharStream with encoding informations. The
- * encoding can be found in the InputSource or in the CSS document. Since
- * this method marks the reader and make a reset after looking for the
- * charset declaration, you'll find the charset declaration into the stream.
+ * Convert the source into a CharStream with encoding informations.
+ * The encoding can be found in the InputSource or in the CSS document.
+ * Since this method marks the reader and make a reset after looking for
+ * the charset declaration, you'll find the charset declaration into the
+ * stream.
*/
private CharStream getCharStreamWithLurk(InputSource source)
throws CSSException, IOException {
@@ -324,7 +300,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
}
}
- // use UTF-8 as the default encoding.
+ //use UTF-8 as the default encoding.
String encoding = source.getEncoding();
InputStream input = source.getByteStream();
if (!input.markSupported()) {
@@ -334,7 +310,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
// Mark either the original stream or the wrapped stream
input.mark(100);
- if (encoding == null) {
+ if(encoding == null){
encoding = "ASCII";
char c = ' ';
@@ -343,15 +319,14 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
if (c == '@') {
// hum, is it a charset ?
- int size = 100;
+ int size = 100;
byte[] buf = new byte[size];
input.read(buf, 0, 7);
String keyword = new String(buf, 0, 7);
if (keyword.equals("charset")) {
// Yes, this is the charset declaration !
- // here I don't use the right declaration : white space are
- // ' '.
+ // here I don't use the right declaration : white space are ' '.
while ((c = (char) input.read()) == ' ') {
// find the first quote
}
@@ -378,17 +353,15 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
if (c != ';') {
// no semi colon at the end ?
throw new CSSException("invalid charset declaration: "
- + "missing semi colon");
+ + "missing semi colon");
}
encoding = new String(buf, 0, i);
if (source.getEncoding() != null) {
// compare the two encoding informations.
- // For example, I don't accept to have ASCII and after
- // UTF-8.
+ // For example, I don't accept to have ASCII and after UTF-8.
// Is it really good ? That is the question.
if (!encoding.equals(source.getEncoding())) {
- throw new CSSException(
- "invalid encoding information.");
+ throw new CSSException("invalid encoding information.");
}
}
} // else no charset declaration available
@@ -398,7 +371,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
source.setEncoding(encoding);
// set the real reader of this source.
source.setCharacterStream(new InputStreamReader(source.getByteStream(),
- Encoding.getJavaEncoding(encoding)));
+ Encoding.getJavaEncoding(encoding)));
// reset the stream (leave the charset declaration in the stream).
input.reset();
@@ -406,7 +379,6 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
private LocatorImpl currentLocator;
-
private Locator getLocator() {
if (currentLocator == null) {
currentLocator = new LocatorImpl(this);
@@ -414,7 +386,6 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
return currentLocator.reInit(this);
}
-
private LocatorImpl getLocator(Token save) {
if (currentLocator == null) {
currentLocator = new LocatorImpl(this, save);
@@ -431,8 +402,8 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
if (pe.specialConstructor) {
StringBuffer errorM = new StringBuffer();
if (pe.currentToken != null) {
- errorM.append("encountered \u005c"").append(
- pe.currentToken.next);
+ errorM.append("encountered \u005c"")
+ .append(pe.currentToken.next);
}
errorM.append('"');
if (pe.expectedTokenSequences.length != 0) {
@@ -448,10 +419,10 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
}
errorHandler.error(new CSSParseException(errorM.toString(),
- l, e));
+ l, e));
} else {
- errorHandler.error(new CSSParseException(e.getMessage(), l,
- e));
+ errorHandler.error(new CSSParseException(e.getMessage(),
+ l, e));
}
} else if (e == null) {
errorHandler.error(new CSSParseException("error", l, null));
@@ -462,5406 +433,5423 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
}
private void reportWarningSkipText(Locator l, String text) {
- if (errorHandler != null && text != null) {
+ if (errorHandler != null && text != null) {
errorHandler.warning(new CSSParseException("Skipping: " + text, l));
}
}
- /*
- * The grammar of CSS2
- */
+/*
+ * The grammar of CSS2
+ */
- /**
- * The main entry for the parser.
- *
- * @exception ParseException
- * exception during the parse
- */
- final public void parserUnit() throws ParseException {
- try {
- documentHandler.startDocument(source);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case CHARSET_SYM:
- charset();
- break;
- default:
- jj_la1[0] = jj_gen;
- ;
- }
- label_1: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- case CDO:
- case CDC:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[1] = jj_gen;
- break label_1;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- jj_consume_token(S);
- comments();
- break;
- case CDO:
- case CDC:
- case ATKEYWORD:
- ignoreStatement();
- break;
- default:
- jj_la1[2] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- label_2: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IMPORT_SYM:
- ;
- break;
- default:
- jj_la1[3] = jj_gen;
- break label_2;
- }
- importDeclaration();
- label_3: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case CDO:
- case CDC:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[4] = jj_gen;
- break label_3;
- }
- ignoreStatement();
- label_4: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[5] = jj_gen;
- break label_4;
- }
- jj_consume_token(S);
- }
- }
- }
- afterImportDeclaration();
- jj_consume_token(0);
- } finally {
- documentHandler.endDocument(source);
+/**
+ * The main entry for the parser.
+ *
+ * @exception ParseException exception during the parse
+ */
+ final public void parserUnit() throws ParseException {
+ try {
+ documentHandler.startDocument(source);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case CHARSET_SYM:
+ charset();
+ break;
+ default:
+ jj_la1[0] = jj_gen;
+ ;
+ }
+ label_1:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ case CDO:
+ case CDC:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[1] = jj_gen;
+ break label_1;
}
- }
-
- final public void charset() throws ParseException {
- Token n;
- try {
- jj_consume_token(CHARSET_SYM);
- label_5: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[6] = jj_gen;
- break label_5;
- }
- jj_consume_token(S);
- }
- n = jj_consume_token(STRING);
- label_6: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[7] = jj_gen;
- break label_6;
- }
- jj_consume_token(S);
- }
- jj_consume_token(SEMICOLON);
- } catch (ParseException e) {
- reportError(getLocator(e.currentToken.next), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
-
- } catch (Exception e) {
- reportError(getLocator(), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
-
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ jj_consume_token(S);
+ comments();
+ break;
+ case CDO:
+ case CDC:
+ case ATKEYWORD:
+ ignoreStatement();
+ break;
+ default:
+ jj_la1[2] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ label_2:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IMPORT_SYM:
+ ;
+ break;
+ default:
+ jj_la1[3] = jj_gen;
+ break label_2;
}
- }
-
- final public void afterImportDeclaration() throws ParseException {
- String ret;
- Locator l;
- label_7: while (true) {
+ importDeclaration();
+ label_3:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case CDO:
+ case CDC:
+ case ATKEYWORD:
;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case DEBUG_SYM:
- case WARN_SYM:
- debuggingDirective();
- break;
- case MIXIN_SYM:
- mixinDirective();
- break;
- case EACH_SYM:
- case IF_SYM:
- controlDirective();
- break;
- case INCLUDE_SYM:
- includeDirective();
- 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 MEDIA_SYM:
- media();
- break;
- case PAGE_SYM:
- page();
- break;
- case FONT_FACE_SYM:
- fontFace();
- break;
- case KEY_FRAME_SYM:
- keyframes();
- break;
+ break;
+ default:
+ jj_la1[4] = jj_gen;
+ break label_3;
+ }
+ ignoreStatement();
+ label_4:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[8] = jj_gen;
- if (jj_2_1(2147483647)) {
- variable();
- } else {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case VARIABLE:
- listModifyDirective();
- break;
- default:
- jj_la1[9] = jj_gen;
- l = getLocator();
- ret = skipStatement();
- if ((ret == null) || (ret.length() == 0)) {
- {
- if (true) {
- return;
- }
- }
- }
- if (ret.charAt(0) == '@') {
- documentHandler.unrecognizedRule(ret);
- } else {
- reportWarningSkipText(l, ret);
- }
- }
- }
- }
- label_8: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case CDO:
- case CDC:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[10] = jj_gen;
- break label_8;
- }
- ignoreStatement();
- label_9: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[11] = jj_gen;
- break label_9;
- }
- jj_consume_token(S);
- }
+ jj_la1[5] = jj_gen;
+ break label_4;
}
- }
- }
-
- final public void ignoreStatement() throws ParseException {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case CDO:
- jj_consume_token(CDO);
+ jj_consume_token(S);
+ }
+ }
+ }
+ afterImportDeclaration();
+ jj_consume_token(0);
+ } finally {
+ documentHandler.endDocument(source);
+ }
+ }
+
+ final public void charset() throws ParseException {
+ Token n;
+ try {
+ jj_consume_token(CHARSET_SYM);
+ label_5:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[6] = jj_gen;
+ break label_5;
+ }
+ jj_consume_token(S);
+ }
+ n = jj_consume_token(STRING);
+ label_6:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[7] = jj_gen;
+ break label_6;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(SEMICOLON);
+ } catch (ParseException e) {
+ reportError(getLocator(e.currentToken.next), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
+
+ } catch (Exception e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
+
+ }
+ }
+
+ final public void afterImportDeclaration() throws ParseException {
+ String ret;
+ Locator l;
+ label_7:
+ while (true) {
+ ;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case DEBUG_SYM:
+ case WARN_SYM:
+ debuggingDirective();
+ break;
+ case MIXIN_SYM:
+ mixinDirective();
+ break;
+ case EACH_SYM:
+ case IF_SYM:
+ controlDirective();
+ break;
+ case INCLUDE_SYM:
+ includeDirective();
+ 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 MEDIA_SYM:
+ media();
+ break;
+ case PAGE_SYM:
+ page();
+ break;
+ case FONT_FACE_SYM:
+ fontFace();
+ break;
+ case KEY_FRAME_SYM:
+ keyframes();
+ break;
+ default:
+ jj_la1[8] = jj_gen;
+ if (jj_2_1(2147483647)) {
+ variable();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case VARIABLE:
+ listModifyDirective();
break;
+ default:
+ jj_la1[9] = jj_gen;
+ l = getLocator();
+ ret = skipStatement();
+ if ((ret == null) || (ret.length() == 0)) {
+ {if (true) return;}
+ }
+ if (ret.charAt(0) == '@') {
+ documentHandler.unrecognizedRule(ret);
+ } else {
+ reportWarningSkipText(l, ret);
+ }
+ }
+ }
+ }
+ label_8:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case CDO:
case CDC:
- jj_consume_token(CDC);
- break;
case ATKEYWORD:
- atRuleDeclaration();
- break;
+ ;
+ break;
default:
- jj_la1[12] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
+ jj_la1[10] = jj_gen;
+ break label_8;
}
- }
-
- /**
- * The import statement
- *
- * @exception ParseException
- * exception during the parse
- */
- final public void importDeclaration() throws ParseException {
- Token n;
- String uri;
- MediaListImpl ml = new MediaListImpl();
- boolean isURL = false;
- try {
- jj_consume_token(IMPORT_SYM);
- label_10: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[13] = jj_gen;
- break label_10;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case STRING:
- n = jj_consume_token(STRING);
- uri = convertStringIndex(n.image, 1, n.image.length() - 1);
- break;
- case URL:
- n = jj_consume_token(URL);
- isURL = true;
- uri = n.image.substring(4, n.image.length() - 1).trim();
- if ((uri.charAt(0) == '"') || (uri.charAt(0) == '\u005c'')) {
- uri = uri.substring(1, uri.length() - 1);
- }
- break;
- default:
- jj_la1[14] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_11: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[15] = jj_gen;
- break label_11;
- }
- jj_consume_token(S);
- }
- mediaStatement(ml);
- jj_consume_token(SEMICOLON);
- label_12: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[16] = jj_gen;
- break label_12;
- }
- jj_consume_token(S);
- }
- if (ml.getLength() == 0) {
- // see section 6.3 of the CSS2 recommandation.
- ml.addItem("all");
- }
- documentHandler.importStyle(uri, ml, isURL);
- } catch (ParseException e) {
- reportError(getLocator(), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
+ ignoreStatement();
+ label_9:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[11] = jj_gen;
+ break label_9;
+ }
+ jj_consume_token(S);
+ }
+ }
+ }
+ }
+
+ final public void ignoreStatement() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case CDO:
+ jj_consume_token(CDO);
+ break;
+ case CDC:
+ jj_consume_token(CDC);
+ break;
+ case ATKEYWORD:
+ atRuleDeclaration();
+ break;
+ default:
+ jj_la1[12] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+/**
+ * The import statement
+ *
+ * @exception ParseException exception during the parse
+ */
+ final public void importDeclaration() throws ParseException {
+ Token n;
+ String uri;
+ MediaListImpl ml = new MediaListImpl();
+ boolean isURL = false;
+ try {
+ jj_consume_token(IMPORT_SYM);
+ label_10:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[13] = jj_gen;
+ break label_10;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case STRING:
+ n = jj_consume_token(STRING);
+ uri = convertStringIndex(n.image, 1,
+ n.image.length() -1);
+ break;
+ case URL:
+ n = jj_consume_token(URL);
+ isURL=true;
+ uri = n.image.substring(4, n.image.length()-1).trim();
+ if ((uri.charAt(0) == '"')
+ || (uri.charAt(0) == '\u005c'')) {
+ uri = uri.substring(1, uri.length()-1);
+ }
+ break;
+ default:
+ jj_la1[14] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_11:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[15] = jj_gen;
+ break label_11;
+ }
+ jj_consume_token(S);
+ }
+ mediaStatement(ml);
+ jj_consume_token(SEMICOLON);
+ label_12:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[16] = jj_gen;
+ break label_12;
}
- }
+ jj_consume_token(S);
+ }
+ if (ml.getLength() == 0) {
+ // see section 6.3 of the CSS2 recommandation.
+ ml.addItem("all");
+ }
+ documentHandler.importStyle(uri, ml, isURL);
+ } catch (ParseException e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void keyframes() throws ParseException {
- Token n;
- boolean start = false;
- String keyframeName = null;
- String animationname = "";
- try {
- n = jj_consume_token(KEY_FRAME_SYM);
- label_13: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[17] = jj_gen;
- break label_13;
- }
- jj_consume_token(S);
- }
- keyframeName = n.image;
- label_14: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- n = jj_consume_token(IDENT);
- animationname += n.image;
- break;
- case INTERPOLATION:
- n = jj_consume_token(INTERPOLATION);
- animationname += n.image;
- break;
- default:
- jj_la1[18] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- ;
- break;
- default:
- jj_la1[19] = jj_gen;
- break label_14;
- }
- }
- label_15: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[20] = jj_gen;
- break label_15;
- }
- jj_consume_token(S);
- }
- start = true;
- documentHandler.startKeyFrames(keyframeName, animationname);
- jj_consume_token(LBRACE);
- label_16: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[21] = jj_gen;
- break label_16;
- }
- jj_consume_token(S);
- }
- label_17: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case TO:
- case FROM:
- case CONTENT_SYM:
- case PERCENTAGE:
- ;
- break;
- default:
- jj_la1[22] = jj_gen;
- break label_17;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case TO:
- case FROM:
- case PERCENTAGE:
- keyframeSelector();
- break;
- case CONTENT_SYM:
- contentDirective();
- break;
- default:
- jj_la1[23] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- jj_consume_token(RBRACE);
- label_18: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[24] = jj_gen;
- break label_18;
- }
- jj_consume_token(S);
- }
- } catch (ParseException e) {
- reportError(getLocator(), e);
- skipStatement();
- } finally {
- if (start) {
- documentHandler.endKeyFrames();
- }
- }
}
+ }
- final public void keyframeSelector() throws ParseException {
- Token n;
- String selector = "";
- boolean start = false;
- try {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case FROM:
- n = jj_consume_token(FROM);
- break;
- case TO:
- n = jj_consume_token(TO);
- break;
- case PERCENTAGE:
- n = jj_consume_token(PERCENTAGE);
- break;
- default:
- jj_la1[25] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- selector += n.image;
- label_19: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[26] = jj_gen;
- break label_19;
- }
- jj_consume_token(S);
- }
- label_20: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[27] = jj_gen;
- break label_20;
- }
- jj_consume_token(COMMA);
- label_21: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[28] = jj_gen;
- break label_21;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case FROM:
- n = jj_consume_token(FROM);
- break;
- case TO:
- n = jj_consume_token(TO);
- break;
- case PERCENTAGE:
- n = jj_consume_token(PERCENTAGE);
- break;
- default:
- jj_la1[29] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- selector += (", " + n.image);
- label_22: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[30] = jj_gen;
- break label_22;
- }
- jj_consume_token(S);
- }
- }
- jj_consume_token(LBRACE);
- label_23: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[31] = jj_gen;
- break label_23;
- }
- jj_consume_token(S);
- }
- start = true;
- documentHandler.startKeyframeSelector(selector);
- label_24: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case MICROSOFT_RULE:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[32] = jj_gen;
- break label_24;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ifContentStatement();
- break;
- case MICROSOFT_RULE:
- microsoftExtension();
- break;
- default:
- jj_la1[33] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- jj_consume_token(RBRACE);
- label_25: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[34] = jj_gen;
- break label_25;
- }
- jj_consume_token(S);
- }
- } catch (ThrowedParseException e) {
- if (errorHandler != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.e.currentToken.next.beginLine,
- e.e.currentToken.next.beginColumn - 1);
- reportError(li, e.e);
- }
- } catch (ParseException e) {
- reportError(getLocator(), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
-
- } catch (TokenMgrError e) {
- reportWarningSkipText(getLocator(), skipStatement());
- } finally {
- if (start) {
- documentHandler.endKeyframeSelector();
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void keyframes() throws ParseException {
+ Token n;
+ boolean start = false;
+ String keyframeName = null;
+ String animationname = "";
+ try {
+ n = jj_consume_token(KEY_FRAME_SYM);
+ label_13:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[17] = jj_gen;
+ break label_13;
+ }
+ jj_consume_token(S);
+ }
+ keyframeName = n.image;
+ label_14:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ n = jj_consume_token(IDENT);
+ animationname += n.image;
+ break;
+ case INTERPOLATION:
+ n = jj_consume_token(INTERPOLATION);
+ animationname += n.image;
+ break;
+ default:
+ jj_la1[18] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
}
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- /* see http://www.w3.org/TR/css3-mediaqueries/ */
- final public void media() throws ParseException {
- boolean start = false;
- String ret;
- MediaListImpl ml = new MediaListImpl();
- try {
- jj_consume_token(MEDIA_SYM);
- label_26: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[35] = jj_gen;
- break label_26;
- }
- jj_consume_token(S);
- }
- mediaStatement(ml);
- start = true;
- documentHandler.startMedia(ml);
- jj_consume_token(LBRACE);
- label_27: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[36] = jj_gen;
- break label_27;
- }
- jj_consume_token(S);
- }
- label_28: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case CDO:
- case LBRACE:
- case DASHMATCH:
- case INCLUDES:
- case PLUS:
- case MINUS:
- case COMMA:
- case SEMICOLON:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case NONASCII:
- case DEBUG_SYM:
- case WARN_SYM:
- case STRING:
- case IDENT:
- case NUMBER:
- case URL:
- case PERCENTAGE:
- case HASH:
- 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:
- ;
- break;
- default:
- jj_la1[37] = 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();
- }
- }
- jj_consume_token(RBRACE);
- label_29: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[39] = jj_gen;
- break label_29;
- }
- jj_consume_token(S);
- }
- } catch (ParseException e) {
- reportError(getLocator(), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
-
- } finally {
- if (start) {
- documentHandler.endMedia(ml);
- }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ ;
+ break;
+ default:
+ jj_la1[19] = jj_gen;
+ break label_14;
}
- }
-
- final public void mediaStatement(MediaListImpl ml) throws ParseException {
- Token t;
- t = getToken(1);
- // loop over comma separated parts, add each to ml
- while ((t.kind != LBRACE) && (t.kind != EOF) && (t.kind != SEMICOLON)) {
- StringBuffer s = new StringBuffer();
- s.append(getToken(0).image);
- while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF)
- && (t.kind != SEMICOLON)) {
- s.append(t.image);
- getNextToken();
- t = getToken(1);
- }
- if (t.kind == COMMA) {
- // skip the comma and the token before it that is still the
- // active token
- getNextToken();
- getNextToken();
- t = getToken(1);
- }
- String str = s.toString().trim();
- if (str.length() > 0) {
- ml.addItem(str);
- }
+ }
+ label_15:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[20] = jj_gen;
+ break label_15;
+ }
+ jj_consume_token(S);
+ }
+ start = true; documentHandler.startKeyFrames(keyframeName, animationname);
+ jj_consume_token(LBRACE);
+ label_16:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[21] = jj_gen;
+ break label_16;
+ }
+ jj_consume_token(S);
+ }
+ label_17:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case TO:
+ case FROM:
+ case CONTENT_SYM:
+ case PERCENTAGE:
+ ;
+ break;
+ default:
+ jj_la1[22] = jj_gen;
+ break label_17;
}
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String medium() throws ParseException {
- Token n;
- n = jj_consume_token(IDENT);
- {
- if (true) {
- return convertIdent(n.image);
- }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case TO:
+ case FROM:
+ case PERCENTAGE:
+ keyframeSelector();
+ break;
+ case CONTENT_SYM:
+ contentDirective();
+ break;
+ default:
+ jj_la1[23] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_18:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[24] = jj_gen;
+ break label_18;
+ }
+ jj_consume_token(S);
+ }
+ } catch (ParseException e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ } finally {
+ if (start) {
+ documentHandler.endKeyFrames();
+ }
+ }
+ }
+
+ final public void keyframeSelector() throws ParseException {
+ Token n;
+ String selector = "";
+ boolean start = false;
+ try {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case FROM:
+ n = jj_consume_token(FROM);
+ break;
+ case TO:
+ n = jj_consume_token(TO);
+ break;
+ case PERCENTAGE:
+ n = jj_consume_token(PERCENTAGE);
+ break;
+ default:
+ jj_la1[25] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ selector += n.image;
+ label_19:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[26] = jj_gen;
+ break label_19;
+ }
+ jj_consume_token(S);
+ }
+ label_20:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
+ default:
+ jj_la1[27] = jj_gen;
+ break label_20;
}
- throw new Error("Missing return statement in function");
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void page() throws ParseException {
- boolean start = false;
- Token n = null;
- String page = null;
- String pseudo = null;
- try {
- jj_consume_token(PAGE_SYM);
- label_30: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[40] = jj_gen;
- break label_30;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- n = jj_consume_token(IDENT);
- label_31: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[41] = jj_gen;
- break label_31;
- }
- jj_consume_token(S);
- }
- break;
- default:
- jj_la1[42] = jj_gen;
- ;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COLON:
- pseudo = pseudo_page();
- break;
- default:
- jj_la1[43] = jj_gen;
- ;
- }
- if (n != null) {
- page = convertIdent(n.image);
- }
- jj_consume_token(LBRACE);
- label_32: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[44] = jj_gen;
- break label_32;
- }
- jj_consume_token(S);
- }
- start = true;
- documentHandler.startPage(page, pseudo);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[45] = jj_gen;
- ;
- }
- label_33: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[46] = jj_gen;
- break label_33;
- }
- jj_consume_token(SEMICOLON);
- label_34: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[47] = jj_gen;
- break label_34;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[48] = jj_gen;
- ;
- }
- }
- jj_consume_token(RBRACE);
- label_35: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[49] = jj_gen;
- break label_35;
- }
- jj_consume_token(S);
- }
- } catch (ParseException e) {
- if (errorHandler != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.currentToken.next.beginLine,
- e.currentToken.next.beginColumn - 1);
- reportError(li, e);
- skipStatement();
- // reportWarningSkipText(li, skipStatement());
- } else {
- skipStatement();
- }
- } finally {
- if (start) {
- documentHandler.endPage(page, pseudo);
- }
+ jj_consume_token(COMMA);
+ label_21:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[28] = jj_gen;
+ break label_21;
+ }
+ jj_consume_token(S);
}
- }
-
- final public String pseudo_page() throws ParseException {
- Token n;
- jj_consume_token(COLON);
- n = jj_consume_token(IDENT);
- label_36: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[50] = jj_gen;
- break label_36;
- }
- jj_consume_token(S);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case FROM:
+ n = jj_consume_token(FROM);
+ break;
+ case TO:
+ n = jj_consume_token(TO);
+ break;
+ case PERCENTAGE:
+ n = jj_consume_token(PERCENTAGE);
+ break;
+ default:
+ jj_la1[29] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
}
- {
- if (true) {
- return convertIdent(n.image);
- }
+ selector += (", " + n.image);
+ label_22:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[30] = jj_gen;
+ break label_22;
+ }
+ jj_consume_token(S);
+ }
+ }
+ jj_consume_token(LBRACE);
+ label_23:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[31] = jj_gen;
+ break label_23;
+ }
+ jj_consume_token(S);
+ }
+ start = true;
+ documentHandler.startKeyframeSelector(selector);
+ label_24:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case MICROSOFT_RULE:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[32] = jj_gen;
+ break label_24;
}
- throw new Error("Missing return statement in function");
- }
-
- final public void fontFace() throws ParseException {
- boolean start = false;
- try {
- jj_consume_token(FONT_FACE_SYM);
- label_37: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[51] = jj_gen;
- break label_37;
- }
- jj_consume_token(S);
- }
- jj_consume_token(LBRACE);
- label_38: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[52] = jj_gen;
- break label_38;
- }
- jj_consume_token(S);
- }
- start = true;
- documentHandler.startFontFace();
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[53] = jj_gen;
- ;
- }
- label_39: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[54] = jj_gen;
- break label_39;
- }
- jj_consume_token(SEMICOLON);
- label_40: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[55] = jj_gen;
- break label_40;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[56] = jj_gen;
- ;
- }
- }
- jj_consume_token(RBRACE);
- label_41: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[57] = jj_gen;
- break label_41;
- }
- jj_consume_token(S);
- }
- } catch (ParseException e) {
- reportError(getLocator(), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
-
- } finally {
- if (start) {
- documentHandler.endFontFace();
- }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ifContentStatement();
+ break;
+ case MICROSOFT_RULE:
+ microsoftExtension();
+ break;
+ default:
+ jj_la1[33] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_25:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[34] = jj_gen;
+ break label_25;
}
- }
+ jj_consume_token(S);
+ }
+ } catch (ThrowedParseException e) {
+ if (errorHandler != null) {
+ LocatorImpl li = new LocatorImpl(this,
+ e.e.currentToken.next.beginLine,
+ e.e.currentToken.next.beginColumn-1);
+ reportError(li, e.e);
+ }
+ } catch (ParseException e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void atRuleDeclaration() throws ParseException {
- Token n;
- String ret;
- n = jj_consume_token(ATKEYWORD);
- ret = skipStatement();
- if ((ret != null) && (ret.charAt(0) == '@')) {
- documentHandler.unrecognizedRule(ret);
- } else {
- reportWarningSkipText(getLocator(), ret);
+ } catch (TokenMgrError e) {
+ reportWarningSkipText(getLocator(), skipStatement());
+ } finally {
+ if (start) {
+ documentHandler.endKeyframeSelector();
}
}
+ }
- final public void skipUnknownRule() throws ParseException {
- Token n;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case ATKEYWORD:
- n = jj_consume_token(ATKEYWORD);
- break;
+/**
+ * @exception ParseException exception during the parse
+ */
+/* see http://www.w3.org/TR/css3-mediaqueries/ */
+ final public void media() throws ParseException {
+ boolean start = false;
+ String ret;
+ MediaListImpl ml = new MediaListImpl();
+ try {
+ jj_consume_token(MEDIA_SYM);
+ label_26:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[35] = jj_gen;
+ break label_26;
+ }
+ jj_consume_token(S);
+ }
+ mediaStatement(ml);
+ start = true; documentHandler.startMedia(ml);
+ jj_consume_token(LBRACE);
+ label_27:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[36] = jj_gen;
+ break label_27;
+ }
+ jj_consume_token(S);
+ }
+ label_28:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case CDO:
- n = jj_consume_token(CDO);
- break;
- case CHARSET_SYM:
- n = jj_consume_token(CHARSET_SYM);
- break;
- case COMMA:
- n = jj_consume_token(COMMA);
- break;
+ case LBRACE:
case DASHMATCH:
- n = jj_consume_token(DASHMATCH);
- break;
- case FONT_FACE_SYM:
- n = jj_consume_token(FONT_FACE_SYM);
- break;
- case FUNCTION:
- n = jj_consume_token(FUNCTION);
- break;
- case IMPORTANT_SYM:
- n = jj_consume_token(IMPORTANT_SYM);
- break;
- case IMPORT_SYM:
- n = jj_consume_token(IMPORT_SYM);
- break;
case INCLUDES:
- n = jj_consume_token(INCLUDES);
- break;
- case LBRACE:
- n = jj_consume_token(LBRACE);
- break;
- case MEDIA_SYM:
- n = jj_consume_token(MEDIA_SYM);
- break;
+ case PLUS:
+ case MINUS:
+ case COMMA:
+ case SEMICOLON:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
case NONASCII:
- n = jj_consume_token(NONASCII);
- break;
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case CONTENT_SYM:
+ case STRING:
+ case IDENT:
case NUMBER:
- n = jj_consume_token(NUMBER);
- break;
- case PAGE_SYM:
- n = jj_consume_token(PAGE_SYM);
- break;
+ case URL:
case PERCENTAGE:
- n = jj_consume_token(PERCENTAGE);
- break;
- case STRING:
- n = jj_consume_token(STRING);
- break;
+ case HASH:
+ case IMPORT_SYM:
+ case MEDIA_SYM:
+ case CHARSET_SYM:
+ case PAGE_SYM:
+ case FONT_FACE_SYM:
+ case ATKEYWORD:
+ case IMPORTANT_SYM:
case UNICODERANGE:
- n = jj_consume_token(UNICODERANGE);
- break;
- case URL:
- n = jj_consume_token(URL);
- break;
- case SEMICOLON:
- n = jj_consume_token(SEMICOLON);
- break;
- case MINUS:
- n = jj_consume_token(MINUS);
- break;
+ case FUNCTION:
case UNKNOWN:
- n = jj_consume_token(UNKNOWN);
- break;
+ ;
+ break;
default:
- jj_la1[58] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
+ jj_la1[37] = jj_gen;
+ break label_28;
+ }
+ mediaDirective();
+ }
+ jj_consume_token(RBRACE);
+ label_29:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[38] = jj_gen;
+ break label_29;
+ }
+ jj_consume_token(S);
+ }
+ } catch (ParseException e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
+
+ } finally {
+ if (start) {
+ 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[39] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void mediaStatement(MediaListImpl ml) throws ParseException {
+ Token t;
+ t = getToken(1);
+ // loop over comma separated parts, add each to ml
+ while ((t.kind != LBRACE) && (t.kind != EOF) && (t.kind != SEMICOLON)) {
+ StringBuffer s = new StringBuffer();
+ s.append(getToken(0).image);
+ while ((t.kind != COMMA) && (t.kind != LBRACE) && (t.kind != EOF) && (t.kind != SEMICOLON)) {
+ s.append(t.image);
+ getNextToken();
+ t = getToken(1);
}
- String ret;
- Locator loc = getLocator();
- ret = skipStatement();
- if ((ret != null) && (n.image.charAt(0) == '@')) {
- documentHandler.unrecognizedRule(ret);
- } else {
- reportWarningSkipText(loc, ret);
+ if (t.kind == COMMA) {
+ // skip the comma and the token before it that is still the active token
+ getNextToken();
+ getNextToken();
+ t = getToken(1);
}
- }
+ String str = s.toString().trim();
+ if (str.length() > 0) {
+ ml.addItem(str);
+ }
+ }
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public char combinator() throws ParseException {
- char connector = ' ';
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- connector = combinatorChar();
- break;
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String medium() throws ParseException {
+ Token n;
+ n = jj_consume_token(IDENT);
+ {if (true) return convertIdent(n.image);}
+ throw new Error("Missing return statement in function");
+ }
+
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void page() throws ParseException {
+ boolean start = false;
+ Token n = null;
+ String page = null;
+ String pseudo = null;
+ try {
+ jj_consume_token(PAGE_SYM);
+ label_30:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case S:
- jj_consume_token(S);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- connector = combinatorChar();
- break;
- default:
- jj_la1[59] = jj_gen;
- ;
- }
- break;
+ ;
+ break;
default:
- jj_la1[60] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
+ jj_la1[40] = jj_gen;
+ break label_30;
}
- {
- if (true) {
- return connector;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- /** to refactor combinator and reuse in selector(). */
- final public char combinatorChar() throws ParseException {
- Token t;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- t = jj_consume_token(PLUS);
- break;
- case PRECEDES:
- t = jj_consume_token(PRECEDES);
- break;
- case SIBLING:
- t = jj_consume_token(SIBLING);
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ n = jj_consume_token(IDENT);
+ label_31:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
break;
+ default:
+ jj_la1[41] = jj_gen;
+ break label_31;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[42] = jj_gen;
+ ;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COLON:
+ pseudo = pseudo_page();
+ break;
+ default:
+ jj_la1[43] = jj_gen;
+ ;
+ }
+ if (n != null) {
+ page = convertIdent(n.image);
+ }
+ jj_consume_token(LBRACE);
+ label_32:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[61] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_42: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[62] = jj_gen;
- break label_42;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return t.image.charAt(0);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public void microsoftExtension() throws ParseException {
- Token n;
- String name = "";
- String value = "";
- // This is not really taking the syntax of filter rules into account
- n = jj_consume_token(MICROSOFT_RULE);
- label_43: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[63] = jj_gen;
- break label_43;
- }
- jj_consume_token(S);
- }
- name = n.image;
- jj_consume_token(COLON);
- label_44: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- n = jj_consume_token(IDENT);
- value += n.image;
- break;
- case NUMBER:
- n = jj_consume_token(NUMBER);
- value += n.image;
- break;
- case STRING:
- n = jj_consume_token(STRING);
- value += n.image;
- break;
- case COMMA:
- n = jj_consume_token(COMMA);
- value += n.image;
- break;
- case INTERPOLATION:
- n = jj_consume_token(INTERPOLATION);
- value += n.image;
- break;
- case COLON:
- n = jj_consume_token(COLON);
- value += n.image;
- break;
- case FUNCTION:
- n = jj_consume_token(FUNCTION);
- value += n.image;
- break;
- case RPARAN:
- n = jj_consume_token(RPARAN);
- value += n.image;
- break;
- case EQ:
- n = jj_consume_token(EQ);
- value += n.image;
- break;
- case DOT:
- n = jj_consume_token(DOT);
- value += n.image;
- break;
- case S:
- n = jj_consume_token(S);
- if (value.lastIndexOf(' ') != value.length() - 1) {
- value += n.image;
- }
- break;
- default:
- jj_la1[64] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- case EQ:
- case COMMA:
- case DOT:
- case RPARAN:
- case COLON:
- case INTERPOLATION:
- case STRING:
- case IDENT:
- case NUMBER:
- case FUNCTION:
- ;
- break;
- default:
- jj_la1[65] = jj_gen;
- break label_44;
- }
+ jj_la1[44] = jj_gen;
+ break label_32;
+ }
+ jj_consume_token(S);
+ }
+ start = true;
+ documentHandler.startPage(page, pseudo);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[45] = jj_gen;
+ ;
+ }
+ label_33:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[46] = jj_gen;
+ break label_33;
}
jj_consume_token(SEMICOLON);
- label_45: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[66] = jj_gen;
- break label_45;
- }
- jj_consume_token(S);
- }
- documentHandler.microsoftDirective(name, value);
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String property() throws ParseException {
- Token t;
- String s = "";
- label_46: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- t = jj_consume_token(IDENT);
- s += t.image;
- break;
- case INTERPOLATION:
- t = jj_consume_token(INTERPOLATION);
- s += t.image;
- break;
- default:
- jj_la1[67] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- ;
- break;
- default:
- jj_la1[68] = jj_gen;
- break label_46;
- }
- }
- label_47: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[69] = jj_gen;
- break label_47;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return s;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public String variableName() throws ParseException {
- Token n;
- n = jj_consume_token(VARIABLE);
- label_48: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[70] = jj_gen;
- break label_48;
- }
- jj_consume_token(S);
+ label_34:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[47] = jj_gen;
+ break label_34;
+ }
+ jj_consume_token(S);
}
- {
- if (true) {
- return convertIdent(n.image.substring(1));
- }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[48] = jj_gen;
+ ;
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_35:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[49] = jj_gen;
+ break label_35;
+ }
+ jj_consume_token(S);
+ }
+ } catch (ParseException e) {
+ if (errorHandler != null) {
+ LocatorImpl li = new LocatorImpl(this,
+ e.currentToken.next.beginLine,
+ e.currentToken.next.beginColumn-1);
+ reportError(li, e);
+ skipStatement();
+ // reportWarningSkipText(li, skipStatement());
+ } else {
+ skipStatement();
+ }
+ } finally {
+ if (start) {
+ documentHandler.endPage(page, pseudo);
+ }
+ }
+ }
+
+ final public String pseudo_page() throws ParseException {
+ Token n;
+ jj_consume_token(COLON);
+ n = jj_consume_token(IDENT);
+ label_36:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[50] = jj_gen;
+ break label_36;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return convertIdent(n.image);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void fontFace() throws ParseException {
+ boolean start = false;
+ try {
+ jj_consume_token(FONT_FACE_SYM);
+ label_37:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[51] = jj_gen;
+ break label_37;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(LBRACE);
+ label_38:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[52] = jj_gen;
+ break label_38;
+ }
+ jj_consume_token(S);
+ }
+ start = true; documentHandler.startFontFace();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[53] = jj_gen;
+ ;
+ }
+ label_39:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[54] = jj_gen;
+ break label_39;
}
- throw new Error("Missing return statement in function");
- }
-
- final public String functionName() throws ParseException {
- Token n;
- n = jj_consume_token(FUNCTION);
- label_49: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[71] = jj_gen;
- break label_49;
- }
- jj_consume_token(S);
+ jj_consume_token(SEMICOLON);
+ label_40:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[55] = jj_gen;
+ break label_40;
+ }
+ jj_consume_token(S);
}
- {
- if (true) {
- return convertIdent(n.image.substring(0, n.image.length() - 1));
- }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[56] = jj_gen;
+ ;
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_41:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[57] = jj_gen;
+ break label_41;
}
- throw new Error("Missing return statement in function");
- }
+ jj_consume_token(S);
+ }
+ } catch (ParseException e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void styleRule() throws ParseException {
- boolean start = false;
- ArrayList<String> l = null;
- Token save;
- Locator loc;
- try {
- l = selectorList();
- save = token;
- jj_consume_token(LBRACE);
- label_50: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[72] = jj_gen;
- break label_50;
- }
- jj_consume_token(S);
- }
- start = true;
- documentHandler.startSelector(l);
- label_51: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case MICROSOFT_RULE:
- case IDENT:
- case VARIABLE:
- case HASH:
- case IMPORT_SYM:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[73] = jj_gen;
- break label_51;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ifContentStatement();
- break;
- case MICROSOFT_RULE:
- microsoftExtension();
- break;
- case IMPORT_SYM:
- importDeclaration();
- break;
- default:
- jj_la1[74] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- jj_consume_token(RBRACE);
- label_52: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[75] = jj_gen;
- break label_52;
- }
- jj_consume_token(S);
- }
- } catch (ThrowedParseException e) {
- if (errorHandler != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.e.currentToken.next.beginLine,
- e.e.currentToken.next.beginColumn - 1);
- reportError(li, e.e);
- }
- } catch (ParseException e) {
- reportError(getLocator(), e);
- skipStatement();
- // reportWarningSkipText(getLocator(), skipStatement());
-
- } catch (TokenMgrError e) {
- reportWarningSkipText(getLocator(), skipStatement());
- } finally {
- if (start) {
- documentHandler.endSelector();
- }
- }
+ } finally {
+ if (start) {
+ documentHandler.endFontFace();
+ }
}
+ }
- final public ArrayList<String> selectorList() throws ParseException {
- ArrayList<String> selectors = new ArrayList<String>();
- String selector;
- selector = selector();
- label_53: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[76] = jj_gen;
- break label_53;
- }
- jj_consume_token(COMMA);
- label_54: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[77] = jj_gen;
- break label_54;
- }
- jj_consume_token(S);
- }
- selectors.add(selector);
- selector = selector();
- }
- selectors.add(selector);
- {
- if (true) {
- return selectors;
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void atRuleDeclaration() throws ParseException {
+ Token n;
+ String ret;
+ n = jj_consume_token(ATKEYWORD);
+ ret=skipStatement();
+ if ((ret != null) && (ret.charAt(0) == '@')) {
+ documentHandler.unrecognizedRule(ret);
+ } else {
+ reportWarningSkipText(getLocator(), ret);
}
- throw new Error("Missing return statement in function");
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String selector() throws ParseException {
- String selector = null;
- char comb;
- try {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case IDENT:
- case HASH:
- selector = simple_selector(null, ' ');
- break;
- case PLUS:
- case PRECEDES:
- case SIBLING:
- comb = combinatorChar();
- selector = simple_selector(selector, comb);
- break;
- default:
- jj_la1[78] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_55: while (true) {
- if (jj_2_2(2)) {
- ;
- } else {
- break label_55;
- }
- comb = combinator();
- selector = simple_selector(selector, comb);
- }
- label_56: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[79] = jj_gen;
- break label_56;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return selector;
- }
- }
- } catch (ParseException e) {
- /*
- * Token t = getToken(1); StringBuffer s = new StringBuffer();
- * s.append(getToken(0).image); while ((t.kind != COMMA) && (t.kind
- * != SEMICOLON) && (t.kind != LBRACE) && (t.kind != EOF)) {
- * s.append(t.image); getNextToken(); t = getToken(1); }
- * reportWarningSkipText(getLocator(), s.toString());
- */
- Token t = getToken(1);
- while ((t.kind != COMMA) && (t.kind != SEMICOLON)
- && (t.kind != LBRACE) && (t.kind != EOF)) {
- getNextToken();
- t = getToken(1);
- }
+ }
+
+ final public void skipUnknownRule() throws ParseException {
+ Token n;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ATKEYWORD:
+ n = jj_consume_token(ATKEYWORD);
+ break;
+ case CDO:
+ n = jj_consume_token(CDO);
+ break;
+ case CHARSET_SYM:
+ n = jj_consume_token(CHARSET_SYM);
+ break;
+ case COMMA:
+ n = jj_consume_token(COMMA);
+ break;
+ case DASHMATCH:
+ n = jj_consume_token(DASHMATCH);
+ break;
+ case FONT_FACE_SYM:
+ n = jj_consume_token(FONT_FACE_SYM);
+ break;
+ case FUNCTION:
+ n = jj_consume_token(FUNCTION);
+ break;
+ case IMPORTANT_SYM:
+ n = jj_consume_token(IMPORTANT_SYM);
+ break;
+ case IMPORT_SYM:
+ n = jj_consume_token(IMPORT_SYM);
+ break;
+ case INCLUDES:
+ n = jj_consume_token(INCLUDES);
+ break;
+ case LBRACE:
+ n = jj_consume_token(LBRACE);
+ break;
+ case MEDIA_SYM:
+ n = jj_consume_token(MEDIA_SYM);
+ break;
+ case NONASCII:
+ n = jj_consume_token(NONASCII);
+ break;
+ case NUMBER:
+ n = jj_consume_token(NUMBER);
+ break;
+ case PAGE_SYM:
+ n = jj_consume_token(PAGE_SYM);
+ break;
+ case PERCENTAGE:
+ n = jj_consume_token(PERCENTAGE);
+ break;
+ case STRING:
+ n = jj_consume_token(STRING);
+ break;
+ case UNICODERANGE:
+ n = jj_consume_token(UNICODERANGE);
+ break;
+ case URL:
+ n = jj_consume_token(URL);
+ break;
+ case SEMICOLON:
+ n = jj_consume_token(SEMICOLON);
+ break;
+ case MINUS:
+ n = jj_consume_token(MINUS);
+ break;
+ case UNKNOWN:
+ n = jj_consume_token(UNKNOWN);
+ break;
+ default:
+ jj_la1[58] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ String ret;
+ Locator loc = getLocator();
+ ret=skipStatement();
+ if ((ret != null) && (n.image.charAt(0) == '@')) {
+ documentHandler.unrecognizedRule(ret);
+ } else {
+ reportWarningSkipText(loc, ret);
+ }
+ }
- {
- if (true) {
- throw new ThrowedParseException(e);
- }
- }
- }
- throw new Error("Missing return statement in function");
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public char combinator() throws ParseException {
+char connector = ' ';
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ connector = combinatorChar();
+ break;
+ case S:
+ jj_consume_token(S);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ connector = combinatorChar();
+ break;
+ default:
+ jj_la1[59] = jj_gen;
+ ;
+ }
+ break;
+ default:
+ jj_la1[60] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ {if (true) return connector;}
+ throw new Error("Missing return statement in function");
+ }
+
+/**to refactor combinator and reuse in selector().*/
+ final public char combinatorChar() throws ParseException {
+ Token t;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ t = jj_consume_token(PLUS);
+ break;
+ case PRECEDES:
+ t = jj_consume_token(PRECEDES);
+ break;
+ case SIBLING:
+ t = jj_consume_token(SIBLING);
+ break;
+ default:
+ jj_la1[61] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_42:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[62] = jj_gen;
+ break label_42;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return t.image.charAt(0);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void microsoftExtension() throws ParseException {
+ Token n;
+ String name = "";
+ String value = "";
+ // This is not really taking the syntax of filter rules into account
+ n = jj_consume_token(MICROSOFT_RULE);
+ label_43:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[63] = jj_gen;
+ break label_43;
+ }
+ jj_consume_token(S);
+ }
+ name = n.image;
+ jj_consume_token(COLON);
+ label_44:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ n = jj_consume_token(IDENT);
+ value += n.image;
+ break;
+ case NUMBER:
+ n = jj_consume_token(NUMBER);
+ value += n.image;
+ break;
+ case STRING:
+ n = jj_consume_token(STRING);
+ value += n.image;
+ break;
+ case COMMA:
+ n = jj_consume_token(COMMA);
+ value += n.image;
+ break;
+ case INTERPOLATION:
+ n = jj_consume_token(INTERPOLATION);
+ value += n.image;
+ break;
+ case COLON:
+ n = jj_consume_token(COLON);
+ value += n.image;
+ break;
+ case FUNCTION:
+ n = jj_consume_token(FUNCTION);
+ value += n.image;
+ break;
+ case RPARAN:
+ n = jj_consume_token(RPARAN);
+ value += n.image;
+ break;
+ case EQ:
+ n = jj_consume_token(EQ);
+ value += n.image;
+ break;
+ case DOT:
+ n = jj_consume_token(DOT);
+ value += n.image;
+ break;
+ case S:
+ n = jj_consume_token(S);
+ if(value.lastIndexOf(' ') != value.length()-1)
+ { value += n.image; }
+ break;
+ default:
+ jj_la1[64] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ case EQ:
+ case COMMA:
+ case DOT:
+ case RPARAN:
+ case COLON:
+ case INTERPOLATION:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case FUNCTION:
+ ;
+ break;
+ default:
+ jj_la1[65] = jj_gen;
+ break label_44;
+ }
+ }
+ jj_consume_token(SEMICOLON);
+ label_45:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[66] = jj_gen;
+ break label_45;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.microsoftDirective(name, value);
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String simple_selector(String selector, char comb)
- throws ParseException {
- String simple_current = null;
- String cond = null;
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String property() throws ParseException {
+ Token t;String s = "";
+ label_46:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ t = jj_consume_token(IDENT);
+ s += t.image;
+ break;
+ case INTERPOLATION:
+ t = jj_consume_token(INTERPOLATION);
+ s += t.image;
+ break;
+ default:
+ jj_la1[67] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ ;
+ break;
+ default:
+ jj_la1[68] = jj_gen;
+ break label_46;
+ }
+ }
+ label_47:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[69] = jj_gen;
+ break label_47;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return s;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public String variableName() throws ParseException {
+ Token n;
+ n = jj_consume_token(VARIABLE);
+ label_48:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[70] = jj_gen;
+ break label_48;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return convertIdent(n.image.substring(1));}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public String functionName() throws ParseException {
+ Token n;
+ n = jj_consume_token(FUNCTION);
+ label_49:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[71] = jj_gen;
+ break label_49;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return convertIdent(n.image.substring(0, n.image.length()-1));}
+ throw new Error("Missing return statement in function");
+ }
- pseudoElt = null;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void styleRule() throws ParseException {
+ boolean start = false;
+ ArrayList<String> l = null;
+ Token save;
+ Locator loc;
+ try {
+ l = selectorList();
+ save = token;
+ jj_consume_token(LBRACE);
+ label_50:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[72] = jj_gen;
+ break label_50;
+ }
+ jj_consume_token(S);
+ }
+ start = true;
+ documentHandler.startSelector(l);
+ label_51:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
case ANY:
case PARENT:
+ case DOT:
+ case COLON:
case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case MICROSOFT_RULE:
case IDENT:
- simple_current = element_name();
- label_57: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case LBRACKET:
- case DOT:
- case COLON:
- case HASH:
- ;
- break;
- default:
- jj_la1[80] = jj_gen;
- break label_57;
- }
- 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[81] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- break;
+ case VARIABLE:
+ case HASH:
+ case IMPORT_SYM:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[73] = jj_gen;
+ break label_51;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
case LBRACKET:
+ case ANY:
+ case PARENT:
case DOT:
case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
case HASH:
- label_58: while (true) {
- 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[82] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case LBRACKET:
- case DOT:
- case COLON:
- case HASH:
- ;
- break;
- default:
- jj_la1[83] = jj_gen;
- break label_58;
- }
- }
- break;
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ifContentStatement();
+ break;
+ case MICROSOFT_RULE:
+ microsoftExtension();
+ break;
+ case IMPORT_SYM:
+ importDeclaration();
+ break;
default:
- jj_la1[84] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- if (simple_current == null) {
- simple_current = "";
- }
- if (cond != null) {
- simple_current = simple_current + cond;
- }
- StringBuilder builder = new StringBuilder();
- switch (comb) {
- case ' ':
- if (selector != null) {
- builder.append(selector).append(" ");
- }
- break;
- case '+':
- case '>':
- case '~':
- if (selector != null) {
- builder.append(selector).append(" ");
- }
- builder.append(comb).append(" ");
- break;
- default: {
- if (true) {
- throw new ParseException("invalid state. send a bug report");
- }
- }
- }
- builder.append(simple_current);
- selector = builder.toString();
-
- if (pseudoElt != null) {
- selector = selector + pseudoElt;
- }
- {
- if (true) {
- return selector;
- }
+ jj_la1[74] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_52:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[75] = jj_gen;
+ break label_52;
+ }
+ jj_consume_token(S);
+ }
+ } catch (ThrowedParseException e) {
+ if (errorHandler != null) {
+ LocatorImpl li = new LocatorImpl(this,
+ e.e.currentToken.next.beginLine,
+ e.e.currentToken.next.beginColumn-1);
+ reportError(li, e.e);
+ }
+ } catch (ParseException e) {
+ reportError(getLocator(), e);
+ skipStatement();
+ // reportWarningSkipText(getLocator(), skipStatement());
+
+ } catch (TokenMgrError e) {
+ reportWarningSkipText(getLocator(), skipStatement());
+ } finally {
+ if (start) {
+ documentHandler.endSelector();
+ }
+ }
+ }
+
+ final public ArrayList<String> selectorList() throws ParseException {
+ ArrayList<String> selectors = new ArrayList<String>();
+ String selector;
+ selector = selector();
+ label_53:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
+ default:
+ jj_la1[76] = jj_gen;
+ break label_53;
+ }
+ jj_consume_token(COMMA);
+ label_54:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[77] = jj_gen;
+ break label_54;
}
- throw new Error("Missing return statement in function");
+ jj_consume_token(S);
+ }
+ selectors.add(selector);
+ selector = selector();
}
+ selectors.add(selector);
+ {if (true) return selectors;}
+ throw new Error("Missing return statement in function");
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String _class(String pred) throws ParseException {
- Token t;
- String s = ".";
- jj_consume_token(DOT);
- label_59: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- t = jj_consume_token(IDENT);
- s += t.image;
- break;
- case INTERPOLATION:
- t = jj_consume_token(INTERPOLATION);
- s += t.image;
- break;
- default:
- jj_la1[85] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- ;
- break;
- default:
- jj_la1[86] = jj_gen;
- break label_59;
- }
- }
- if (pred == null) {
- {
- if (true) {
- return s;
- }
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String selector() throws ParseException {
+ String selector = null;
+ char comb;
+ try {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case IDENT:
+ case HASH:
+ selector = simple_selector(null, ' ');
+ break;
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ comb = combinatorChar();
+ selector = simple_selector(selector, comb);
+ break;
+ default:
+ jj_la1[78] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_55:
+ while (true) {
+ if (jj_2_2(2)) {
+ ;
} else {
- {
- if (true) {
- return pred + s;
- }
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String element_name() throws ParseException {
- Token t;
- String s = "";
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- label_60: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- t = jj_consume_token(IDENT);
- s += t.image;
- break;
- case INTERPOLATION:
- t = jj_consume_token(INTERPOLATION);
- s += t.image;
- break;
- default:
- jj_la1[87] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- ;
- break;
- default:
- jj_la1[88] = jj_gen;
- break label_60;
- }
- }
- {
- if (true) {
- return s;
- }
- }
- break;
- case ANY:
- jj_consume_token(ANY);
- {
- if (true) {
- return "*";
- }
- }
- break;
- case PARENT:
- jj_consume_token(PARENT);
- {
- if (true) {
- return "&";
- }
- }
- break;
+ break label_55;
+ }
+ comb = combinator();
+ selector = simple_selector(selector, comb);
+ }
+ label_56:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[89] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- throw new Error("Missing return statement in function");
+ jj_la1[79] = jj_gen;
+ break label_56;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return selector;}
+ } catch (ParseException e) {
+ /*
+ Token t = getToken(1);
+ StringBuffer s = new StringBuffer();
+ s.append(getToken(0).image);
+ while ((t.kind != COMMA) && (t.kind != SEMICOLON)
+ && (t.kind != LBRACE) && (t.kind != EOF)) {
+ s.append(t.image);
+ getNextToken();
+ t = getToken(1);
+ }
+ reportWarningSkipText(getLocator(), s.toString());
+ */
+ Token t = getToken(1);
+ while ((t.kind != COMMA) && (t.kind != SEMICOLON)
+ && (t.kind != LBRACE) && (t.kind != EOF)) {
+ getNextToken();
+ t = getToken(1);
+ }
+
+ {if (true) throw new ThrowedParseException(e);}
}
+ throw new Error("Missing return statement in function");
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String attrib(String pred) throws ParseException {
- int cases = 0;
- Token att = null;
- Token val = null;
- String attValue = null;
- jj_consume_token(LBRACKET);
- label_61: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[90] = jj_gen;
- break label_61;
- }
- jj_consume_token(S);
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String simple_selector(String selector, char comb) throws ParseException {
+ String simple_current = null;
+ String cond = null;
+
+ pseudoElt = null;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ANY:
+ case PARENT:
+ case INTERPOLATION:
+ case IDENT:
+ simple_current = element_name();
+ label_57:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ case DOT:
+ case COLON:
+ case HASH:
+ ;
+ break;
+ default:
+ jj_la1[80] = jj_gen;
+ break label_57;
}
- att = jj_consume_token(IDENT);
- label_62: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[91] = jj_gen;
- break label_62;
- }
- jj_consume_token(S);
+ 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[81] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ break;
+ case LBRACKET:
+ case DOT:
+ case COLON:
+ case HASH:
+ label_58:
+ while (true) {
+ 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[82] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
}
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case DASHMATCH:
- case CARETMATCH:
- case DOLLARMATCH:
- case STARMATCH:
- case INCLUDES:
- case EQ:
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case EQ:
- jj_consume_token(EQ);
- cases = 1;
- break;
- case INCLUDES:
- jj_consume_token(INCLUDES);
- cases = 2;
- break;
- case DASHMATCH:
- jj_consume_token(DASHMATCH);
- cases = 3;
- break;
- case CARETMATCH:
- jj_consume_token(CARETMATCH);
- cases = 4;
- break;
- case DOLLARMATCH:
- jj_consume_token(DOLLARMATCH);
- cases = 5;
- break;
- case STARMATCH:
- jj_consume_token(STARMATCH);
- cases = 6;
- break;
- default:
- jj_la1[92] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_63: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACKET:
+ case DOT:
+ case COLON:
+ case HASH:
+ ;
+ break;
+ default:
+ jj_la1[83] = jj_gen;
+ break label_58;
+ }
+ }
+ break;
+ default:
+ jj_la1[84] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ if (simple_current == null) {
+ simple_current = "";
+ }
+ if (cond != null) {
+ simple_current = simple_current + cond;
+ }
+ StringBuilder builder = new StringBuilder();
+ switch (comb) {
+ case ' ':
+ if(selector!=null){
+ builder.append(selector).append(" ");
+ }
break;
- default:
- jj_la1[93] = jj_gen;
- break label_63;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- val = jj_consume_token(IDENT);
- attValue = val.image;
- break;
- case STRING:
- val = jj_consume_token(STRING);
- attValue = val.image;
- break;
- default:
- jj_la1[94] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_64: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
+ case '+':
+ case '>':
+ case '~':
+ if(selector!=null){
+ builder.append(selector).append(" ");
+ }
+ builder.append(comb).append(" ");
break;
default:
- jj_la1[95] = jj_gen;
- break label_64;
- }
- jj_consume_token(S);
- }
- break;
- default:
- jj_la1[96] = jj_gen;
- ;
- }
- jj_consume_token(RBRACKET);
- String name = convertIdent(att.image);
- String c;
- switch (cases) {
- case 0:
- c = name;
- break;
- case 1:
- c = name + "=" + attValue;
- break;
- case 2:
- c = name + "~=" + attValue;
- break;
- case 3:
- c = name + "|=" + attValue;
- break;
- case 4:
- c = name + "^=" + attValue;
- break;
- case 5:
- c = name + "$=" + attValue;
- break;
- case 6:
- c = name + "*=" + attValue;
- break;
- default:
- // never reached.
- c = null;
- }
- c = "[" + c + "]";
- if (pred == null) {
- {
- if (true) {
- return c;
- }
+ {if (true) throw new ParseException("invalid state. send a bug report");}
}
- } else {
- {
- if (true) {
- return pred + c;
- }
+ builder.append(simple_current);
+ selector = builder.toString();
+
+ if (pseudoElt != null) {
+ selector = selector + pseudoElt;
}
- }
- throw new Error("Missing return statement in function");
- }
+ {if (true) return selector;}
+ throw new Error("Missing return statement in function");
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String pseudo(String pred) throws ParseException {
- Token n;
- Token param;
- String d;
- boolean isPseudoElement = false;
- jj_consume_token(COLON);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COLON:
- jj_consume_token(COLON);
- isPseudoElement = true;
- break;
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String _class(String pred) throws ParseException {
+ Token t;
+String s = ".";
+ jj_consume_token(DOT);
+ label_59:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ t = jj_consume_token(IDENT);
+ s += t.image;
+ break;
+ case INTERPOLATION:
+ t = jj_consume_token(INTERPOLATION);
+ s += t.image;
+ break;
+ default:
+ jj_la1[85] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ ;
+ break;
+ default:
+ jj_la1[86] = jj_gen;
+ break label_59;
+ }
+ }
+ if (pred == null) {
+ {if (true) return s;}
+ } else {
+ {if (true) return pred + s;}
+ }
+ throw new Error("Missing return statement in function");
+ }
+
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String element_name() throws ParseException {
+ Token t; String s = "";
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ label_60:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ t = jj_consume_token(IDENT);
+ s += t.image;
+ break;
+ case INTERPOLATION:
+ t = jj_consume_token(INTERPOLATION);
+ s += t.image;
+ break;
default:
- jj_la1[97] = jj_gen;
- ;
+ jj_la1[87] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
}
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
case IDENT:
- n = jj_consume_token(IDENT);
+ ;
+ break;
+ default:
+ jj_la1[88] = jj_gen;
+ break label_60;
+ }
+ }
+ {if (true) return s;}
+ break;
+ case ANY:
+ jj_consume_token(ANY);
+ {if (true) return "*";}
+ break;
+ case PARENT:
+ jj_consume_token(PARENT);
+ {if (true) return "&";}
+ break;
+ default:
+ jj_la1[89] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ throw new Error("Missing return statement in function");
+ }
+
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String attrib(String pred) throws ParseException {
+ int cases = 0;
+ Token att = null;
+ Token val = null;
+ String attValue = null;
+ jj_consume_token(LBRACKET);
+ label_61:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[90] = jj_gen;
+ break label_61;
+ }
+ jj_consume_token(S);
+ }
+ att = jj_consume_token(IDENT);
+ label_62:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[91] = jj_gen;
+ break label_62;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case DASHMATCH:
+ case CARETMATCH:
+ case DOLLARMATCH:
+ case STARMATCH:
+ case INCLUDES:
+ case EQ:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case EQ:
+ jj_consume_token(EQ);
+ cases = 1;
+ break;
+ case INCLUDES:
+ jj_consume_token(INCLUDES);
+ cases = 2;
+ break;
+ case DASHMATCH:
+ jj_consume_token(DASHMATCH);
+ cases = 3;
+ break;
+ case CARETMATCH:
+ jj_consume_token(CARETMATCH);
+ cases = 4;
+ break;
+ case DOLLARMATCH:
+ jj_consume_token(DOLLARMATCH);
+ cases = 5;
+ break;
+ case STARMATCH:
+ jj_consume_token(STARMATCH);
+ cases = 6;
+ break;
+ default:
+ jj_la1[92] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_63:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[93] = jj_gen;
+ break label_63;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ val = jj_consume_token(IDENT);
+ attValue = val.image;
+ break;
+ case STRING:
+ val = jj_consume_token(STRING);
+ attValue = val.image;
+ break;
+ default:
+ jj_la1[94] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_64:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[95] = jj_gen;
+ break label_64;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[96] = jj_gen;
+ ;
+ }
+ jj_consume_token(RBRACKET);
+ String name = convertIdent(att.image);
+ String c;
+ switch (cases) {
+ case 0:
+ c = name;
+ break;
+ case 1:
+ c = name + "=" + attValue;
+ break;
+ case 2:
+ c = name + "~=" + attValue;
+ break;
+ case 3:
+ c = name + "|=" +attValue;
+ break;
+ case 4:
+ c = name + "^=" +attValue;
+ break;
+ case 5:
+ c = name + "$=" +attValue;
+ break;
+ case 6:
+ c = name + "*=" +attValue;
+ break;
+ default:
+ // never reached.
+ c = null;
+ }
+ c = "[" + c + "]";
+ if (pred == null) {
+ {if (true) return c;}
+ } else {
+ {if (true) return pred + c;}
+ }
+ throw new Error("Missing return statement in function");
+ }
+
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String pseudo(String pred) throws ParseException {
+ Token n;
+Token param;
+String d;
+boolean isPseudoElement = false;
+ jj_consume_token(COLON);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COLON:
+ jj_consume_token(COLON);
+ isPseudoElement=true;
+ break;
+ default:
+ jj_la1[97] = jj_gen;
+ ;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ n = jj_consume_token(IDENT);
String s = ":" + convertIdent(n.image);
if (isPseudoElement) {
if (pseudoElt != null) {
- {
- if (true) {
- throw new CSSParseException(
- "duplicate pseudo element definition " + s,
- getLocator());
- }
- }
+ {if (true) throw new CSSParseException("duplicate pseudo element definition "
+ + s, getLocator());}
} else {
- pseudoElt = ":" + s;
- {
- if (true) {
- return pred;
- }
- }
+ pseudoElt = ":"+s;
+ {if (true) return pred;}
}
} else {
String c = s;
if (pred == null) {
- {
- if (true) {
- return c;
- }
- }
+ {if (true) return c;}
} else {
- {
- if (true) {
- return pred + c;
- }
- }
- }
- }
- break;
- case FUNCTION:
- n = jj_consume_token(FUNCTION);
- label_65: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[98] = jj_gen;
- break label_65;
+ {if (true) return pred + c;}
}
- jj_consume_token(S);
}
- d = skipStatementUntilMatchingRightParan();
- jj_consume_token(RPARAN);
- // accept anything between function and a right parenthesis
- String f = convertIdent(n.image);
- String colons = isPseudoElement ? "::" : ":";
- String pseudofn = colons + f + d + ")";
- if (pred == null) {
- {
- if (true) {
- return pseudofn;
- }
- }
- } else {
- {
- if (true) {
- return pred + pseudofn;
- }
- }
- }
- break;
+ break;
+ case FUNCTION:
+ n = jj_consume_token(FUNCTION);
+ label_65:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[99] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- throw new Error("Missing return statement in function");
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String hash(String pred) throws ParseException {
- Token n;
- n = jj_consume_token(HASH);
- String d = n.image;
- if (pred == null) {
- {
- if (true) {
- return d;
- }
- }
- } else {
- {
- if (true) {
- return pred + d;
- }
- }
- }
- throw new Error("Missing return statement in function");
- }
+ jj_la1[98] = jj_gen;
+ break label_65;
+ }
+ jj_consume_token(S);
+ }
+ d = skipStatementUntilMatchingRightParan();
+ jj_consume_token(RPARAN);
+ // accept anything between function and a right parenthesis
+ String f = convertIdent(n.image);
+ String colons = isPseudoElement ? "::" : ":";
+ String pseudofn = colons + f + d + ")";
+ if (pred == null) {
+ {if (true) return pseudofn;}
+ } else {
+ {if (true) return pred + pseudofn;}
+ }
+ break;
+ default:
+ jj_la1[99] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ throw new Error("Missing return statement in function");
+ }
- final public void variable() throws ParseException {
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String hash(String pred) throws ParseException {
+ Token n;
+ n = jj_consume_token(HASH);
+ String d = n.image;
+ if (pred == null) {
+ {if (true) return d;}
+ } else {
+ {if (true) return pred + d;}
+ }
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void variable() throws ParseException {
String name;
LexicalUnitImpl exp = null;
boolean guarded = false;
String raw;
- try {
- name = variableName();
- jj_consume_token(COLON);
- label_66: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[100] = jj_gen;
- break label_66;
- }
- jj_consume_token(S);
- }
- exp = expr();
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case GUARDED_SYM:
- guarded = guarded();
- break;
- default:
- jj_la1[101] = jj_gen;
- ;
- }
- label_67: while (true) {
- jj_consume_token(SEMICOLON);
- label_68: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[102] = jj_gen;
- break label_68;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[103] = jj_gen;
- break label_67;
- }
- }
- documentHandler.variable(name, exp, guarded);
- } catch (JumpException e) {
+ try {
+ name = variableName();
+ jj_consume_token(COLON);
+ label_66:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[100] = jj_gen;
+ break label_66;
+ }
+ jj_consume_token(S);
+ }
+ exp = expr();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case GUARDED_SYM:
+ guarded = guarded();
+ break;
+ default:
+ jj_la1[101] = jj_gen;
+ ;
+ }
+ label_67:
+ while (true) {
+ jj_consume_token(SEMICOLON);
+ label_68:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[102] = jj_gen;
+ break label_68;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[103] = jj_gen;
+ break label_67;
+ }
+ }
+ exp = replaceNullValues(exp);
+ documentHandler.variable(name, exp, guarded);
+ } catch (JumpException e) {
skipAfterExpression();
- } catch (NumberFormatException e) {
+ } catch (NumberFormatException e) {
if (errorHandler != null) {
errorHandler.error(new CSSParseException("Invalid number "
- + e.getMessage(), getLocator(), e));
+ + e.getMessage(),
+ getLocator(),
+ e));
}
reportWarningSkipText(getLocator(), skipAfterExpression());
- } catch (ParseException e) {
+ } catch (ParseException e) {
if (errorHandler != null) {
if (e.currentToken != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.currentToken.next.beginLine,
- e.currentToken.next.beginColumn - 1);
- reportError(li, e);
+ LocatorImpl li = new LocatorImpl(this,
+ e.currentToken.next.beginLine,
+ e.currentToken.next.beginColumn-1);
+ reportError(li, e);
} else {
- reportError(getLocator(), e);
- }
+ reportError(getLocator(), e);
+ }
skipAfterExpression();
} else {
skipAfterExpression();
}
- }
}
+ }
- final public void controlDirective() throws ParseException {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IF_SYM:
- ifDirective();
- break;
+ LexicalUnitImpl replaceNullValues(LexicalUnitImpl unit) throws ParseException {
+ if(unit == null){
+ return null;
+ }
+ if (unit.getNextLexicalUnit() != null) {
+ unit.setNextLexicalUnit(replaceNullValues(unit.getNextLexicalUnit()));
+ }
+ if (unit.getLexicalUnitType() == SCSSLexicalUnit.SAC_IDENT
+ && "null".equals(unit.getStringValue())) {
+ LexicalUnitImpl next = unit.getNextLexicalUnit();
+ unit = LexicalUnitImpl.createNull(unit.getLineNumber(), unit.getColumnNumber(),
+ unit.getPreviousLexicalUnit());
+ unit.setNextLexicalUnit(next);
+ }
+ return unit;
+ }
+
+ final public void controlDirective() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IF_SYM:
+ ifDirective();
+ break;
+ case EACH_SYM:
+ eachDirective();
+ break;
+ default:
+ jj_la1[104] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void ifContentStatement() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case CONTENT_SYM:
+ contentDirective();
+ break;
+ case INCLUDE_SYM:
+ includeDirective();
+ break;
+ case MEDIA_SYM:
+ media();
+ break;
+ case EXTEND_SYM:
+ extendDirective();
+ break;
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case IDENT:
+ case HASH:
+ styleRuleOrDeclarationOrNestedProperties();
+ break;
+ case KEY_FRAME_SYM:
+ keyframes();
+ break;
+ default:
+ jj_la1[105] = jj_gen;
+ if (jj_2_3(2147483647)) {
+ variable();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case VARIABLE:
+ listModifyDirective();
+ break;
case EACH_SYM:
- eachDirective();
- break;
+ case IF_SYM:
+ controlDirective();
+ break;
+ case ATKEYWORD:
+ atRuleDeclaration();
+ break;
default:
- jj_la1[104] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void ifContentStatement() throws ParseException {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case CONTENT_SYM:
- contentDirective();
- break;
- case INCLUDE_SYM:
- includeDirective();
- break;
- case MEDIA_SYM:
- media();
- break;
- case EXTEND_SYM:
- extendDirective();
- break;
+ jj_la1[106] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ }
+ }
+
+ final public void ifDirective() throws ParseException {
+ Token n = null;
+ String s = null;
+ String evaluator = "";
+ jj_consume_token(IF_SYM);
+ label_69:
+ while (true) {
+ s = booleanExpressionToken();
+ evaluator += s;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ case EQ:
+ case PLUS:
+ case MINUS:
+ case PRECEDES:
+ case SUCCEEDS:
+ case DIV:
+ case ANY:
+ case LPARAN:
+ case RPARAN:
+ case COMPARE:
+ case OR:
+ case AND:
+ case NOT_EQ:
+ case IDENT:
+ case NUMBER:
+ case VARIABLE:
+ case CONTAINS:
+ ;
+ break;
+ default:
+ jj_la1[107] = jj_gen;
+ break label_69;
+ }
+ }
+ jj_consume_token(LBRACE);
+ label_70:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[108] = jj_gen;
+ break label_70;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.startIfElseDirective();
+ documentHandler.ifDirective(evaluator);
+ label_71:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case FONT_FACE_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[109] = jj_gen;
+ break label_71;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ifContentStatement();
+ break;
+ case FONT_FACE_SYM:
+ fontFace();
+ break;
+ default:
+ jj_la1[110] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_72:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[111] = jj_gen;
+ break label_72;
+ }
+ jj_consume_token(S);
+ }
+ label_73:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case ELSE_SYM:
+ ;
+ break;
+ default:
+ jj_la1[112] = jj_gen;
+ break label_73;
+ }
+ elseDirective();
+ }
+ documentHandler.endIfElseDirective();
+ }
+
+ final public void elseDirective() throws ParseException {
+ String evaluator = "";
+ Token n = null;
+ String s = null;
+ jj_consume_token(ELSE_SYM);
+ label_74:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[113] = jj_gen;
+ break label_74;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IF:
+ jj_consume_token(IF);
+ label_75:
+ while (true) {
+ s = booleanExpressionToken();
+ evaluator += s;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ case EQ:
case PLUS:
+ case MINUS:
case PRECEDES:
- case SIBLING:
- case LBRACKET:
+ case SUCCEEDS:
+ case DIV:
case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case DEBUG_SYM:
- case WARN_SYM:
- case IDENT:
- case HASH:
- styleRuleOrDeclarationOrNestedProperties();
- break;
- case KEY_FRAME_SYM:
- keyframes();
- break;
- default:
- jj_la1[105] = jj_gen;
- if (jj_2_3(2147483647)) {
- variable();
- } else {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case VARIABLE:
- listModifyDirective();
- break;
- case EACH_SYM:
- case IF_SYM:
- controlDirective();
- break;
- case ATKEYWORD:
- atRuleDeclaration();
- break;
- default:
- jj_la1[106] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
- }
-
- final public void ifDirective() throws ParseException {
- Token n = null;
- String s = null;
- String evaluator = "";
- jj_consume_token(IF_SYM);
- label_69: while (true) {
- s = booleanExpressionToken();
- evaluator += s;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- case EQ:
- case PLUS:
- case MINUS:
- case PRECEDES:
- case SUCCEEDS:
- case DIV:
- case ANY:
- case LPARAN:
- case RPARAN:
- case COMPARE:
- case OR:
- case AND:
- case NOT_EQ:
- case IDENT:
- case NUMBER:
- case VARIABLE:
- case CONTAINS:
- ;
- break;
- default:
- jj_la1[107] = jj_gen;
- break label_69;
- }
- }
- jj_consume_token(LBRACE);
- label_70: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[108] = jj_gen;
- break label_70;
- }
- jj_consume_token(S);
- }
- documentHandler.startIfElseDirective();
- documentHandler.ifDirective(evaluator);
- label_71: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case FONT_FACE_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[109] = jj_gen;
- break label_71;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ifContentStatement();
- break;
- case FONT_FACE_SYM:
- fontFace();
- break;
- default:
- jj_la1[110] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- jj_consume_token(RBRACE);
- label_72: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[111] = jj_gen;
- break label_72;
- }
- jj_consume_token(S);
- }
- label_73: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case ELSE_SYM:
- ;
- break;
- default:
- jj_la1[112] = jj_gen;
- break label_73;
- }
- elseDirective();
- }
- documentHandler.endIfElseDirective();
- }
-
- final public void elseDirective() throws ParseException {
- String evaluator = "";
- Token n = null;
- String s = null;
- jj_consume_token(ELSE_SYM);
- label_74: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[113] = jj_gen;
- break label_74;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IF:
- jj_consume_token(IF);
- label_75: while (true) {
- s = booleanExpressionToken();
- evaluator += s;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- case EQ:
- case PLUS:
- case MINUS:
- case PRECEDES:
- case SUCCEEDS:
- case DIV:
- case ANY:
- case LPARAN:
- case RPARAN:
- case COMPARE:
- case OR:
- case AND:
- case NOT_EQ:
- case IDENT:
- case NUMBER:
- case VARIABLE:
- case CONTAINS:
- ;
- break;
- default:
- jj_la1[114] = jj_gen;
- break label_75;
- }
- }
- break;
- default:
- jj_la1[115] = jj_gen;
- ;
- }
- jj_consume_token(LBRACE);
- label_76: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[116] = jj_gen;
- break label_76;
- }
- jj_consume_token(S);
- }
- if (!evaluator.trim().equals("")) {
- documentHandler.ifDirective(evaluator);
- } else {
- documentHandler.elseDirective();
- }
- label_77: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case FONT_FACE_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[117] = jj_gen;
- break label_77;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ifContentStatement();
- break;
- case FONT_FACE_SYM:
- fontFace();
- break;
- default:
- jj_la1[118] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- jj_consume_token(RBRACE);
- label_78: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[119] = jj_gen;
- break label_78;
- }
- jj_consume_token(S);
- }
- }
-
- final public String booleanExpressionToken() throws ParseException {
- Token n = null;
- String s = null;
- if (jj_2_4(2147483647)) {
- s = containsDirective();
- } else {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case VARIABLE:
- n = jj_consume_token(VARIABLE);
- break;
- case IDENT:
- n = jj_consume_token(IDENT);
- break;
- case NUMBER:
- n = jj_consume_token(NUMBER);
- break;
- case LPARAN:
- n = jj_consume_token(LPARAN);
- break;
- case RPARAN:
- n = jj_consume_token(RPARAN);
- break;
- case PLUS:
- n = jj_consume_token(PLUS);
- break;
- case MINUS:
- n = jj_consume_token(MINUS);
- break;
- case DIV:
- n = jj_consume_token(DIV);
- break;
- case ANY:
- n = jj_consume_token(ANY);
- break;
- case COMPARE:
- n = jj_consume_token(COMPARE);
- break;
- case EQ:
- n = jj_consume_token(EQ);
- break;
- case PRECEDES:
- n = jj_consume_token(PRECEDES);
- break;
- case SUCCEEDS:
- n = jj_consume_token(SUCCEEDS);
- break;
- case OR:
- n = jj_consume_token(OR);
- break;
- case AND:
- n = jj_consume_token(AND);
- break;
- case S:
- n = jj_consume_token(S);
- break;
- case NOT_EQ:
- n = jj_consume_token(NOT_EQ);
- break;
- default:
- jj_la1[120] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- if (n != null) {
- {
- if (true) {
- return n.image;
- }
- }
- } else {
- {
- if (true) {
- return s;
- }
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public void eachDirective() throws ParseException {
- Token var;
- ArrayList<String> list = null;
- String listVariable = null;
- jj_consume_token(EACH_SYM);
- label_79: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[121] = jj_gen;
- break label_79;
- }
- jj_consume_token(S);
- }
- var = jj_consume_token(VARIABLE);
- label_80: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[122] = jj_gen;
- break label_80;
- }
- jj_consume_token(S);
- }
- jj_consume_token(EACH_IN);
- label_81: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[123] = jj_gen;
- break label_81;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+ case LPARAN:
+ case RPARAN:
+ case COMPARE:
+ case OR:
+ case AND:
+ case NOT_EQ:
case IDENT:
- list = stringList();
- documentHandler.startEachDirective(var.image, list);
- break;
+ case NUMBER:
case VARIABLE:
- listVariable = variableName();
- documentHandler.startEachDirective(var.image, listVariable);
- break;
+ case CONTAINS:
+ ;
+ break;
default:
- jj_la1[124] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- jj_consume_token(LBRACE);
- label_82: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[125] = jj_gen;
- break label_82;
- }
- jj_consume_token(S);
- }
- label_83: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[126] = jj_gen;
- break label_83;
- }
- ifContentStatement();
- }
- jj_consume_token(RBRACE);
- label_84: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[127] = jj_gen;
- break label_84;
- }
- jj_consume_token(S);
- }
- documentHandler.endEachDirective();
- }
-
- final public ArrayList<String> stringList() throws ParseException {
- ArrayList<String> strings = new ArrayList<String>();
+ jj_la1[114] = jj_gen;
+ break label_75;
+ }
+ }
+ break;
+ default:
+ jj_la1[115] = jj_gen;
+ ;
+ }
+ jj_consume_token(LBRACE);
+ label_76:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[116] = jj_gen;
+ break label_76;
+ }
+ jj_consume_token(S);
+ }
+ if(!evaluator.trim().equals("")){ documentHandler.ifDirective(evaluator); }
+ else{ documentHandler.elseDirective(); }
+ label_77:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case FONT_FACE_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[117] = jj_gen;
+ break label_77;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ifContentStatement();
+ break;
+ case FONT_FACE_SYM:
+ fontFace();
+ break;
+ default:
+ jj_la1[118] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_78:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[119] = jj_gen;
+ break label_78;
+ }
+ jj_consume_token(S);
+ }
+ }
+
+ final public String booleanExpressionToken() throws ParseException {
+ Token n = null;
+ String s = null;
+ if (jj_2_4(2147483647)) {
+ s = containsDirective();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case VARIABLE:
+ n = jj_consume_token(VARIABLE);
+ break;
+ case IDENT:
+ n = jj_consume_token(IDENT);
+ break;
+ case NUMBER:
+ n = jj_consume_token(NUMBER);
+ break;
+ case LPARAN:
+ n = jj_consume_token(LPARAN);
+ break;
+ case RPARAN:
+ n = jj_consume_token(RPARAN);
+ break;
+ case PLUS:
+ n = jj_consume_token(PLUS);
+ break;
+ case MINUS:
+ n = jj_consume_token(MINUS);
+ break;
+ case DIV:
+ n = jj_consume_token(DIV);
+ break;
+ case ANY:
+ n = jj_consume_token(ANY);
+ break;
+ case COMPARE:
+ n = jj_consume_token(COMPARE);
+ break;
+ case EQ:
+ n = jj_consume_token(EQ);
+ break;
+ case PRECEDES:
+ n = jj_consume_token(PRECEDES);
+ break;
+ case SUCCEEDS:
+ n = jj_consume_token(SUCCEEDS);
+ break;
+ case OR:
+ n = jj_consume_token(OR);
+ break;
+ case AND:
+ n = jj_consume_token(AND);
+ break;
+ case S:
+ n = jj_consume_token(S);
+ break;
+ case NOT_EQ:
+ n = jj_consume_token(NOT_EQ);
+ break;
+ default:
+ jj_la1[120] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ if(n!=null){{if (true) return n.image;}}
+ else{{if (true) return s;}}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void eachDirective() throws ParseException {
+ Token var;
+ ArrayList<String> list = null;
+ String listVariable = null;
+ jj_consume_token(EACH_SYM);
+ label_79:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[121] = jj_gen;
+ break label_79;
+ }
+ jj_consume_token(S);
+ }
+ var = jj_consume_token(VARIABLE);
+ label_80:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[122] = jj_gen;
+ break label_80;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(EACH_IN);
+ label_81:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[123] = jj_gen;
+ break label_81;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ list = stringList();
+ documentHandler.startEachDirective(var.image, list);
+ break;
+ case VARIABLE:
+ listVariable = variableName();
+ documentHandler.startEachDirective(var.image, listVariable);
+ break;
+ default:
+ jj_la1[124] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ jj_consume_token(LBRACE);
+ label_82:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[125] = jj_gen;
+ break label_82;
+ }
+ jj_consume_token(S);
+ }
+ label_83:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[126] = jj_gen;
+ break label_83;
+ }
+ ifContentStatement();
+ }
+ jj_consume_token(RBRACE);
+ label_84:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[127] = jj_gen;
+ break label_84;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.endEachDirective();
+ }
+
+ final public ArrayList<String > stringList() throws ParseException {
+ ArrayList<String > strings = new ArrayList<String >();
Token input;
- input = jj_consume_token(IDENT);
- label_85: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[128] = jj_gen;
- break label_85;
- }
- jj_consume_token(S);
- }
- strings.add(input.image);
- label_86: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[129] = jj_gen;
- break label_86;
- }
- jj_consume_token(COMMA);
- label_87: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[130] = jj_gen;
- break label_87;
- }
- jj_consume_token(S);
- }
- input = jj_consume_token(IDENT);
- strings.add(input.image);
- label_88: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[131] = jj_gen;
- break label_88;
- }
- jj_consume_token(S);
- }
- }
- {
- if (true) {
- return strings;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public void mixinDirective() throws ParseException {
- String name;
- ArrayList<VariableNode> args = null;
- String body;
- jj_consume_token(MIXIN_SYM);
- label_89: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[132] = jj_gen;
- break label_89;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- name = property();
- break;
- case FUNCTION:
- name = functionName();
- args = arglist();
- jj_consume_token(RPARAN);
- label_90: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[133] = jj_gen;
- break label_90;
- }
- jj_consume_token(S);
- }
- break;
+ input = jj_consume_token(IDENT);
+ label_85:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[128] = jj_gen;
+ break label_85;
+ }
+ jj_consume_token(S);
+ }
+ strings.add(input.image);
+ label_86:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
+ default:
+ jj_la1[129] = jj_gen;
+ break label_86;
+ }
+ jj_consume_token(COMMA);
+ label_87:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[134] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- jj_consume_token(LBRACE);
- label_91: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[135] = jj_gen;
- break label_91;
- }
- jj_consume_token(S);
- }
- documentHandler.startMixinDirective(name, args);
- label_92: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case PAGE_SYM:
- case FONT_FACE_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ;
- break;
- default:
- jj_la1[136] = jj_gen;
- break label_92;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case INCLUDE_SYM:
- case DEBUG_SYM:
- case WARN_SYM:
- case EACH_SYM:
- case IF_SYM:
- case EXTEND_SYM:
- case CONTENT_SYM:
- case IDENT:
- case VARIABLE:
- case HASH:
- case MEDIA_SYM:
- case KEY_FRAME_SYM:
- case ATKEYWORD:
- ifContentStatement();
- break;
- case FONT_FACE_SYM:
- fontFace();
- break;
- case PAGE_SYM:
- page();
- break;
- default:
- jj_la1[137] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
+ jj_la1[130] = jj_gen;
+ break label_87;
+ }
+ jj_consume_token(S);
+ }
+ input = jj_consume_token(IDENT);
+ strings.add(input.image);
+ label_88:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[131] = jj_gen;
+ break label_88;
+ }
+ jj_consume_token(S);
+ }
+ }
+ {if (true) return strings;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void mixinDirective() throws ParseException {
+ String name;
+ ArrayList<VariableNode> args = null;
+ String body;
+ jj_consume_token(MIXIN_SYM);
+ label_89:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[132] = jj_gen;
+ break label_89;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ name = property();
+ break;
+ case FUNCTION:
+ name = functionName();
+ args = arglist();
+ jj_consume_token(RPARAN);
+ label_90:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[133] = jj_gen;
+ break label_90;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[134] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ jj_consume_token(LBRACE);
+ label_91:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[135] = jj_gen;
+ break label_91;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.startMixinDirective(name, args);
+ label_92:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case PAGE_SYM:
+ case FONT_FACE_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ;
+ break;
+ default:
+ jj_la1[136] = jj_gen;
+ break label_92;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case INCLUDE_SYM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case EACH_SYM:
+ case IF_SYM:
+ case EXTEND_SYM:
+ case CONTENT_SYM:
+ case IDENT:
+ case VARIABLE:
+ case HASH:
+ case MEDIA_SYM:
+ case KEY_FRAME_SYM:
+ case ATKEYWORD:
+ ifContentStatement();
+ break;
+ case FONT_FACE_SYM:
+ fontFace();
+ break;
+ case PAGE_SYM:
+ page();
+ break;
+ default:
+ jj_la1[137] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_93:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[138] = jj_gen;
+ break label_93;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.endMixinDirective(name, args);
+ }
+
+ final public ArrayList<VariableNode> arglist() throws ParseException {
+ ArrayList<VariableNode> args = new ArrayList<VariableNode>();
+ VariableNode arg;
+ boolean hasNonOptionalArgument = false;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case VARIABLE:
+ arg = mixinArg();
+ label_94:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
+ default:
+ jj_la1[139] = jj_gen;
+ break label_94;
}
- jj_consume_token(RBRACE);
- label_93: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[138] = jj_gen;
- break label_93;
- }
- jj_consume_token(S);
+ jj_consume_token(COMMA);
+ label_95:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[140] = jj_gen;
+ break label_95;
+ }
+ jj_consume_token(S);
}
- documentHandler.endMixinDirective(name, args);
- }
-
- final public ArrayList<VariableNode> arglist() throws ParseException {
- ArrayList<VariableNode> args = new ArrayList<VariableNode>();
- VariableNode arg;
- boolean hasNonOptionalArgument = false;
+ hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg);
arg = mixinArg();
- label_94: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[139] = jj_gen;
- break label_94;
- }
- jj_consume_token(COMMA);
- label_95: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[140] = jj_gen;
- break label_95;
- }
- jj_consume_token(S);
- }
- hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg,
- hasNonOptionalArgument);
- args.add(arg);
- arg = mixinArg();
- }
- hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg,
- hasNonOptionalArgument);
- args.add(arg);
- {
- if (true) {
- return args;
- }
- }
- throw new Error("Missing return statement in function");
+ }
+ hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg);
+ break;
+ default:
+ jj_la1[141] = jj_gen;
+ ;
}
+ {if (true) return args;}
+ throw new Error("Missing return statement in function");
+ }
- boolean checkMixinForNonOptionalArguments(VariableNode arg,
- boolean hasNonOptionalArguments) throws ParseException {
- boolean currentArgHasArguments = arg.getExpr() != null
- && arg.getExpr().getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE
- && arg.getExpr().getNextLexicalUnit() != null;
+ boolean checkMixinForNonOptionalArguments(VariableNode arg, boolean hasNonOptionalArguments) throws ParseException {
+ boolean currentArgHasArguments = arg.getExpr() != null && arg.getExpr().getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE && arg.getExpr().getNextLexicalUnit() != null;
- if (currentArgHasArguments) {
- if (hasNonOptionalArguments) {
- throw new ParseException("Sass Error: Required argument $"
- + arg.getName()
- + " must come before any optional arguments.");
- }
- return hasNonOptionalArguments;
- } else {
- return true;
- }
- }
-
- final public VariableNode mixinArg() throws ParseException {
- String name;
- Token variable = null;
- LexicalUnitImpl first = null;
- LexicalUnitImpl prev = null;
- LexicalUnitImpl next = null;
- name = variableName();
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COLON:
- case VARIABLE:
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COLON:
- jj_consume_token(COLON);
- label_96: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[141] = jj_gen;
- break label_96;
- }
- jj_consume_token(S);
- }
- first = nonVariableTerm(null);
- prev = first;
- label_97: while (true) {
- if (jj_2_5(3)) {
- ;
- } else {
- break label_97;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- jj_consume_token(COMMA);
- label_98: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[142] = jj_gen;
- break label_98;
- }
- jj_consume_token(S);
- }
- break;
- default:
- jj_la1[143] = jj_gen;
- ;
- }
- prev = nonVariableTerm(prev);
+ if(currentArgHasArguments)
+ {
+ if(hasNonOptionalArguments)
+ {
+ throw new ParseException("Sass Error: Required argument $"+ arg.getName() +" must come before any optional arguments.");
}
- break;
- case VARIABLE:
- variable = jj_consume_token(VARIABLE);
- first = LexicalUnitImpl.createVariable(token.beginLine,
- token.beginColumn, prev, variable.image);
- break;
- default:
- jj_la1[144] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- break;
- default:
- jj_la1[145] = jj_gen;
- ;
- }
- VariableNode arg = new VariableNode(name, first, false);
+ return hasNonOptionalArguments;
+ }else
{
- if (true) {
- return arg;
- }
+ return true;
+ }
+ }
+
+ final public VariableNode mixinArg() throws ParseException {
+ String name;
+ Token variable = null;
+ LexicalUnitImpl first = null;
+ LexicalUnitImpl prev = null;
+ LexicalUnitImpl next = null;
+ name = variableName();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COLON:
+ case VARIABLE:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COLON:
+ jj_consume_token(COLON);
+ label_96:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[142] = jj_gen;
+ break label_96;
+ }
+ jj_consume_token(S);
}
- throw new Error("Missing return statement in function");
- }
-
- final public ArrayList<LexicalUnitImpl> argValuelist()
- throws ParseException {
- ArrayList<LexicalUnitImpl> args = new ArrayList<LexicalUnitImpl>();
- LexicalUnitImpl first = null;
- LexicalUnitImpl next = null;
- LexicalUnitImpl prev = null;
- first = term(null);
- args.add(first);
+ first = nonVariableTerm(null);
prev = first;
- label_99: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- case DOT:
- case COLON:
- case TO:
- case THROUGH:
- case FROM:
- case STRING:
- case IDENT:
- case NUMBER:
- case URL:
- case VARIABLE:
- case PERCENTAGE:
- case PT:
- case MM:
- case CM:
- case PC:
- case IN:
- case PX:
- case EMS:
- case LEM:
- case REM:
- case EXS:
- case DEG:
- case RAD:
- case GRAD:
- case MS:
- case SECOND:
- case HZ:
- case KHZ:
- case DIMEN:
- case HASH:
- case UNICODERANGE:
- case FUNCTION:
- ;
- break;
- default:
- jj_la1[146] = jj_gen;
- break label_99;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COLON:
- jj_consume_token(COLON);
- label_100: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[147] = jj_gen;
- break label_100;
- }
- jj_consume_token(S);
- }
- break;
- default:
- jj_la1[148] = jj_gen;
- ;
- }
- next = term(prev);
- prev.setNextLexicalUnit(next);
- prev = next;
- }
- label_101: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- ;
- break;
- default:
- jj_la1[149] = jj_gen;
- break label_101;
- }
+ label_97:
+ while (true) {
+ if (jj_2_5(3)) {
+ ;
+ } else {
+ break label_97;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
jj_consume_token(COMMA);
- label_102: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[150] = jj_gen;
- break label_102;
- }
- jj_consume_token(S);
- }
- first = term(null);
- args.add(first);
- prev = first;
- label_103: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- case DOT:
- case COLON:
- case TO:
- case THROUGH:
- case FROM:
- case STRING:
- case IDENT:
- case NUMBER:
- case URL:
- case VARIABLE:
- case PERCENTAGE:
- case PT:
- case MM:
- case CM:
- case PC:
- case IN:
- case PX:
- case EMS:
- case LEM:
- case REM:
- case EXS:
- case DEG:
- case RAD:
- case GRAD:
- case MS:
- case SECOND:
- case HZ:
- case KHZ:
- case DIMEN:
- case HASH:
- case UNICODERANGE:
- case FUNCTION:
- ;
- break;
- default:
- jj_la1[151] = jj_gen;
- break label_103;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COLON:
- jj_consume_token(COLON);
- label_104: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[152] = jj_gen;
- break label_104;
- }
- jj_consume_token(S);
- }
- break;
- default:
- jj_la1[153] = jj_gen;
- ;
- }
- next = term(prev);
- prev.setNextLexicalUnit(next);
- prev = next;
- }
- }
- {
- if (true) {
- return args;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public void includeDirective() throws ParseException {
- String name;
- ArrayList<LexicalUnitImpl> args = null;
- jj_consume_token(INCLUDE_SYM);
- label_105: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
+ label_98:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
;
break;
- default:
- jj_la1[154] = jj_gen;
- break label_105;
+ default:
+ jj_la1[143] = jj_gen;
+ break label_98;
+ }
+ jj_consume_token(S);
}
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- name = property();
break;
+ default:
+ jj_la1[144] = jj_gen;
+ ;
+ }
+ prev = nonVariableTerm(prev);
+ }
+ break;
+ case VARIABLE:
+ variable = jj_consume_token(VARIABLE);
+ first = LexicalUnitImpl.createVariable(token.beginLine, token.beginColumn,
+ prev, variable.image);
+ break;
+ default:
+ jj_la1[145] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ default:
+ jj_la1[146] = jj_gen;
+ ;
+ }
+ VariableNode arg = new VariableNode(name, first, false);
+ {if (true) return arg;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public ArrayList<LexicalUnitImpl> argValuelist() throws ParseException {
+ ArrayList<LexicalUnitImpl> args = new ArrayList<LexicalUnitImpl>();
+ LexicalUnitImpl first = null;
+ LexicalUnitImpl next = null;
+ LexicalUnitImpl prev = null;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case DOT:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case URL:
+ case VARIABLE:
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case HASH:
+ case UNICODERANGE:
+ case FUNCTION:
+ first = term(null);
+ args.add(first); prev = first;
+ label_99:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case DOT:
+ case COLON:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case URL:
case VARIABLE:
- name = variableName();
- name = "$" + name;
- break;
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case HASH:
+ case UNICODERANGE:
case FUNCTION:
- name = functionName();
- args = argValuelist();
- jj_consume_token(RPARAN);
- label_106: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[155] = jj_gen;
- break label_106;
- }
- jj_consume_token(S);
- }
- break;
+ ;
+ break;
default:
- jj_la1[156] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
+ jj_la1[147] = jj_gen;
+ break label_99;
}
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- label_107: while (true) {
- jj_consume_token(SEMICOLON);
- label_108: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[157] = jj_gen;
- break label_108;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[158] = jj_gen;
- break label_107;
- }
- }
- documentHandler.includeDirective(name, args);
- break;
- case LBRACE:
- jj_consume_token(LBRACE);
- label_109: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[159] = jj_gen;
- break label_109;
- }
- jj_consume_token(S);
- }
- documentHandler.startIncludeContentBlock(name, args);
- label_110: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case TO:
- case FROM:
- case DEBUG_SYM:
- case WARN_SYM:
- case IDENT:
- case PERCENTAGE:
- case HASH:
- ;
- break;
- default:
- jj_la1[160] = jj_gen;
- break label_110;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case DEBUG_SYM:
- case WARN_SYM:
- case IDENT:
- case HASH:
- styleRuleOrDeclarationOrNestedProperties();
- break;
- case TO:
- case FROM:
- case PERCENTAGE:
- keyframeSelector();
- break;
- default:
- jj_la1[161] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- jj_consume_token(RBRACE);
- label_111: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[162] = jj_gen;
- break label_111;
- }
- jj_consume_token(S);
- }
- documentHandler.endIncludeContentBlock();
- break;
- default:
- jj_la1[163] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public String interpolation() throws ParseException {
- Token n;
- n = jj_consume_token(INTERPOLATION);
- {
- if (true) {
- return n.image;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public void listModifyDirective() throws ParseException {
- String list = null;
- String remove = null;
- String separator = null;
- String variable = null;
- Token n = null;
- Token type = null;
- // refactor, remove those 3 LOOKAHEAD(5).
- n = jj_consume_token(VARIABLE);
- variable = n.image;
- label_112: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COLON:
+ jj_consume_token(COLON);
+ label_100:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case S:
- ;
- break;
+ ;
+ break;
default:
- jj_la1[164] = jj_gen;
- break label_112;
+ jj_la1[148] = jj_gen;
+ break label_100;
}
jj_consume_token(S);
- }
- jj_consume_token(COLON);
- label_113: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[165] = jj_gen;
- break label_113;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case APPEND:
- type = jj_consume_token(APPEND);
- break;
- case REMOVE:
- type = jj_consume_token(REMOVE);
- break;
- case CONTAINS:
- type = jj_consume_token(CONTAINS);
- break;
+ }
+ break;
default:
- jj_la1[166] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_114: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[167] = jj_gen;
- break label_114;
- }
- jj_consume_token(S);
- }
- list = listModifyDirectiveArgs(0);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case RPARAN:
- jj_consume_token(RPARAN);
- break;
+ jj_la1[149] = jj_gen;
+ ;
+ }
+ next = term(prev);
+ prev.setNextLexicalUnit(next); prev = next;
+ }
+ label_101:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ ;
+ break;
default:
- jj_la1[168] = jj_gen;
- ;
+ jj_la1[150] = jj_gen;
+ break label_101;
}
jj_consume_token(COMMA);
- label_115: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[169] = jj_gen;
- break label_115;
- }
- jj_consume_token(S);
- }
- remove = listModifyDirectiveArgs(1);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- jj_consume_token(COMMA);
- label_116: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[170] = jj_gen;
- break label_116;
- }
- jj_consume_token(S);
- }
- n = jj_consume_token(IDENT);
- separator = n.image;
- label_117: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[171] = jj_gen;
- break label_117;
- }
- jj_consume_token(S);
- }
- break;
- default:
- jj_la1[172] = jj_gen;
+ label_102:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
;
- }
- jj_consume_token(RPARAN);
- switch (type.kind) {
- case APPEND:
- documentHandler.appendDirective(variable, list, remove, separator);
- break;
- case REMOVE:
- documentHandler.removeDirective(variable, list, remove, separator);
- break;
- case CONTAINS:
- if (variable == null) {
- variable = "$var_" + UUID.randomUUID();
- }
- documentHandler
- .containsDirective(variable, list, remove, separator);
- break;
- default:
break;
+ default:
+ jj_la1[151] = jj_gen;
+ break label_102;
+ }
+ jj_consume_token(S);
}
- label_118: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
+ first = term(null);
+ args.add(first); prev = first;
+ label_103:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case DOT:
+ case COLON:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case URL:
+ case VARIABLE:
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case HASH:
+ case UNICODERANGE:
+ case FUNCTION:
+ ;
+ break;
+ default:
+ jj_la1[152] = jj_gen;
+ break label_103;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COLON:
+ jj_consume_token(COLON);
+ label_104:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
;
break;
- default:
- jj_la1[173] = jj_gen;
- break label_118;
+ default:
+ jj_la1[153] = jj_gen;
+ break label_104;
+ }
+ jj_consume_token(S);
}
- jj_consume_token(S);
- }
+ break;
+ default:
+ jj_la1[154] = jj_gen;
+ ;
+ }
+ next = term(prev);
+ prev.setNextLexicalUnit(next); prev = next;
+ }
+ }
+ break;
+ default:
+ jj_la1[155] = jj_gen;
+ ;
+ }
+ {if (true) return args;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void includeDirective() throws ParseException {
+ String name;
+ ArrayList<LexicalUnitImpl> args=null;
+ jj_consume_token(INCLUDE_SYM);
+ label_105:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[156] = jj_gen;
+ break label_105;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ name = property();
+ break;
+ case VARIABLE:
+ name = variableName();
+ name = "$"+name;
+ break;
+ case FUNCTION:
+ name = functionName();
+ args = argValuelist();
+ jj_consume_token(RPARAN);
+ label_106:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[157] = jj_gen;
+ break label_106;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[158] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ documentHandler.startInclude(name, args);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case LBRACE:
+ includeDirectiveBlockContents();
+ break;
+ case SEMICOLON:
+ includeDirectiveTerminator();
+ break;
+ default:
+ jj_la1[159] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ documentHandler.endInclude();
+ }
+
+ final public void includeDirectiveTerminator() throws ParseException {
+ try {
+ label_107:
+ while (true) {
jj_consume_token(SEMICOLON);
- label_119: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[174] = jj_gen;
- break label_119;
- }
- jj_consume_token(S);
+ label_108:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[160] = jj_gen;
+ break label_108;
+ }
+ jj_consume_token(S);
}
- }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[161] = jj_gen;
+ break label_107;
+ }
+ }
+ } catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
+ }
+
+ final public void includeDirectiveBlockContents() throws ParseException {
+ jj_consume_token(LBRACE);
+ label_109:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[162] = jj_gen;
+ break label_109;
+ }
+ jj_consume_token(S);
+ }
+ label_110:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case TO:
+ case FROM:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case IDENT:
+ case PERCENTAGE:
+ case HASH:
+ ;
+ break;
+ default:
+ jj_la1[163] = jj_gen;
+ break label_110;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case DEBUG_SYM:
+ case WARN_SYM:
+ case IDENT:
+ case HASH:
+ styleRuleOrDeclarationOrNestedProperties();
+ break;
+ case TO:
+ case FROM:
+ case PERCENTAGE:
+ keyframeSelector();
+ break;
+ default:
+ jj_la1[164] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+ jj_consume_token(RBRACE);
+ label_111:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[165] = jj_gen;
+ break label_111;
+ }
+ jj_consume_token(S);
+ }
+ }
+
+ final public String interpolation() throws ParseException {
+ Token n;
+ n = jj_consume_token(INTERPOLATION);
+ {if (true) return n.image;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void listModifyDirective() throws ParseException {
+ String list = null;
+ String remove = null;
+ String separator = null;
+ String variable = null;
+ Token n = null;
+ Token type = null;
+ //refactor, remove those 3 LOOKAHEAD(5).
+ n = jj_consume_token(VARIABLE);
+ variable = n.image;
+ label_112:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[166] = jj_gen;
+ break label_112;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(COLON);
+ label_113:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[167] = jj_gen;
+ break label_113;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case APPEND:
+ type = jj_consume_token(APPEND);
+ break;
+ case REMOVE:
+ type = jj_consume_token(REMOVE);
+ break;
+ case CONTAINS:
+ type = jj_consume_token(CONTAINS);
+ break;
+ default:
+ jj_la1[168] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_114:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[169] = jj_gen;
+ break label_114;
+ }
+ jj_consume_token(S);
+ }
+ list = listModifyDirectiveArgs(0);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case RPARAN:
+ jj_consume_token(RPARAN);
+ break;
+ default:
+ jj_la1[170] = jj_gen;
+ ;
+ }
+ jj_consume_token(COMMA);
+ label_115:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[171] = jj_gen;
+ break label_115;
+ }
+ jj_consume_token(S);
+ }
+ remove = listModifyDirectiveArgs(1);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ jj_consume_token(COMMA);
+ label_116:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[172] = jj_gen;
+ break label_116;
+ }
+ jj_consume_token(S);
+ }
+ n = jj_consume_token(IDENT);
+ separator = n.image;
+ label_117:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[173] = jj_gen;
+ break label_117;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[174] = jj_gen;
+ ;
+ }
+ jj_consume_token(RPARAN);
+ switch (type.kind) {
+ case APPEND:
+ documentHandler.appendDirective(variable,list,remove,separator);
+ break;
+ case REMOVE:
+ documentHandler.removeDirective(variable,list,remove,separator);
+ break;
+ case CONTAINS:
+ if(variable == null){
+ variable = "$var_"+UUID.randomUUID();
+ }
+ documentHandler.containsDirective(variable,list,remove,separator);
+ break;
+ default:
+ break;
+ }
+ label_118:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[175] = jj_gen;
+ break label_118;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(SEMICOLON);
+ label_119:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[176] = jj_gen;
+ break label_119;
+ }
+ jj_consume_token(S);
+ }
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void appendDirective() throws ParseException {
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void appendDirective() throws ParseException {
String list = null;
String remove = null;
String separator = null;
String variable = null;
Token n = null;
- n = jj_consume_token(VARIABLE);
- variable = n.image;
- label_120: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[175] = jj_gen;
- break label_120;
- }
- jj_consume_token(S);
- }
- jj_consume_token(COLON);
- label_121: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[176] = jj_gen;
- break label_121;
- }
- jj_consume_token(S);
- }
- jj_consume_token(APPEND);
- label_122: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[177] = jj_gen;
- break label_122;
- }
- jj_consume_token(S);
- }
- list = listModifyDirectiveArgs(0);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case RPARAN:
- jj_consume_token(RPARAN);
- break;
+ n = jj_consume_token(VARIABLE);
+ variable = n.image;
+ label_120:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[177] = jj_gen;
+ break label_120;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(COLON);
+ label_121:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[178] = jj_gen;
+ break label_121;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(APPEND);
+ label_122:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[179] = jj_gen;
+ break label_122;
+ }
+ jj_consume_token(S);
+ }
+ list = listModifyDirectiveArgs(0);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case RPARAN:
+ jj_consume_token(RPARAN);
+ break;
+ default:
+ jj_la1[180] = jj_gen;
+ ;
+ }
+ jj_consume_token(COMMA);
+ label_123:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[181] = jj_gen;
+ break label_123;
+ }
+ jj_consume_token(S);
+ }
+ remove = listModifyDirectiveArgs(1);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ jj_consume_token(COMMA);
+ label_124:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[178] = jj_gen;
- ;
- }
- jj_consume_token(COMMA);
- label_123: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[179] = jj_gen;
- break label_123;
- }
- jj_consume_token(S);
- }
- remove = listModifyDirectiveArgs(1);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- jj_consume_token(COMMA);
- label_124: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[180] = jj_gen;
- break label_124;
- }
- jj_consume_token(S);
- }
- n = jj_consume_token(IDENT);
- separator = n.image;
- label_125: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[181] = jj_gen;
- break label_125;
- }
- jj_consume_token(S);
- }
- break;
+ jj_la1[182] = jj_gen;
+ break label_124;
+ }
+ jj_consume_token(S);
+ }
+ n = jj_consume_token(IDENT);
+ separator = n.image;
+ label_125:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[182] = jj_gen;
- ;
+ jj_la1[183] = jj_gen;
+ break label_125;
}
- jj_consume_token(RPARAN);
- documentHandler.appendDirective(variable, list, remove, separator);
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[184] = jj_gen;
+ ;
}
+ jj_consume_token(RPARAN);
+ documentHandler.appendDirective(variable,list,remove,separator);
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void removeDirective() throws ParseException {
- String list = null;
- String remove = null;
- String separator = null;
- String variable = null;
- Token n = null;
- n = jj_consume_token(VARIABLE);
- variable = n.image;
- label_126: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[183] = jj_gen;
- break label_126;
- }
- jj_consume_token(S);
- }
- jj_consume_token(COLON);
- label_127: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[184] = jj_gen;
- break label_127;
- }
- jj_consume_token(S);
- }
- jj_consume_token(REMOVE);
- label_128: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[185] = jj_gen;
- break label_128;
- }
- jj_consume_token(S);
- }
- list = listModifyDirectiveArgs(0);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case RPARAN:
- jj_consume_token(RPARAN);
- break;
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void removeDirective() throws ParseException {
+ String list = null;
+ String remove = null;
+ String separator = null;
+ String variable = null;
+ Token n = null;
+ n = jj_consume_token(VARIABLE);
+ variable = n.image;
+ label_126:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[185] = jj_gen;
+ break label_126;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(COLON);
+ label_127:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[186] = jj_gen;
+ break label_127;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(REMOVE);
+ label_128:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[187] = jj_gen;
+ break label_128;
+ }
+ jj_consume_token(S);
+ }
+ list = listModifyDirectiveArgs(0);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case RPARAN:
+ jj_consume_token(RPARAN);
+ break;
+ default:
+ jj_la1[188] = jj_gen;
+ ;
+ }
+ jj_consume_token(COMMA);
+ label_129:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[189] = jj_gen;
+ break label_129;
+ }
+ jj_consume_token(S);
+ }
+ remove = listModifyDirectiveArgs(1);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ jj_consume_token(COMMA);
+ label_130:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[186] = jj_gen;
- ;
- }
- jj_consume_token(COMMA);
- label_129: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[187] = jj_gen;
- break label_129;
- }
- jj_consume_token(S);
- }
- remove = listModifyDirectiveArgs(1);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- jj_consume_token(COMMA);
- label_130: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[188] = jj_gen;
- break label_130;
- }
- jj_consume_token(S);
- }
- n = jj_consume_token(IDENT);
- separator = n.image;
- label_131: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[189] = jj_gen;
- break label_131;
- }
- jj_consume_token(S);
- }
- break;
+ jj_la1[190] = jj_gen;
+ break label_130;
+ }
+ jj_consume_token(S);
+ }
+ n = jj_consume_token(IDENT);
+ separator = n.image;
+ label_131:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[190] = jj_gen;
- ;
+ jj_la1[191] = jj_gen;
+ break label_131;
}
- jj_consume_token(RPARAN);
- documentHandler.removeDirective(variable, list, remove, separator);
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[192] = jj_gen;
+ ;
}
+ jj_consume_token(RPARAN);
+ documentHandler.removeDirective(variable,list,remove,separator);
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public String containsDirective() throws ParseException {
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public String containsDirective() throws ParseException {
String list = null;
String remove = null;
String separator = null;
String variable = null;
Token n = null;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case VARIABLE:
- n = jj_consume_token(VARIABLE);
- variable = n.image;
- label_132: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[191] = jj_gen;
- break label_132;
- }
- jj_consume_token(S);
- }
- jj_consume_token(COLON);
- label_133: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[192] = jj_gen;
- break label_133;
- }
- jj_consume_token(S);
- }
- break;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case VARIABLE:
+ n = jj_consume_token(VARIABLE);
+ variable = n.image;
+ label_132:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[193] = jj_gen;
- ;
- }
- jj_consume_token(CONTAINS);
- label_134: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[194] = jj_gen;
- break label_134;
- }
- jj_consume_token(S);
- }
- list = listModifyDirectiveArgs(0);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case RPARAN:
- jj_consume_token(RPARAN);
- break;
+ jj_la1[193] = jj_gen;
+ break label_132;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(COLON);
+ label_133:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[195] = jj_gen;
- ;
- }
- jj_consume_token(COMMA);
- label_135: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[196] = jj_gen;
- break label_135;
- }
- jj_consume_token(S);
- }
- remove = listModifyDirectiveArgs(1);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- jj_consume_token(COMMA);
- label_136: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[197] = jj_gen;
- break label_136;
- }
- jj_consume_token(S);
- }
- n = jj_consume_token(IDENT);
- separator = n.image;
- label_137: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[198] = jj_gen;
- break label_137;
- }
- jj_consume_token(S);
- }
- break;
+ jj_la1[194] = jj_gen;
+ break label_133;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[195] = jj_gen;
+ ;
+ }
+ jj_consume_token(CONTAINS);
+ label_134:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[196] = jj_gen;
+ break label_134;
+ }
+ jj_consume_token(S);
+ }
+ list = listModifyDirectiveArgs(0);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case RPARAN:
+ jj_consume_token(RPARAN);
+ break;
+ default:
+ jj_la1[197] = jj_gen;
+ ;
+ }
+ jj_consume_token(COMMA);
+ label_135:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[198] = jj_gen;
+ break label_135;
+ }
+ jj_consume_token(S);
+ }
+ remove = listModifyDirectiveArgs(1);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ jj_consume_token(COMMA);
+ label_136:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[199] = jj_gen;
- ;
- }
- jj_consume_token(RPARAN);
- /*
- * if it is not in the form like
- * "$contains : contains($items, .v-button);"for example in @if, like
- * "@if (contains(a b c, b))", then create a tempvariable for contains(a
- * b c, b);
- */
- if (variable == null) {
- variable = "$var_" + UUID.randomUUID();
- }
- documentHandler.containsDirective(variable, list, remove, separator);
- {
- if (true) {
- return variable;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- String listModifyDirectiveArgs(int nest) throws ParseException {
+ jj_la1[199] = jj_gen;
+ break label_136;
+ }
+ jj_consume_token(S);
+ }
+ n = jj_consume_token(IDENT);
+ separator = n.image;
+ label_137:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[200] = jj_gen;
+ break label_137;
+ }
+ jj_consume_token(S);
+ }
+ break;
+ default:
+ jj_la1[201] = jj_gen;
+ ;
+ }
+ jj_consume_token(RPARAN);
+ /*
+ *if it is not in the form like "$contains : contains($items, .v-button);"
+ *for example in @if, like "@if (contains(a b c, b))", then create a temp
+ *variable for contains(a b c, b);
+ */
+ if(variable == null){
+ variable = "$var_"+UUID.randomUUID();
+ }
+ documentHandler.containsDirective(variable,list,remove,separator);
+ {if (true) return variable;}
+ throw new Error("Missing return statement in function");
+ }
+
+ String listModifyDirectiveArgs(int nest) throws ParseException {
String list = "";
int nesting = nest;
Token t = null;
- while (true) {
- t = getToken(1);
- String s = t.image;
- if (t.kind == VARIABLE || t.kind == IDENT) {
- list += s;
- } else if (s.toLowerCase().equals("auto")
- || s.toLowerCase().equals("space")
- || s.toLowerCase().equals("comma")) {
- int i = 2;
- Token temp = getToken(i);
- boolean isLast = true;
- while (temp.kind != SEMICOLON) {
- if (temp.kind != RPARAN || temp.kind != S) {
- isLast = false;
- }
- i++;
- temp = getToken(i);
- }
+ while(true)
+ {
+ t = getToken(1);
+ String s = t.image;
+ if(t.kind == VARIABLE||t.kind == IDENT)
+ {
+ list += s;
+ }else if(s.toLowerCase().equals("auto")||s.toLowerCase().equals("space")||s.toLowerCase().equals("comma"))
+ {
+ int i = 2;
+ Token temp = getToken(i);
+ boolean isLast = true;
+ while(temp.kind != SEMICOLON)
+ {
+ if(temp.kind != RPARAN || temp.kind != S)
+ {
+ isLast = false;
+ }
+ i++;
+ temp = getToken(i);
+ }
- if (isLast) {
- return list;
- }
- } else if (t.kind == STRING) {
- list += s.substring(1, s.length()).substring(0, s.length() - 2);
-
- } else if (t.kind == LPARAN) {
- nesting++;
- if (nesting > nest + 1) {
- throw new CSSParseException(
- "Only one ( ) pair per parameter allowed",
- getLocator());
- }
- } else if (t.kind == RPARAN) {
- nesting--;
- if (nesting == 0) {
- return list;
- }
- } else if (t.kind == COMMA) {
- if (nesting == nest) {
- return list;
- } else {
- list += ",";
+ if(isLast)
+ {
+ return list;
+ }
}
+ else if(t.kind == STRING)
+ {
+ list += s.substring(1,s.length()).substring(0,s.length()-2);
- } else if (t.kind == S) {
- list += " ";
- } else if (t.kind == LBRACE) {
- throw new CSSParseException("Invalid token,'{' found",
- getLocator());
- }
+ }else if(t.kind == LPARAN)
+ {
+ nesting++;
+ if(nesting > nest+1)
+ {
+ throw new CSSParseException("Only one ( ) pair per parameter allowed", getLocator());
+ }
+ }else if(t.kind == RPARAN)
+ {
+ nesting--;
+ if(nesting == 0)
+ {
+ return list;
+ }
+ } else if(t.kind == COMMA)
+ {
+ if(nesting == nest)
+ {
+ return list;
+ }else
+ {
+ list += ",";
+ }
- getNextToken();
- }
- }
+ }else if(t.kind == S)
+ {
+ list += " ";
+ } else if(t.kind == LBRACE)
+ {
+ throw new CSSParseException("Invalid token,'{' found", getLocator());
+ }
- final public Node returnDirective() throws ParseException {
- String raw;
- raw = skipStatement();
- {
- if (true) {
- return null;
- }
+ getNextToken();
}
- throw new Error("Missing return statement in function");
- }
-
- final public void debuggingDirective() throws ParseException {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case DEBUG_SYM:
- debugDirective();
- break;
- case WARN_SYM:
- warnDirective();
- break;
+ }
+
+ final public Node returnDirective() throws ParseException {
+ String raw;
+ raw = skipStatement();
+ {if (true) return null;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void debuggingDirective() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case DEBUG_SYM:
+ debugDirective();
+ break;
+ case WARN_SYM:
+ warnDirective();
+ break;
+ default:
+ jj_la1[202] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ }
+
+ final public void debugDirective() throws ParseException {
+ jj_consume_token(DEBUG_SYM);
+ String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF});
+ // TODO should evaluate the content expression, call documentHandler.debugDirective() etc.
+ Logger.getLogger(Parser.class.getName()).log(Level.INFO, content);
+ try {
+ jj_consume_token(SEMICOLON);
+ label_138:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[200] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
-
- final public void debugDirective() throws ParseException {
- jj_consume_token(DEBUG_SYM);
- String content = skipStatementUntilSemiColon();
- // TODO should evaluate the content expression, call
- // documentHandler.debugDirective() etc.
- System.out.println(content);
- label_138: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[201] = jj_gen;
- break label_138;
- }
- jj_consume_token(S);
- }
- }
-
- final public void warnDirective() throws ParseException {
- jj_consume_token(WARN_SYM);
- String content = skipStatementUntilSemiColon();
- // TODO should evaluate the content expression, call
- // documentHandler.warnDirective() etc.
- System.err.println(content);
- label_139: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[202] = jj_gen;
- break label_139;
- }
- jj_consume_token(S);
- }
- }
-
- final public Node forDirective() throws ParseException {
- String var;
- String from;
- String to;
- boolean exclusive;
- String body;
- Token tok;
- var = variableName();
- int[] toThrough = { TO, THROUGH };
+ jj_la1[203] = jj_gen;
+ break label_138;
+ }
+ jj_consume_token(S);
+ }
+ } catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
+ }
+
+ final public void warnDirective() throws ParseException {
+ jj_consume_token(WARN_SYM);
+ String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF});
+ // TODO should evaluate the content expression, call documentHandler.warnDirective() etc.
+ Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, content);
+ try {
+ jj_consume_token(SEMICOLON);
+ label_139:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[204] = jj_gen;
+ break label_139;
+ }
+ jj_consume_token(S);
+ }
+ } catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
+ }
+
+ final public Node forDirective() throws ParseException {
+ String var;
+ String from;
+ String to;
+ boolean exclusive;
+ String body;
+ Token tok;
+ var = variableName();
+ int[] toThrough = {TO, THROUGH};
from = skipStatementUntil(toThrough);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case TO:
- tok = jj_consume_token(TO);
- exclusive = true;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case TO:
+ tok = jj_consume_token(TO);
+ exclusive = true;
+ break;
+ case THROUGH:
+ tok = jj_consume_token(THROUGH);
+ exclusive = false;
+ break;
+ default:
+ jj_la1[205] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ to = skipStatementUntilLeftBrace();
+ label_140:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[206] = jj_gen;
+ break label_140;
+ }
+ jj_consume_token(S);
+ }
+ body = skipStatement();
+ {if (true) return documentHandler.forDirective(var, from, to, exclusive, body);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public Node whileDirective() throws ParseException {
+ String condition;
+ String body;
+ condition = skipStatementUntilLeftBrace();
+ body = skipStatement();
+ {if (true) return documentHandler.whileDirective(condition, body);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public void extendDirective() throws ParseException {
+ ArrayList<String> list;
+ jj_consume_token(EXTEND_SYM);
+ label_141:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[207] = jj_gen;
+ break label_141;
+ }
+ jj_consume_token(S);
+ }
+ list = selectorList();
+ documentHandler.extendDirective(list);
+ try {
+ label_142:
+ while (true) {
+ jj_consume_token(SEMICOLON);
+ label_143:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
break;
- case THROUGH:
- tok = jj_consume_token(THROUGH);
- exclusive = false;
+ default:
+ jj_la1[208] = jj_gen;
+ break label_143;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[209] = jj_gen;
+ break label_142;
+ }
+ }
+ } catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
+ }
+
+ final public void contentDirective() throws ParseException {
+ jj_consume_token(CONTENT_SYM);
+ label_144:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[210] = jj_gen;
+ break label_144;
+ }
+ jj_consume_token(S);
+ }
+ 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[211] = jj_gen;
+ break label_146;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
default:
- jj_la1[203] = jj_gen;
+ jj_la1[212] = jj_gen;
+ break label_145;
+ }
+ }
+ } catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
+ documentHandler.contentDirective();
+ }
+
+ Node importDirective() throws ParseException {
+ return null;
+ }
+
+ Node charsetDirective() throws ParseException {
+ return null;
+ }
+
+ Node mozDocumentDirective() throws ParseException {
+ return null;
+ }
+
+ Node supportsDirective() throws ParseException {
+ return null;
+ }
+
+ final public void nestedProperties() throws ParseException {
+ String name;
+LexicalUnit exp;
+ name = property();
+ jj_consume_token(COLON);
+ label_147:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[213] = jj_gen;
+ break label_147;
+ }
+ jj_consume_token(S);
+ }
+ jj_consume_token(LBRACE);
+ label_148:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[214] = jj_gen;
+ break label_148;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.startNestedProperties(name);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[215] = jj_gen;
+ ;
+ }
+ label_149:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[216] = jj_gen;
+ break label_149;
+ }
+ jj_consume_token(SEMICOLON);
+ label_150:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[217] = jj_gen;
+ break label_150;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[218] = jj_gen;
+ ;
+ }
+ }
+ jj_consume_token(RBRACE);
+ documentHandler.endNestedProperties(name);
+ label_151:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[219] = jj_gen;
+ break label_151;
+ }
+ jj_consume_token(S);
+ }
+ }
+
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void styleRuleOrDeclarationOrNestedProperties() throws ParseException {
+ try {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case DEBUG_SYM:
+ case WARN_SYM:
+ debuggingDirective();
+ break;
+ default:
+ jj_la1[220] = jj_gen;
+ if (jj_2_6(2147483647)) {
+ styleRule();
+ } else if (jj_2_7(3)) {
+ declarationOrNestedProperties();
+ } else {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case PRECEDES:
+ case SIBLING:
+ case LBRACKET:
+ case ANY:
+ case PARENT:
+ case DOT:
+ case COLON:
+ case INTERPOLATION:
+ case IDENT:
+ case HASH:
+ styleRule();
+ break;
+ default:
+ jj_la1[221] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
- }
- to = skipStatementUntilLeftBrace();
- label_140: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[204] = jj_gen;
- break label_140;
- }
- jj_consume_token(S);
- }
- body = skipStatement();
- {
- if (true) {
- return documentHandler.forDirective(var, from, to, exclusive,
- body);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public Node whileDirective() throws ParseException {
- String condition;
- String body;
- condition = skipStatementUntilLeftBrace();
- body = skipStatement();
- {
- if (true) {
- return documentHandler.whileDirective(condition, body);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public void extendDirective() throws ParseException {
- ArrayList<String> list;
- jj_consume_token(EXTEND_SYM);
- label_141: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[205] = jj_gen;
- break label_141;
- }
- jj_consume_token(S);
- }
- list = selectorList();
- label_142: while (true) {
- jj_consume_token(SEMICOLON);
- label_143: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[206] = jj_gen;
- break label_143;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[207] = jj_gen;
- break label_142;
- }
- }
- documentHandler.extendDirective(list);
- }
-
- final public void contentDirective() throws ParseException {
- jj_consume_token(CONTENT_SYM);
- label_144: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[208] = jj_gen;
- break label_144;
- }
- jj_consume_token(S);
- }
- 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[209] = jj_gen;
- break label_146;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[210] = jj_gen;
- break label_145;
- }
- }
- documentHandler.contentDirective();
- }
-
- Node importDirective() throws ParseException {
- return null;
- }
-
- Node charsetDirective() throws ParseException {
- return null;
- }
-
- Node mozDocumentDirective() throws ParseException {
- return null;
- }
-
- Node supportsDirective() throws ParseException {
- return null;
+ }
+ }
+ }
+ } catch (JumpException e) {
+ skipAfterExpression();
+ // reportWarningSkipText(getLocator(), skipAfterExpression());
+
+ } catch (ParseException e) {
+ if (errorHandler != null) {
+ if (e.currentToken != null) {
+ LocatorImpl li = new LocatorImpl(this,
+ e.currentToken.next.beginLine,
+ e.currentToken.next.beginColumn-1);
+ reportError(li, e);
+ } else {
+ reportError(getLocator(), e);
+ }
+ skipAfterExpression();
+ /*
+ LocatorImpl loc = (LocatorImpl) getLocator();
+ loc.column--;
+ reportWarningSkipText(loc, skipAfterExpression());
+ */
+ } else {
+ skipAfterExpression();
+ }
}
+ }
- final public void nestedProperties() throws ParseException {
- String name;
- LexicalUnit exp;
- name = property();
- jj_consume_token(COLON);
- label_147: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[211] = jj_gen;
- break label_147;
- }
- jj_consume_token(S);
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void declarationOrNestedProperties() throws ParseException {
+ boolean important = false;
+ String name;
+ LexicalUnitImpl exp;
+ Token save;
+ String comment = null;
+ try {
+ name = property();
+ save = token;
+ jj_consume_token(COLON);
+ label_152:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[222] = jj_gen;
+ break label_152;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case DOT:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case URL:
+ case VARIABLE:
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case HASH:
+ case UNICODERANGE:
+ case FUNCTION:
+ exp = expr();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IMPORTANT_SYM:
+ important = prio();
+ break;
+ default:
+ jj_la1[223] = jj_gen;
+ ;
+ }
+ Token next = getToken(1);
+ if(next.kind == SEMICOLON || next.kind == RBRACE){
+ while(next.kind == SEMICOLON){
+ skipStatement();
+ next = getToken(1);
+ }
+ //only add special token kept for sprites '/**'
+ if(token.specialToken!=null && token.specialToken!=null && token.specialToken.image.startsWith("/**")){
+ documentHandler.property(name, exp, important, token.specialToken.image);
+ }else{
+ documentHandler.property(name, exp, important, null);
+ }
+ }
+ break;
+ case LBRACE:
jj_consume_token(LBRACE);
- label_148: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[212] = jj_gen;
- break label_148;
- }
- jj_consume_token(S);
- }
- documentHandler.startNestedProperties(name);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+ label_153:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[224] = jj_gen;
+ break label_153;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.startNestedProperties(name);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case INTERPOLATION:
case IDENT:
- declaration();
- break;
+ declaration();
+ break;
default:
- jj_la1[213] = jj_gen;
- ;
- }
- label_149: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[214] = jj_gen;
- break label_149;
- }
- jj_consume_token(SEMICOLON);
- label_150: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[215] = jj_gen;
- break label_150;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[216] = jj_gen;
- ;
- }
- }
- jj_consume_token(RBRACE);
- documentHandler.endNestedProperties(name);
- label_151: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[217] = jj_gen;
- break label_151;
- }
- jj_consume_token(S);
- }
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void styleRuleOrDeclarationOrNestedProperties()
- throws ParseException {
- try {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case DEBUG_SYM:
- case WARN_SYM:
- debuggingDirective();
- break;
- default:
- jj_la1[218] = jj_gen;
- if (jj_2_6(2147483647)) {
- styleRule();
- } else if (jj_2_7(3)) {
- declarationOrNestedProperties();
- } else {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case PRECEDES:
- case SIBLING:
- case LBRACKET:
- case ANY:
- case PARENT:
- case DOT:
- case COLON:
- case INTERPOLATION:
- case IDENT:
- case HASH:
- styleRule();
- break;
- default:
- jj_la1[219] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- }
- }
- } catch (JumpException e) {
- skipAfterExpression();
- // reportWarningSkipText(getLocator(), skipAfterExpression());
-
- } catch (ParseException e) {
- if (errorHandler != null) {
- if (e.currentToken != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.currentToken.next.beginLine,
- e.currentToken.next.beginColumn - 1);
- reportError(li, e);
- } else {
- reportError(getLocator(), e);
- }
- skipAfterExpression();
- /*
- * LocatorImpl loc = (LocatorImpl) getLocator(); loc.column--;
- * reportWarningSkipText(loc, skipAfterExpression());
- */
- } else {
- skipAfterExpression();
- }
- }
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void declarationOrNestedProperties() throws ParseException {
- boolean important = false;
- String name;
- LexicalUnitImpl exp;
- Token save;
- String comment = null;
- try {
- name = property();
- save = token;
- jj_consume_token(COLON);
- label_152: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[220] = jj_gen;
- break label_152;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- case DOT:
- case TO:
- case THROUGH:
- case FROM:
- case STRING:
- case IDENT:
- case NUMBER:
- case URL:
- case VARIABLE:
- case PERCENTAGE:
- case PT:
- case MM:
- case CM:
- case PC:
- case IN:
- case PX:
- case EMS:
- case LEM:
- case REM:
- case EXS:
- case DEG:
- case RAD:
- case GRAD:
- case MS:
- case SECOND:
- case HZ:
- case KHZ:
- case DIMEN:
- case HASH:
- case UNICODERANGE:
- case FUNCTION:
- exp = expr();
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IMPORTANT_SYM:
- important = prio();
- break;
- default:
- jj_la1[221] = jj_gen;
- ;
- }
- Token next = getToken(1);
- if (next.kind == SEMICOLON || next.kind == RBRACE) {
- while (next.kind == SEMICOLON) {
- skipStatement();
- next = getToken(1);
- }
- // only add special token kept for sprites '/**'
- if (token.specialToken != null
- && token.specialToken != null
- && token.specialToken.image.startsWith("/**")) {
- documentHandler.property(name, exp, important,
- token.specialToken.image);
- } else {
- documentHandler.property(name, exp, important, null);
- }
- }
- break;
- case LBRACE:
- jj_consume_token(LBRACE);
- label_153: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[222] = jj_gen;
- break label_153;
- }
- jj_consume_token(S);
- }
- documentHandler.startNestedProperties(name);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[223] = jj_gen;
- ;
- }
- label_154: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[224] = jj_gen;
- break label_154;
- }
- jj_consume_token(SEMICOLON);
- label_155: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[225] = jj_gen;
- break label_155;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[226] = jj_gen;
- ;
- }
- }
- jj_consume_token(RBRACE);
- label_156: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[227] = jj_gen;
- break label_156;
- }
- jj_consume_token(S);
- }
- documentHandler.endNestedProperties(name);
- break;
- default:
- jj_la1[228] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- } catch (JumpException e) {
- skipAfterExpression();
- // reportWarningSkipText(getLocator(), skipAfterExpression());
-
- } catch (NumberFormatException e) {
- if (errorHandler != null) {
- errorHandler.error(new CSSParseException("Invalid number "
- + e.getMessage(), getLocator(), e));
- }
- reportWarningSkipText(getLocator(), skipAfterExpression());
- } catch (ParseException e) {
- if (errorHandler != null) {
- if (e.currentToken != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.currentToken.next.beginLine,
- e.currentToken.next.beginColumn - 1);
- reportError(li, e);
- } else {
- reportError(getLocator(), e);
- }
- skipAfterExpression();
- /*
- * LocatorImpl loc = (LocatorImpl) getLocator(); loc.column--;
- * reportWarningSkipText(loc, skipAfterExpression());
- */
- } else {
- skipAfterExpression();
- }
+ jj_la1[225] = jj_gen;
+ ;
}
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public void declaration() throws ParseException {
- boolean important = false;
- String name;
- LexicalUnit exp;
- Token save;
- try {
- name = property();
- save = token;
- jj_consume_token(COLON);
- label_157: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[229] = jj_gen;
- break label_157;
- }
- jj_consume_token(S);
- }
- exp = expr();
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IMPORTANT_SYM:
- important = prio();
- break;
- default:
- jj_la1[230] = jj_gen;
- ;
- }
- documentHandler.property(name, exp, important);
- } catch (JumpException e) {
- skipAfterExpression();
- // reportWarningSkipText(getLocator(), skipAfterExpression());
-
- } catch (NumberFormatException e) {
- if (errorHandler != null) {
- errorHandler.error(new CSSParseException("Invalid number "
- + e.getMessage(), getLocator(), e));
- }
- reportWarningSkipText(getLocator(), skipAfterExpression());
- } catch (ParseException e) {
- if (errorHandler != null) {
- if (e.currentToken != null) {
- LocatorImpl li = new LocatorImpl(this,
- e.currentToken.next.beginLine,
- e.currentToken.next.beginColumn - 1);
- reportError(li, e);
- } else {
- reportError(getLocator(), e);
- }
- skipAfterExpression();
- /*
- * LocatorImpl loc = (LocatorImpl) getLocator(); loc.column--;
- * reportWarningSkipText(loc, skipAfterExpression());
- */
- } else {
- skipAfterExpression();
- }
- }
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public boolean prio() throws ParseException {
- jj_consume_token(IMPORTANT_SYM);
- label_158: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[231] = jj_gen;
- break label_158;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return true;
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public boolean guarded() throws ParseException {
- jj_consume_token(GUARDED_SYM);
- label_159: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
+ label_154:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[226] = jj_gen;
+ break label_154;
+ }
+ jj_consume_token(SEMICOLON);
+ label_155:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case S:
- ;
- break;
+ ;
+ break;
default:
- jj_la1[232] = jj_gen;
- break label_159;
+ jj_la1[227] = jj_gen;
+ break label_155;
}
jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[228] = jj_gen;
+ ;
+ }
}
- {
- if (true) {
- return true;
- }
- }
- throw new Error("Missing return statement in function");
+ jj_consume_token(RBRACE);
+ label_156:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[229] = jj_gen;
+ break label_156;
+ }
+ jj_consume_token(S);
+ }
+ documentHandler.endNestedProperties(name);
+ break;
+ default:
+ jj_la1[230] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ } catch (JumpException e) {
+ skipAfterExpression();
+ // reportWarningSkipText(getLocator(), skipAfterExpression());
+
+ } catch (NumberFormatException e) {
+ if (errorHandler != null) {
+ errorHandler.error(new CSSParseException("Invalid number "
+ + e.getMessage(),
+ getLocator(),
+ e));
+ }
+ reportWarningSkipText(getLocator(), skipAfterExpression());
+ } catch (ParseException e) {
+ if (errorHandler != null) {
+ if (e.currentToken != null) {
+ LocatorImpl li = new LocatorImpl(this,
+ e.currentToken.next.beginLine,
+ e.currentToken.next.beginColumn-1);
+ reportError(li, e);
+ } else {
+ reportError(getLocator(), e);
+ }
+ skipAfterExpression();
+ /*
+ LocatorImpl loc = (LocatorImpl) getLocator();
+ loc.column--;
+ reportWarningSkipText(loc, skipAfterExpression());
+ */
+ } else {
+ skipAfterExpression();
+ }
}
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public LexicalUnitImpl operator(LexicalUnitImpl prev)
- throws ParseException {
- Token n;
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case COMMA:
- /*
- * (comments copied from basic_arithmetics.scss)supports: 1.
- * standard arithmetic operations (+, -, *, /, %) 2. / is treated as
- * css operator, unless one of its operands is variable or there is
- * another binary arithmetic operatorlimits: 1. cannot mix
- * arithmetic and css operations, e.g. "margin: 1px + 3px 2px" will
- * fail 2. space between add and minus operator and their following
- * operand is mandatory. e.g. "1 + 2" is valid, "1+2" is not 3.
- * parenthesis is not supported now.
- */
- n = jj_consume_token(COMMA);
- label_160: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[233] = jj_gen;
- break label_160;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return LexicalUnitImpl.createComma(n.beginLine,
- n.beginColumn, prev);
- }
- }
- break;
- case DIV:
- n = jj_consume_token(DIV);
- label_161: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[234] = jj_gen;
- break label_161;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return LexicalUnitImpl.createSlash(n.beginLine,
- n.beginColumn, prev);
- }
- }
- break;
- case ANY:
- n = jj_consume_token(ANY);
- label_162: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[235] = jj_gen;
- break label_162;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return LexicalUnitImpl.createMultiply(n.beginLine,
- n.beginColumn, prev);
- }
- }
- break;
- case MOD:
- n = jj_consume_token(MOD);
- label_163: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[236] = jj_gen;
- break label_163;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return LexicalUnitImpl.createModulo(n.beginLine,
- n.beginColumn, prev);
- }
- }
- break;
- case PLUS:
- n = jj_consume_token(PLUS);
- label_164: while (true) {
- jj_consume_token(S);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[237] = jj_gen;
- break label_164;
- }
- }
- {
- if (true) {
- return LexicalUnitImpl.createAdd(n.beginLine,
- n.beginColumn, prev);
- }
- }
- break;
- case MINUS:
- n = jj_consume_token(MINUS);
- label_165: while (true) {
- jj_consume_token(S);
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[238] = jj_gen;
- break label_165;
- }
- }
- {
- if (true) {
- return LexicalUnitImpl.createMinus(n.beginLine,
- n.beginColumn, prev);
- }
- }
- break;
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public void declaration() throws ParseException {
+ boolean important = false;
+ String name;
+ LexicalUnit exp;
+ Token save;
+ try {
+ name = property();
+ save = token;
+ jj_consume_token(COLON);
+ label_157:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[239] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- throw new Error("Missing return statement in function");
- }
+ jj_la1[231] = jj_gen;
+ break label_157;
+ }
+ jj_consume_token(S);
+ }
+ exp = expr();
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IMPORTANT_SYM:
+ important = prio();
+ break;
+ default:
+ jj_la1[232] = jj_gen;
+ ;
+ }
+ documentHandler.property(name, exp, important);
+ } catch (JumpException e) {
+ skipAfterExpression();
+ // reportWarningSkipText(getLocator(), skipAfterExpression());
+
+ } catch (NumberFormatException e) {
+ if (errorHandler != null) {
+ errorHandler.error(new CSSParseException("Invalid number "
+ + e.getMessage(),
+ getLocator(),
+ e));
+ }
+ reportWarningSkipText(getLocator(), skipAfterExpression());
+ } catch (ParseException e) {
+ if (errorHandler != null) {
+ if (e.currentToken != null) {
+ LocatorImpl li = new LocatorImpl(this,
+ e.currentToken.next.beginLine,
+ e.currentToken.next.beginColumn-1);
+ reportError(li, e);
+ } else {
+ reportError(getLocator(), e);
+ }
+ skipAfterExpression();
+ /*
+ LocatorImpl loc = (LocatorImpl) getLocator();
+ loc.column--;
+ reportWarningSkipText(loc, skipAfterExpression());
+ */
+ } else {
+ skipAfterExpression();
+ }
+ }
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public LexicalUnitImpl expr() throws ParseException {
- LexicalUnitImpl first, res;
- char op;
- first = term(null);
- res = first;
- label_166: while (true) {
- if (jj_2_8(2)) {
- ;
- } else {
- break label_166;
- }
- if (jj_2_9(2)) {
- res = operator(res);
- } else {
- ;
- }
- res = term(res);
- }
- {
- if (true) {
- return first;
- }
- }
- throw new Error("Missing return statement in function");
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public boolean prio() throws ParseException {
+ jj_consume_token(IMPORTANT_SYM);
+ label_158:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[233] = jj_gen;
+ break label_158;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return true;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public boolean guarded() throws ParseException {
+ jj_consume_token(GUARDED_SYM);
+ label_159:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[234] = jj_gen;
+ break label_159;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return true;}
+ throw new Error("Missing return statement in function");
+ }
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public char unaryOperator() throws ParseException {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case MINUS:
- jj_consume_token(MINUS);
- {
- if (true) {
- return '-';
- }
- }
- break;
- case PLUS:
- jj_consume_token(PLUS);
- {
- if (true) {
- return '+';
- }
- }
- break;
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public LexicalUnitImpl operator(LexicalUnitImpl prev) throws ParseException {
+ Token n;
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case COMMA:
+ /* (comments copied from basic_arithmetics.scss)
+ *supports:
+ * 1. standard arithmetic operations (+, -, *, /, %)
+ * 2. / is treated as css operator, unless one of its operands is variable or there is another binary arithmetic operator
+ *limits:
+ * 1. cannot mix arithmetic and css operations, e.g. "margin: 1px + 3px 2px" will fail
+ * 2. space between add and minus operator and their following operand is mandatory. e.g. "1 + 2" is valid, "1+2" is not
+ * 3. parenthesis is not supported now.
+ */
+ n = jj_consume_token(COMMA);
+ label_160:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[240] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- throw new Error("Missing return statement in function");
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public LexicalUnitImpl term(LexicalUnitImpl prev)
- throws ParseException {
- LexicalUnitImpl result = null;
- Token n = null;
- char op = ' ';
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- case DOT:
- case TO:
- case THROUGH:
- case FROM:
- case STRING:
- case IDENT:
- case NUMBER:
- case URL:
- case PERCENTAGE:
- case PT:
- case MM:
- case CM:
- case PC:
- case IN:
- case PX:
- case EMS:
- case LEM:
- case REM:
- case EXS:
- case DEG:
- case RAD:
- case GRAD:
- case MS:
- case SECOND:
- case HZ:
- case KHZ:
- case DIMEN:
- case HASH:
- case UNICODERANGE:
- case FUNCTION:
- result = nonVariableTerm(prev);
- break;
- case VARIABLE:
- result = variableTerm(prev);
- break;
+ jj_la1[235] = jj_gen;
+ break label_160;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return LexicalUnitImpl.createComma(n.beginLine,
+ n.beginColumn,
+ prev);}
+ break;
+ case DIV:
+ n = jj_consume_token(DIV);
+ label_161:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
default:
- jj_la1[241] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- {
- if (true) {
- return result;
- }
- }
- throw new Error("Missing return statement in function");
- }
+ jj_la1[236] = jj_gen;
+ break label_161;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return LexicalUnitImpl.createSlash(n.beginLine,
+ n.beginColumn,
+ prev);}
+ break;
+ case ANY:
+ n = jj_consume_token(ANY);
+ label_162:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[237] = jj_gen;
+ break label_162;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return LexicalUnitImpl.createMultiply(n.beginLine,
+ n.beginColumn,
+ prev);}
+ break;
+ case MOD:
+ n = jj_consume_token(MOD);
+ label_163:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[238] = jj_gen;
+ break label_163;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return LexicalUnitImpl.createModulo(n.beginLine,
+ n.beginColumn,
+ prev);}
+ break;
+ case PLUS:
+ n = jj_consume_token(PLUS);
+ label_164:
+ while (true) {
+ jj_consume_token(S);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[239] = jj_gen;
+ break label_164;
+ }
+ }
+ {if (true) return LexicalUnitImpl.createAdd(n.beginLine,
+ n.beginColumn,
+ prev);}
+ break;
+ case MINUS:
+ n = jj_consume_token(MINUS);
+ label_165:
+ while (true) {
+ jj_consume_token(S);
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[240] = jj_gen;
+ break label_165;
+ }
+ }
+ {if (true) return LexicalUnitImpl.createMinus(n.beginLine,
+ n.beginColumn,
+ prev);}
+ break;
+ default:
+ jj_la1[241] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ throw new Error("Missing return statement in function");
+ }
- final public LexicalUnitImpl variableTerm(LexicalUnitImpl prev)
- throws ParseException {
- LexicalUnitImpl result = null;
- String varName = "";
- varName = variableName();
- result = LexicalUnitImpl.createVariable(token.beginLine,
- token.beginColumn, prev, varName);
- {
- if (true) {
- return result;
- }
- }
- throw new Error("Missing return statement in function");
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public LexicalUnitImpl expr() throws ParseException {
+ LexicalUnitImpl first, res;
+ char op;
+ first = term(null);
+ res = first;
+ label_166:
+ while (true) {
+ if (jj_2_8(2)) {
+ ;
+ } else {
+ break label_166;
+ }
+ if (jj_2_9(2)) {
+ res = operator(res);
+ } else {
+ ;
+ }
+ res = term(res);
+ }
+ {if (true) return first;}
+ throw new Error("Missing return statement in function");
+ }
- final public LexicalUnitImpl nonVariableTerm(LexicalUnitImpl prev)
- throws ParseException {
- LexicalUnitImpl result = null;
- Token n = null;
- char op = ' ';
- String varName;
- String s = "";
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- case NUMBER:
- case PERCENTAGE:
- case PT:
- case MM:
- case CM:
- case PC:
- case IN:
- case PX:
- case EMS:
- case LEM:
- case REM:
- case EXS:
- case DEG:
- case RAD:
- case GRAD:
- case MS:
- case SECOND:
- case HZ:
- case KHZ:
- case DIMEN:
- case FUNCTION:
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- op = unaryOperator();
- break;
- default:
- jj_la1[242] = jj_gen;
- ;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case NUMBER:
- n = jj_consume_token(NUMBER);
- result = LexicalUnitImpl.createNumber(n.beginLine,
- n.beginColumn, prev, number(op, n, 0));
- break;
- case PERCENTAGE:
- n = jj_consume_token(PERCENTAGE);
- result = LexicalUnitImpl.createPercentage(n.beginLine,
- n.beginColumn, prev, number(op, n, 1));
- break;
- case PT:
- n = jj_consume_token(PT);
- result = LexicalUnitImpl.createPT(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case CM:
- n = jj_consume_token(CM);
- result = LexicalUnitImpl.createCM(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case MM:
- n = jj_consume_token(MM);
- result = LexicalUnitImpl.createMM(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case PC:
- n = jj_consume_token(PC);
- result = LexicalUnitImpl.createPC(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case IN:
- n = jj_consume_token(IN);
- result = LexicalUnitImpl.createIN(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case PX:
- n = jj_consume_token(PX);
- result = LexicalUnitImpl.createPX(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case EMS:
- n = jj_consume_token(EMS);
- result = LexicalUnitImpl.createEMS(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case LEM:
- n = jj_consume_token(LEM);
- result = LexicalUnitImpl.createLEM(n.beginLine, n.beginColumn,
- prev, number(op, n, 3));
- break;
- case REM:
- n = jj_consume_token(REM);
- result = LexicalUnitImpl.createREM(n.beginLine, n.beginColumn,
- prev, number(op, n, 3));
- break;
- case EXS:
- n = jj_consume_token(EXS);
- result = LexicalUnitImpl.createEXS(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case DEG:
- n = jj_consume_token(DEG);
- result = LexicalUnitImpl.createDEG(n.beginLine, n.beginColumn,
- prev, number(op, n, 3));
- break;
- case RAD:
- n = jj_consume_token(RAD);
- result = LexicalUnitImpl.createRAD(n.beginLine, n.beginColumn,
- prev, number(op, n, 3));
- break;
- case GRAD:
- n = jj_consume_token(GRAD);
- result = LexicalUnitImpl.createGRAD(n.beginLine, n.beginColumn,
- prev, number(op, n, 3));
- break;
- case SECOND:
- n = jj_consume_token(SECOND);
- result = LexicalUnitImpl.createS(n.beginLine, n.beginColumn,
- prev, number(op, n, 1));
- break;
- case MS:
- n = jj_consume_token(MS);
- result = LexicalUnitImpl.createMS(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case HZ:
- n = jj_consume_token(HZ);
- result = LexicalUnitImpl.createHZ(n.beginLine, n.beginColumn,
- prev, number(op, n, 2));
- break;
- case KHZ:
- n = jj_consume_token(KHZ);
- result = LexicalUnitImpl.createKHZ(n.beginLine, n.beginColumn,
- prev, number(op, n, 3));
- break;
- case DIMEN:
- n = jj_consume_token(DIMEN);
- s = n.image;
- int i = 0;
- while (i < s.length()
- && (Character.isDigit(s.charAt(i)) || (s.charAt(i) == '.'))) {
- i++;
- }
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public char unaryOperator() throws ParseException {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case MINUS:
+ jj_consume_token(MINUS);
+ {if (true) return '-';}
+ break;
+ case PLUS:
+ jj_consume_token(PLUS);
+ {if (true) return '+';}
+ break;
+ default:
+ jj_la1[242] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ throw new Error("Missing return statement in function");
+ }
- result = LexicalUnitImpl.createDimen(n.beginLine,
- n.beginColumn, prev, number(op, n, s.length() - i),
- s.substring(i));
- break;
- case FUNCTION:
- result = function(op, prev);
- break;
- default:
- jj_la1[243] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public LexicalUnitImpl term(LexicalUnitImpl prev) throws ParseException {
+ LexicalUnitImpl result = null;
+ Token n = null;
+ char op = ' ';
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case DOT:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case URL:
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case HASH:
+ case UNICODERANGE:
+ case FUNCTION:
+ result = nonVariableTerm(prev);
+ break;
+ case VARIABLE:
+ result = variableTerm(prev);
+ break;
+ default:
+ jj_la1[243] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ {if (true) return result;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public LexicalUnitImpl variableTerm(LexicalUnitImpl prev) throws ParseException {
+ LexicalUnitImpl result = null;
+ String varName = "";
+ varName = variableName();
+ result = LexicalUnitImpl.createVariable(token.beginLine, token.beginColumn,
+ prev, varName); {if (true) return result;}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public LexicalUnitImpl nonVariableTerm(LexicalUnitImpl prev) throws ParseException {
+LexicalUnitImpl result = null;
+ Token n = null;
+ char op = ' ';
+ String varName;
+ String s = "";
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case NUMBER:
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case FUNCTION:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ op = unaryOperator();
+ break;
+ default:
+ jj_la1[244] = jj_gen;
+ ;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case NUMBER:
+ n = jj_consume_token(NUMBER);
+ result = LexicalUnitImpl.createNumber(n.beginLine, n.beginColumn,
+ prev, number(op, n, 0));
+ break;
+ case PERCENTAGE:
+ n = jj_consume_token(PERCENTAGE);
+ result = LexicalUnitImpl.createPercentage(n.beginLine, n.beginColumn,
+ prev, number(op, n, 1));
+ break;
+ case PT:
+ n = jj_consume_token(PT);
+ result = LexicalUnitImpl.createPT(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case CM:
+ n = jj_consume_token(CM);
+ result = LexicalUnitImpl.createCM(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case MM:
+ n = jj_consume_token(MM);
+ result = LexicalUnitImpl.createMM(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case PC:
+ n = jj_consume_token(PC);
+ result = LexicalUnitImpl.createPC(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case IN:
+ n = jj_consume_token(IN);
+ result = LexicalUnitImpl.createIN(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case PX:
+ n = jj_consume_token(PX);
+ result = LexicalUnitImpl.createPX(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case EMS:
+ n = jj_consume_token(EMS);
+ result = LexicalUnitImpl.createEMS(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case LEM:
+ n = jj_consume_token(LEM);
+ result = LexicalUnitImpl.createLEM(n.beginLine, n.beginColumn,
+ prev, number(op, n, 3));
+ break;
+ case REM:
+ n = jj_consume_token(REM);
+ result = LexicalUnitImpl.createREM(n.beginLine, n.beginColumn,
+ prev, number(op, n, 3));
+ break;
+ case EXS:
+ n = jj_consume_token(EXS);
+ result = LexicalUnitImpl.createEXS(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case DEG:
+ n = jj_consume_token(DEG);
+ result = LexicalUnitImpl.createDEG(n.beginLine, n.beginColumn,
+ prev, number(op, n, 3));
+ break;
+ case RAD:
+ n = jj_consume_token(RAD);
+ result = LexicalUnitImpl.createRAD(n.beginLine, n.beginColumn,
+ prev, number(op, n, 3));
+ break;
+ case GRAD:
+ n = jj_consume_token(GRAD);
+ result = LexicalUnitImpl.createGRAD(n.beginLine, n.beginColumn,
+ prev, number(op, n, 3));
+ break;
+ case SECOND:
+ n = jj_consume_token(SECOND);
+ result = LexicalUnitImpl.createS(n.beginLine, n.beginColumn,
+ prev, number(op, n, 1));
+ break;
+ case MS:
+ n = jj_consume_token(MS);
+ result = LexicalUnitImpl.createMS(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case HZ:
+ n = jj_consume_token(HZ);
+ result = LexicalUnitImpl.createHZ(n.beginLine, n.beginColumn,
+ prev, number(op, n, 2));
+ break;
+ case KHZ:
+ n = jj_consume_token(KHZ);
+ result = LexicalUnitImpl.createKHZ(n.beginLine, n.beginColumn,
+ prev, number(op, n, 3));
+ break;
+ case DIMEN:
+ n = jj_consume_token(DIMEN);
+ s = n.image;
+ int i = 0;
+ while (i < s.length()
+ && (Character.isDigit(s.charAt(i)) || (s.charAt(i) == '.'))) {
+ i++;
}
- break;
+
+ result = LexicalUnitImpl.createDimen(n.beginLine, n.beginColumn, prev,
+ number(op,n,s.length()-i),
+ s.substring(i));
+ break;
+ case FUNCTION:
+ result = function(op, prev);
+ break;
+ default:
+ jj_la1[245] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ case DOT:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case URL:
+ case HASH:
+ case UNICODERANGE:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case STRING:
+ n = jj_consume_token(STRING);
+ result =
+ LexicalUnitImpl.createString(n.beginLine, n.beginColumn, prev,
+ convertStringIndex(n.image, 1,
+ n.image.length() -1));
+ break;
+ case DOT:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case IDENT:
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case DOT:
+ jj_consume_token(DOT);
+ s+=".";
+ break;
+ default:
+ jj_la1[246] = jj_gen;
+ ;
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IDENT:
+ n = jj_consume_token(IDENT);
+ break;
case TO:
+ n = jj_consume_token(TO);
+ break;
case THROUGH:
+ n = jj_consume_token(THROUGH);
+ break;
case FROM:
- case STRING:
- case IDENT:
- case URL:
- case HASH:
- case UNICODERANGE:
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case STRING:
- n = jj_consume_token(STRING);
- result = LexicalUnitImpl.createString(n.beginLine,
- n.beginColumn, prev,
- convertStringIndex(n.image, 1, n.image.length() - 1));
- break;
- case DOT:
- case TO:
- case THROUGH:
- case FROM:
- case IDENT:
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case DOT:
- jj_consume_token(DOT);
- s += ".";
- break;
- default:
- jj_la1[244] = jj_gen;
- ;
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IDENT:
- n = jj_consume_token(IDENT);
- break;
- case TO:
- n = jj_consume_token(TO);
- break;
- case THROUGH:
- n = jj_consume_token(THROUGH);
- break;
- case FROM:
- n = jj_consume_token(FROM);
- break;
- default:
- jj_la1[245] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- s += convertIdent(n.image);
- if ("inherit".equals(s)) {
- result = LexicalUnitImpl.createInherit(n.beginLine,
- n.beginColumn, prev);
- } else {
- result = LexicalUnitImpl.createIdent(n.beginLine,
- n.beginColumn, prev, convertIdent(n.image));
- }
-
- /*
- * / Auto correction code used in the CSS Validator but must not
- * be used by a conformant CSS2 parser. Common error : H1 {
- * color : black background : white }
- *
- * Token t = getToken(1); Token semicolon = new Token();
- * semicolon.kind = SEMICOLON; semicolon.image = ";"; if (t.kind
- * == COLON) { // @@SEEME. (generate a warning?) // @@SEEME if
- * expression is a single ident, generate an error ?
- * rejectToken(semicolon);
- *
- * result = prev; } /
- */
-
- break;
- case HASH:
- result = hexcolor(prev);
- break;
- case URL:
- result = url(prev);
- break;
- case UNICODERANGE:
- result = unicode(prev);
- break;
- default:
- jj_la1[246] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- break;
+ n = jj_consume_token(FROM);
+ break;
default:
- jj_la1[247] = jj_gen;
- jj_consume_token(-1);
- throw new ParseException();
- }
- label_167: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[248] = jj_gen;
- break label_167;
- }
- jj_consume_token(S);
- }
- {
- if (true) {
- return result;
- }
- }
- throw new Error("Missing return statement in function");
- }
+ jj_la1[247] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ s += convertIdent(n.image);
+ if ("inherit".equals(s)) {
+ result = LexicalUnitImpl.createInherit(n.beginLine, n.beginColumn,
+ prev);
+ } else {
+ result = LexicalUnitImpl.createIdent(n.beginLine, n.beginColumn,
+ prev, convertIdent(n.image));
+ }
+
+ /* /
+ Auto correction code used in the CSS Validator but must not
+ be used by a conformant CSS2 parser.
+ * Common error :
+ * H1 {
+ * color : black
+ * background : white
+ * }
+ *
+ Token t = getToken(1);
+ Token semicolon = new Token();
+ semicolon.kind = SEMICOLON;
+ semicolon.image = ";";
+ if (t.kind == COLON) {
+ // @@SEEME. (generate a warning?)
+ // @@SEEME if expression is a single ident,
+ generate an error ?
+ rejectToken(semicolon);
+
+ result = prev;
+ }
+ / */
+
+ break;
+ case HASH:
+ result = hexcolor(prev);
+ break;
+ case URL:
+ result = url(prev);
+ break;
+ case UNICODERANGE:
+ result = unicode(prev);
+ break;
+ default:
+ jj_la1[248] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ break;
+ default:
+ jj_la1[249] = jj_gen;
+ jj_consume_token(-1);
+ throw new ParseException();
+ }
+ label_167:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[250] = jj_gen;
+ break label_167;
+ }
+ jj_consume_token(S);
+ }
+ {if (true) return result;}
+ throw new Error("Missing return statement in function");
+ }
- /**
- * Handle all CSS2 functions.
- *
- * @exception ParseException
- * exception during the parse
- */
- final public LexicalUnitImpl function(char operator, LexicalUnitImpl prev)
- throws ParseException {
- Token n;
- LexicalUnit params = null;
- n = jj_consume_token(FUNCTION);
- label_168: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[249] = jj_gen;
- break label_168;
- }
- jj_consume_token(S);
- }
+/**
+ * Handle all CSS2 functions.
+ * @exception ParseException exception during the parse
+ */
+ final public LexicalUnitImpl function(char operator, LexicalUnitImpl prev) throws ParseException {
+ Token n;
+ LexicalUnit params = null;
+ n = jj_consume_token(FUNCTION);
+ label_168:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[251] = jj_gen;
+ break label_168;
+ }
+ jj_consume_token(S);
+ }
String fname = convertIdent(n.image);
- if ("alpha(".equals(fname)) {
+ if("alpha(".equals(fname)){
String body = skipStatementUntilSemiColon();
- {
- if (true) {
- return LexicalUnitImpl.createIdent(n.beginLine,
- n.beginColumn, null, "alpha(" + body);
- }
- }
- } else if ("expression(".equals(fname)) {
+ {if (true) return LexicalUnitImpl.createIdent(n.beginLine, n.beginColumn,
+ null, "alpha("+body);}
+ }else if("expression(".equals(fname)){
String body = skipStatementUntilSemiColon();
- {
- if (true) {
- return LexicalUnitImpl.createIdent(n.beginLine,
- n.beginColumn, null, "expression(" + body);
- }
- }
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case PLUS:
- case MINUS:
- case DOT:
- case TO:
- case THROUGH:
- case FROM:
- case STRING:
- case IDENT:
- case NUMBER:
- case URL:
- case VARIABLE:
- case PERCENTAGE:
- case PT:
- case MM:
- case CM:
- case PC:
- case IN:
- case PX:
- case EMS:
- case LEM:
- case REM:
- case EXS:
- case DEG:
- case RAD:
- case GRAD:
- case MS:
- case SECOND:
- case HZ:
- case KHZ:
- case DIMEN:
- case HASH:
- case UNICODERANGE:
- case FUNCTION:
- params = expr();
- break;
- default:
- jj_la1[250] = jj_gen;
- ;
- }
- jj_consume_token(RPARAN);
+ {if (true) return LexicalUnitImpl.createIdent(n.beginLine, n.beginColumn,
+ null, "expression("+body);}
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case PLUS:
+ case MINUS:
+ case DOT:
+ case TO:
+ case THROUGH:
+ case FROM:
+ case STRING:
+ case IDENT:
+ case NUMBER:
+ case URL:
+ case VARIABLE:
+ case PERCENTAGE:
+ case PT:
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case PX:
+ case EMS:
+ case LEM:
+ case REM:
+ case EXS:
+ case DEG:
+ case RAD:
+ case GRAD:
+ case MS:
+ case SECOND:
+ case HZ:
+ case KHZ:
+ case DIMEN:
+ case HASH:
+ case UNICODERANGE:
+ case FUNCTION:
+ params = expr();
+ break;
+ default:
+ jj_la1[252] = jj_gen;
+ ;
+ }
+ jj_consume_token(RPARAN);
if (operator != ' ') {
- {
- if (true) {
- throw new CSSParseException(
- "invalid operator before a function.", getLocator());
- }
- }
+ {if (true) throw new CSSParseException("invalid operator before a function.",
+ getLocator());}
}
String f = convertIdent(n.image);
LexicalUnitImpl l = (LexicalUnitImpl) params;
@@ -5871,38 +5859,32 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
int i = 0;
while (loop && l != null && i < 5) {
switch (i) {
- case 0:
- case 2:
- case 4:
- if ((l.getLexicalUnitType() != LexicalUnit.SAC_INTEGER)
+ case 0:
+ case 2:
+ case 4:
+ if ((l.getLexicalUnitType() != LexicalUnit.SAC_INTEGER)
&& (l.getLexicalUnitType() != LexicalUnit.SAC_PERCENTAGE)) {
- loop = false;
- }
- break;
- case 1:
- case 3:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
- loop = false;
- }
- break;
- default: {
- if (true) {
- throw new ParseException("implementation error");
- }
- }
+ loop = false;
+ }
+ break;
+ case 1:
+ case 3:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
+ loop = false;
+ }
+ break;
+ default:
+ {if (true) throw new ParseException("implementation error");}
}
if (loop) {
- l = l.getNextLexicalUnit();
- i++;
+ l = (LexicalUnitImpl) l.getNextLexicalUnit();
+ i ++;
}
}
if ((i == 5) && loop && (l == null)) {
- {
- if (true) {
- return LexicalUnitImpl.createRGBColor(n.beginLine,
- n.beginColumn, prev, params);
- }
- }
+ {if (true) return LexicalUnitImpl.createRGBColor(n.beginLine,
+ n.beginColumn,
+ prev, params);}
} else {
if (errorHandler != null) {
String errorText;
@@ -5910,63 +5892,54 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
if (i < 5) {
if (params == null) {
loc = new LocatorImpl(this, n.beginLine,
- n.beginColumn - 1);
+ n.beginColumn-1);
errorText = "not enough parameters.";
} else if (l == null) {
loc = new LocatorImpl(this, n.beginLine,
- n.beginColumn - 1);
+ n.beginColumn-1);
errorText = "not enough parameters: "
- + params.toString();
+ + params.toString();
} else {
loc = new LocatorImpl(this, l.getLineNumber(),
- l.getColumnNumber());
- errorText = "invalid parameter: " + l.toString();
+ l.getColumnNumber());
+ errorText = "invalid parameter: "
+ + l.toString();
}
} else {
loc = new LocatorImpl(this, l.getLineNumber(),
- l.getColumnNumber());
- errorText = "too many parameters: " + l.toString();
+ l.getColumnNumber());
+ errorText = "too many parameters: "
+ + l.toString();
}
errorHandler.error(new CSSParseException(errorText, loc));
}
- {
- if (true) {
- throw new JumpException();
- }
- }
+ {if (true) throw new JumpException();}
}
} else if ("counter".equals(f)) {
int i = 0;
while (loop && l != null && i < 3) {
switch (i) {
- case 0:
- case 2:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_IDENT) {
- loop = false;
- }
- break;
- case 1:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
- loop = false;
- }
- break;
- default: {
- if (true) {
- throw new ParseException("implementation error");
- }
- }
+ case 0:
+ case 2:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_IDENT) {
+ loop = false;
+ }
+ break;
+ case 1:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
+ loop = false;
+ }
+ break;
+ default:
+ {if (true) throw new ParseException("implementation error");}
}
- l = l.getNextLexicalUnit();
- i++;
+ l = (LexicalUnitImpl) l.getNextLexicalUnit();
+ i ++;
}
if (((i == 1) || (i == 3)) && loop && (l == null)) {
- {
- if (true) {
- return LexicalUnitImpl.createCounter(n.beginLine,
- n.beginColumn, prev, params);
- }
- }
+ {if (true) return LexicalUnitImpl.createCounter(n.beginLine, n.beginColumn,
+ prev, params);}
}
} else if ("counters(".equals(f)) {
@@ -5974,2650 +5947,1943 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
int i = 0;
while (loop && l != null && i < 5) {
switch (i) {
- case 0:
- case 4:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_IDENT) {
- loop = false;
- }
- break;
- case 2:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_STRING_VALUE) {
- loop = false;
- }
- break;
- case 1:
- case 3:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
- loop = false;
- }
- break;
- default: {
- if (true) {
- throw new ParseException("implementation error");
- }
- }
+ case 0:
+ case 4:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_IDENT) {
+ loop = false;
+ }
+ break;
+ case 2:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_STRING_VALUE) {
+ loop = false;
+ }
+ break;
+ case 1:
+ case 3:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
+ loop = false;
+ }
+ break;
+ default:
+ {if (true) throw new ParseException("implementation error");}
}
- l = l.getNextLexicalUnit();
- i++;
+ l = (LexicalUnitImpl) l.getNextLexicalUnit();
+ i ++;
}
if (((i == 3) || (i == 5)) && loop && (l == null)) {
- {
- if (true) {
- return LexicalUnitImpl.createCounters(n.beginLine,
- n.beginColumn, prev, params);
- }
- }
+ {if (true) return LexicalUnitImpl.createCounters(n.beginLine, n.beginColumn,
+ prev, params);}
}
} else if ("attr(".equals(f)) {
- if ((l != null) && (l.getNextLexicalUnit() == null)
- && (l.getLexicalUnitType() == LexicalUnit.SAC_IDENT)) {
- {
- if (true) {
- return LexicalUnitImpl.createAttr(l.getLineNumber(),
- l.getColumnNumber(), prev, l.getStringValue());
- }
- }
+ if ((l != null)
+ && (l.getNextLexicalUnit() == null)
+ && (l.getLexicalUnitType() == LexicalUnit.SAC_IDENT)) {
+ {if (true) return LexicalUnitImpl.createAttr(l.getLineNumber(),
+ l.getColumnNumber(),
+ prev, l.getStringValue());}
}
} else if ("rect(".equals(f)) {
int i = 0;
while (loop && l != null && i < 7) {
switch (i) {
- case 0:
- case 2:
- case 4:
- case 6:
- switch (l.getLexicalUnitType()) {
- case LexicalUnit.SAC_INTEGER:
- if (l.getIntegerValue() != 0) {
+ case 0:
+ case 2:
+ case 4:
+ case 6:
+ switch (l.getLexicalUnitType()) {
+ case LexicalUnit.SAC_INTEGER:
+ if (l.getIntegerValue() != 0) {
+ loop = false;
+ }
+ break;
+ case LexicalUnit.SAC_IDENT:
+ if (!l.getStringValue().equals("auto")) {
+ loop = false;
+ }
+ break;
+ case LexicalUnit.SAC_EM:
+ case LexicalUnit.SAC_EX:
+ case LexicalUnit.SAC_PIXEL:
+ case LexicalUnit.SAC_CENTIMETER:
+ case LexicalUnit.SAC_MILLIMETER:
+ case LexicalUnit.SAC_INCH:
+ case LexicalUnit.SAC_POINT:
+ case LexicalUnit.SAC_PICA:
+ // nothing
+ break;
+ default:
loop = false;
}
break;
- case LexicalUnit.SAC_IDENT:
- if (!l.getStringValue().equals("auto")) {
+ case 1:
+ case 3:
+ case 5:
+ if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
loop = false;
}
break;
- case LexicalUnit.SAC_EM:
- case LexicalUnit.SAC_EX:
- case LexicalUnit.SAC_PIXEL:
- case LexicalUnit.SAC_CENTIMETER:
- case LexicalUnit.SAC_MILLIMETER:
- case LexicalUnit.SAC_INCH:
- case LexicalUnit.SAC_POINT:
- case LexicalUnit.SAC_PICA:
- // nothing
- break;
default:
- loop = false;
- }
- break;
- case 1:
- case 3:
- case 5:
- if (l.getLexicalUnitType() != LexicalUnit.SAC_OPERATOR_COMMA) {
- loop = false;
- }
- break;
- default: {
- if (true) {
- throw new ParseException("implementation error");
- }
+ {if (true) throw new ParseException("implementation error");}
}
- }
- l = l.getNextLexicalUnit();
- i++;
+ l = (LexicalUnitImpl) l.getNextLexicalUnit();
+ i ++;
}
if ((i == 7) && loop && (l == null)) {
- {
- if (true) {
- return LexicalUnitImpl.createRect(n.beginLine,
- n.beginColumn, prev, params);
- }
- }
- }
- }
- {
- if (true) {
- return LexicalUnitImpl.createFunction(n.beginLine,
- n.beginColumn, prev, f.substring(0, f.length() - 1),
- params);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public LexicalUnitImpl unicode(LexicalUnitImpl prev)
- throws ParseException {
- Token n;
- n = jj_consume_token(UNICODERANGE);
- LexicalUnitImpl params = null;
- String s = n.image.substring(2);
- int index = s.indexOf('-');
- if (index == -1) {
- params = LexicalUnitImpl.createInteger(n.beginLine, n.beginColumn,
- params, Integer.parseInt(s, 16));
- } else {
- String s1 = s.substring(0, index);
- String s2 = s.substring(index);
-
- params = LexicalUnitImpl.createInteger(n.beginLine, n.beginColumn,
- params, Integer.parseInt(s1, 16));
- params = LexicalUnitImpl.createInteger(n.beginLine, n.beginColumn,
- params, Integer.parseInt(s2, 16));
- }
-
- {
- if (true) {
- return LexicalUnitImpl.createUnicodeRange(n.beginLine,
- n.beginColumn, prev, params);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- final public LexicalUnitImpl url(LexicalUnitImpl prev)
- throws ParseException {
- Token n;
- n = jj_consume_token(URL);
- String urlname = n.image.substring(4, n.image.length() - 1).trim();
- {
- if (true) {
- return LexicalUnitImpl.createURL(n.beginLine, n.beginColumn,
- prev, urlname);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- /**
- * @exception ParseException
- * exception during the parse
- */
- final public LexicalUnitImpl hexcolor(LexicalUnitImpl prev)
- throws ParseException {
- Token n;
- n = jj_consume_token(HASH);
- int r;
- LexicalUnitImpl first, params = null;
- String s = n.image.substring(1);
-
- if (s.length() != 3 && s.length() != 6) {
- first = null;
- {
- if (true) {
- throw new CSSParseException(
- "invalid hexadecimal notation for RGB: " + s,
- getLocator());
- }
- }
- }
- {
- if (true) {
- return LexicalUnitImpl.createIdent(n.beginLine, n.beginColumn,
- prev, n.image);
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- float number(char operator, Token n, int lengthUnit) throws ParseException {
- String image = n.image;
- float f = 0;
-
- if (lengthUnit != 0) {
- image = image.substring(0, image.length() - lengthUnit);
- }
- f = Float.valueOf(image).floatValue();
- return (operator == '-') ? -f : f;
- }
-
- String skipStatementUntilSemiColon() throws ParseException {
- int[] semicolon = { SEMICOLON };
- return skipStatementUntil(semicolon);
- }
-
- String skipStatementUntilLeftBrace() throws ParseException {
- int[] lBrace = { LBRACE };
- return skipStatementUntil(lBrace);
- }
-
- String skipStatementUntilMatchingRightParan() throws ParseException {
- int[] leftTokens = { LPARAN, FUNCTION }; // a FUNCTION also contains "("
- int[] rightTokens = { RPARAN };
- StringBuffer s = new StringBuffer();
- int difference = 1;
- Token tok;
- while (difference != 0) {
- tok = getToken(1);
- if (tok.kind == EOF) {
- return null;
- }
- for (int sym : leftTokens) {
- if (tok.kind == sym) {
- difference++;
- }
- }
- for (int sym : rightTokens) {
- if (tok.kind == sym) {
- difference--;
- }
- }
- if (difference != 0) {
- if (tok.image != null) {
- s.append(tok.image);
- }
- getNextToken();
- }
- }
- return s.toString().trim();
- }
+ {if (true) return LexicalUnitImpl.createRect(n.beginLine, n.beginColumn,
+ prev, params);}
+ }
+ }
+ {if (true) return LexicalUnitImpl.createFunction(n.beginLine, n.beginColumn, prev,
+ f.substring(0,
+ f.length() -1),
+ params);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public LexicalUnitImpl unicode(LexicalUnitImpl prev) throws ParseException {
+ Token n;
+ n = jj_consume_token(UNICODERANGE);
+ LexicalUnitImpl params = null;
+ String s = n.image.substring(2);
+ int index = s.indexOf('-');
+ if (index == -1) {
+ params = LexicalUnitImpl.createInteger(n.beginLine, n.beginColumn,
+ params, Integer.parseInt(s, 16));
+ } else {
+ String s1 = s.substring(0, index);
+ String s2 = s.substring(index);
+
+ params = LexicalUnitImpl.createInteger(n.beginLine, n.beginColumn,
+ params, Integer.parseInt(s1, 16));
+ params = LexicalUnitImpl.createInteger(n.beginLine, n.beginColumn,
+ params, Integer.parseInt(s2, 16));
+ }
+
+ {if (true) return LexicalUnitImpl.createUnicodeRange(n.beginLine, n.beginColumn,
+ prev, params);}
+ throw new Error("Missing return statement in function");
+ }
+
+ final public LexicalUnitImpl url(LexicalUnitImpl prev) throws ParseException {
+ Token n;
+ n = jj_consume_token(URL);
+ String urlname = n.image.substring(4, n.image.length()-1).trim();
+ {if (true) return LexicalUnitImpl.createURL(n.beginLine, n.beginColumn, prev, urlname);}
+ throw new Error("Missing return statement in function");
+ }
- String skipStatementUntil(int[] symbols) throws ParseException {
- StringBuffer s = new StringBuffer();
- boolean stop = false;
- Token tok;
- while (!stop) {
- tok = getToken(1);
- if (tok.kind == EOF) {
- return null;
- }
- for (int sym : symbols) {
- if (tok.kind == sym) {
- stop = true;
- break;
- }
- }
- if (!stop) {
- if (tok.image != null) {
- s.append(tok.image);
- }
- getNextToken();
+/**
+ * @exception ParseException exception during the parse
+ */
+ final public LexicalUnitImpl hexcolor(LexicalUnitImpl prev) throws ParseException {
+ Token n;
+ n = jj_consume_token(HASH);
+ int r;
+ LexicalUnitImpl first, params = null;
+ String s = n.image.substring(1);
+
+ if(s.length()!=3 && s.length()!=6) {
+ first = null;
+ {if (true) throw new CSSParseException("invalid hexadecimal notation for RGB: " + s,
+ getLocator());}
+ }
+ {if (true) return LexicalUnitImpl.createIdent(n.beginLine, n.beginColumn,
+ prev, n.image);}
+ throw new Error("Missing return statement in function");
+ }
+
+ float number(char operator, Token n, int lengthUnit) throws ParseException {
+ String image = n.image;
+ float f = 0;
+
+ if (lengthUnit != 0) {
+ image = image.substring(0, image.length() - lengthUnit);
+ }
+ f = Float.valueOf(image).floatValue();
+ return (operator == '-')? -f: f;
+ }
+
+ String skipStatementUntilSemiColon() throws ParseException {
+ int[] semicolon = {SEMICOLON};
+ return skipStatementUntil(semicolon);
+ }
+
+ String skipStatementUntilLeftBrace() throws ParseException {
+ int[] lBrace = {LBRACE};
+ return skipStatementUntil(lBrace);
+ }
+
+ String skipStatementUntilMatchingRightParan() throws ParseException {
+ int[] leftTokens = {LPARAN, FUNCTION}; // a FUNCTION also contains "("
+ int[] rightTokens = {RPARAN};
+ StringBuffer s = new StringBuffer();
+ int difference = 1;
+ Token tok;
+ while(difference != 0){
+ tok = getToken(1);
+ if(tok.kind == EOF) {
+ return null;
+ }
+ for(int sym : leftTokens){
+ if(tok.kind == sym){
+ difference++;
+ }
+ }
+ for(int sym : rightTokens){
+ if(tok.kind == sym){
+ difference--;
+ }
+ }
+ if(difference != 0){
+ if (tok.image != null) {
+ s.append(tok.image);
}
+ getNextToken();
}
- return s.toString().trim();
}
+ return s.toString().trim();
+ }
- String skipStatement() throws ParseException {
- StringBuffer s = new StringBuffer();
- Token tok = getToken(0);
- if (tok.image != null) {
- s.append(tok.image);
- }
- while (true) {
- tok = getToken(1);
- if (tok.kind == EOF) {
- return null;
- }
- s.append(tok.image);
- if (tok.kind == LBRACE) {
- getNextToken();
- s.append(skip_to_matching_brace());
- getNextToken();
- tok = getToken(1);
- break;
- } else if (tok.kind == RBRACE) {
- getNextToken();
- tok = getToken(1);
- break;
- } else if (tok.kind == SEMICOLON) {
- getNextToken();
- tok = getToken(1);
+ String skipStatementUntil(int[] symbols) throws ParseException {
+ StringBuffer s = new StringBuffer();
+ boolean found = false;
+ Token tok;
+ while(!found){
+ tok = getToken(1);
+ for(int sym : symbols){
+ if(tok.kind == sym){
+ found = true;
break;
}
- getNextToken();
}
-
- // skip white space
- while (true) {
- if (tok.kind != S) {
- break;
- }
- tok = getNextToken();
- tok = getToken(1);
+ if(tok.kind == EOF) {
+ break;
}
-
- return s.toString().trim();
- }
-
- String skip_to_matching_brace() throws ParseException {
- StringBuffer s = new StringBuffer();
- Token tok;
- int nesting = 1;
- while (true) {
- tok = getToken(1);
- if (tok.kind == EOF) {
- break;
- }
- s.append(tok.image);
- if (tok.kind == LBRACE) {
- nesting++;
- } else if (tok.kind == RBRACE) {
- nesting--;
- if (nesting == 0) {
- break;
- }
+ if(!found){
+ if (tok.image != null) {
+ s.append(tok.image);
}
getNextToken();
}
- return s.toString();
- }
-
- String convertStringIndex(String s, int start, int len)
- throws ParseException {
- StringBuffer buf = new StringBuffer(len);
- int index = start;
-
- while (index < len) {
- char c = s.charAt(index);
- if (c == '\u005c\u005c') {
- if (++index < len) {
- c = s.charAt(index);
- switch (c) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- buf.append('\u005c\u005c');
- while (index < len) {
- buf.append(s.charAt(index++));
- }
- break;
- case '\u005cn':
- case '\u005cf':
- break;
- case '\u005cr':
- if (index + 1 < len) {
- if (s.charAt(index + 1) == '\u005cn') {
- index++;
- }
- }
- break;
- default:
- buf.append(c);
- }
- } else {
- throw new CSSParseException("invalid string " + s,
- getLocator());
- }
- } else {
- buf.append(c);
- }
- index++;
- }
-
- return buf.toString();
- }
-
- String convertIdent(String s) throws ParseException {
- return convertStringIndex(s, 0, s.length());
}
+ return found ? s.toString().trim() : null;
+ }
- String convertString(String s) throws ParseException {
- return convertStringIndex(s, 0, s.length());
+ String skipStatement() throws ParseException {
+ StringBuffer s = new StringBuffer();
+ Token tok = getToken(0);
+ if (tok.image != null) {
+ s.append(tok.image);
}
-
- void comments() throws ParseException {
- /*
- * keeps only the multiple line comments, single line comments are
- * skipped
- */
- if (token.specialToken != null && token.specialToken.image != null
- && token.specialToken.image.startsWith("/*")) {
- Token tmp_t = token.specialToken;
- while (tmp_t.specialToken != null) {
- tmp_t = tmp_t.specialToken;
- }
- while (tmp_t != null) {
- documentHandler.comment(tmp_t.image);
- tmp_t = tmp_t.next;
- }
+ while (true) {
+ tok = getToken(1);
+ if (tok.kind == EOF) {
+ return null;
}
- }
-
- void rejectToken(Token t) throws ParseException {
- Token fakeToken = new Token();
- t.next = token;
- fakeToken.next = t;
- token = fakeToken;
- }
-
- String skipAfterExpression() throws ParseException {
- Token t = getToken(1);
- StringBuffer s = new StringBuffer();
- s.append(getToken(0).image);
-
- while ((t.kind != RBRACE) && (t.kind != SEMICOLON) && (t.kind != EOF)) {
- s.append(t.image);
+ s.append(tok.image);
+ if (tok.kind == LBRACE) {
getNextToken();
- t = getToken(1);
- }
-
- return s.toString();
- }
-
- /**
- * The following functions are useful for a DOM CSS implementation only and
- * are not part of the general CSS2 parser.
- */
- // TODO required by original parser but not used by Vaadin?
- final public void _parseRule() throws ParseException {
- String ret = null;
- label_169: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[251] = jj_gen;
- break label_169;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case IMPORT_SYM:
- importDeclaration();
- break;
- 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 MEDIA_SYM:
- media();
+ s.append(skip_to_matching_brace());
+ getNextToken();
+ tok = getToken(1);
break;
- case PAGE_SYM:
- page();
+ } else if (tok.kind == RBRACE) {
+ getNextToken();
+ tok = getToken(1);
break;
- case FONT_FACE_SYM:
- fontFace();
+ } else if (tok.kind == SEMICOLON) {
+ getNextToken();
+ tok = getToken(1);
break;
- default:
- jj_la1[252] = jj_gen;
- ret = skipStatement();
- if ((ret == null) || (ret.length() == 0)) {
- {
- if (true) {
- return;
- }
- }
- }
- if (ret.charAt(0) == '@') {
- documentHandler.unrecognizedRule(ret);
- } else {
- {
- if (true) {
- throw new CSSParseException("unrecognize rule: " + ret,
- getLocator());
- }
- }
- }
}
+ getNextToken();
}
- final public void _parseImportRule() throws ParseException {
- label_170: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[253] = jj_gen;
- break label_170;
- }
- jj_consume_token(S);
+ // skip white space
+ while (true) {
+ if (tok.kind != S) {
+ break;
}
- importDeclaration();
+ tok = getNextToken();
+ tok = getToken(1);
}
- final public void _parseMediaRule() throws ParseException {
- label_171: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[254] = jj_gen;
- break label_171;
- }
- jj_consume_token(S);
- }
- media();
- }
+ return s.toString().trim();
+ }
- final public void _parseDeclarationBlock() throws ParseException {
- label_172: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
- break;
- default:
- jj_la1[255] = jj_gen;
- break label_172;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
+ String skip_to_matching_brace() throws ParseException {
+ StringBuffer s = new StringBuffer();
+ Token tok;
+ int nesting = 1;
+ while (true) {
+ tok = getToken(1);
+ if (tok.kind == EOF) {
break;
- default:
- jj_la1[256] = jj_gen;
- ;
}
- label_173: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case SEMICOLON:
- ;
- break;
- default:
- jj_la1[257] = jj_gen;
- break label_173;
- }
- jj_consume_token(SEMICOLON);
- label_174: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
+ s.append(tok.image);
+ if (tok.kind == LBRACE) {
+ nesting++;
+ } else if (tok.kind == RBRACE) {
+ nesting--;
+ if (nesting == 0) {
+ break;
+ }
+ }
+ getNextToken();
+ }
+ return s.toString();
+ }
+
+ String convertStringIndex(String s, int start, int len) throws ParseException {
+ StringBuffer buf = new StringBuffer(len);
+ int index = start;
+
+ while (index < len) {
+ char c = s.charAt(index);
+ if (c == '\u005c\u005c') {
+ if (++index < len) {
+ c = s.charAt(index);
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ buf.append('\u005c\u005c');
+ while (index < len) {
+ buf.append(s.charAt(index++));
+ }
break;
- default:
- jj_la1[258] = jj_gen;
- break label_174;
- }
- jj_consume_token(S);
- }
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case INTERPOLATION:
- case IDENT:
- declaration();
- break;
- default:
- jj_la1[259] = jj_gen;
- ;
- }
- }
- }
-
- final public ArrayList<String> _parseSelectors() throws ParseException {
- ArrayList<String> p = null;
- try {
- label_175: while (true) {
- switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
- case S:
- ;
+ case '\u005cn':
+ case '\u005cf':
break;
- default:
- jj_la1[260] = jj_gen;
- break label_175;
- }
- jj_consume_token(S);
- }
- p = selectorList();
- {
- if (true) {
- return p;
- }
- }
- } catch (ThrowedParseException e) {
- {
- if (true) {
- throw (ParseException) e.e.fillInStackTrace();
- }
- }
- }
- throw new Error("Missing return statement in function");
- }
-
- private boolean jj_2_1(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_1();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(0, xla);
- }
- }
-
- private boolean jj_2_2(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_2();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(1, xla);
- }
- }
-
- private boolean jj_2_3(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_3();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(2, xla);
- }
- }
-
- private boolean jj_2_4(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_4();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(3, xla);
- }
- }
-
- private boolean jj_2_5(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_5();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(4, xla);
- }
- }
-
- private boolean jj_2_6(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_6();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(5, xla);
- }
- }
-
- private boolean jj_2_7(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_7();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(6, xla);
- }
- }
-
- private boolean jj_2_8(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_8();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(7, xla);
- }
- }
-
- private boolean jj_2_9(int xla) {
- jj_la = xla;
- jj_lastpos = jj_scanpos = token;
- try {
- return !jj_3_9();
- } catch (LookaheadSuccess ls) {
- return true;
- } finally {
- jj_save(8, xla);
- }
- }
-
- private boolean jj_3R_209() {
- if (jj_scan_token(MINUS)) {
- return true;
- }
- Token xsp;
- if (jj_scan_token(1)) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_188() {
- if (jj_3R_210()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_208() {
- if (jj_scan_token(PLUS)) {
- return true;
- }
- Token xsp;
- if (jj_scan_token(1)) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_207() {
- if (jj_scan_token(MOD)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_206() {
- if (jj_scan_token(ANY)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_205() {
- if (jj_scan_token(DIV)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- 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;
- }
- }
- return false;
- }
-
- private boolean jj_3R_185() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_204()) {
- jj_scanpos = xsp;
- if (jj_3R_205()) {
- jj_scanpos = xsp;
- if (jj_3R_206()) {
- jj_scanpos = xsp;
- if (jj_3R_207()) {
- jj_scanpos = xsp;
- if (jj_3R_208()) {
- jj_scanpos = xsp;
- if (jj_3R_209()) {
- return true;
- }
- }
- }
- }
- }
- }
- return false;
- }
-
- private boolean jj_3R_212() {
- if (jj_3R_211()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_211() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_scan_token(18)) {
- jj_scanpos = xsp;
- if (jj_scan_token(22)) {
- jj_scanpos = xsp;
- if (jj_scan_token(23)) {
- return true;
- }
- }
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_191() {
- if (jj_scan_token(S)) {
- return true;
- }
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_212()) {
- jj_scanpos = xsp;
- }
- return false;
- }
-
- private boolean jj_3R_210() {
- if (jj_scan_token(GUARDED_SYM)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_176() {
- if (jj_3R_186()) {
- 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_187()) {
- return true;
- }
- xsp = jj_scanpos;
- if (jj_3R_188()) {
- jj_scanpos = xsp;
- }
- if (jj_3R_189()) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_189()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_190() {
- if (jj_3R_211()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_177() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_190()) {
- jj_scanpos = xsp;
- if (jj_3R_191()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3R_194() {
- 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_179() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_194()) {
- jj_scanpos = xsp;
- }
- if (jj_scan_token(CONTAINS)) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- if (true) {
- jj_la = 0;
- jj_scanpos = jj_lastpos;
- return false;
- }
- return false;
- }
-
- private boolean jj_3R_262() {
- if (jj_scan_token(HASH)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_279() {
- if (jj_scan_token(IDENT)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_280() {
- if (jj_scan_token(FUNCTION)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- if (true) {
- jj_la = 0;
- jj_scanpos = jj_lastpos;
- return false;
- }
- return false;
- }
-
- private boolean jj_3R_278() {
- if (jj_scan_token(COLON)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_265() {
- if (jj_scan_token(COLON)) {
- return true;
- }
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_278()) {
- jj_scanpos = xsp;
- }
- xsp = jj_scanpos;
- if (jj_3R_279()) {
- jj_scanpos = xsp;
- if (jj_3R_280()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3_7() {
- if (jj_3R_183()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_201() {
- if (jj_scan_token(LBRACE)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_290() {
- if (jj_scan_token(STRING)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_288() {
- if (jj_scan_token(STARMATCH)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_287() {
- if (jj_scan_token(DOLLARMATCH)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_289() {
- if (jj_scan_token(IDENT)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_286() {
- if (jj_scan_token(CARETMATCH)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_285() {
- if (jj_scan_token(DASHMATCH)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_284() {
- if (jj_scan_token(INCLUDES)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_270() {
- if (jj_scan_token(INTERPOLATION)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_283() {
- if (jj_scan_token(EQ)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_200() {
- if (jj_3R_187()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_277() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_283()) {
- jj_scanpos = xsp;
- if (jj_3R_284()) {
- jj_scanpos = xsp;
- if (jj_3R_285()) {
- jj_scanpos = xsp;
- if (jj_3R_286()) {
- jj_scanpos = xsp;
- if (jj_3R_287()) {
- jj_scanpos = xsp;
- if (jj_3R_288()) {
- return true;
- }
+ case '\u005cr':
+ if (index + 1 < len) {
+ if (s.charAt(index + 1) == '\u005cn') {
+ index ++;
}
}
+ break;
+ default:
+ buf.append(c);
}
+ } else {
+ throw new CSSParseException("invalid string " + s, getLocator());
}
+ } else {
+ buf.append(c);
}
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- xsp = jj_scanpos;
- if (jj_3R_289()) {
- jj_scanpos = xsp;
- if (jj_3R_290()) {
- return true;
- }
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3_6() {
- if (jj_3R_182()) {
- return true;
- }
- if (jj_scan_token(LBRACE)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_264() {
- if (jj_scan_token(LBRACKET)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- if (jj_scan_token(IDENT)) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- xsp = jj_scanpos;
- if (jj_3R_277()) {
- jj_scanpos = xsp;
- }
- if (jj_scan_token(RBRACKET)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_183() {
- if (jj_3R_199()) {
- 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;
- }
- }
- xsp = jj_scanpos;
- if (jj_3R_200()) {
- jj_scanpos = xsp;
- if (jj_3R_201()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3R_282() {
- if (jj_scan_token(INTERPOLATION)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_268() {
- if (jj_3R_187()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_248() {
- if (jj_scan_token(PARENT)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_247() {
- if (jj_scan_token(ANY)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_261() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_269()) {
- jj_scanpos = xsp;
- if (jj_3R_270()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3R_269() {
- if (jj_scan_token(IDENT)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_213() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_246()) {
- jj_scanpos = xsp;
- if (jj_3R_247()) {
- jj_scanpos = xsp;
- if (jj_3R_248()) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean jj_3R_246() {
- Token xsp;
- if (jj_3R_261()) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_261()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_254() {
- 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_268()) {
- jj_scanpos = xsp;
- }
- if (jj_scan_token(RPARAN)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_180() {
- if (jj_scan_token(COMMA)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_241() {
- if (jj_3R_258()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_276() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_281()) {
- jj_scanpos = xsp;
- if (jj_3R_282()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3R_281() {
- if (jj_scan_token(IDENT)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_240() {
- if (jj_3R_257()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_239() {
- if (jj_3R_256()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3_5() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_180()) {
- jj_scanpos = xsp;
- }
- if (jj_3R_181()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_263() {
- if (jj_scan_token(DOT)) {
- return true;
- }
- Token xsp;
- if (jj_3R_276()) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_276()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_252() {
- if (jj_3R_265()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_275() {
- if (jj_3R_265()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_273() {
- if (jj_3R_263()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_250() {
- if (jj_3R_263()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_251() {
- if (jj_3R_264()) {
- return true;
- }
- return false;
+ index++;
}
- private boolean jj_3R_274() {
- if (jj_3R_264()) {
- return true;
- }
- return false;
- }
+ return buf.toString();
+ }
- private boolean jj_3R_255() {
- if (jj_scan_token(DOT)) {
- return true;
- }
- return false;
- }
+ String convertIdent(String s) throws ParseException {
+ return convertStringIndex(s, 0, s.length());
+ }
- private boolean jj_3R_271() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_272()) {
- jj_scanpos = xsp;
- if (jj_3R_273()) {
- jj_scanpos = xsp;
- if (jj_3R_274()) {
- jj_scanpos = xsp;
- if (jj_3R_275()) {
- return true;
- }
- }
- }
- }
- return false;
- }
+ String convertString(String s) throws ParseException {
+ return convertStringIndex(s, 0, s.length());
+ }
- private boolean jj_3R_272() {
- if (jj_3R_262()) {
- return true;
+ void comments() throws ParseException {
+ /*keeps only the multiple line comments, single line comments are skipped*/
+ if (token.specialToken != null && token.specialToken.image!=null && token.specialToken.image.startsWith("/*")){
+ Token tmp_t = token.specialToken;
+ while (tmp_t.specialToken != null) tmp_t = tmp_t.specialToken;
+ while (tmp_t != null) {
+ documentHandler.comment(tmp_t.image);
+ tmp_t = tmp_t.next;
}
- return false;
}
+ }
- private boolean jj_3R_238() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_255()) {
- 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;
- }
+ void rejectToken(Token t) throws ParseException {
+ Token fakeToken = new Token();
+ t.next = token;
+ fakeToken.next = t;
+ token = fakeToken;
+ }
- private boolean jj_3R_237() {
- if (jj_scan_token(STRING)) {
- return true;
- }
- return false;
- }
+ String skipAfterExpression() throws ParseException {
+ Token t = getToken(1);
+ StringBuffer s = new StringBuffer();
+ s.append(getToken(0).image);
- private boolean jj_3R_214() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_249()) {
- jj_scanpos = xsp;
- if (jj_3R_250()) {
- jj_scanpos = xsp;
- if (jj_3R_251()) {
- jj_scanpos = xsp;
- if (jj_3R_252()) {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- private boolean jj_3R_249() {
- if (jj_3R_262()) {
- return true;
- }
- return false;
+ while ((t.kind != RBRACE) && (t.kind != SEMICOLON) && (t.kind != EOF)) {
+ s.append(t.image);
+ getNextToken();
+ t = getToken(1);
}
- private boolean jj_3R_236() {
- if (jj_3R_254()) {
- return true;
- }
- return false;
- }
+ return s.toString();
+ }
- private boolean jj_3R_196() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_237()) {
- jj_scanpos = xsp;
- if (jj_3R_238()) {
- jj_scanpos = xsp;
- if (jj_3R_239()) {
- jj_scanpos = xsp;
- if (jj_3R_240()) {
- jj_scanpos = xsp;
- if (jj_3R_241()) {
- return true;
- }
+/**
+ * The following functions are useful for a DOM CSS implementation only and are
+ * not part of the general CSS2 parser.
+ */
+// TODO required by original parser but not used by Vaadin?
+ final public void _parseRule() throws ParseException {
+ String ret = null;
+ label_169:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[253] = jj_gen;
+ break label_169;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case IMPORT_SYM:
+ importDeclaration();
+ break;
+ 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 MEDIA_SYM:
+ media();
+ break;
+ case PAGE_SYM:
+ page();
+ break;
+ case FONT_FACE_SYM:
+ fontFace();
+ break;
+ default:
+ jj_la1[254] = jj_gen;
+ ret = skipStatement();
+ if ((ret == null) || (ret.length() == 0)) {
+ {if (true) return;}
}
- }
- }
- }
- return false;
- }
-
- private boolean jj_3R_193() {
- Token xsp;
- if (jj_3R_214()) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_214()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_192() {
- if (jj_3R_213()) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_271()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_178() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_192()) {
- jj_scanpos = xsp;
- if (jj_3R_193()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3R_243() {
- if (jj_3R_211()) {
- return true;
- }
- if (jj_3R_178()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_235() {
- if (jj_scan_token(DIMEN)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_234() {
- if (jj_scan_token(KHZ)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_233() {
- if (jj_scan_token(HZ)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_232() {
- if (jj_scan_token(MS)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_231() {
- if (jj_scan_token(SECOND)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_230() {
- if (jj_scan_token(GRAD)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_229() {
- if (jj_scan_token(RAD)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_228() {
- if (jj_scan_token(DEG)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_227() {
- if (jj_scan_token(EXS)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_226() {
- if (jj_scan_token(REM)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3_2() {
- if (jj_3R_177()) {
- return true;
- }
- if (jj_3R_178()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_225() {
- if (jj_scan_token(LEM)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_224() {
- if (jj_scan_token(EMS)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_198() {
- 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_197()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_242() {
- if (jj_3R_178()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_223() {
- if (jj_scan_token(PX)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_222() {
- if (jj_scan_token(IN)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_197() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_242()) {
- jj_scanpos = xsp;
- if (jj_3R_243()) {
- 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_3R_221() {
- if (jj_scan_token(PC)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_220() {
- if (jj_scan_token(MM)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_219() {
- if (jj_scan_token(CM)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_218() {
- if (jj_scan_token(PT)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_217() {
- if (jj_scan_token(PERCENTAGE)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_203() {
- if (jj_3R_245()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3_1() {
- if (jj_3R_176()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_182() {
- if (jj_3R_197()) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_198()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_216() {
- if (jj_scan_token(NUMBER)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_215() {
- if (jj_3R_253()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_195() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_215()) {
- jj_scanpos = xsp;
- }
- xsp = jj_scanpos;
- if (jj_3R_216()) {
- jj_scanpos = xsp;
- if (jj_3R_217()) {
- jj_scanpos = xsp;
- if (jj_3R_218()) {
- jj_scanpos = xsp;
- if (jj_3R_219()) {
- jj_scanpos = xsp;
- if (jj_3R_220()) {
- jj_scanpos = xsp;
- if (jj_3R_221()) {
- jj_scanpos = xsp;
- if (jj_3R_222()) {
- jj_scanpos = xsp;
- if (jj_3R_223()) {
- jj_scanpos = xsp;
- if (jj_3R_224()) {
- jj_scanpos = xsp;
- if (jj_3R_225()) {
- jj_scanpos = xsp;
- if (jj_3R_226()) {
- jj_scanpos = xsp;
- if (jj_3R_227()) {
- jj_scanpos = xsp;
- if (jj_3R_228()) {
- jj_scanpos = xsp;
- if (jj_3R_229()) {
- jj_scanpos = xsp;
- if (jj_3R_230()) {
- jj_scanpos = xsp;
- if (jj_3R_231()) {
- jj_scanpos = xsp;
- if (jj_3R_232()) {
- jj_scanpos = xsp;
- if (jj_3R_233()) {
- jj_scanpos = xsp;
- if (jj_3R_234()) {
- jj_scanpos = xsp;
- if (jj_3R_235()) {
- jj_scanpos = xsp;
- if (jj_3R_236()) {
- return true;
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
+ if (ret.charAt(0) == '@') {
+ documentHandler.unrecognizedRule(ret);
+ } else {
+ {if (true) throw new CSSParseException("unrecognize rule: " + ret,
+ getLocator());}
}
- }
- }
- }
- return false;
- }
-
- private boolean jj_3R_181() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_195()) {
- jj_scanpos = xsp;
- if (jj_3R_196()) {
- return true;
- }
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- private boolean jj_3R_256() {
- if (jj_scan_token(HASH)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3_4() {
- if (jj_3R_179()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_245() {
- if (jj_3R_186()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_257() {
- if (jj_scan_token(URL)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_202() {
- if (jj_3R_181()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_260() {
- if (jj_scan_token(INTERPOLATION)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_184() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_202()) {
- jj_scanpos = xsp;
- if (jj_3R_203()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3_9() {
- if (jj_3R_185()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3_3() {
- if (jj_3R_176()) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_267() {
- if (jj_scan_token(PLUS)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_253() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_266()) {
- jj_scanpos = xsp;
- if (jj_3R_267()) {
- return true;
- }
- }
- return false;
- }
-
- private boolean jj_3R_266() {
- if (jj_scan_token(MINUS)) {
- return true;
- }
- return false;
- }
-
- private boolean jj_3R_258() {
- if (jj_scan_token(UNICODERANGE)) {
- return true;
- }
- return false;
}
+ }
+
+ final public void _parseImportRule() throws ParseException {
+ label_170:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[255] = jj_gen;
+ break label_170;
+ }
+ jj_consume_token(S);
+ }
+ importDeclaration();
+ }
+
+ final public void _parseMediaRule() throws ParseException {
+ label_171:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[256] = jj_gen;
+ break label_171;
+ }
+ jj_consume_token(S);
+ }
+ media();
+ }
+
+ final public void _parseDeclarationBlock() throws ParseException {
+ label_172:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[257] = jj_gen;
+ break label_172;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[258] = jj_gen;
+ ;
+ }
+ label_173:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case SEMICOLON:
+ ;
+ break;
+ default:
+ jj_la1[259] = jj_gen;
+ break label_173;
+ }
+ jj_consume_token(SEMICOLON);
+ label_174:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[260] = jj_gen;
+ break label_174;
+ }
+ jj_consume_token(S);
+ }
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case INTERPOLATION:
+ case IDENT:
+ declaration();
+ break;
+ default:
+ jj_la1[261] = jj_gen;
+ ;
+ }
+ }
+ }
+
+ final public ArrayList<String> _parseSelectors() throws ParseException {
+ ArrayList<String> p = null;
+ try {
+ label_175:
+ while (true) {
+ switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+ case S:
+ ;
+ break;
+ default:
+ jj_la1[262] = jj_gen;
+ break label_175;
+ }
+ jj_consume_token(S);
+ }
+ p = selectorList();
+ {if (true) return p;}
+ } catch (ThrowedParseException e) {
+ {if (true) throw (ParseException) e.e.fillInStackTrace();}
+ }
+ 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(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(0, xla); }
+ }
+
+ private boolean jj_2_2(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_2(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(1, xla); }
+ }
+
+ private boolean jj_2_3(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_3(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(2, xla); }
+ }
+
+ private boolean jj_2_4(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_4(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(3, xla); }
+ }
+
+ private boolean jj_2_5(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_5(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(4, xla); }
+ }
+
+ private boolean jj_2_6(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_6(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(5, xla); }
+ }
+
+ private boolean jj_2_7(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_7(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(6, xla); }
+ }
+
+ private boolean jj_2_8(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_8(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(7, xla); }
+ }
+
+ private boolean jj_2_9(int xla) {
+ jj_la = xla; jj_lastpos = jj_scanpos = token;
+ try { return !jj_3_9(); }
+ catch(LookaheadSuccess ls) { return true; }
+ finally { jj_save(8, xla); }
+ }
+
+ private boolean jj_3R_194() {
+ 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_179() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_194()) jj_scanpos = xsp;
+ if (jj_scan_token(CONTAINS)) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ if (true) { jj_la = 0; jj_scanpos = jj_lastpos; return false;}
+ return false;
+ }
+
+ private boolean jj_3R_212() {
+ if (jj_3R_211()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_211() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_scan_token(18)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(22)) {
+ jj_scanpos = xsp;
+ if (jj_scan_token(23)) return true;
+ }
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_191() {
+ if (jj_scan_token(S)) return true;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_212()) jj_scanpos = xsp;
+ return false;
+ }
+
+ private boolean jj_3R_176() {
+ if (jj_3R_186()) 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_187()) return true;
+ xsp = jj_scanpos;
+ if (jj_3R_188()) jj_scanpos = xsp;
+ if (jj_3R_189()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_189()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_190() {
+ if (jj_3R_211()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_177() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_190()) {
+ jj_scanpos = xsp;
+ if (jj_3R_191()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_262() {
+ if (jj_scan_token(HASH)) return true;
+ return false;
+ }
+
+ private boolean jj_3_7() {
+ if (jj_3R_183()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_279() {
+ if (jj_scan_token(IDENT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_280() {
+ if (jj_scan_token(FUNCTION)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ if (true) { jj_la = 0; jj_scanpos = jj_lastpos; return false;}
+ return false;
+ }
+
+ private boolean jj_3R_201() {
+ if (jj_scan_token(LBRACE)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_278() {
+ if (jj_scan_token(COLON)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_200() {
+ if (jj_3R_187()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_265() {
+ if (jj_scan_token(COLON)) return true;
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_278()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_279()) {
+ jj_scanpos = xsp;
+ if (jj_3R_280()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3_6() {
+ if (jj_3R_182()) return true;
+ if (jj_scan_token(LBRACE)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_183() {
+ if (jj_3R_199()) 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; }
+ }
+ xsp = jj_scanpos;
+ if (jj_3R_200()) {
+ jj_scanpos = xsp;
+ if (jj_3R_201()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_268() {
+ if (jj_3R_187()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_254() {
+ 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_268()) jj_scanpos = xsp;
+ if (jj_scan_token(RPARAN)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_241() {
+ if (jj_3R_258()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_240() {
+ if (jj_3R_257()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_239() {
+ if (jj_3R_256()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_290() {
+ if (jj_scan_token(STRING)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_288() {
+ if (jj_scan_token(STARMATCH)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_287() {
+ if (jj_scan_token(DOLLARMATCH)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_289() {
+ if (jj_scan_token(IDENT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_286() {
+ if (jj_scan_token(CARETMATCH)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_285() {
+ if (jj_scan_token(DASHMATCH)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_284() {
+ if (jj_scan_token(INCLUDES)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_270() {
+ if (jj_scan_token(INTERPOLATION)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_283() {
+ if (jj_scan_token(EQ)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_277() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_283()) {
+ jj_scanpos = xsp;
+ if (jj_3R_284()) {
+ jj_scanpos = xsp;
+ if (jj_3R_285()) {
+ jj_scanpos = xsp;
+ if (jj_3R_286()) {
+ jj_scanpos = xsp;
+ if (jj_3R_287()) {
+ jj_scanpos = xsp;
+ if (jj_3R_288()) return true;
+ }
+ }
+ }
+ }
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ xsp = jj_scanpos;
+ if (jj_3R_289()) {
+ jj_scanpos = xsp;
+ if (jj_3R_290()) 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(LBRACKET)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ if (jj_scan_token(IDENT)) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ xsp = jj_scanpos;
+ if (jj_3R_277()) jj_scanpos = xsp;
+ if (jj_scan_token(RBRACKET)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_180() {
+ if (jj_scan_token(COMMA)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_282() {
+ if (jj_scan_token(INTERPOLATION)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_248() {
+ if (jj_scan_token(PARENT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_247() {
+ if (jj_scan_token(ANY)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_255() {
+ if (jj_scan_token(DOT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_238() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_255()) 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_180()) jj_scanpos = xsp;
+ if (jj_3R_181()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_261() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_269()) {
+ jj_scanpos = xsp;
+ if (jj_3R_270()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_269() {
+ if (jj_scan_token(IDENT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_237() {
+ if (jj_scan_token(STRING)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_213() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_246()) {
+ jj_scanpos = xsp;
+ if (jj_3R_247()) {
+ jj_scanpos = xsp;
+ if (jj_3R_248()) return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_246() {
+ Token xsp;
+ if (jj_3R_261()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_261()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_236() {
+ if (jj_3R_254()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_196() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_237()) {
+ jj_scanpos = xsp;
+ if (jj_3R_238()) {
+ jj_scanpos = xsp;
+ if (jj_3R_239()) {
+ jj_scanpos = xsp;
+ if (jj_3R_240()) {
+ jj_scanpos = xsp;
+ if (jj_3R_241()) return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_235() {
+ if (jj_scan_token(DIMEN)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_276() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_281()) {
+ jj_scanpos = xsp;
+ if (jj_3R_282()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_281() {
+ if (jj_scan_token(IDENT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_234() {
+ if (jj_scan_token(KHZ)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_233() {
+ if (jj_scan_token(HZ)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_263() {
+ if (jj_scan_token(DOT)) return true;
+ Token xsp;
+ if (jj_3R_276()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_276()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_232() {
+ if (jj_scan_token(MS)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_231() {
+ if (jj_scan_token(SECOND)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_230() {
+ if (jj_scan_token(GRAD)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_252() {
+ if (jj_3R_265()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_275() {
+ if (jj_3R_265()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_229() {
+ if (jj_scan_token(RAD)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_228() {
+ if (jj_scan_token(DEG)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_273() {
+ if (jj_3R_263()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_227() {
+ if (jj_scan_token(EXS)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_250() {
+ if (jj_3R_263()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_226() {
+ if (jj_scan_token(REM)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_225() {
+ if (jj_scan_token(LEM)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_224() {
+ if (jj_scan_token(EMS)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_223() {
+ if (jj_scan_token(PX)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_251() {
+ if (jj_3R_264()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_274() {
+ if (jj_3R_264()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_222() {
+ if (jj_scan_token(IN)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_271() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_272()) {
+ jj_scanpos = xsp;
+ if (jj_3R_273()) {
+ jj_scanpos = xsp;
+ if (jj_3R_274()) {
+ jj_scanpos = xsp;
+ if (jj_3R_275()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_272() {
+ if (jj_3R_262()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_221() {
+ if (jj_scan_token(PC)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_214() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_249()) {
+ jj_scanpos = xsp;
+ if (jj_3R_250()) {
+ jj_scanpos = xsp;
+ if (jj_3R_251()) {
+ jj_scanpos = xsp;
+ if (jj_3R_252()) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_249() {
+ if (jj_3R_262()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_220() {
+ if (jj_scan_token(MM)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_193() {
+ Token xsp;
+ if (jj_3R_214()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_214()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_219() {
+ if (jj_scan_token(CM)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_192() {
+ if (jj_3R_213()) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_271()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_218() {
+ if (jj_scan_token(PT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_178() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_192()) {
+ jj_scanpos = xsp;
+ if (jj_3R_193()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_217() {
+ if (jj_scan_token(PERCENTAGE)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_243() {
+ if (jj_3R_211()) return true;
+ if (jj_3R_178()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_203() {
+ if (jj_3R_245()) return true;
+ return false;
+ }
- private boolean jj_3_8() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3_9()) {
- jj_scanpos = xsp;
- }
- if (jj_3R_184()) {
- return true;
- }
- return false;
+ private boolean jj_3R_216() {
+ if (jj_scan_token(NUMBER)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_215() {
+ if (jj_3R_253()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_195() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_215()) jj_scanpos = xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_216()) {
+ jj_scanpos = xsp;
+ if (jj_3R_217()) {
+ jj_scanpos = xsp;
+ if (jj_3R_218()) {
+ jj_scanpos = xsp;
+ if (jj_3R_219()) {
+ jj_scanpos = xsp;
+ if (jj_3R_220()) {
+ jj_scanpos = xsp;
+ if (jj_3R_221()) {
+ jj_scanpos = xsp;
+ if (jj_3R_222()) {
+ jj_scanpos = xsp;
+ if (jj_3R_223()) {
+ jj_scanpos = xsp;
+ if (jj_3R_224()) {
+ jj_scanpos = xsp;
+ if (jj_3R_225()) {
+ jj_scanpos = xsp;
+ if (jj_3R_226()) {
+ jj_scanpos = xsp;
+ if (jj_3R_227()) {
+ jj_scanpos = xsp;
+ if (jj_3R_228()) {
+ jj_scanpos = xsp;
+ if (jj_3R_229()) {
+ jj_scanpos = xsp;
+ if (jj_3R_230()) {
+ jj_scanpos = xsp;
+ if (jj_3R_231()) {
+ jj_scanpos = xsp;
+ if (jj_3R_232()) {
+ jj_scanpos = xsp;
+ if (jj_3R_233()) {
+ jj_scanpos = xsp;
+ if (jj_3R_234()) {
+ jj_scanpos = xsp;
+ if (jj_3R_235()) {
+ jj_scanpos = xsp;
+ if (jj_3R_236()) 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()) return true;
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_256() {
+ if (jj_scan_token(HASH)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_245() {
+ if (jj_3R_186()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_257() {
+ if (jj_scan_token(URL)) return true;
+ return false;
+ }
+
+ private boolean jj_3_2() {
+ if (jj_3R_177()) return true;
+ if (jj_3R_178()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_202() {
+ if (jj_3R_181()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_184() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_202()) {
+ jj_scanpos = xsp;
+ if (jj_3R_203()) return true;
}
+ return false;
+ }
- private boolean jj_3R_186() {
- if (jj_scan_token(VARIABLE)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
+ private boolean jj_3_9() {
+ if (jj_3R_185()) return true;
+ return false;
+ }
- private boolean jj_3R_189() {
- if (jj_scan_token(SEMICOLON)) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
+ private boolean jj_3R_198() {
+ 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_197()) return true;
+ return false;
+ }
- private boolean jj_3R_187() {
- if (jj_3R_184()) {
- return true;
- }
- Token xsp;
- while (true) {
- xsp = jj_scanpos;
- if (jj_3_8()) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
+ private boolean jj_3R_242() {
+ if (jj_3R_178()) return true;
+ return false;
+ }
- private boolean jj_3R_244() {
- Token xsp;
- xsp = jj_scanpos;
- if (jj_3R_259()) {
- jj_scanpos = xsp;
- if (jj_3R_260()) {
- return true;
- }
- }
- return false;
+ private boolean jj_3R_197() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_242()) {
+ jj_scanpos = xsp;
+ if (jj_3R_243()) return true;
}
-
- private boolean jj_3R_259() {
- if (jj_scan_token(IDENT)) {
- return true;
- }
- return false;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_2()) { jj_scanpos = xsp; break; }
}
-
- private boolean jj_3R_199() {
- Token xsp;
- if (jj_3R_244()) {
- return true;
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_3R_244()) {
- jj_scanpos = xsp;
- break;
- }
- }
- while (true) {
- xsp = jj_scanpos;
- if (jj_scan_token(1)) {
- jj_scanpos = xsp;
- break;
- }
- }
- return false;
- }
-
- /** Generated Token Manager. */
- public ParserTokenManager token_source;
- /** Current token. */
- public Token token;
- /** Next token. */
- public Token jj_nt;
- private int jj_ntk;
- private Token jj_scanpos, jj_lastpos;
- private int jj_la;
- private int jj_gen;
- final private int[] jj_la1 = new int[261];
- static private int[] jj_la1_0;
- static private int[] jj_la1_1;
- static private int[] jj_la1_2;
- static private int[] jj_la1_3;
- static {
- jj_la1_init_0();
- jj_la1_init_1();
- jj_la1_init_2();
- 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, 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, 0x2, 0x2, 0x100000, 0x0, 0x0, 0x800c0000,
- 0x2, 0x0, 0x100000, 0x2, 0x800c0000, 0x2, 0x0, 0x2, 0x2, 0x0,
- 0x2, 0x200000, 0x2, 0xd4c40000, 0xd4c40000, 0x2, 0x200400, 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, };
- }
-
- 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, 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, 0x40,
- 0x40, 0x160040, 0x0, 0x40, 0x0, 0x0, 0x160040, 0x0, 0x40, 0x0,
- 0x0, 0x80, 0x0, 0x0, 0x0, 0x61200c0, 0x61200c0, 0x0, 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, };
- }
-
- 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,
- 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, 0x0, 0x0, 0x0, 0x1000,
- 0x1000, 0xfffffb80, 0x0, 0x0, 0x0, 0x0, 0xfffffb80, 0x0, 0x0,
- 0x0, 0x0, 0x1100, 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, 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, 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, 0x440001, 0x0, 0x0, 0x0, 0x0, 0x440001, 0x0,
- 0x0, 0x0, 0x0, 0x400000, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 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;
- private int jj_gc = 0;
-
- /** Constructor with user supplied CharStream. */
- public Parser(CharStream stream) {
- token_source = new ParserTokenManager(stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 261; i++) {
- jj_la1[i] = -1;
- }
- for (int i = 0; i < jj_2_rtns.length; i++) {
- jj_2_rtns[i] = new JJCalls();
- }
- }
-
- /** Reinitialise. */
- public void ReInit(CharStream stream) {
- token_source.ReInit(stream);
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 261; i++) {
- jj_la1[i] = -1;
- }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_267() {
+ if (jj_scan_token(PLUS)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_253() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_266()) {
+ jj_scanpos = xsp;
+ if (jj_3R_267()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_266() {
+ if (jj_scan_token(MINUS)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_258() {
+ if (jj_scan_token(UNICODERANGE)) return true;
+ return false;
+ }
+
+ private boolean jj_3_8() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3_9()) jj_scanpos = xsp;
+ if (jj_3R_184()) return true;
+ return false;
+ }
+
+ private boolean jj_3_4() {
+ if (jj_3R_179()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_187() {
+ if (jj_3R_184()) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3_8()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_182() {
+ if (jj_3R_197()) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_198()) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3_1() {
+ if (jj_3R_176()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_209() {
+ if (jj_scan_token(MINUS)) return true;
+ Token xsp;
+ if (jj_scan_token(1)) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_208() {
+ if (jj_scan_token(PLUS)) return true;
+ Token xsp;
+ if (jj_scan_token(1)) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3_3() {
+ if (jj_3R_176()) return true;
+ return false;
+ }
+
+ private boolean jj_3R_207() {
+ if (jj_scan_token(MOD)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_206() {
+ if (jj_scan_token(ANY)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_260() {
+ if (jj_scan_token(INTERPOLATION)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_205() {
+ if (jj_scan_token(DIV)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ 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; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_185() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_204()) {
+ jj_scanpos = xsp;
+ if (jj_3R_205()) {
+ jj_scanpos = xsp;
+ if (jj_3R_206()) {
+ jj_scanpos = xsp;
+ if (jj_3R_207()) {
+ jj_scanpos = xsp;
+ if (jj_3R_208()) {
+ jj_scanpos = xsp;
+ if (jj_3R_209()) return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_210() {
+ if (jj_scan_token(GUARDED_SYM)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_186() {
+ if (jj_scan_token(VARIABLE)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_189() {
+ if (jj_scan_token(SEMICOLON)) return true;
+ Token xsp;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_244() {
+ Token xsp;
+ xsp = jj_scanpos;
+ if (jj_3R_259()) {
+ jj_scanpos = xsp;
+ if (jj_3R_260()) return true;
+ }
+ return false;
+ }
+
+ private boolean jj_3R_259() {
+ if (jj_scan_token(IDENT)) return true;
+ return false;
+ }
+
+ private boolean jj_3R_199() {
+ Token xsp;
+ if (jj_3R_244()) return true;
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_3R_244()) { jj_scanpos = xsp; break; }
+ }
+ while (true) {
+ xsp = jj_scanpos;
+ if (jj_scan_token(1)) { jj_scanpos = xsp; break; }
+ }
+ return false;
+ }
+
+ private boolean jj_3R_188() {
+ if (jj_3R_210()) return true;
+ return false;
+ }
+
+ /** Generated Token Manager. */
+ public ParserTokenManager token_source;
+ /** Current token. */
+ public Token token;
+ /** Next token. */
+ public Token jj_nt;
+ private int jj_ntk;
+ private Token jj_scanpos, jj_lastpos;
+ private int jj_la;
+ private int jj_gen;
+ final private int[] jj_la1 = new int[263];
+ static private int[] jj_la1_0;
+ static private int[] jj_la1_1;
+ static private int[] jj_la1_2;
+ static private int[] jj_la1_3;
+ static {
+ jj_la1_init_0();
+ jj_la1_init_1();
+ jj_la1_init_2();
+ 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,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,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,};
+ }
+ 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,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,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,};
+ }
+ 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,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,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,};
+ }
+ 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,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,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,};
+ }
+ final private JJCalls[] jj_2_rtns = new JJCalls[9];
+ private boolean jj_rescan = false;
+ private int jj_gc = 0;
+
+ /** Constructor with user supplied CharStream. */
+ public Parser(CharStream stream) {
+ token_source = new ParserTokenManager(stream);
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 263; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+ }
+
+ /** Reinitialise. */
+ public void ReInit(CharStream stream) {
+ token_source.ReInit(stream);
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 263; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+ }
+
+ /** Constructor with generated Token Manager. */
+ public Parser(ParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 263; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+ }
+
+ /** Reinitialise. */
+ public void ReInit(ParserTokenManager tm) {
+ token_source = tm;
+ token = new Token();
+ jj_ntk = -1;
+ jj_gen = 0;
+ for (int i = 0; i < 263; i++) jj_la1[i] = -1;
+ for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+ }
+
+ private Token jj_consume_token(int kind) throws ParseException {
+ Token oldToken;
+ if ((oldToken = token).next != null) token = token.next;
+ else token = token.next = token_source.getNextToken();
+ jj_ntk = -1;
+ if (token.kind == kind) {
+ jj_gen++;
+ if (++jj_gc > 100) {
+ jj_gc = 0;
for (int i = 0; i < jj_2_rtns.length; i++) {
- jj_2_rtns[i] = new JJCalls();
- }
- }
-
- /** Constructor with generated Token Manager. */
- public Parser(ParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 261; i++) {
- jj_la1[i] = -1;
- }
- for (int i = 0; i < jj_2_rtns.length; i++) {
- jj_2_rtns[i] = new JJCalls();
- }
- }
-
- /** Reinitialise. */
- public void ReInit(ParserTokenManager tm) {
- token_source = tm;
- token = new Token();
- jj_ntk = -1;
- jj_gen = 0;
- for (int i = 0; i < 261; i++) {
- jj_la1[i] = -1;
- }
- for (int i = 0; i < jj_2_rtns.length; i++) {
- jj_2_rtns[i] = new JJCalls();
- }
- }
-
- private Token jj_consume_token(int kind) throws ParseException {
- Token oldToken;
- if ((oldToken = token).next != null) {
- token = token.next;
- } else {
- token = token.next = token_source.getNextToken();
- }
- jj_ntk = -1;
- if (token.kind == kind) {
- jj_gen++;
- if (++jj_gc > 100) {
- jj_gc = 0;
- for (int i = 0; i < jj_2_rtns.length; i++) {
- JJCalls c = jj_2_rtns[i];
- while (c != null) {
- if (c.gen < jj_gen) {
- c.first = null;
- }
- c = c.next;
- }
- }
- }
- return token;
- }
- token = oldToken;
- jj_kind = kind;
- throw generateParseException();
- }
-
- static private final class LookaheadSuccess extends java.lang.Error {
- }
-
- final private LookaheadSuccess jj_ls = new LookaheadSuccess();
-
- private boolean jj_scan_token(int kind) {
- if (jj_scanpos == jj_lastpos) {
- jj_la--;
- if (jj_scanpos.next == null) {
- jj_lastpos = jj_scanpos = jj_scanpos.next = token_source
- .getNextToken();
- } else {
- jj_lastpos = jj_scanpos = jj_scanpos.next;
- }
- } else {
- jj_scanpos = jj_scanpos.next;
- }
- if (jj_rescan) {
- int i = 0;
- Token tok = token;
- while (tok != null && tok != jj_scanpos) {
- i++;
- tok = tok.next;
- }
- if (tok != null) {
- jj_add_error_token(kind, i);
- }
- }
- if (jj_scanpos.kind != kind) {
- return true;
- }
- if (jj_la == 0 && jj_scanpos == jj_lastpos) {
- throw jj_ls;
- }
- return false;
- }
-
- /** Get the next Token. */
- final public Token getNextToken() {
- if (token.next != null) {
- token = token.next;
- } else {
- token = token.next = token_source.getNextToken();
- }
- jj_ntk = -1;
- jj_gen++;
- return token;
- }
-
- /** Get the specific Token. */
- final public Token getToken(int index) {
- Token t = token;
- for (int i = 0; i < index; i++) {
- if (t.next != null) {
- t = t.next;
- } else {
- t = t.next = token_source.getNextToken();
- }
- }
- return t;
- }
-
- private int jj_ntk() {
- if ((jj_nt = token.next) == null) {
- return (jj_ntk = (token.next = token_source.getNextToken()).kind);
- } else {
- return (jj_ntk = jj_nt.kind);
- }
- }
-
- private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
- private int[] jj_expentry;
- private int jj_kind = -1;
- private int[] jj_lasttokens = new int[100];
- private int jj_endpos;
-
- private void jj_add_error_token(int kind, int pos) {
- if (pos >= 100) {
- return;
- }
- if (pos == jj_endpos + 1) {
- jj_lasttokens[jj_endpos++] = kind;
- } else if (jj_endpos != 0) {
- jj_expentry = new int[jj_endpos];
- for (int i = 0; i < jj_endpos; i++) {
- jj_expentry[i] = jj_lasttokens[i];
- }
- jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries
- .iterator(); it.hasNext();) {
- int[] oldentry = (int[]) (it.next());
- if (oldentry.length == jj_expentry.length) {
- for (int i = 0; i < jj_expentry.length; i++) {
- if (oldentry[i] != jj_expentry[i]) {
- continue jj_entries_loop;
- }
- }
- jj_expentries.add(jj_expentry);
- break jj_entries_loop;
- }
- }
- if (pos != 0) {
- jj_lasttokens[(jj_endpos = pos) - 1] = kind;
- }
- }
- }
-
- /** Generate ParseException. */
- public ParseException generateParseException() {
- jj_expentries.clear();
- boolean[] la1tokens = new boolean[120];
- if (jj_kind >= 0) {
- la1tokens[jj_kind] = true;
- jj_kind = -1;
- }
- for (int i = 0; i < 261; i++) {
- if (jj_la1[i] == jj_gen) {
- for (int j = 0; j < 32; j++) {
- if ((jj_la1_0[i] & (1 << j)) != 0) {
- la1tokens[j] = true;
- }
- if ((jj_la1_1[i] & (1 << j)) != 0) {
- la1tokens[32 + j] = true;
- }
- if ((jj_la1_2[i] & (1 << j)) != 0) {
- la1tokens[64 + j] = true;
- }
- if ((jj_la1_3[i] & (1 << j)) != 0) {
- la1tokens[96 + j] = true;
- }
- }
- }
- }
- for (int i = 0; i < 120; i++) {
- if (la1tokens[i]) {
- jj_expentry = new int[1];
- jj_expentry[0] = i;
- jj_expentries.add(jj_expentry);
- }
- }
- jj_endpos = 0;
- jj_rescan_token();
- jj_add_error_token(0, 0);
- int[][] exptokseq = new int[jj_expentries.size()][];
- for (int i = 0; i < jj_expentries.size(); i++) {
- exptokseq[i] = jj_expentries.get(i);
- }
- return new ParseException(token, exptokseq, tokenImage);
- }
-
- /** Enable tracing. */
- final public void enable_tracing() {
- }
-
- /** Disable tracing. */
- final public void disable_tracing() {
- }
-
- private void jj_rescan_token() {
- jj_rescan = true;
- for (int i = 0; i < 9; i++) {
- try {
- JJCalls p = jj_2_rtns[i];
- do {
- if (p.gen > jj_gen) {
- jj_la = p.arg;
- jj_lastpos = jj_scanpos = p.first;
- switch (i) {
- case 0:
- jj_3_1();
- break;
- case 1:
- jj_3_2();
- break;
- case 2:
- jj_3_3();
- break;
- case 3:
- jj_3_4();
- break;
- case 4:
- jj_3_5();
- break;
- case 5:
- jj_3_6();
- break;
- case 6:
- jj_3_7();
- break;
- case 7:
- jj_3_8();
- break;
- case 8:
- jj_3_9();
- break;
- }
- }
- p = p.next;
- } while (p != null);
- } catch (LookaheadSuccess ls) {
- }
- }
- jj_rescan = false;
- }
-
- private void jj_save(int index, int xla) {
- JJCalls p = jj_2_rtns[index];
- while (p.gen > jj_gen) {
- if (p.next == null) {
- p = p.next = new JJCalls();
- break;
- }
- p = p.next;
- }
- p.gen = jj_gen + xla - jj_la;
- p.first = token;
- p.arg = xla;
- }
-
- static final class JJCalls {
- int gen;
- Token first;
- int arg;
- JJCalls next;
- }
+ JJCalls c = jj_2_rtns[i];
+ while (c != null) {
+ if (c.gen < jj_gen) c.first = null;
+ c = c.next;
+ }
+ }
+ }
+ return token;
+ }
+ token = oldToken;
+ jj_kind = kind;
+ throw generateParseException();
+ }
+
+ static private final class LookaheadSuccess extends java.lang.Error { }
+ final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+ private boolean jj_scan_token(int kind) {
+ if (jj_scanpos == jj_lastpos) {
+ jj_la--;
+ if (jj_scanpos.next == null) {
+ jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+ } else {
+ jj_lastpos = jj_scanpos = jj_scanpos.next;
+ }
+ } else {
+ jj_scanpos = jj_scanpos.next;
+ }
+ if (jj_rescan) {
+ int i = 0; Token tok = token;
+ while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+ if (tok != null) jj_add_error_token(kind, i);
+ }
+ if (jj_scanpos.kind != kind) return true;
+ if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
+ return false;
+ }
+
+
+/** Get the next Token. */
+ final public Token getNextToken() {
+ if (token.next != null) token = token.next;
+ else token = token.next = token_source.getNextToken();
+ jj_ntk = -1;
+ jj_gen++;
+ return token;
+ }
+
+/** Get the specific Token. */
+ final public Token getToken(int index) {
+ Token t = token;
+ for (int i = 0; i < index; i++) {
+ if (t.next != null) t = t.next;
+ else t = t.next = token_source.getNextToken();
+ }
+ return t;
+ }
+
+ private int jj_ntk() {
+ if ((jj_nt=token.next) == null)
+ return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+ else
+ return (jj_ntk = jj_nt.kind);
+ }
+
+ private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
+ private int[] jj_expentry;
+ private int jj_kind = -1;
+ private int[] jj_lasttokens = new int[100];
+ private int jj_endpos;
+
+ private void jj_add_error_token(int kind, int pos) {
+ if (pos >= 100) return;
+ if (pos == jj_endpos + 1) {
+ jj_lasttokens[jj_endpos++] = kind;
+ } else if (jj_endpos != 0) {
+ jj_expentry = new int[jj_endpos];
+ for (int i = 0; i < jj_endpos; i++) {
+ jj_expentry[i] = jj_lasttokens[i];
+ }
+ jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
+ int[] oldentry = (int[])(it.next());
+ if (oldentry.length == jj_expentry.length) {
+ for (int i = 0; i < jj_expentry.length; i++) {
+ if (oldentry[i] != jj_expentry[i]) {
+ continue jj_entries_loop;
+ }
+ }
+ jj_expentries.add(jj_expentry);
+ break jj_entries_loop;
+ }
+ }
+ if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+ }
+ }
+
+ /** Generate ParseException. */
+ public ParseException generateParseException() {
+ jj_expentries.clear();
+ boolean[] la1tokens = new boolean[120];
+ if (jj_kind >= 0) {
+ la1tokens[jj_kind] = true;
+ jj_kind = -1;
+ }
+ for (int i = 0; i < 263; i++) {
+ if (jj_la1[i] == jj_gen) {
+ for (int j = 0; j < 32; j++) {
+ if ((jj_la1_0[i] & (1<<j)) != 0) {
+ la1tokens[j] = true;
+ }
+ if ((jj_la1_1[i] & (1<<j)) != 0) {
+ la1tokens[32+j] = true;
+ }
+ if ((jj_la1_2[i] & (1<<j)) != 0) {
+ la1tokens[64+j] = true;
+ }
+ if ((jj_la1_3[i] & (1<<j)) != 0) {
+ la1tokens[96+j] = true;
+ }
+ }
+ }
+ }
+ for (int i = 0; i < 120; i++) {
+ if (la1tokens[i]) {
+ jj_expentry = new int[1];
+ jj_expentry[0] = i;
+ jj_expentries.add(jj_expentry);
+ }
+ }
+ jj_endpos = 0;
+ jj_rescan_token();
+ jj_add_error_token(0, 0);
+ int[][] exptokseq = new int[jj_expentries.size()][];
+ for (int i = 0; i < jj_expentries.size(); i++) {
+ exptokseq[i] = jj_expentries.get(i);
+ }
+ return new ParseException(token, exptokseq, tokenImage);
+ }
+
+ /** Enable tracing. */
+ final public void enable_tracing() {
+ }
+
+ /** Disable tracing. */
+ final public void disable_tracing() {
+ }
+
+ private void jj_rescan_token() {
+ jj_rescan = true;
+ for (int i = 0; i < 9; i++) {
+ try {
+ JJCalls p = jj_2_rtns[i];
+ do {
+ if (p.gen > jj_gen) {
+ jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+ switch (i) {
+ case 0: jj_3_1(); break;
+ case 1: jj_3_2(); break;
+ case 2: jj_3_3(); break;
+ case 3: jj_3_4(); break;
+ case 4: jj_3_5(); break;
+ case 5: jj_3_6(); break;
+ case 6: jj_3_7(); break;
+ case 7: jj_3_8(); break;
+ case 8: jj_3_9(); break;
+ }
+ }
+ p = p.next;
+ } while (p != null);
+ } catch(LookaheadSuccess ls) { }
+ }
+ jj_rescan = false;
+ }
+
+ private void jj_save(int index, int xla) {
+ JJCalls p = jj_2_rtns[index];
+ while (p.gen > jj_gen) {
+ if (p.next == null) { p = p.next = new JJCalls(); break; }
+ p = p.next;
+ }
+ p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+ }
+
+ static final class JJCalls {
+ int gen;
+ Token first;
+ int arg;
+ JJCalls next;
+ }
}
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 5fb7f2315f..f8b6a86af7 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
@@ -40,6 +40,8 @@ import java.util.ArrayList;
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;
@@ -912,18 +914,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;
@@ -1485,6 +1493,7 @@ void variable() :
":" ( <S> )* exp=expr() ( guarded=guarded() )?(";"(<S>)*)+
//raw=skipStatementUntilSemiColon()
{
+ exp = replaceNullValues(exp);
documentHandler.variable(name, exp, guarded);
}
}catch (JumpException e) {
@@ -1514,6 +1523,24 @@ void variable() :
}
}
+JAVACODE
+LexicalUnitImpl replaceNullValues(LexicalUnitImpl unit) {
+ if(unit == null){
+ return null;
+ }
+ if (unit.getNextLexicalUnit() != null) {
+ unit.setNextLexicalUnit(replaceNullValues(unit.getNextLexicalUnit()));
+ }
+ if (unit.getLexicalUnitType() == SCSSLexicalUnit.SAC_IDENT
+ && "null".equals(unit.getStringValue())) {
+ LexicalUnitImpl next = unit.getNextLexicalUnit();
+ unit = LexicalUnitImpl.createNull(unit.getLineNumber(), unit.getColumnNumber(),
+ unit.getPreviousLexicalUnit());
+ unit.setNextLexicalUnit(next);
+ }
+ return unit;
+}
+
void controlDirective() :
{}
{
@@ -1655,21 +1682,30 @@ ArrayList<VariableNode> arglist() :
boolean hasNonOptionalArgument = false;
}
{
- arg=mixinArg() ( <COMMA> (<S>)* { hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg); }
- arg=mixinArg() )*
- { hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg);
+ (arg=mixinArg() ( <COMMA> (<S>)* { hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg); }
+ arg=mixinArg() )*
+ { hasNonOptionalArgument = checkMixinForNonOptionalArguments(arg, hasNonOptionalArgument); args.add(arg); }
+ )?
+ {
return args;
}
}
JAVACODE
-boolean checkMixinForNonOptionalArguments(VariableNode arg, boolean hasNonOptionalArguments) {
+boolean checkMixinForNonOptionalArguments(VariableNode arg, boolean hasNonOptionalArguments)
+{
boolean currentArgHasArguments = arg.getExpr() != null && arg.getExpr().getLexicalUnitType() == LexicalUnitImpl.SCSS_VARIABLE && arg.getExpr().getNextLexicalUnit() != null;
- if(currentArgHasArguments) {
- if(hasNonOptionalArguments) { throw new ParseException("Sass Error: Required argument $"+ arg.getName() +" must come before any optional arguments.");
+
+ if(currentArgHasArguments)
+ {
+ if(hasNonOptionalArguments)
+ {
+ throw new ParseException("Sass Error: Required argument $"+ arg.getName() +" must come before any optional arguments.");
}
return hasNonOptionalArguments;
- }else { return true;
+ }else
+ {
+ return true;
}
}
@@ -1684,9 +1720,13 @@ VariableNode mixinArg() :
{
name=variableName() (< COLON > (< S >)*
- ( first = nonVariableTerm(null) {
- prev = first; }
- (LOOKAHEAD(3)(< COMMA >(< S >)*)? prev = nonVariableTerm(prev))* )
+ (
+ first = nonVariableTerm(null)
+ {
+ prev = first;
+ }
+ (LOOKAHEAD(3)(< COMMA >(< S >)*)? prev = nonVariableTerm(prev))*
+ )
| (variable = < VARIABLE >{ first = LexicalUnitImpl.createVariable(token.beginLine, token.beginColumn,
prev, variable.image);}
@@ -1706,10 +1746,11 @@ ArrayList<LexicalUnitImpl> argValuelist() :
LexicalUnitImpl prev = null;
}
{
- first = term(null) { args.add(first); prev = first;}((< COLON > (< S >)*)?next=term(prev){prev.setNextLexicalUnit(next); prev = next;})*
- ( <COMMA> (<S>)*
- first = term(null) { args.add(first); prev = first;}((< COLON > (< S >)*)?next=term(prev){prev.setNextLexicalUnit(next); prev = next;})*
- )*
+ (first = term(null) { args.add(first); prev = first;}((< COLON > (< S >)*)?next=term(prev){prev.setNextLexicalUnit(next); prev = next;})*
+ ( <COMMA> (<S>)*
+ first = term(null) { args.add(first); prev = first;}((< COLON > (< S >)*)?next=term(prev){prev.setNextLexicalUnit(next); prev = next;})*
+ )*
+ )?
{return args;}
}
@@ -1721,17 +1762,33 @@ void includeDirective() :
{
<INCLUDE_SYM>
(<S>)*
- (name = property()|name = variableName(){ name = "$"+name;}
- |(name = functionName()
- args = argValuelist()) <RPARAN>(<S>)*)
- ((";"(<S>)*)+
- {documentHandler.includeDirective(name, args);}
- | <LBRACE> (<S>)* {documentHandler.startIncludeContentBlock(name, args);}
- (styleRuleOrDeclarationOrNestedProperties() | keyframeSelector())*
- <RBRACE> (<S>)* {documentHandler.endIncludeContentBlock();}
- )
+ (name = property() | name = variableName(){ name = "$"+name;}
+ | (name = functionName() args = argValuelist()) <RPARAN>(<S>)*)
+ {documentHandler.startInclude(name, args);}
+ (includeDirectiveBlockContents() | includeDirectiveTerminator())
+ {documentHandler.endInclude();}
+}
+
+void includeDirectiveTerminator():
+{}
+{
+ try {
+ (";"(<S>)*)+
+ }
+ catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
+}
+
+void includeDirectiveBlockContents():
+{}
+{
+ <LBRACE> (<S>)*
+ (styleRuleOrDeclarationOrNestedProperties() | keyframeSelector())*
+ <RBRACE> (<S>)*
}
+
String interpolation() :
{
Token n;
@@ -1873,39 +1930,66 @@ String listModifyDirectiveArgs(int nest)
{
t = getToken(1);
String s = t.image;
- if(t.kind == VARIABLE||t.kind == IDENT) {
+ if(t.kind == VARIABLE||t.kind == IDENT)
+ {
list += s;
- }else if(s.toLowerCase().equals("auto")||s.toLowerCase().equals("space")||s.toLowerCase().equals("comma")) {
+ }else if(s.toLowerCase().equals("auto")||s.toLowerCase().equals("space")||s.toLowerCase().equals("comma"))
+ {
int i = 2;
Token temp = getToken(i);
boolean isLast = true;
while(temp.kind != SEMICOLON)
- { if(temp.kind != RPARAN || temp.kind != S)
- { isLast = false; }
+ {
+ if(temp.kind != RPARAN || temp.kind != S)
+ {
+ isLast = false;
+ }
i++;
temp = getToken(i);
}
- if(isLast) { return list;
+ if(isLast)
+ {
+ return list;
}
- } else if(t.kind == STRING) { list += s.substring(1,s.length()).substring(0,s.length()-2);
+ }
+ else if(t.kind == STRING)
+ {
+ list += s.substring(1,s.length()).substring(0,s.length()-2);
- }else if(t.kind == LPARAN) { nesting++;
- if(nesting > nest+1) { throw new CSSParseException("Only one ( ) pair per parameter allowed", getLocator());
+ }else if(t.kind == LPARAN)
+ {
+ nesting++;
+ if(nesting > nest+1)
+ {
+ throw new CSSParseException("Only one ( ) pair per parameter allowed", getLocator());
}
- }else if(t.kind == RPARAN) { nesting--;
- if(nesting == 0) {
+ }else if(t.kind == RPARAN)
+ {
+ nesting--;
+ if(nesting == 0)
+ {
return list;
}
- } else if(t.kind == COMMA) {
- if(nesting == nest) {
- return list; }else {
- list += ","; }
+ } else if(t.kind == COMMA)
+ {
+ if(nesting == nest)
+ {
+ return list;
+ }else
+ {
+ list += ",";
+ }
- }else if(t.kind == S) {
- list += " "; } else if(t.kind == LBRACE) {
- throw new CSSParseException("Invalid token,'{' found", getLocator()); }
- getNextToken();
+ }else if(t.kind == S)
+ {
+ list += " ";
+ } else if(t.kind == LBRACE)
+ {
+ throw new CSSParseException("Invalid token,'{' found", getLocator());
+ }
+
+ getNextToken();
}
}
@@ -1929,11 +2013,16 @@ void debugDirective() :
{
<DEBUG_SYM>
{
- String content = skipStatementUntilSemiColon();
+ String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF});
// TODO should evaluate the content expression, call documentHandler.debugDirective() etc.
- System.out.println(content);
+ Logger.getLogger(Parser.class.getName()).log(Level.INFO, content);
+ }
+ try {
+ ";" (<S>)*
+ }
+ catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
}
- (<S>)*
}
void warnDirective() :
@@ -1941,11 +2030,16 @@ void warnDirective() :
{
<WARN_SYM>
{
- String content = skipStatementUntilSemiColon();
+ String content = skipStatementUntil(new int[] {SEMICOLON,RBRACE,EOF});
// TODO should evaluate the content expression, call documentHandler.warnDirective() etc.
- System.err.println(content);
+ Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, content);
+ }
+ try {
+ ";" (<S>)*
+ }
+ catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
}
- (<S>)*
}
Node forDirective() :
@@ -1988,8 +2082,13 @@ void extendDirective() :
<EXTEND_SYM>
(<S>)*
list = selectorList()
- (";"(<S>)*)+
{documentHandler.extendDirective(list);}
+ try {
+ (";"(<S>)*)+
+ }
+ catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
}
void contentDirective() :
@@ -1997,7 +2096,12 @@ void contentDirective() :
{
<CONTENT_SYM>
(<S>)*
- (";"(<S>)*)+
+ try {
+ (";"(<S>)*)+
+ }
+ catch (ParseException e) {
+ acceptMissingSemicolonBeforeRbrace(e);
+ }
{documentHandler.contentDirective();}
}
@@ -2297,14 +2401,20 @@ LexicalUnitImpl term(LexicalUnitImpl prev) :
}
}
-LexicalUnitImpl variableTerm(LexicalUnitImpl prev) : {
+LexicalUnitImpl variableTerm(LexicalUnitImpl prev) :
+{
LexicalUnitImpl result = null;
- String varName = ""; } {
+ String varName = "";
+}
+{
varName = variableName()
{result = LexicalUnitImpl.createVariable(token.beginLine, token.beginColumn,
- prev, varName); return result;} }
+ prev, varName); return result;}
+}
-LexicalUnitImpl nonVariableTerm(LexicalUnitImpl prev) : { LexicalUnitImpl result = null;
+LexicalUnitImpl nonVariableTerm(LexicalUnitImpl prev) :
+{
+LexicalUnitImpl result = null;
Token n = null;
char op = ' ';
String varName;
@@ -2427,7 +2537,9 @@ LexicalUnitImpl nonVariableTerm(LexicalUnitImpl prev) : { LexicalUnitImpl result
| result=unicode(prev)
) ) ( <S> )*
{
- return result; } }
+ return result;
+ }
+}
/**
* Handle all CSS2 functions.
@@ -2766,27 +2878,27 @@ String skipStatementUntilMatchingRightParan(){
JAVACODE
String skipStatementUntil(int[] symbols){
StringBuffer s = new StringBuffer();
- boolean stop = false;
+ boolean found = false;
Token tok;
- while(!stop){
+ while(!found){
tok = getToken(1);
- if(tok.kind == EOF) {
- return null;
- }
for(int sym : symbols){
if(tok.kind == sym){
- stop = true;
+ found = true;
break;
}
}
- if(!stop){
+ if(tok.kind == EOF) {
+ break;
+ }
+ if(!found){
if (tok.image != null) {
s.append(tok.image);
}
getNextToken();
}
}
- return s.toString().trim();
+ return found ? s.toString().trim() : null;
}
@@ -3021,6 +3133,15 @@ 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..0db4e4e2f8 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/ParserTokenManager.java
@@ -21,6 +21,8 @@ import java.util.ArrayList;
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/SCSSLexicalUnit.java b/theme-compiler/src/com/vaadin/sass/internal/parser/SCSSLexicalUnit.java
index 709d1d3576..84b0563493 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/parser/SCSSLexicalUnit.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/SCSSLexicalUnit.java
@@ -22,6 +22,8 @@ public interface SCSSLexicalUnit extends LexicalUnit {
static final short SCSS_OPERATOR_LEFT_PAREN = 101;
static final short SCSS_OPERATOR_RIGHT_PAREN = 102;
+ static final short SCSS_NULL = 110;
+
static final short SAC_LEM = 200;
static final short SAC_REM = 201;
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..7f88649e84
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/AbsFunctionGenerator.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.sass.internal.parser.function;
+
+import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+
+/**
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class AbsFunctionGenerator implements SCSSFunctionGenerator {
+
+ @Override
+ public String getFunctionName() {
+ return "abs";
+ }
+
+ @Override
+ public String printState(LexicalUnitImpl function) {
+ LexicalUnitImpl firstParam = function.getParameters();
+ firstParam.setFloatValue(Math.abs(firstParam.getFloatValue()));
+ return firstParam.toString();
+ }
+
+}
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..7d19734fe7
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/CeilFunctionGenerator.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.sass.internal.parser.function;
+
+import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+
+/**
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class CeilFunctionGenerator implements SCSSFunctionGenerator {
+
+ @Override
+ public String getFunctionName() {
+ return "ceil";
+ }
+
+ @Override
+ public String printState(LexicalUnitImpl function) {
+ LexicalUnitImpl firstParam = function.getParameters();
+ firstParam.setFloatValue((float) Math.ceil(firstParam.getFloatValue()));
+ return firstParam.toString();
+ }
+
+}
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..2fbf0b2427
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/DarkenFunctionGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.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) {
+ LexicalUnitImpl dark = ColorUtil.darken(function);
+ return dark.toString();
+ }
+}
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..d972a5bee8
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/DefaultFunctionGenerator.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+/**
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class DefaultFunctionGenerator implements SCSSFunctionGenerator {
+
+ @Override
+ public String getFunctionName() {
+ return null;
+ }
+
+ @Override
+ public String printState(LexicalUnitImpl function) {
+ StringBuilder builder = new StringBuilder(function.getFunctionName());
+ return builder.append('(').append(printParameters(function))
+ .append(')').toString();
+ }
+
+ private String printParameters(LexicalUnitImpl function) {
+ if (function.getParameters() == null) {
+ return null;
+ }
+ return function.getParameters().toString();
+ }
+}
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..57a0dcbf56
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/FloorFunctionGenerator.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;
+
+/**
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class FloorFunctionGenerator implements SCSSFunctionGenerator {
+
+ @Override
+ public String getFunctionName() {
+ return "floor";
+ }
+
+ @Override
+ public String printState(LexicalUnitImpl function) {
+ LexicalUnitImpl firstParam = function.getParameters();
+ firstParam
+ .setFloatValue((float) Math.floor(firstParam.getFloatValue()));
+ return firstParam.toString();
+ }
+
+}
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..b911593457
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/LightenFunctionGenerator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.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) {
+ return ColorUtil.lighten(function).toString();
+ }
+
+}
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..b8e8194f21
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/RoundFunctionGenerator.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.sass.internal.parser.function;
+
+import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+
+/**
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+public class RoundFunctionGenerator implements SCSSFunctionGenerator {
+
+ @Override
+ public String getFunctionName() {
+ return "round";
+ }
+
+ @Override
+ public String printState(LexicalUnitImpl function) {
+ LexicalUnitImpl firstParam = function.getParameters();
+ firstParam.setFloatValue(Math.round(firstParam.getFloatValue()));
+ return firstParam.toString();
+ }
+
+}
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..4d34b59578
--- /dev/null
+++ b/theme-compiler/src/com/vaadin/sass/internal/parser/function/SCSSFunctionGenerator.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.sass.internal.parser.function;
+
+import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+
+/**
+ * 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
+ * @return String state representation of the function
+ */
+ String printState(LexicalUnitImpl function);
+}
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..8db522ea1a 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;
@@ -109,7 +111,8 @@ 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);
}
}
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..dcabd2ff01 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;
@@ -54,7 +56,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/MixinNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/MixinNode.java
index e702bc8577..c5ffb6d73d 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;
@@ -119,7 +121,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/RuleNode.java b/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java
index cc6dbb7b75..a8fa87eb0a 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/tree/RuleNode.java
@@ -58,13 +58,18 @@ public class RuleNode extends Node implements IVariableNode {
@Override
public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append(variable).append(": ").append(value.toString());
- builder.append(important ? " !important;" : ";");
+ String stringValue = value.toString()
+ + (important ? " !important" : "");
+ if (!"".equals(stringValue.trim())) {
+ stringValue = variable + ": " + stringValue + ";";
+ } else {
+ stringValue = "";
+ }
+
if (comment != null) {
- builder.append(comment);
+ stringValue += comment;
}
- return builder.toString();
+ return stringValue;
}
public boolean isImportant() {
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..8449a9d891 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,6 +15,9 @@
*/
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;
@@ -40,7 +43,8 @@ public class IfElseDefNode extends Node {
IfElseNodeHandler.traverse(this);
} catch (Exception e) {
- e.printStackTrace();
+ Logger.getLogger(IfElseDefNode.class.getName()).log(Level.SEVERE,
+ null, e);
}
}
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 e52767bb5a..daf01a3eab 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java
@@ -19,6 +19,8 @@ package com.vaadin.sass.internal.visitor;
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;
@@ -78,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/com/vaadin/sass/internal/visitor/VariableNodeHandler.java b/theme-compiler/src/com/vaadin/sass/internal/visitor/VariableNodeHandler.java
index 6da035426e..a794def8cb 100644
--- a/theme-compiler/src/com/vaadin/sass/internal/visitor/VariableNodeHandler.java
+++ b/theme-compiler/src/com/vaadin/sass/internal/visitor/VariableNodeHandler.java
@@ -17,16 +17,20 @@
package com.vaadin.sass.internal.visitor;
import com.vaadin.sass.internal.ScssStylesheet;
+import com.vaadin.sass.internal.parser.SCSSLexicalUnit;
import com.vaadin.sass.internal.tree.VariableNode;
public class VariableNodeHandler {
public static void traverse(VariableNode node) {
- if (ScssStylesheet.getVariable(node.getName()) == null
- || !node.isGuarded()) {
+ VariableNode variable = ScssStylesheet.getVariable(node.getName());
+ if (!node.isGuarded()
+ || variable == null
+ || variable.getExpr() == null
+ || (variable.getExpr().getLexicalUnitType() == SCSSLexicalUnit.SCSS_NULL && variable
+ .getExpr().getNextLexicalUnit() == null)) {
ScssStylesheet.addVariable(node);
}
node.getParentNode().removeChild(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/variable-defaults-with-null.css b/theme-compiler/tests/resources/automatic/css/variable-defaults-with-null.css
new file mode 100644
index 0000000000..0e3483817b
--- /dev/null
+++ b/theme-compiler/tests/resources/automatic/css/variable-defaults-with-null.css
@@ -0,0 +1,5 @@
+.test {
+ first: "Non-null";
+ second: "Also non-null";
+ third: "Not null";
+} \ 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/variable-defaults-with-null.scss b/theme-compiler/tests/resources/automatic/scss/variable-defaults-with-null.scss
new file mode 100644
index 0000000000..0bfa374304
--- /dev/null
+++ b/theme-compiler/tests/resources/automatic/scss/variable-defaults-with-null.scss
@@ -0,0 +1,19 @@
+$var: null;
+$var: "Non-null" !default;
+
+$var2: null;
+$var2: "Also non-null" !default;
+$var2: "Null content" !default;
+
+$list-of-nulls: null null;
+$list-of-nulls: "Non-null" !default;
+
+$mixed-list: null "Not null" null;
+$mixed-list: "null" !default;
+
+.test {
+ first: $var;
+ second: $var2;
+ hidden: $list-of-nulls;
+ third: $mixed-list;
+} \ No newline at end of file
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/106-test_pseudoclass_remains_at_end_of_selector.css b/theme-compiler/tests/resources/sasslang/css/106-test_pseudoclass_remains_at_end_of_selector.css
index 2118fad2a2..2118fad2a2 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/106-test_pseudoclass_remains_at_end_of_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/106-test_pseudoclass_remains_at_end_of_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/107-test_pseudoelement_goes_lefter_than_not.css b/theme-compiler/tests/resources/sasslang/css/107-test_pseudoelement_goes_lefter_than_not.css
index 7a53dec628..7a53dec628 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/107-test_pseudoelement_goes_lefter_than_not.css
+++ b/theme-compiler/tests/resources/sasslang/css/107-test_pseudoelement_goes_lefter_than_not.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/108-test_pseudoelement_goes_lefter_than_pseudoclass.css b/theme-compiler/tests/resources/sasslang/css/108-test_pseudoelement_goes_lefter_than_pseudoclass.css
index a5ae5ac363..a5ae5ac363 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/108-test_pseudoelement_goes_lefter_than_pseudoclass.css
+++ b/theme-compiler/tests/resources/sasslang/css/108-test_pseudoelement_goes_lefter_than_pseudoclass.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/109-test_pseudoelement_remains_at_end_of_selector.css b/theme-compiler/tests/resources/sasslang/css/109-test_pseudoelement_remains_at_end_of_selector.css
index aa379e70b3..aa379e70b3 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/109-test_pseudoelement_remains_at_end_of_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/109-test_pseudoelement_remains_at_end_of_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/110-test_redundant_selector_elimination.css b/theme-compiler/tests/resources/sasslang/css/110-test_redundant_selector_elimination.css
index 7be91d143a..7be91d143a 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/110-test_redundant_selector_elimination.css
+++ b/theme-compiler/tests/resources/sasslang/css/110-test_redundant_selector_elimination.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/112-test_target_with_child.css b/theme-compiler/tests/resources/sasslang/css/112-test_target_with_child.css
index cee3a34a5a..cee3a34a5a 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/112-test_target_with_child.css
+++ b/theme-compiler/tests/resources/sasslang/css/112-test_target_with_child.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/2-test_basic.css b/theme-compiler/tests/resources/sasslang/css/2-test_basic.css
index 4504b8d829..4504b8d829 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/2-test_basic.css
+++ b/theme-compiler/tests/resources/sasslang/css/2-test_basic.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.css b/theme-compiler/tests/resources/sasslang/css/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.css
index 47d93c5dc1..47d93c5dc1 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.css
+++ b/theme-compiler/tests/resources/sasslang/css/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/33-test_extend_redundancy_elimination_never_eliminates_base_selector.css b/theme-compiler/tests/resources/sasslang/css/33-test_extend_redundancy_elimination_never_eliminates_base_selector.css
index 4a4aa6d222..4a4aa6d222 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/33-test_extend_redundancy_elimination_never_eliminates_base_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/33-test_extend_redundancy_elimination_never_eliminates_base_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/333-test_empty_content.css b/theme-compiler/tests/resources/sasslang/css/333-test_empty_content.css
index f1c0f6c996..f1c0f6c996 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/333-test_empty_content.css
+++ b/theme-compiler/tests/resources/sasslang/css/333-test_empty_content.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.css b/theme-compiler/tests/resources/sasslang/css/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.css
index eb28eca8fa..eb28eca8fa 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.css
+++ b/theme-compiler/tests/resources/sasslang/css/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/350-test_interpolation.css b/theme-compiler/tests/resources/sasslang/css/350-test_interpolation.css
index 8b44646800..8b44646800 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/350-test_interpolation.css
+++ b/theme-compiler/tests/resources/sasslang/css/350-test_interpolation.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/368-test_mixins_with_args.css b/theme-compiler/tests/resources/sasslang/css/368-test_mixins_with_args.css
index 318a3f6ffb..318a3f6ffb 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/368-test_mixins_with_args.css
+++ b/theme-compiler/tests/resources/sasslang/css/368-test_mixins_with_args.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/369-test_mixins_with_empty_args.css b/theme-compiler/tests/resources/sasslang/css/369-test_mixins_with_empty_args.css
index 234d524066..234d524066 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/369-test_mixins_with_empty_args.css
+++ b/theme-compiler/tests/resources/sasslang/css/369-test_mixins_with_empty_args.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/390-test_parent_selector_with_parent_and_subject.css b/theme-compiler/tests/resources/sasslang/css/390-test_parent_selector_with_parent_and_subject.css
index 234fea7aa5..234fea7aa5 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/390-test_parent_selector_with_parent_and_subject.css
+++ b/theme-compiler/tests/resources/sasslang/css/390-test_parent_selector_with_parent_and_subject.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/420-test_warn_directive.css b/theme-compiler/tests/resources/sasslang/css/420-test_warn_directive.css
index 6d661f2404..6d661f2404 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/420-test_warn_directive.css
+++ b/theme-compiler/tests/resources/sasslang/css/420-test_warn_directive.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/55-test_long_extendee.css b/theme-compiler/tests/resources/sasslang/css/55-test_long_extendee.css
index 0d6bd2ec98..0d6bd2ec98 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/55-test_long_extendee.css
+++ b/theme-compiler/tests/resources/sasslang/css/55-test_long_extendee.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/63-test_multiple_extendees.css b/theme-compiler/tests/resources/sasslang/css/63-test_multiple_extendees.css
index d3fae7600f..d3fae7600f 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/63-test_multiple_extendees.css
+++ b/theme-compiler/tests/resources/sasslang/css/63-test_multiple_extendees.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/65-test_multiple_extends_with_multiple_extenders_and_single_target.css b/theme-compiler/tests/resources/sasslang/css/65-test_multiple_extends_with_multiple_extenders_and_single_target.css
index 44196e6602..44196e6602 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/65-test_multiple_extends_with_multiple_extenders_and_single_target.css
+++ b/theme-compiler/tests/resources/sasslang/css/65-test_multiple_extends_with_multiple_extenders_and_single_target.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/66-test_multiple_extends_with_single_extender_and_single_target.css b/theme-compiler/tests/resources/sasslang/css/66-test_multiple_extends_with_single_extender_and_single_target.css
index 9b5770d7c5..9b5770d7c5 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/66-test_multiple_extends_with_single_extender_and_single_target.css
+++ b/theme-compiler/tests/resources/sasslang/css/66-test_multiple_extends_with_single_extender_and_single_target.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/67-test_multiple_targets.css b/theme-compiler/tests/resources/sasslang/css/67-test_multiple_targets.css
index 779bd00f75..779bd00f75 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/67-test_multiple_targets.css
+++ b/theme-compiler/tests/resources/sasslang/css/67-test_multiple_targets.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/7-test_combinator_unification_angle_sibling.css b/theme-compiler/tests/resources/sasslang/css/7-test_combinator_unification_angle_sibling.css
index 657d1ec2f6..657d1ec2f6 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/7-test_combinator_unification_angle_sibling.css
+++ b/theme-compiler/tests/resources/sasslang/css/7-test_combinator_unification_angle_sibling.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/70-test_nested_extender.css b/theme-compiler/tests/resources/sasslang/css/70-test_nested_extender.css
index 1c4e604b71..1c4e604b71 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/70-test_nested_extender.css
+++ b/theme-compiler/tests/resources/sasslang/css/70-test_nested_extender.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/80-test_nested_extender_merges_with_same_selector.css b/theme-compiler/tests/resources/sasslang/css/80-test_nested_extender_merges_with_same_selector.css
index d1a50d50e3..d1a50d50e3 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/80-test_nested_extender_merges_with_same_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/80-test_nested_extender_merges_with_same_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/81-test_nested_extender_runs_unification.css b/theme-compiler/tests/resources/sasslang/css/81-test_nested_extender_runs_unification.css
index 9aa8d14958..9aa8d14958 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/81-test_nested_extender_runs_unification.css
+++ b/theme-compiler/tests/resources/sasslang/css/81-test_nested_extender_runs_unification.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/85-test_nested_extender_with_child_selector.css b/theme-compiler/tests/resources/sasslang/css/85-test_nested_extender_with_child_selector.css
index f7bd620245..f7bd620245 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/85-test_nested_extender_with_child_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/85-test_nested_extender_with_child_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/86-test_nested_extender_with_child_selector_merges_with_same_selector.css b/theme-compiler/tests/resources/sasslang/css/86-test_nested_extender_with_child_selector_merges_with_same_selector.css
index 75561708b3..75561708b3 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/86-test_nested_extender_with_child_selector_merges_with_same_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/86-test_nested_extender_with_child_selector_merges_with_same_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.css b/theme-compiler/tests/resources/sasslang/css/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.css
index 4285daf8dd..4285daf8dd 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.css
+++ b/theme-compiler/tests/resources/sasslang/css/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/90-test_nested_extender_with_sibling_selector.css b/theme-compiler/tests/resources/sasslang/css/90-test_nested_extender_with_sibling_selector.css
index e9fe832391..e9fe832391 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/90-test_nested_extender_with_sibling_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/90-test_nested_extender_with_sibling_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/91-test_nested_selector_with_child_selector_hack_extendee.css b/theme-compiler/tests/resources/sasslang/css/91-test_nested_selector_with_child_selector_hack_extendee.css
index 5556837892..5556837892 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/91-test_nested_selector_with_child_selector_hack_extendee.css
+++ b/theme-compiler/tests/resources/sasslang/css/91-test_nested_selector_with_child_selector_hack_extendee.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/96-test_nested_target.css b/theme-compiler/tests/resources/sasslang/css/96-test_nested_target.css
index d1a50d50e3..d1a50d50e3 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/96-test_nested_target.css
+++ b/theme-compiler/tests/resources/sasslang/css/96-test_nested_target.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/css/98-test_not_remains_at_end_of_selector.css b/theme-compiler/tests/resources/sasslang/css/98-test_not_remains_at_end_of_selector.css
index 540e6f8bf4..540e6f8bf4 100644
--- a/theme-compiler/tests/resources/sasslangbroken/css/98-test_not_remains_at_end_of_selector.css
+++ b/theme-compiler/tests/resources/sasslang/css/98-test_not_remains_at_end_of_selector.css
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/106-test_pseudoclass_remains_at_end_of_selector.scss b/theme-compiler/tests/resources/sasslang/scss/106-test_pseudoclass_remains_at_end_of_selector.scss
index 619bbb51cd..619bbb51cd 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/106-test_pseudoclass_remains_at_end_of_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/106-test_pseudoclass_remains_at_end_of_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/107-test_pseudoelement_goes_lefter_than_not.scss b/theme-compiler/tests/resources/sasslang/scss/107-test_pseudoelement_goes_lefter_than_not.scss
index f50ad04b12..f50ad04b12 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/107-test_pseudoelement_goes_lefter_than_not.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/107-test_pseudoelement_goes_lefter_than_not.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/108-test_pseudoelement_goes_lefter_than_pseudoclass.scss b/theme-compiler/tests/resources/sasslang/scss/108-test_pseudoelement_goes_lefter_than_pseudoclass.scss
index 230f925a10..230f925a10 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/108-test_pseudoelement_goes_lefter_than_pseudoclass.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/108-test_pseudoelement_goes_lefter_than_pseudoclass.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/109-test_pseudoelement_remains_at_end_of_selector.scss b/theme-compiler/tests/resources/sasslang/scss/109-test_pseudoelement_remains_at_end_of_selector.scss
index cd588ed24a..cd588ed24a 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/109-test_pseudoelement_remains_at_end_of_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/109-test_pseudoelement_remains_at_end_of_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/110-test_redundant_selector_elimination.scss b/theme-compiler/tests/resources/sasslang/scss/110-test_redundant_selector_elimination.scss
index ab8ba4845f..ab8ba4845f 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/110-test_redundant_selector_elimination.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/110-test_redundant_selector_elimination.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/112-test_target_with_child.scss b/theme-compiler/tests/resources/sasslang/scss/112-test_target_with_child.scss
index 3748f64233..3748f64233 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/112-test_target_with_child.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/112-test_target_with_child.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/2-test_basic.scss b/theme-compiler/tests/resources/sasslang/scss/2-test_basic.scss
index 9f3cde0011..9f3cde0011 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/2-test_basic.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/2-test_basic.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.scss b/theme-compiler/tests/resources/sasslang/scss/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.scss
index a5a0dff1d0..a5a0dff1d0 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/29-test_extend_does_not_warn_when_one_extension_fails_but_others_dont.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/33-test_extend_redundancy_elimination_never_eliminates_base_selector.scss b/theme-compiler/tests/resources/sasslang/scss/33-test_extend_redundancy_elimination_never_eliminates_base_selector.scss
index ac6ad58994..ac6ad58994 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/33-test_extend_redundancy_elimination_never_eliminates_base_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/33-test_extend_redundancy_elimination_never_eliminates_base_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/333-test_empty_content.scss b/theme-compiler/tests/resources/sasslang/scss/333-test_empty_content.scss
index ad8df41f25..ad8df41f25 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/333-test_empty_content.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/333-test_empty_content.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.scss b/theme-compiler/tests/resources/sasslang/scss/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.scss
index 30a9d092cb..30a9d092cb 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/35-test_extend_redundancy_elimination_when_it_would_reduce_specificity.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/350-test_interpolation.scss b/theme-compiler/tests/resources/sasslang/scss/350-test_interpolation.scss
index bb9c9a2c8f..bb9c9a2c8f 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/350-test_interpolation.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/350-test_interpolation.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/368-test_mixins_with_args.scss b/theme-compiler/tests/resources/sasslang/scss/368-test_mixins_with_args.scss
index 3ba39ecac2..3ba39ecac2 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/368-test_mixins_with_args.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/368-test_mixins_with_args.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/369-test_mixins_with_empty_args.scss b/theme-compiler/tests/resources/sasslang/scss/369-test_mixins_with_empty_args.scss
index f608979293..f608979293 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/369-test_mixins_with_empty_args.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/369-test_mixins_with_empty_args.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/390-test_parent_selector_with_parent_and_subject.scss b/theme-compiler/tests/resources/sasslang/scss/390-test_parent_selector_with_parent_and_subject.scss
index 646238f379..646238f379 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/390-test_parent_selector_with_parent_and_subject.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/390-test_parent_selector_with_parent_and_subject.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/420-test_warn_directive.scss b/theme-compiler/tests/resources/sasslang/scss/420-test_warn_directive.scss
index 53546355cc..53546355cc 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/420-test_warn_directive.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/420-test_warn_directive.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/55-test_long_extendee.scss b/theme-compiler/tests/resources/sasslang/scss/55-test_long_extendee.scss
index 26ab65d344..26ab65d344 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/55-test_long_extendee.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/55-test_long_extendee.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/63-test_multiple_extendees.scss b/theme-compiler/tests/resources/sasslang/scss/63-test_multiple_extendees.scss
index 2c0f5aa72a..2c0f5aa72a 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/63-test_multiple_extendees.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/63-test_multiple_extendees.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/65-test_multiple_extends_with_multiple_extenders_and_single_target.scss b/theme-compiler/tests/resources/sasslang/scss/65-test_multiple_extends_with_multiple_extenders_and_single_target.scss
index 4c2a4c59f8..4c2a4c59f8 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/65-test_multiple_extends_with_multiple_extenders_and_single_target.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/65-test_multiple_extends_with_multiple_extenders_and_single_target.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/66-test_multiple_extends_with_single_extender_and_single_target.scss b/theme-compiler/tests/resources/sasslang/scss/66-test_multiple_extends_with_single_extender_and_single_target.scss
index 48d9c5b733..48d9c5b733 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/66-test_multiple_extends_with_single_extender_and_single_target.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/66-test_multiple_extends_with_single_extender_and_single_target.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/67-test_multiple_targets.scss b/theme-compiler/tests/resources/sasslang/scss/67-test_multiple_targets.scss
index fdcba65999..fdcba65999 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/67-test_multiple_targets.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/67-test_multiple_targets.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/7-test_combinator_unification_angle_sibling.scss b/theme-compiler/tests/resources/sasslang/scss/7-test_combinator_unification_angle_sibling.scss
index b0120ac34e..b0120ac34e 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/7-test_combinator_unification_angle_sibling.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/7-test_combinator_unification_angle_sibling.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/70-test_nested_extender.scss b/theme-compiler/tests/resources/sasslang/scss/70-test_nested_extender.scss
index 6245cdfda7..6245cdfda7 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/70-test_nested_extender.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/70-test_nested_extender.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/80-test_nested_extender_merges_with_same_selector.scss b/theme-compiler/tests/resources/sasslang/scss/80-test_nested_extender_merges_with_same_selector.scss
index d959cce374..d959cce374 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/80-test_nested_extender_merges_with_same_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/80-test_nested_extender_merges_with_same_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/81-test_nested_extender_runs_unification.scss b/theme-compiler/tests/resources/sasslang/scss/81-test_nested_extender_runs_unification.scss
index 32c2c0cc62..32c2c0cc62 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/81-test_nested_extender_runs_unification.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/81-test_nested_extender_runs_unification.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/85-test_nested_extender_with_child_selector.scss b/theme-compiler/tests/resources/sasslang/scss/85-test_nested_extender_with_child_selector.scss
index da249ad564..da249ad564 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/85-test_nested_extender_with_child_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/85-test_nested_extender_with_child_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/86-test_nested_extender_with_child_selector_merges_with_same_selector.scss b/theme-compiler/tests/resources/sasslang/scss/86-test_nested_extender_with_child_selector_merges_with_same_selector.scss
index 224945cd71..224945cd71 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/86-test_nested_extender_with_child_selector_merges_with_same_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/86-test_nested_extender_with_child_selector_merges_with_same_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.scss b/theme-compiler/tests/resources/sasslang/scss/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.scss
index f2b8c6c07b..f2b8c6c07b 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/88-test_nested_extender_with_early_child_selectors_doesnt_subseq_them.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/90-test_nested_extender_with_sibling_selector.scss b/theme-compiler/tests/resources/sasslang/scss/90-test_nested_extender_with_sibling_selector.scss
index b9d495ce76..b9d495ce76 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/90-test_nested_extender_with_sibling_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/90-test_nested_extender_with_sibling_selector.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/91-test_nested_selector_with_child_selector_hack_extendee.scss b/theme-compiler/tests/resources/sasslang/scss/91-test_nested_selector_with_child_selector_hack_extendee.scss
index 928bc64f93..928bc64f93 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/91-test_nested_selector_with_child_selector_hack_extendee.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/91-test_nested_selector_with_child_selector_hack_extendee.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/96-test_nested_target.scss b/theme-compiler/tests/resources/sasslang/scss/96-test_nested_target.scss
index 6662dea791..6662dea791 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/96-test_nested_target.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/96-test_nested_target.scss
diff --git a/theme-compiler/tests/resources/sasslangbroken/scss/98-test_not_remains_at_end_of_selector.scss b/theme-compiler/tests/resources/sasslang/scss/98-test_not_remains_at_end_of_selector.scss
index c1af8b1b2a..c1af8b1b2a 100644
--- a/theme-compiler/tests/resources/sasslangbroken/scss/98-test_not_remains_at_end_of_selector.scss
+++ b/theme-compiler/tests/resources/sasslang/scss/98-test_not_remains_at_end_of_selector.scss
diff --git a/theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java b/theme-compiler/tests/src/com/vaadin/sass/AbstractTestBase.java
index d867e6ccd0..01187b4502 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 = 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 = 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/internal/expression/ArithmeticExpressionEvaluatorTest.java b/theme-compiler/tests/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java
index 8978eb812e..c408255d0e 100644
--- a/theme-compiler/tests/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java
+++ b/theme-compiler/tests/src/com/vaadin/sass/internal/expression/ArithmeticExpressionEvaluatorTest.java
@@ -19,6 +19,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.w3c.css.sac.LexicalUnit;
+import com.vaadin.sass.internal.expression.exception.ArithmeticException;
import com.vaadin.sass.internal.expression.exception.IncompatibleUnitsException;
import com.vaadin.sass.internal.parser.LexicalUnitImpl;
@@ -122,4 +123,15 @@ public class ArithmeticExpressionEvaluatorTest {
Assert.assertEquals(LexicalUnit.SAC_CENTIMETER,
result.getLexicalUnitType());
}
+
+ @Test(expected = ArithmeticException.class)
+ public void testNonExistingSignal() {
+ LexicalUnitImpl operand2Integer = LexicalUnitImpl.createInteger(2, 3,
+ null, 2);
+ LexicalUnitImpl operatorComma = LexicalUnitImpl.createComma(2, 3,
+ operand2Integer);
+ LexicalUnitImpl operand3Integer = LexicalUnitImpl.createInteger(2, 3,
+ operatorComma, 3);
+ LexicalUnitImpl result = evaluator.evaluate(operand2Integer);
+ }
}
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/CompassImports.java b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java
index 1e3eb09f0c..4e87eb2197 100644
--- a/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java
+++ b/theme-compiler/tests/src/com/vaadin/sass/testcases/scss/CompassImports.java
@@ -68,12 +68,14 @@ public class CompassImports extends AbstractTestBase {
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.toString();
+ parsedScss = parsedScss.replaceAll(CR, "");
Assert.assertEquals("Original CSS and parsed CSS do not match",
comparisonCss, parsedScss);
}
diff --git a/uitest/ivy.xml b/uitest/ivy.xml
index 9c86b2b68c..6270ec54de 100644
--- a/uitest/ivy.xml
+++ b/uitest/ivy.xml
@@ -83,7 +83,10 @@
<dependency org="org.hsqldb" name="hsqldb" rev="2.2.6"
conf="build,ide -> default" />
<dependency org="com.vaadin" name="vaadin-testbench"
- rev="3.1.1" conf="build-provided,ide -> default" />
+ rev="3.1.2" 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/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
index a2f3c59f07..47d3a19fde 100644
--- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
+++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java
@@ -280,7 +280,7 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet {
}
- throw new ClassNotFoundException();
+ throw new ClassNotFoundException(baseName);
}
private Logger getLogger() {
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/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/applicationservlet/NoApplicationClass.html b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html
deleted file mode 100644
index 6ed410fdb6..0000000000
--- a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.html
+++ /dev/null
@@ -1,26 +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/ClassThatIsNotPresent?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>//pre[2]</td>
- <td>*java.lang.InstantiationException: Failed to load application class: ClassThatIsNotPresent*</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java
new file mode 100644
index 0000000000..9d1b052182
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.applicationservlet;
+
+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.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class NoApplicationClassTest extends MultiBrowserTest {
+
+ @Test
+ public void testInvalidApplicationClass() {
+ openTestURL();
+ String exceptionMessage = getDriver().findElement(By.xpath("//pre[2]"))
+ .getText();
+ Assert.assertTrue(exceptionMessage
+ .contains("ServletException: java.lang.ClassNotFoundException: ClassThatIsNotPresent"));
+ }
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return Collections.singletonList(Browser.CHROME
+ .getDesiredCapabilities());
+ }
+
+ @Override
+ protected String getDeploymentPath() {
+ return "/run/ClassThatIsNotPresent";
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java b/uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.java
new file mode 100644
index 0000000000..54fb7212ca
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/browserfeatures/WebkitPositionAbsoluteScrollbarsTest.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.tests.browserfeatures;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class WebkitPositionAbsoluteScrollbarsTest extends MultiBrowserTest {
+
+ @Override
+ protected String getDeploymentPath() {
+ return "/statictestfiles/browserfeatures/WebkitPositionAbsoluteScrollbars.html";
+ }
+
+ @Test
+ public void testWebkitScrollbarProblem() throws Exception {
+ openTestURL();
+ getDriver().findElement(By.id("step1")).click();
+ getDriver().findElement(By.id("step2")).click();
+ getDriver().findElement(By.id("step3")).click();
+ getDriver().findElement(By.id("step4")).click();
+ compareScreen("no-scrollbars");
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/gwtadapter/componentlocator/TestDetachedNotPresent.html b/uitest/src/com/vaadin/tests/componentlocator/TestDetachedNotPresent.html
index 24e5e992ca..24e5e992ca 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 8f92ff3118..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;
@@ -148,6 +148,10 @@ public abstract class AbstractTestUI extends UI {
getLayout().addComponent(c);
}
+ public void addComponents(Component... c) {
+ getLayout().addComponents(c);
+ }
+
public void removeComponent(Component c) {
getLayout().removeComponent(c);
}
diff --git a/uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java b/uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java
new file mode 100644
index 0000000000..b6358b6c56
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java
@@ -0,0 +1,47 @@
+/*
+ * 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 com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.AbstractComponent;
+
+public class UnknownComponentConnector extends AbstractTestUI {
+
+ public static class ComponentWithoutConnector extends AbstractComponent {
+
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ ComponentWithoutConnector component = new ComponentWithoutConnector();
+ component.setId("no-connector-component");
+ addComponent(component);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html b/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html
deleted file mode 100644
index 20f0e8e71e..0000000000
--- a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html
+++ /dev/null
@@ -1,27 +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>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.UnknownComponentConnectorTest?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsUnknownComponentConnectorTest::/VVerticalLayout[0]/VVerticalLayout[0]/VUnknownComponent[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
- <td>Widgetset does not contain implementation for com.vaadin.tests.components.UnknownComponentConnectorTest.ComponentWithoutConnector. Check its component connector's @Connect mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions.</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java b/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java
index ff113d631e..49a3c29e2d 100644
--- a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java
+++ b/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java
@@ -13,33 +13,29 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-
package com.vaadin.tests.components;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.ui.AbstractComponent;
-
-public class UnknownComponentConnectorTest extends AbstractTestUI {
+import static org.junit.Assert.assertTrue;
- public static class ComponentWithoutConnector extends AbstractComponent {
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
- }
-
- @Override
- protected void setup(VaadinRequest request) {
- addComponent(new ComponentWithoutConnector());
- }
+import com.vaadin.tests.tb3.MultiBrowserTest;
- @Override
- protected String getTestDescription() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- protected Integer getTicketNumber() {
- // TODO Auto-generated method stub
- return null;
+/**
+ * Tests that a user is notified about a missing component from the widgetset
+ */
+public class UnknownComponentConnectorTest extends MultiBrowserTest {
+
+ @Test
+ public void testConnectorNotFoundInWidgetset() throws Exception {
+ openTestURL();
+ WebElement component = vaadinElementById("no-connector-component");
+ assertTrue(component
+ .getText()
+ .startsWith(
+ "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain "
+ + "implementation for com.vaadin.tests.components.UnknownComponentConnector."
+ + "ComponentWithoutConnector."));
}
-
}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java
new file mode 100644
index 0000000000..5e81750e58
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java
@@ -0,0 +1,114 @@
+/*
+ * 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.calendar;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import com.vaadin.event.Action;
+import com.vaadin.event.Action.Handler;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Calendar;
+import com.vaadin.ui.Calendar.TimeFormat;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler;
+import com.vaadin.ui.components.calendar.event.BasicEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEvent;
+import com.vaadin.ui.components.calendar.event.CalendarEventProvider;
+
+public class CalendarActionEventSource extends AbstractTestUI {
+
+ private Calendar calendar;
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ calendar = new Calendar(new CalendarEventProvider() {
+
+ @Override
+ public List<com.vaadin.ui.components.calendar.event.CalendarEvent> getEvents(
+ Date startDate, Date endDate) {
+
+ List<CalendarEvent> events = new ArrayList<CalendarEvent>();
+
+ CalendarEvent event = null;
+ try {
+ event = new BasicEvent("NAME", "TOOLTIP",
+ new SimpleDateFormat("yyyy-MM-dd hh:mm")
+ .parse("2013-01-01 07:00"),
+ new SimpleDateFormat("yyyy-MM-dd hh:mm")
+ .parse("2013-01-01 11:00"));
+ } catch (ParseException e) {
+ // Nothing to do
+ }
+ events.add(event);
+
+ return events;
+ }
+
+ });
+ try {
+ calendar.setStartDate(new SimpleDateFormat("yyyy-MM-dd")
+ .parse("2013-01-01"));
+ calendar.setEndDate(new SimpleDateFormat("yyyy-MM-dd")
+ .parse("2013-01-31"));
+ } catch (ParseException e) {
+ // Nothing to do
+ }
+ calendar.setImmediate(true);
+ calendar.setFirstVisibleHourOfDay(6);
+ calendar.setLastVisibleHourOfDay(22);
+ calendar.setTimeFormat(TimeFormat.Format24H);
+ calendar.setHandler((EventResizeHandler) null);
+
+ setEnabled(true);
+ calendar.addActionHandler(new Handler() {
+ @Override
+ public void handleAction(Action action, Object sender, Object target) {
+ Label label1 = new Label(calendar.toString());
+ label1.setId("calendarlabel");
+ addComponent(label1);
+
+ Label label2 = new Label(sender.toString());
+ label2.setId("senderlabel");
+ addComponent(label2);
+ }
+
+ @Override
+ public Action[] getActions(Object target, Object sender) {
+ return new Action[] { new Action("ACTION") };
+ }
+ });
+ addComponent(calendar);
+ calendar.setSizeFull();
+ setSizeFull();
+
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Calendar action event source should be the calendar itself";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13191;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java
new file mode 100644
index 0000000000..6fbe77040f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.calendar;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.tb3.PrivateTB3Configuration;
+
+/**
+ * Test that calendar action event source is the calendar, not a private nested
+ * class in it.
+ *
+ * The related code is not browser dependent so only running on a single
+ * browser.
+ *
+ * @author Vaadin Ltd
+ */
+public class CalendarActionEventSourceTest extends PrivateTB3Configuration {
+ @Test
+ public void testActionEventSourceIsCalendarForEmptyCell() throws Exception {
+ openTestURL();
+
+ // perform action on empty cell
+ WebElement element = getDriver().findElement(
+ By.className("v-calendar-spacer"));
+ performAction(element);
+
+ checkEventSourceIsCalendar();
+ }
+
+ @Test
+ public void testActionEventSourceIsCalendarForEvent() throws Exception {
+ openTestURL();
+
+ // perform action on calendar event
+ WebElement element = getDriver().findElement(
+ By.className("v-calendar-event"));
+ performAction(element);
+
+ checkEventSourceIsCalendar();
+ }
+
+ private void performAction(WebElement element) {
+ // right click
+ new Actions(getDriver()).contextClick(element).perform();
+ WebElement menuItem = getDriver().findElement(
+ By.className("gwt-MenuItem"));
+ menuItem.click();
+ }
+
+ private void checkEventSourceIsCalendar() {
+ String calendarObject = getDriver().findElement(By.id("calendarlabel"))
+ .getText();
+ String actionSourceObject = getDriver().findElement(
+ By.id("senderlabel")).getText();
+ Assert.assertEquals(
+ "Calendar action event source must be the calendar itself",
+ calendarObject, actionSourceObject);
+ }
+
+ @Override
+ protected Class<?> getUIClass() {
+ return CalendarActionEventSource.class;
+ }
+
+}
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..95a2c9f493
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionHoverTest.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.orderedlayout;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+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);
+
+ // Verify that there's no error notification
+ WebElement error = vaadinElement("Root/VNotification[0]");
+ assertNull("No error should be found", error);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionTooltip.html b/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionTooltip.html
deleted file mode 100644
index 4f574a92c7..0000000000
--- a/uitest/src/com/vaadin/tests/components/orderedlayout/NestedLayoutCaptionTooltip.html
+++ /dev/null
@@ -1,33 +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>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.applicationcontext.CloseSession?restartApplication&amp;debug</td>
- <td></td>
-</tr>
-<!-- Show tooltip for the Events caption -->
-<tr>
- <td>showTooltip</td>
- <td>//div[@id='gwt-uid-4']/span</td>
- <td></td>
-</tr>
-<!-- Verify that there's no error notification -->
-<tr>
- <td>assertElementNotPresent</td>
- <td>vaadin=runcomvaadintestsapplicationcontextCloseSession::Root/VNotification[0]</td>
- <td></td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java
new file mode 100644
index 0000000000..1e7d817094
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java
@@ -0,0 +1,63 @@
+/*
+ * 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.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class VerticalLayoutFocusWithDOMChanges extends AbstractTestUI implements
+ ValueChangeListener {
+
+ Button dummyButton = new Button("Just a button");
+ TextField listenedTextField = new TextField();
+ TextField changingTextField = new TextField();
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ VerticalLayout content = new VerticalLayout();
+ setSizeFull();
+ listenedTextField.addValueChangeListener(this);
+ listenedTextField.setImmediate(true);
+ changingTextField.setImmediate(true);
+ content.addComponent(dummyButton);
+ content.addComponent(listenedTextField);
+ content.addComponent(changingTextField);
+ content.setMargin(true);
+ content.setSpacing(true);
+ setContent(content);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Check that creating or removing caption wrap doesn't lose focus";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12967;
+ }
+
+ @Override
+ public void valueChange(ValueChangeEvent event) {
+ changingTextField.setRequired(!changingTextField.isRequired());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java
new file mode 100644
index 0000000000..14c26a0e17
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.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.components.orderedlayout;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.By;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class VerticalLayoutFocusWithDOMChangesTest extends MultiBrowserTest {
+
+ private String initialText = "Some";
+ private String incrementalText = " text";
+
+ @Test
+ public void inputTextAndChangeFocus() throws InterruptedException {
+ openTestURL();
+ List<WebElement> textFields = getDriver().findElements(
+ By.tagName("input"));
+ WebElement tf1 = textFields.get(0);
+ WebElement tf2 = textFields.get(1);
+ tf1.sendKeys(initialText);
+ new Actions(getDriver()).moveToElement(tf2).click().build().perform();
+
+ WebElement activeElement = getFocusedElement();
+ Assert.assertEquals("input", activeElement.getTagName());
+ Assert.assertEquals("", activeElement.getAttribute("value"));
+
+ tf1.sendKeys(incrementalText);
+ new Actions(getDriver())
+ .moveToElement(
+ getDriver().findElement(By.className("v-button")))
+ .click().build().perform();
+ activeElement = getFocusedElement();
+ Assert.assertEquals("Just a button", activeElement.getText());
+
+ DesiredCapabilities capabilities = getDesiredCapabilities();
+ if (capabilities.equals(BrowserUtil.ie(8))
+ || capabilities.equals(BrowserUtil.ie(9))) {
+ // IE8 and IE9 insert cursor in the start of input instead of end.
+ Assert.assertEquals(incrementalText + initialText,
+ tf1.getAttribute("value"));
+ } else {
+ Assert.assertEquals(initialText + incrementalText,
+ tf1.getAttribute("value"));
+ }
+ }
+
+ @Test
+ public void moveFocusAndChangeFieldWithValue() {
+ openTestURL();
+ List<WebElement> textFields = getDriver().findElements(
+ By.tagName("input"));
+ WebElement tf1 = textFields.get(0);
+ WebElement tf2 = textFields.get(1);
+
+ String firstText = "This is";
+ String secondText = " default value";
+
+ tf2.sendKeys(firstText);
+ tf1.sendKeys(initialText);
+ new Actions(getDriver()).moveToElement(tf2).click().build().perform();
+
+ WebElement activeElement = getFocusedElement();
+ Assert.assertEquals("input", activeElement.getTagName());
+ Assert.assertEquals(firstText, activeElement.getAttribute("value"));
+
+ new Actions(getDriver()).sendKeys(secondText).build().perform();
+ DesiredCapabilities capabilities = getDesiredCapabilities();
+ if (capabilities.equals(BrowserUtil.ie(8))
+ || capabilities.equals(BrowserUtil.ie(9))) {
+ // IE8 and IE9 insert cursor in the start of input instead of end.
+ Assert.assertEquals(secondText + firstText,
+ tf2.getAttribute("value"));
+ } else {
+ Assert.assertEquals(firstText + secondText,
+ tf2.getAttribute("value"));
+ }
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html
new file mode 100644
index 0000000000..2f8532de61
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html
@@ -0,0 +1,47 @@
+<?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>SelectItemCaptionRefresh</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">SelectItemCaptionRefresh</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.select.SelectItemCaptionRefresh?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#button</td>
+ <td>10,14</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td/span</td>
+ <td>16,11</td>
+</tr>
+<tr>
+ <td>verifyValue</td>
+ <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#textbox</td>
+ <td>start</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>verifyValue</td>
+ <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#textbox</td>
+ <td>0</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java
new file mode 100644
index 0000000000..de068ed230
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java
@@ -0,0 +1,75 @@
+/*
+ * 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.select;
+
+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.Select;
+
+public class SelectItemCaptionRefresh extends AbstractTestUI {
+
+ final Object itemId = new Object();
+ Select select;
+
+ Button.ClickListener clickListener = new Button.ClickListener() {
+ Integer i = Integer.valueOf(0);
+
+ @Override
+ public void buttonClick(final ClickEvent event) {
+ select.setItemCaption(itemId, (i++).toString());
+ }
+ };
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ select = new Select("Foo");
+
+ select.addItem(itemId);
+ select.setItemCaption(itemId, "start");
+
+ addComponent(select);
+ addComponent(new Button("Update item's caption", clickListener));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription()
+ */
+ @Override
+ protected String getTestDescription() {
+ return "Selected option should be updated when item caption changes in the Select.";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber()
+ */
+ @Override
+ protected Integer getTicketNumber() {
+ return 9250;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/ExpandingContainer.java b/uitest/src/com/vaadin/tests/components/table/ExpandingContainer.java
new file mode 100644
index 0000000000..829c29b95b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/ExpandingContainer.java
@@ -0,0 +1,429 @@
+package com.vaadin.tests.components.table;
+
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.Property;
+import com.vaadin.data.util.AbstractContainer;
+import com.vaadin.data.util.BeanItem;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+
+@SuppressWarnings("serial")
+public class ExpandingContainer extends AbstractContainer implements
+ Container.Ordered, Container.Indexed, Container.ItemSetChangeNotifier {
+
+ public static final List<String> PROPERTY_IDS = Arrays.asList("id",
+ "column1", "column2");
+
+ private final Label sizeLabel;
+ private final Logger log = Logger.getLogger(this.getClass().getName());
+
+ private int currentSize = 300;
+
+ private boolean loggingEnabled;
+
+ public ExpandingContainer(Label sizeLabel) {
+ this.sizeLabel = sizeLabel;
+ updateLabel();
+ }
+
+ private void log(String message) {
+ if (loggingEnabled) {
+ log.info(message);
+ }
+ }
+
+ // Expand container if we scroll past 85%
+ public int checkExpand(int index) {
+ log("checkExpand(" + index + ")");
+ if (index >= currentSize * 0.85) {
+ final int oldsize = currentSize;
+ currentSize = (int) (oldsize * 1.3333);
+ log("*** getSizeWithHint(" + index + "): went past 85% of size="
+ + oldsize + ", new size=" + currentSize);
+ updateLabel();
+ }
+ return currentSize;
+ };
+
+ @Override
+ public void fireItemSetChange() {
+ super.fireItemSetChange();
+ }
+
+ private void updateLabel() {
+ sizeLabel.setValue("Container size: " + currentSize);
+ }
+
+ public void triggerItemSetChange() {
+ log("*** triggerItemSetChange(): scheduling item set change event");
+ final VaadinSession session = VaadinSession.getCurrent();
+ new Thread() {
+ @Override
+ public void run() {
+ ExpandingContainer.this.invoke(session, new Runnable() {
+ @Override
+ public void run() {
+ log("*** Firing item set change event");
+ ExpandingContainer.this.fireItemSetChange();
+ }
+ });
+ }
+ }.start();
+ }
+
+ private void invoke(VaadinSession session, Runnable action) {
+ session.lock();
+ VaadinSession previousSession = VaadinSession.getCurrent();
+ VaadinSession.setCurrent(session);
+ try {
+ action.run();
+ } finally {
+ session.unlock();
+ VaadinSession.setCurrent(previousSession);
+ }
+ }
+
+ // Container
+
+ @Override
+ public BeanItem<MyBean> getItem(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return null;
+ }
+ final int index = ((Integer) itemId).intValue();
+ return new BeanItem<MyBean>(new MyBean(index));
+ }
+
+ @Override
+ public Collection<Integer> getItemIds() {
+ return new IntList(size());
+ }
+
+ @Override
+ public List<String> getContainerPropertyIds() {
+ return PROPERTY_IDS;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Property/* <?> */getContainerProperty(Object itemId,
+ Object propertyId) {
+ BeanItem<MyBean> item = getItem(itemId);
+ return item != null ? item.getItemProperty(propertyId) : null;
+ }
+
+ @Override
+ public Class<?> getType(Object propertyId) {
+ return Component.class;
+ }
+
+ @Override
+ public int size() {
+ return currentSize;
+ }
+
+ @Override
+ public boolean containsId(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return false;
+ }
+ int index = ((Integer) itemId).intValue();
+ checkExpand(index);
+ return index >= 0 && index < currentSize;
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public Item addItem(Object itemId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public Item addItem() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public boolean removeItem(Object itemId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public boolean addContainerProperty(Object propertyId, Class<?> type,
+ Object defaultValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public boolean removeContainerProperty(Object propertyId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public boolean removeAllItems() {
+ throw new UnsupportedOperationException();
+ }
+
+ // Container.Indexed
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public Object addItemAt(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public Item addItemAt(int index, Object newItemId) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Integer getIdByIndex(int index) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException("index < " + index);
+ }
+ final int size = currentSize;
+ if (index >= size) {
+ throw new IndexOutOfBoundsException("index=" + index + " but size="
+ + size);
+ }
+ checkExpand(index);
+ return index;
+ }
+
+ @Override
+ public List<Integer> getItemIds(int startIndex, int numberOfItems) {
+ if (numberOfItems < 0) {
+ throw new IllegalArgumentException("numberOfItems < 0");
+ }
+ final int size = currentSize;
+ checkExpand(startIndex);
+ if (startIndex < 0 || startIndex > size) {
+ throw new IndexOutOfBoundsException("startIndex=" + startIndex
+ + " but size=" + size);
+ }
+ if (startIndex + numberOfItems > size) {
+ numberOfItems = size - startIndex;
+ }
+ return new IntList(startIndex, numberOfItems);
+ }
+
+ @Override
+ public int indexOfId(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return -1;
+ }
+ final int index = ((Integer) itemId).intValue();
+ checkExpand(index);
+ if (index < 0 || index >= currentSize) {
+ return -1;
+ }
+ return index;
+ }
+
+ // Container.Ordered
+
+ @Override
+ public Integer nextItemId(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return null;
+ }
+ int index = ((Integer) itemId).intValue();
+ checkExpand(index);
+ if (index < 0 || index + 1 >= currentSize) {
+ return null;
+ }
+ return index + 1;
+ }
+
+ @Override
+ public Integer prevItemId(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return null;
+ }
+ int index = ((Integer) itemId).intValue();
+ checkExpand(index);
+ if (index - 1 < 0 || index >= currentSize) {
+ return null;
+ }
+ return index - 1;
+ }
+
+ @Override
+ public Integer firstItemId() {
+ return currentSize == 0 ? null : 0;
+ }
+
+ @Override
+ public Integer lastItemId() {
+ final int size = currentSize;
+ return size == 0 ? null : size - 1;
+ }
+
+ @Override
+ public boolean isFirstId(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return false;
+ }
+ final int index = ((Integer) itemId).intValue();
+ checkExpand(index);
+ final int size = currentSize;
+ return size > 0 && index == 0;
+ }
+
+ @Override
+ public boolean isLastId(Object itemId) {
+ if (!(itemId instanceof Integer)) {
+ return false;
+ }
+ int index = ((Integer) itemId).intValue();
+ checkExpand(index);
+ int size = currentSize;
+ return size > 0 && index == size - 1;
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public Item addItemAfter(Object previousItemId) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @throws UnsupportedOperationException
+ * always
+ */
+ @Override
+ public Item addItemAfter(Object previousItemId, Object newItemId) {
+ throw new UnsupportedOperationException();
+ }
+
+ // Container.ItemSetChangeNotifier
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void addListener(Container.ItemSetChangeListener listener) {
+ super.addListener(listener);
+ }
+
+ @Override
+ public void addItemSetChangeListener(
+ Container.ItemSetChangeListener listener) {
+ super.addItemSetChangeListener(listener);
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void removeListener(Container.ItemSetChangeListener listener) {
+ super.removeListener(listener);
+ }
+
+ @Override
+ public void removeItemSetChangeListener(
+ Container.ItemSetChangeListener listener) {
+ super.removeItemSetChangeListener(listener);
+ }
+
+ // IntList
+
+ private static class IntList extends AbstractList<Integer> {
+
+ private final int min;
+ private final int size;
+
+ public IntList(int size) {
+ this(0, size);
+ }
+
+ public IntList(int min, int size) {
+ if (size < 0) {
+ throw new IllegalArgumentException("size < 0");
+ }
+ this.min = min;
+ this.size = size;
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public Integer get(int index) {
+ if (index < 0 || index >= size) {
+ throw new IndexOutOfBoundsException();
+ }
+ return min + index;
+ }
+ }
+
+ // MyBean
+ public class MyBean {
+
+ private final int index;
+
+ public MyBean(int index) {
+ this.index = index;
+ }
+
+ public String getId() {
+ return "ROW #" + index;
+ }
+
+ public String getColumn1() {
+ return genText();
+ }
+
+ public String getColumn2() {
+ return genText();
+ }
+
+ private String genText() {
+ return "this is a line of text in row #" + index;
+ }
+ }
+
+ public void logDetails(boolean enabled) {
+ loggingEnabled = enabled;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceCondition.java b/uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceCondition.java
new file mode 100644
index 0000000000..8ad2d7f9c7
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceCondition.java
@@ -0,0 +1,67 @@
+package com.vaadin.tests.components.table;
+
+import java.util.Map;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+
+@SuppressWarnings("serial")
+public class ExpandingContainerVisibleRowRaceCondition extends UI {
+
+ static final String TABLE = "table";
+
+ @Override
+ public void init(VaadinRequest request) {
+ final VerticalLayout rootLayout = new VerticalLayout();
+
+ rootLayout.setSpacing(true);
+ rootLayout.setSizeFull();
+ rootLayout.setMargin(true);
+
+ final Label sizeLabel = new Label();
+ final ExpandingContainer container = new ExpandingContainer(sizeLabel);
+ container.logDetails(false);
+
+ Table table = new Table(null, container) {
+ @Override
+ public void changeVariables(Object source,
+ Map<String, Object> variables) {
+ if (variables.containsKey("firstvisible")) {
+ int index = (Integer) variables.get("firstvisible");
+ container.checkExpand(index);
+ }
+ if (variables.containsKey("reqfirstrow")
+ || variables.containsKey("reqrows")) {
+ try {
+ int index = ((Integer) variables
+ .get("lastToBeRendered")).intValue();
+ container.checkExpand(index);
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ super.changeVariables(source, variables);
+ }
+ };
+ table.setId(TABLE);
+ table.setCacheRate(0);
+ table.setSizeFull();
+ table.setVisibleColumns(ExpandingContainer.PROPERTY_IDS
+ .toArray(new String[ExpandingContainer.PROPERTY_IDS.size()]));
+
+ table.setCurrentPageFirstItemIndex(120);
+
+ rootLayout.addComponent(table);
+ rootLayout.setExpandRatio(table, 1);
+
+ rootLayout.addComponent(sizeLabel);
+
+ setContent(rootLayout);
+
+ container.checkExpand(300);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceConditionTest.java b/uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceConditionTest.java
new file mode 100644
index 0000000000..73dd7b1f81
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/ExpandingContainerVisibleRowRaceConditionTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 com.vaadin.tests.components.table.ExpandingContainerVisibleRowRaceCondition.TABLE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class ExpandingContainerVisibleRowRaceConditionTest extends
+ MultiBrowserTest {
+
+ private static final int ROW_HEIGHT = 20;
+
+ @Test
+ public void testScrollingWorksWithoutJumpingWhenItemSetChangeOccurs() {
+ openTestURL();
+ sleep(1000);
+
+ WebElement table = vaadinElementById(TABLE);
+ assertFirstRowIdIs("ROW #120");
+
+ testBenchElement(table.findElement(By.className("v-scrollable")))
+ .scroll(320 * ROW_HEIGHT);
+ sleep(1000);
+
+ assertRowIdIsInThePage("ROW #330");
+ assertScrollPositionIsNotVisible();
+ }
+
+ @Override
+ protected void sleep(int milliseconds) {
+ try {
+ super.sleep(milliseconds);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void assertFirstRowIdIs(String expected) {
+ List<WebElement> cellsOfFirstColumn = getCellsOfFirstColumn();
+ WebElement first = cellsOfFirstColumn.get(0);
+ assertEquals(expected, first.getText());
+ }
+
+ private void assertRowIdIsInThePage(String expected) {
+ List<WebElement> cellsOfFirstColumn = getCellsOfFirstColumn();
+ for (WebElement rowId : cellsOfFirstColumn) {
+ if (expected.equals(rowId.getText())) {
+ return;
+ }
+ }
+ fail("Expected row was not found");
+ }
+
+ private void assertScrollPositionIsNotVisible() {
+ WebElement table = vaadinElementById(TABLE);
+ WebElement scrollPosition = table.findElement(By
+ .className("v-table-scrollposition"));
+ assertFalse(scrollPosition.isDisplayed());
+ }
+
+ private List<WebElement> getCellsOfFirstColumn() {
+ WebElement table = vaadinElementById(TABLE);
+ List<WebElement> firstCellOfRows = table.findElements(By
+ .cssSelector(".v-table-table tr > td"));
+ return firstCellOfRows;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/SelectAllRows.java b/uitest/src/com/vaadin/tests/components/table/SelectAllRows.java
new file mode 100644
index 0000000000..6007ea2984
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/SelectAllRows.java
@@ -0,0 +1,83 @@
+/*
+ * 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.Set;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class SelectAllRows extends AbstractTestUI {
+
+ static final String TABLE = "table";
+ static final String COUNT_SELECTED_BUTTON = "button";
+ static final int TOTAL_NUMBER_OF_ROWS = 300;
+ static final String COUNT_OF_SELECTED_ROWS_LABEL = "label";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ layout.setSpacing(true);
+ setContent(layout);
+
+ final Table table = new Table();
+ table.setId(TABLE);
+ table.setImmediate(true);
+ table.setMultiSelect(true);
+ table.setSelectable(true);
+ table.addContainerProperty("row", String.class, null);
+ layout.addComponent(table);
+
+ Button button = new Button("Count");
+ button.setId(COUNT_SELECTED_BUTTON);
+ layout.addComponent(button);
+
+ final Label label = new Label();
+ label.setId(COUNT_OF_SELECTED_ROWS_LABEL);
+ label.setCaption("Selected count:");
+ layout.addComponent(label);
+
+ button.addClickListener(new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(Button.ClickEvent event) {
+ Set selected = (Set) table.getValue();
+ label.setValue(String.valueOf(selected.size()));
+ }
+ });
+
+ for (int i = 0; i < TOTAL_NUMBER_OF_ROWS; i++) {
+ Object itemId = table.addItem();
+ table.getContainerProperty(itemId, "row").setValue("row " + i);
+ }
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Selecting all rows does not work by selecting first row, press shift then select last row";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 13008;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java
new file mode 100644
index 0000000000..664b36fa75
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.vaadin.tests.components.table.SelectAllRows.COUNT_OF_SELECTED_ROWS_LABEL;
+import static com.vaadin.tests.components.table.SelectAllRows.COUNT_SELECTED_BUTTON;
+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.List;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class SelectAllRowsTest extends MultiBrowserTest {
+
+ private final static String TABLE_ROW = "v-table-row";
+
+ @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());
+ }
+
+ @Test
+ public void testAllRowsAreSelected() {
+ openTestURL();
+
+ selectAllRowsInTable();
+ int selectedRows = countSelectedItems();
+
+ assertEquals(TOTAL_NUMBER_OF_ROWS, selectedRows);
+ }
+
+ private int countSelectedItems() {
+ WebElement countButton = vaadinElementById(COUNT_SELECTED_BUTTON);
+ countButton.click();
+ WebElement countOfSelectedRows = vaadinElementById(COUNT_OF_SELECTED_ROWS_LABEL);
+ String count = countOfSelectedRows.getText();
+ return Integer.parseInt(count);
+ }
+
+ private void selectAllRowsInTable() {
+ clickFirstRow();
+ scrollTableToBottom();
+ new Actions(getDriver()).keyDown(Keys.SHIFT).perform();
+ clickLastRow();
+ new Actions(getDriver()).keyUp(Keys.SHIFT).perform();
+ }
+
+ private void clickLastRow() {
+ List<WebElement> rows = allVisibleTableRows();
+ WebElement lastRow = rows.get(rows.size() - 1);
+ lastRow.click();
+ }
+
+ private void clickFirstRow() {
+ WebElement firstRow = allVisibleTableRows().get(0);
+ firstRow.click();
+ }
+
+ private void scrollTableToBottom() {
+ WebElement table = vaadinElementById(TABLE);
+ testBenchElement(table.findElement(By.className("v-scrollable")))
+ .scroll(TOTAL_NUMBER_OF_ROWS * 30);
+
+ // Wait for scrolling to complete. Otherwise, clicking last row will
+ // fail with Chrome
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private List<WebElement> allVisibleTableRows() {
+ WebElement table = vaadinElementById(TABLE);
+ List<WebElement> rows = table.findElements(By
+ .cssSelector(".v-table-table tr"));
+ return rows;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java
index 6e4b62e4f7..ab0198f39c 100644
--- a/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java
+++ b/uitest/src/com/vaadin/tests/components/table/TableRemovedQuicklySendsInvalidRpcCalls.java
@@ -16,26 +16,217 @@
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.event.ItemClickEvent;
-import com.vaadin.event.ItemClickEvent.ItemClickListener;
+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) {
- addComponent(new Button("Blink a table", new Button.ClickListener() {
+ 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() {
@@ -47,25 +238,6 @@ public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI {
table.addItem(new Object[] { "Row" }, new Object());
}
- table.addItemClickListener(new ItemClickListener() {
- private int i;
-
- @Override
- public void itemClick(ItemClickEvent event) {
- /*
- * Ignore implementation. This is only an easy way to make the
- * client-side update table's variables (by furiously clicking
- * on the table row.
- *
- * This way, we get variable changes queued. The push call will
- * then remove the Table, while the variable changes being still
- * in the queue, leading to the issue as described in the
- * ticket.
- */
- System.out.println("clicky " + (++i));
- }
- });
-
System.out.println("adding component");
addComponent(table);
@@ -80,6 +252,7 @@ public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI {
public void run() {
System.out.println("removing component");
removeComponent(table);
+ button.setCaption(SUCCESS_CAPTION);
}
});
} catch (InterruptedException e) {
@@ -87,7 +260,7 @@ public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI {
} finally {
getSession().unlock();
}
- };
+ }
}.start();
}
@@ -96,8 +269,9 @@ public class TableRemovedQuicklySendsInvalidRpcCalls extends AbstractTestUI {
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) clicking furiously "
- + "on a row in the table.";
+ + "1) pressing the button 2) checking the server "
+ + "log for any error messages starting with "
+ + "\"RPC call to...\" .";
}
@Override
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/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/TabsheetScrollingTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.java
new file mode 100644
index 0000000000..b55f1057b5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabsheetScrollingTest.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.tabsheet;
+
+import org.junit.Assert;
+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 TabsheetScrollingTest extends MultiBrowserTest {
+
+ @Test
+ public void keyboardScrolling() {
+ openTestURL();
+ getTab(1).click();
+ for (int i = 0; i < 10; i++) {
+ sendKey(Keys.ARROW_RIGHT);
+ }
+ sendKey(Keys.SPACE);
+ Assert.assertEquals("Hide this tab (21)", getHideButtonText());
+ }
+
+ private WebElement getTab(int index) {
+ return getDriver().findElement(
+ By.vaadin("/VVerticalLayout[0]/Slot[1]"
+ + "/VVerticalLayout[0]/Slot[0]/VTabsheet[0]"
+ + "/domChild[0]/domChild[0]/domChild[0]"
+ + "/domChild[0]/domChild[" + index + "]"));
+
+ }
+
+ private String getHideButtonText() {
+ WebElement buttonCaption = getDriver().findElement(
+ By.vaadin("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]"
+ + "/Slot[0]/VTabsheet[0]/VTabsheetPanel[0]"
+ + "/VButton[0]/domChild[0]/domChild[0]"));
+ return buttonCaption.getText();
+ }
+
+ private void sendKey(Keys key) {
+ new Actions(getDriver()).sendKeys(key).perform();
+ }
+
+}
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/TextFieldTruncatesUnderscoresInModalDialogs.java b/uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogs.java
new file mode 100644
index 0000000000..2a9df42ba1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogs.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.textfield;
+
+import com.vaadin.annotations.Theme;
+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.FormLayout;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Window;
+
+@SuppressWarnings("serial")
+@Theme("chameleon")
+public class TextFieldTruncatesUnderscoresInModalDialogs extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Window dialog = new Window();
+
+ FormLayout formLayout = new FormLayout();
+ formLayout.setSpacing(true);
+
+ formLayout.addComponent(new Button("Disappear",
+ new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ event.getButton().setVisible(false);
+ }
+ }));
+
+ formLayout.addComponent(new TextField(null, "____pqjgy____"));
+
+ dialog.setContent(formLayout);
+
+ getUI().addWindow(dialog);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Text field must not truncate underscores in modal dialogs.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12974;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogsTest.java b/uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogsTest.java
new file mode 100644
index 0000000000..66b0df5ff4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/textfield/TextFieldTruncatesUnderscoresInModalDialogsTest.java
@@ -0,0 +1,16 @@
+package com.vaadin.tests.components.textfield;
+
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class TextFieldTruncatesUnderscoresInModalDialogsTest extends
+ MultiBrowserTest {
+
+ @Test
+ public void testWindowRepositioning() throws Exception {
+ openTestURL();
+
+ compareScreen("TextFieldTruncatesUnderscoresInModalDialogs");
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java
new file mode 100644
index 0000000000..8a2b263006
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClick.java
@@ -0,0 +1,53 @@
+package com.vaadin.tests.components.tree;
+
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.MouseEvents;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Tree;
+
+/**
+ * Test for #12618: Trying to select item with right click in Tree causes focus
+ * issues.
+ */
+@SuppressWarnings("serial")
+public class TreeScrollingOnRightClick extends AbstractTestUI {
+
+ public static final String TREE_ID = "my-tree";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ final Tree tree = new Tree();
+ tree.setId(TREE_ID);
+ tree.setSizeUndefined();
+
+ // Add item click listener for right click selection
+ tree.addItemClickListener(new ItemClickEvent.ItemClickListener() {
+ @SuppressWarnings("deprecation")
+ @Override
+ public void itemClick(ItemClickEvent event) {
+ if (event.getButton() == MouseEvents.ClickEvent.BUTTON_RIGHT) {
+ tree.select(event.getItemId());
+ }
+ }
+ });
+
+ // Add some items
+ for (int i = 0; i < 200; i++) {
+ tree.addItem(String.format("Node %s", i));
+ }
+
+ addComponent(tree);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Right clicking on items should not scroll Tree.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12618;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java
new file mode 100644
index 0000000000..76ab1b3fdb
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/tree/TreeScrollingOnRightClickTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.tree;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ *
+ * @since 7.1.9
+ * @author Vaadin Ltd
+ */
+public class TreeScrollingOnRightClickTest extends MultiBrowserTest {
+
+ @Test
+ public void testScrollingOnRightClick() throws Throwable {
+ openTestURL();
+
+ // Focus tree
+ WebElement tree = getDriver().findElement(
+ By.id(TreeScrollingOnRightClick.TREE_ID));
+ tree.click();
+
+ // Move selection down 50 items
+ for (int down = 0; down < 50; down++) {
+ tree.sendKeys(Keys.ARROW_DOWN);
+ }
+
+ Thread.sleep(1000);
+
+ // Get location of item 40
+ Point item40Location = getTreeNode("Node 40").getLocation();
+
+ // Right click on item 45
+ WebElement item45 = getTreeNode("Node 45");
+ new Actions(getDriver()).moveToElement(item45).contextClick(item45)
+ .perform();
+
+ // Ensure location of item 40 is still the same (no scrolling)
+ Point item40Location2 = getTreeNode("Node 40").getLocation();
+ assertEquals(item40Location.getY(), item40Location2.getY());
+ }
+
+ private WebElement getTreeNode(String caption) {
+ return getDriver().findElement(
+ By.xpath("//span[text() = '" + caption + "']"));
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.java b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetset.java
index e837321b56..f674567a2d 100644
--- a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.java
+++ b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetset.java
@@ -6,11 +6,13 @@ import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent;
@Widgetset("com.vaadin.tests.widgetset.TestingWidgetSet")
-public class TestUIWidgetset extends AbstractTestUI {
+public class ComponentIncludedInCustomWidgetset extends AbstractTestUI {
@Override
protected void setup(VaadinRequest request) {
- addComponent(new MissingFromDefaultWidgetsetComponent());
+ MissingFromDefaultWidgetsetComponent component = new MissingFromDefaultWidgetsetComponent();
+ component.setId("missing-component");
+ addComponent(component);
}
@Override
diff --git a/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.java b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.java
new file mode 100644
index 0000000000..f27ef5d789
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.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.tests.components.ui;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests if a component is included in a custom widgetset
+ * (com.vaadin.tests.widgetset.TestingWidgetSet)
+ *
+ * @author Vaadin Ltd
+ */
+public class ComponentIncludedInCustomWidgetsetTest extends MultiBrowserTest {
+
+ @Test
+ public void testComponentInTestingWidgetsetNotInDefaultWidgetset() {
+ openTestURL();
+ WebElement component = vaadinElementById("missing-component");
+ assertEquals(
+ "This component is available in TestingWidgetset, but not in DefaultWidgetset",
+ component.getText());
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset2.java b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetset.java
index a68cd91a5e..554a461c37 100644
--- a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset2.java
+++ b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetset.java
@@ -4,11 +4,13 @@ import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent;
-public class TestUIWidgetset2 extends AbstractTestUI {
+public class ComponentMissingFromDefaultWidgetset extends AbstractTestUI {
@Override
protected void setup(VaadinRequest request) {
- addComponent(new MissingFromDefaultWidgetsetComponent());
+ MissingFromDefaultWidgetsetComponent component = new MissingFromDefaultWidgetsetComponent();
+ component.setId("missing-component");
+ addComponent(component);
}
@Override
diff --git a/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java
new file mode 100644
index 0000000000..ec8add75e0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.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.tests.components.ui;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Test for testing if a component is missing from a widgetset.
+ *
+ * @author Vaadin Ltd
+ */
+public class ComponentMissingFromDefaultWidgetsetTest extends MultiBrowserTest {
+
+ @Test
+ public void testComponentInTestingWidgetset() {
+ openTestURL();
+ WebElement component = vaadinElementById("missing-component");
+ assertTrue(component
+ .getText()
+ .startsWith(
+ "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain implementation for com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent."));
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html b/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html
deleted file mode 100644
index 4c10dc4275..0000000000
--- a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html
+++ /dev/null
@@ -1,36 +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>Ticket4607</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">Ticket4607</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.ui.TestUIWidgetset?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiTestUIWidgetset::/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]</td>
- <td>This component is available in TestingWidgetset, but not in DefaultWidgetset</td>
-</tr>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.ui.TestUIWidgetset2?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestscomponentsuiTestUIWidgetset2::/VVerticalLayout[0]/VVerticalLayout[0]/VUnknownComponent[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
- <td>Widgetset does not contain implementation for com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent. Check its component connector's @Connect mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions.</td>
-</tr>
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java
new file mode 100644
index 0000000000..2c649c9ca8
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivity.java
@@ -0,0 +1,74 @@
+/*
+ * 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.server.CustomizedSystemMessages;
+import com.vaadin.server.SystemMessages;
+import com.vaadin.server.SystemMessagesInfo;
+import com.vaadin.server.SystemMessagesProvider;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+
+public class TimeoutRedirectResetsOnActivity extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ setupTimout(request);
+
+ addComponent(new Button("clicky", new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ // NOOP
+ }
+ }));
+ }
+
+ private void setupTimout(VaadinRequest request) {
+ request.getService().setSystemMessagesProvider(
+ new SystemMessagesProvider() {
+ @Override
+ public SystemMessages getSystemMessages(
+ SystemMessagesInfo systemMessagesInfo) {
+ CustomizedSystemMessages msgs = new CustomizedSystemMessages();
+ msgs.setSessionExpiredMessage(null);
+ msgs.setSessionExpiredCaption(null);
+ msgs.setSessionExpiredNotificationEnabled(true);
+ msgs.setSessionExpiredURL("http://example.com/");
+ return msgs;
+ }
+ });
+ /*
+ * NOTE: in practice, this means a timeout after 25 seconds, because of
+ * implementation details in
+ * com.vaadin.server.communication.MetadataWriter
+ */
+ getSession().getSession().setMaxInactiveInterval(10);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "The timeout redirect timer should reset if there's activity between the client and server.";
+ }
+
+ @Override
+ @SuppressWarnings("boxing")
+ protected Integer getTicketNumber() {
+ return 12446;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java
new file mode 100644
index 0000000000..272bacb8d5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.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.components.ui;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public class TimeoutRedirectResetsOnActivityTest extends MultiBrowserTest {
+ @Test
+ public void verifyRedirectWorks() throws Exception {
+ setDebug(true);
+ openTestURL();
+
+ long startTime = System.currentTimeMillis();
+ while (System.currentTimeMillis() - startTime < 30000) {
+ clickTheButton();
+ Thread.sleep(1000);
+ }
+
+ assertTrue("button disappeared before timeout", buttonIsStillThere());
+
+ Thread.sleep(30000);
+ assertTrue("no redirection occurred within 30 seconds",
+ !buttonIsStillThere());
+ }
+
+ private boolean buttonIsStillThere() {
+ try {
+ return getButton() != null;
+ } catch (NoSuchElementException e) {
+ return false;
+ }
+ }
+
+ private void clickTheButton() {
+ getButton().click();
+ }
+
+ private WebElement getButton() {
+ /*
+ * For some reason, the vaadinElement() method doesn't work when tests
+ * are run outside of "/run/" and "/run-push/" contexts. The given error
+ * message says that the generated Vaadin path doesn't match any
+ * elements, but when that selector is put into the recorder, the
+ * recorder finds it.
+ *
+ * XPath works fine.
+ */
+ /*-
+ return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]");
+ */
+ return getDriver().findElement(
+ By.xpath("//div[contains(@class,'v-button')]"));
+ }
+
+ @Override
+ protected String getDeploymentPath() {
+ /*
+ * AbstractTB3Test assumes only /run/ and /run-push/ contexts, so this
+ * method needs some overriding.
+ */
+ return "/12446/"
+ + TimeoutRedirectResetsOnActivity.class.getCanonicalName()
+ + "?restartApplication&debug";
+ }
+}
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/upload/UploadNoSelection.java b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java
new file mode 100644
index 0000000000..c304293170
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelection.java
@@ -0,0 +1,83 @@
+/*
+ * 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.upload;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.ui.Upload;
+import com.vaadin.ui.Upload.FailedEvent;
+import com.vaadin.ui.Upload.FinishedEvent;
+import com.vaadin.ui.Upload.Receiver;
+
+public class UploadNoSelection extends AbstractTestUIWithLog implements
+ Receiver {
+
+ static final String LOG_ID_PREFIX = "Log_row_";
+ static final String UPLOAD_ID = "u";
+
+ static final String UPLOAD_FINISHED = "Upload Finished";
+ static final String RECEIVING_UPLOAD = "Receiving upload";
+
+ static final String FILE_LENGTH_PREFIX = "File length:";
+ static final String FILE_NAME_PREFIX = "File name:";
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 9602;
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Uploading an empty selection (no file) will trigger FinishedEvent with 0-length file size and empty filename.";
+ }
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ Upload u = new Upload("Upload", this);
+ u.setId(UPLOAD_ID);
+ u.setSizeUndefined();
+
+ addComponent(u);
+
+ u.addFinishedListener(new Upload.FinishedListener() {
+ @Override
+ public void uploadFinished(FinishedEvent event) {
+ log(UPLOAD_FINISHED);
+ log(FILE_LENGTH_PREFIX + " " + event.getLength());
+ log(FILE_NAME_PREFIX + " " + event.getFilename());
+ }
+ });
+ u.addFailedListener(new Upload.FailedListener() {
+
+ @Override
+ public void uploadFailed(FailedEvent event) {
+ log("Upload Failed");
+ log(FILE_LENGTH_PREFIX + " " + event.getLength());
+ log(FILE_NAME_PREFIX + " " + event.getFilename());
+ }
+ });
+ }
+
+ @Override
+ public OutputStream receiveUpload(String filename, String MIMEType) {
+ log(RECEIVING_UPLOAD);
+ return new ByteArrayOutputStream();
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java
new file mode 100644
index 0000000000..1b30c4080a
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/upload/UploadNoSelectionTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.upload;
+
+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 UploadNoSelectionTest extends MultiBrowserTest {
+
+ @Test
+ public void testUploadNoSelection() throws Exception {
+ openTestURL();
+
+ // empty content is populated by com.vaadin.tests.util.Log
+ Assert.assertEquals(" ", getLogRow(0));
+
+ getSubmitButton().click();
+
+ // expecting empty file name
+ assertLogRow(0, 4, UploadNoSelection.FILE_NAME_PREFIX);
+ // expecting 0-length file
+ assertLogRow(1, 3, UploadNoSelection.FILE_LENGTH_PREFIX + " " + 0);
+ assertLogRow(2, 2, UploadNoSelection.UPLOAD_FINISHED);
+ assertLogRow(3, 1, UploadNoSelection.RECEIVING_UPLOAD);
+ }
+
+ private WebElement getSubmitButton() {
+ WebElement element = getDriver().findElement(
+ By.id(UploadNoSelection.UPLOAD_ID));
+ WebElement submitButton = element.findElement(By.className("v-button"));
+ return submitButton;
+ }
+
+ private void assertLogRow(int index, int expentedRowNo,
+ String expectedValueWithoutRowNo) {
+ Assert.assertEquals(expentedRowNo + ". " + expectedValueWithoutRowNo,
+ getLogRow(index));
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpened.java b/uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpened.java
new file mode 100644
index 0000000000..2f1c0ff685
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpened.java
@@ -0,0 +1,58 @@
+/*
+ * 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 com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+/**
+ *
+ * @since 7.1.9
+ * @author Vaadin Ltd
+ */
+public class ScrollingBodyElementWithModalOpened extends AbstractTestUI {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ VerticalLayout verticalLayout = new VerticalLayout();
+ verticalLayout.setHeight("10000px");
+
+ Window window = new Window("Caption");
+
+ VerticalLayout layout = new VerticalLayout();
+ layout.setWidth("300px");
+ layout.setHeight("300px");
+ window.setContent(layout);
+
+ addWindow(window);
+
+ window.setModal(true);
+
+ addComponent(verticalLayout);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Screen must not scroll with modal opened.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 12899;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpenedTest.java b/uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpenedTest.java
new file mode 100644
index 0000000000..b6474519b0
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/window/ScrollingBodyElementWithModalOpenedTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.junit.Test;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.commands.TestBenchElementCommands;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class ScrollingBodyElementWithModalOpenedTest extends MultiBrowserTest {
+
+ @Test
+ public void testWindowScrollbars() throws Exception {
+ openTestURL();
+
+ WebElement bodyElement = driver.findElement(By
+ .className("v-modal-window-open"));
+
+ TestBenchElementCommands scrollable = testBenchElement(bodyElement);
+ scrollable.scroll(1000);
+
+ Thread.sleep(1000);
+
+ compareScreen(getScreenshotBaseName());
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java
index 1df036af58..2e0873956c 100644
--- a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java
+++ b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java
@@ -15,7 +15,6 @@
*/
package com.vaadin.tests.components.window;
-import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
@@ -64,7 +63,7 @@ public class SubWindowsTextSelectionTest extends MultiBrowserTest {
}
@Test
- public void verifyNoTextSelectionOnMove() throws MalformedURLException {
+ public void verifyNoTextSelectionOnMove() throws Exception {
openTestURL();
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 575eb652b7..0000000000
--- a/uitest/src/com/vaadin/tests/components/window/TooltipInWindow.html
+++ /dev/null
@@ -1,86 +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>assertElementPositionLeft</td>
- <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]</td>
- <td>-1000</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>assertElementPositionLeft</td>
- <td>vaadin=runcomvaadintestscomponentswindowTooltipInWindow::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td>
- <td>-1000</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/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/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/BasicPushTest.java b/uitest/src/com/vaadin/tests/push/BasicPushTest.java
index ef40ae09dc..e03262ca7e 100644
--- a/uitest/src/com/vaadin/tests/push/BasicPushTest.java
+++ b/uitest/src/com/vaadin/tests/push/BasicPushTest.java
@@ -25,7 +25,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest;
public abstract class BasicPushTest extends MultiBrowserTest {
@Test
- public void testPush() {
+ public void testPush() throws InterruptedException {
openTestURL();
// Test client initiated push
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.java
new file mode 100644
index 0000000000..d90394d3b5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTime.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.tests.push;
+
+import com.vaadin.server.VaadinRequest;
+
+public abstract class ExtremelyLongPushTime extends PushLargeData {
+
+ private static final int DURATION_MS = 48 * 60 * 60 * 1000; // 48 H
+ private static int INTERVAL_MS = 60 * 1000; // 1 minute
+ private static int PAYLOAD_SIZE = 100 * 1024; // 100 KB
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server.
+ * VaadinRequest)
+ */
+ @Override
+ protected void setup(VaadinRequest request) {
+ super.setup(request);
+ duration.setConvertedValue(DURATION_MS);
+ interval.setConvertedValue(INTERVAL_MS);
+ dataSize.setConvertedValue(PAYLOAD_SIZE);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Test which pushes data every minute for 48 hours";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return null;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.java
new file mode 100644
index 0000000000..3e9582740d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreaming.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.STREAMING)
+public class ExtremelyLongPushTimeStreaming 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/ExtremelyLongPushTimeStreamingTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.java
new file mode 100644
index 0000000000..17837cb2d3
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeStreamingTest.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 ExtremelyLongPushTimeStreamingTest extends
+ ExtremelyLongPushTimeTest {
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java
new file mode 100644
index 0000000000..a1ce4b9d8f
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ExcludeFromSuite;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+@ExcludeFromSuite
+public abstract class ExtremelyLongPushTimeTest extends MultiBrowserTest {
+
+ private static final int ONE_HOUR_IN_MS = 20 * 1000;
+
+ @Test
+ public void test24HourPush() 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();
+
+ // Wait for startButton to be present
+ waitForElementToBePresent(vaadinLocatorById("startButton"));
+
+ String logRow0Id = "Log_row_0";
+ By logRow0 = vaadinLocatorById(logRow0Id);
+
+ // Start the test
+ vaadinElementById("startButton").click();
+
+ // Wait for push to start. Should take 60s
+ waitUntil(ExpectedConditions.textToBePresentInElement(logRow0,
+ "Package "), 120);
+
+ // Check every hour that push is still going on
+ for (int i = 0; i < 24; i++) {
+ sleep(ONE_HOUR_IN_MS);
+ ensureStillPushing(logRow0);
+ }
+
+ }
+
+ private void ensureStillPushing(By logRow0) {
+ String logValue = getDriver().findElement(logRow0).getText();
+ // Wait for the log value to change. Should take max 60s
+ waitUntilNot(
+ ExpectedConditions.textToBePresentInElement(logRow0, logValue),
+ 120);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.java
new file mode 100644
index 0000000000..8346d49234
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocket.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.WEBSOCKET)
+public class ExtremelyLongPushTimeWebsocket extends ExtremelyLongPushTime {
+
+ @Override
+ public void init(VaadinRequest request) {
+ super.init(request);
+ // Don't use fallback so we can easier detect if websocket fails
+ getPushConfiguration().setParameter(
+ PushConfigurationState.FALLBACK_TRANSPORT_PARAM, "none");
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java
new file mode 100644
index 0000000000..23d773c7da
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.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.push;
+
+import java.util.List;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.WebsocketTest;
+
+public class ExtremelyLongPushTimeWebsocketTest extends
+ ExtremelyLongPushTimeTest {
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return WebsocketTest.getWebsocketBrowsers();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.java
new file mode 100644
index 0000000000..f9a0a722e5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelStreamingTest.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 IdlePushChannelStreamingTest extends IdlePushChannelTest {
+ @Override
+ protected Class<?> getUIClass() {
+ return BasicPushStreaming.class;
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java
new file mode 100644
index 0000000000..4dcc8a680d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.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.tests.push;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+public abstract class IdlePushChannelTest extends MultiBrowserTest {
+
+ private static final int SEVEN_MINUTES_IN_MS = 7 * 60 * 1000;
+
+ @Test
+ public void longWaitBetweenActions() throws Exception {
+ openTestURL();
+ BasicPushTest.getIncrementButton(this).click();
+ Assert.assertEquals(1, BasicPushTest.getClientCounter(this));
+ sleep(SEVEN_MINUTES_IN_MS);
+ BasicPushTest.getIncrementButton(this).click();
+ Assert.assertEquals(2, BasicPushTest.getClientCounter(this));
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java
new file mode 100644
index 0000000000..3fd9c616fb
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.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.push;
+
+import java.util.List;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.tb3.WebsocketTest;
+
+public class IdlePushChannelWebsocketTest extends IdlePushChannelTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return BasicPushWebsocket.class;
+ }
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return WebsocketTest.getWebsocketBrowsers();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java b/uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.java
new file mode 100644
index 0000000000..81c974e1e5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/push/LongPollingReconnectTest.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 LongPollingReconnectTest extends PushReconnectTest {
+
+ @Override
+ protected Class<?> getUIClass() {
+ return BasicPushLongPolling.class;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/push/PushFromInit.java b/uitest/src/com/vaadin/tests/push/PushFromInit.java
index cb084f1232..0afaa866f7 100644
--- a/uitest/src/com/vaadin/tests/push/PushFromInit.java
+++ b/uitest/src/com/vaadin/tests/push/PushFromInit.java
@@ -15,29 +15,60 @@
*/
package com.vaadin.tests.push;
+import com.vaadin.annotations.Push;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Button;
+@Push
public class PushFromInit extends AbstractTestUIWithLog {
+ public static final String LOG_DURING_INIT = "Logged from access run before init ends";
+ public static final String LOG_AFTER_INIT = "Logged from background thread run after init has finished";
+
@Override
protected void setup(VaadinRequest request) {
- new Thread() {
- @Override
- public void run() {
- access(new Runnable() {
- @Override
- public void run() {
- log("Logged from background thread started in init");
- }
- });
- }
- }.start();
log("Logged in init");
+ Thread t = new Thread(new RunBeforeInitEnds());
+ t.start();
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ new Thread(new RunAfterInit()).start();
addComponent(new Button("Sync"));
}
+ class RunBeforeInitEnds implements Runnable {
+ @Override
+ public void run() {
+ access(new Runnable() {
+ @Override
+ public void run() {
+ log(LOG_DURING_INIT);
+ }
+ });
+ }
+ }
+
+ class RunAfterInit implements Runnable {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ access(new Runnable() {
+ @Override
+ public void run() {
+ log(LOG_AFTER_INIT);
+ }
+ });
+ }
+ }
+
@Override
protected String getTestDescription() {
return "Pusing something to a newly created UI should not cause race conditions";
diff --git a/uitest/src/com/vaadin/tests/push/PushFromInitTest.java b/uitest/src/com/vaadin/tests/push/PushFromInitTest.java
index 3c1bc1b610..4101de29cf 100644
--- a/uitest/src/com/vaadin/tests/push/PushFromInitTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushFromInitTest.java
@@ -15,8 +15,9 @@
*/
package com.vaadin.tests.push;
-import org.junit.Assert;
import org.junit.Test;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ui.ExpectedCondition;
import com.vaadin.tests.tb3.MultiBrowserTest;
@@ -25,26 +26,13 @@ public class PushFromInitTest extends MultiBrowserTest {
public void testPushFromInit() {
openTestURL();
- for (int second = 0;; second++) {
- if (second >= 30) {
- Assert.fail("timeout");
+ waitUntil(new ExpectedCondition<Boolean>() {
+ @Override
+ public Boolean apply(WebDriver input) {
+ return ("3. " + PushFromInit.LOG_AFTER_INIT)
+ .equals(getLogRow(0));
}
- try {
- if ("1. Logged in init".equals(vaadinElementById(
- "Log_row_1").getText())) {
- break;
- }
- } catch (Exception e) {
- }
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- }
- }
-
- Assert.assertEquals(
- "2. Logged from background thread started in init",
- vaadinElementById("Log_row_0").getText());
+ });
}
} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/push/PushLargeData.java b/uitest/src/com/vaadin/tests/push/PushLargeData.java
index 3b72424b32..83f573ed2c 100644
--- a/uitest/src/com/vaadin/tests/push/PushLargeData.java
+++ b/uitest/src/com/vaadin/tests/push/PushLargeData.java
@@ -51,14 +51,20 @@ public abstract class PushLargeData extends AbstractTestUIWithLog {
private final ExecutorService executor = Executors
.newSingleThreadExecutor();
+ protected TextField dataSize;
+
+ protected TextField interval;
+
+ protected TextField duration;
+
@Override
protected void setup(VaadinRequest request) {
dataLabel.setSizeUndefined();
- final TextField dataSize = new TextField("Data size");
+ dataSize = new TextField("Data size");
dataSize.setConverter(Integer.class);
- final TextField interval = new TextField("Interval (ms)");
+ interval = new TextField("Interval (ms)");
interval.setConverter(Integer.class);
- final TextField duration = new TextField("Duration (ms)");
+ duration = new TextField("Duration (ms)");
duration.setConverter(Integer.class);
dataSize.setValue(DEFAULT_SIZE_BYTES + "");
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/PushLargeDataStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java
index 8f10f0fbba..0d71c21118 100644
--- a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java
@@ -24,7 +24,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest;
public class PushLargeDataStreamingTest extends MultiBrowserTest {
@Test
- public void testStreamingLargeData() {
+ public void testStreamingLargeData() throws InterruptedException {
openTestURL();
// Without this there is a large chance that we will wait for all pushes
@@ -38,7 +38,7 @@ public class PushLargeDataStreamingTest extends MultiBrowserTest {
}
- private void push() {
+ private void push() throws InterruptedException {
// Wait for startButton to be present
waitForElementToBePresent(vaadinLocatorById("startButton"));
diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java
index 70a94f743e..cc8668a729 100644
--- a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java
@@ -24,7 +24,7 @@ import com.vaadin.tests.tb3.WebsocketTest;
public class PushLargeDataWebsocketTest extends WebsocketTest {
@Test
- public void testWebsocketLargeData() {
+ public void testWebsocketLargeData() throws Exception {
openTestURL();
// Without this timing will be completly off as pushing "start" can
@@ -38,7 +38,7 @@ public class PushLargeDataWebsocketTest extends WebsocketTest {
}
- private void push() {
+ private void push() throws Exception {
// Wait for startButton to be present
waitForElementToBePresent(vaadinLocatorById("startButton"));
diff --git a/uitest/src/com/vaadin/tests/push/TogglePushTest.java b/uitest/src/com/vaadin/tests/push/TogglePushTest.java
index 68d6f52b9f..1867f4a63a 100644
--- a/uitest/src/com/vaadin/tests/push/TogglePushTest.java
+++ b/uitest/src/com/vaadin/tests/push/TogglePushTest.java
@@ -24,7 +24,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest;
public class TogglePushTest extends MultiBrowserTest {
@Test
- public void togglePushInInit() {
+ public void togglePushInInit() throws Exception {
setPush(true);
String url = getTestUrl();
@@ -58,7 +58,7 @@ public class TogglePushTest extends MultiBrowserTest {
}
@Test
- public void togglePush() {
+ public void togglePush() throws InterruptedException {
setPush(true);
openTestURL();
getDelayedCounterUpdateButton().click();
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/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
index d7b7cd050f..55a2b80918 100644
--- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
+++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
@@ -28,9 +28,13 @@ import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
+import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.HasInputDevices;
+import org.openqa.selenium.interactions.Keyboard;
+import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
@@ -74,6 +78,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
*/
private static final int SCREENSHOT_WIDTH = 1500;
+ /**
+ * Timeout used by the TB grid
+ */
+ private static final int BROWSER_TIMEOUT_IN_MS = 30 * 1000;
+
private DesiredCapabilities desiredCapabilities;
private boolean debug = false;
@@ -270,6 +279,21 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
/**
+ * Uses JavaScript to determine the currently focused element.
+ *
+ * @return Focused element or null
+ */
+ protected WebElement getFocusedElement() {
+ Object focusedElement = ((JavascriptExecutor) getDriver())
+ .executeScript("return document.activeElement");
+ if (null != focusedElement) {
+ return (WebElement) focusedElement;
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Find a Vaadin element based on its id given using Component.setId
*
* @param id
@@ -641,17 +665,21 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
/**
- * Helper method for sleeping X ms in a test. Catches and ignores
- * InterruptedExceptions
+ * Sleeps for the given number of ms but ensures that the browser connection
+ * does not time out.
*
* @param timeoutMillis
* Number of ms to wait
+ * @throws InterruptedException
*/
- protected void sleep(int timeoutMillis) {
- try {
- Thread.sleep(timeoutMillis);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
+ protected void sleep(int timeoutMillis) throws InterruptedException {
+ while (timeoutMillis > 0) {
+ int d = Math.min(BROWSER_TIMEOUT_IN_MS, timeoutMillis);
+ Thread.sleep(d);
+ timeoutMillis -= d;
+
+ // Do something to keep the connection alive
+ getDriver().getTitle();
}
}
@@ -882,4 +910,22 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
+ /**
+ * Returns the mouse object for doing mouse commands
+ *
+ * @return Returns the mouse
+ */
+ public Mouse getMouse() {
+ return ((HasInputDevices) getDriver()).getMouse();
+ }
+
+ /**
+ * Returns the keyboard object for controlling keyboard events
+ *
+ * @return Return the keyboard
+ */
+ public Keyboard getKeyboard() {
+ return ((HasInputDevices) getDriver()).getKeyboard();
+ }
+
}
diff --git a/uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java b/uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java
new file mode 100644
index 0000000000..722b643f78
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/ExcludeFromSuite.java
@@ -0,0 +1,28 @@
+/*
+ * 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.tb3;
+
+/**
+ * Marker interface for a TB3+ test class which will exclude the test from any
+ * test suite which automatically scans for test classes. Mostly useful for long
+ * tests which should not be run in every build.
+ *
+ * @since 7.1.10
+ * @author Vaadin Ltd
+ */
+public @interface ExcludeFromSuite {
+
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
index e1c8edfd60..f1576a9393 100644
--- a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
+++ b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
@@ -223,6 +223,10 @@ public class TB3TestSuite extends Suite {
if (!baseClass.isAssignableFrom(c)) {
return;
}
+ if (!includeInSuite(c)) {
+ return;
+ }
+
if (!Modifier.isAbstract(c.getModifiers()) && !c.isAnonymousClass()) {
result.add((Class<? extends T>) c);
}
@@ -235,4 +239,18 @@ public class TB3TestSuite extends Suite {
}
+ /**
+ * @return true if the class should be included in the suite, false if not
+ */
+ private static boolean includeInSuite(Class<?> c) {
+ if (c.getAnnotation(ExcludeFromSuite.class) != null) {
+ return false;
+ }
+ if (c == Object.class) {
+ return true;
+ }
+
+ return includeInSuite(c.getSuperclass());
+ }
+
} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassConnector.java
new file mode 100644
index 0000000000..fb28e94bfa
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassConnector.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.widgetset.client;
+
+import com.vaadin.client.ui.label.LabelConnector;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.MediaControl;
+import com.vaadin.tests.widgetset.server.ClientRpcClassComponent;
+
+@Connect(ClientRpcClassComponent.class)
+public class ClientRpcClassConnector extends LabelConnector {
+
+ @Override
+ protected void init() {
+ super.init();
+ registerRpc(MediaControl.class, getWidget());
+ }
+
+ @Override
+ public ClientRpcClassWidget getWidget() {
+ return (ClientRpcClassWidget) super.getWidget();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassWidget.java
new file mode 100644
index 0000000000..91b4f19d92
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/client/ClientRpcClassWidget.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.VLabel;
+import com.vaadin.shared.ui.MediaControl;
+
+public class ClientRpcClassWidget extends VLabel implements MediaControl {
+
+ @Override
+ public void play() {
+ setText("play");
+ }
+
+ @Override
+ public void pause() {
+ setText("pause");
+ }
+
+}
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/ClientRpcClass.java b/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClass.java
new file mode 100644
index 0000000000..cbc46b26f5
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClass.java
@@ -0,0 +1,47 @@
+/*
+ * 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.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.tests.widgetset.TestingWidgetSet;
+
+@Widgetset(TestingWidgetSet.NAME)
+public class ClientRpcClass extends AbstractTestUI {
+
+ public static String TEST_COMPONENT_ID = "testComponent";
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ ClientRpcClassComponent component = new ClientRpcClassComponent();
+ component.setId(TEST_COMPONENT_ID);
+ addComponent(component);
+
+ component.pause();
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "UI showing dummy component where the wiget type is implementing the RPC interface.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return Integer.valueOf(13056);
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassComponent.java b/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassComponent.java
new file mode 100644
index 0000000000..135f112fe4
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassComponent.java
@@ -0,0 +1,29 @@
+/*
+ * 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.shared.ui.MediaControl;
+import com.vaadin.ui.Label;
+
+public class ClientRpcClassComponent extends Label {
+ public void play() {
+ getRpcProxy(MediaControl.class).play();
+ }
+
+ public void pause() {
+ getRpcProxy(MediaControl.class).pause();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassTest.java b/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassTest.java
new file mode 100644
index 0000000000..16c5ba4b61
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/widgetset/server/ClientRpcClassTest.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.widgetset.server;
+
+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 ClientRpcClassTest extends MultiBrowserTest {
+
+ @Test
+ public void pauseDisplayed() {
+ openTestURL();
+
+ WebElement element = getDriver().findElement(
+ By.id(ClientRpcClass.TEST_COMPONENT_ID));
+ Assert.assertEquals("pause", element.getText());
+ }
+}