import com.vaadin.client.widgets.Escalator.AbstractRowContainer; | import com.vaadin.client.widgets.Escalator.AbstractRowContainer; | ||||
import com.vaadin.client.widgets.Escalator.SubPartArguments; | import com.vaadin.client.widgets.Escalator.SubPartArguments; | ||||
import com.vaadin.client.widgets.Grid.Editor.State; | import com.vaadin.client.widgets.Grid.Editor.State; | ||||
import com.vaadin.client.widgets.Grid.StaticSection.StaticCell; | |||||
import com.vaadin.client.widgets.Grid.StaticSection.StaticRow; | import com.vaadin.client.widgets.Grid.StaticSection.StaticRow; | ||||
import com.vaadin.shared.Range; | import com.vaadin.shared.Range; | ||||
import com.vaadin.shared.Registration; | import com.vaadin.shared.Registration; | ||||
@Override | @Override | ||||
public void onDrop() { | public void onDrop() { | ||||
final int draggedColumnIndex = eventCell.getColumnIndex(); | final int draggedColumnIndex = eventCell.getColumnIndex(); | ||||
final int colspan = header.getRow(eventCell.getRowIndex()) | |||||
.getCell(eventCell.getColumn()).getColspan(); | |||||
final StaticRow<?> draggedCellRow = header | |||||
.getRow(eventCell.getRowIndex()); | |||||
int colspan = draggedCellRow | |||||
.getSizeOfCellGroup(getColumn(draggedColumnIndex)); | |||||
colspan = colspan == 0 ? 1 : colspan; | |||||
if (latestColumnDropIndex != draggedColumnIndex | if (latestColumnDropIndex != draggedColumnIndex | ||||
&& latestColumnDropIndex != draggedColumnIndex + colspan) { | && latestColumnDropIndex != draggedColumnIndex + colspan) { | ||||
List<Column<?, T>> columns = getColumns(); | List<Column<?, T>> columns = getColumns(); | ||||
} | } | ||||
final boolean isDraggedCellRow = row.equals(draggedCellRow); | final boolean isDraggedCellRow = row.equals(draggedCellRow); | ||||
for (int cellColumnIndex = frozenColumns; cellColumnIndex < getColumnCount(); cellColumnIndex++) { | for (int cellColumnIndex = frozenColumns; cellColumnIndex < getColumnCount(); cellColumnIndex++) { | ||||
StaticCell cell = row.getCell(getColumn(cellColumnIndex)); | |||||
int colspan = cell.getColspan(); | |||||
int colspan = row | |||||
.getSizeOfCellGroup(getColumn(cellColumnIndex)); | |||||
if (colspan <= 1) { | if (colspan <= 1) { | ||||
continue; | continue; | ||||
} | } | ||||
final int cellColumnRightIndex = cellColumnIndex + row | |||||
.getSizeOfCellGroup(getColumn(cellColumnIndex)); | |||||
final int cellColumnRightIndex = cellColumnIndex + colspan; | |||||
final Range cellRange = Range.between(cellColumnIndex, | final Range cellRange = Range.between(cellColumnIndex, | ||||
cellColumnRightIndex); | cellColumnRightIndex); | ||||
final boolean intersects = draggedCellRange | final boolean intersects = draggedCellRange |
@Override | @Override | ||||
public void onDrop() { | public void onDrop() { | ||||
final int draggedColumnIndex = eventCell.getColumnIndex(); | final int draggedColumnIndex = eventCell.getColumnIndex(); | ||||
final int colspan = header.getRow(eventCell.getRowIndex()) | |||||
.getCell(eventCell.getColumn()).getColspan(); | |||||
final StaticRow<?> draggedCellRow = header | |||||
.getRow(eventCell.getRowIndex()); | |||||
Set<Column<?, ?>> cellGroup = draggedCellRow | |||||
.getCellGroupForColumn(getColumn(draggedColumnIndex)); | |||||
final int colspan = cellGroup == null ? 1 : cellGroup.size(); | |||||
if (latestColumnDropIndex != draggedColumnIndex | if (latestColumnDropIndex != draggedColumnIndex | ||||
&& latestColumnDropIndex != draggedColumnIndex + colspan) { | && latestColumnDropIndex != draggedColumnIndex + colspan) { | ||||
List<Column<?, T>> columns = getColumns(); | List<Column<?, T>> columns = getColumns(); |
<!-- Used in OSGi manifests --> | <!-- Used in OSGi manifests --> | ||||
<javax.validation.version>2.0.1.Final</javax.validation.version> | <javax.validation.version>2.0.1.Final</javax.validation.version> | ||||
<jsoup.version>1.14.2</jsoup.version> | |||||
<jsoup.version>1.14.3</jsoup.version> | |||||
<javax.portlet.version>2.0</javax.portlet.version> | <javax.portlet.version>2.0</javax.portlet.version> | ||||
<vaadin.sass.version>0.9.13</vaadin.sass.version> | <vaadin.sass.version>0.9.13</vaadin.sass.version> | ||||
<!-- Note that this should be kept in sync with the class Constants --> | <!-- Note that this should be kept in sync with the class Constants --> |
return createTableRow(traffic_light.format(color="black"), "Test status: unable to retrieve status of tests") | return createTableRow(traffic_light.format(color="black"), "Test status: unable to retrieve status of tests") | ||||
else: | else: | ||||
test_failures_json = test_failures_request.json() | test_failures_json = test_failures_request.json() | ||||
if test_failures_json["count"] == 0: | |||||
# nowadays the responds doesn't contain count keyword when the build is successful | |||||
# while count word can be found when build fails | |||||
if "count" not in test_failures_json: | |||||
return createTableRow(traffic_light.format(color="green"), "Test status: all tests passing") | return createTableRow(traffic_light.format(color="green"), "Test status: all tests passing") | ||||
else: | else: | ||||
return createTableRow(traffic_light.format(color="red"), "Test status: there are " + str(test_failures_json["count"]) + " failing tests, <a href={}>check the build report</a>".format(buildResultUrl)) | return createTableRow(traffic_light.format(color="red"), "Test status: there are " + str(test_failures_json["count"]) + " failing tests, <a href={}>check the build report</a>".format(buildResultUrl)) |
if archetype_metadata_request.status_code != 200: | if archetype_metadata_request.status_code != 200: | ||||
return createTableRow(traffic_light.format(color="black"), "Check archetype metadata: <a href='{url}'>unable to retrieve metadata from {url}</a>".format(url=archetypeMetadataUrl)) | return createTableRow(traffic_light.format(color="black"), "Check archetype metadata: <a href='{url}'>unable to retrieve metadata from {url}</a>".format(url=archetypeMetadataUrl)) | ||||
else: | else: | ||||
if "version=\"{version}\"".format(version=version) in archetype_metadata_request.content: | |||||
if "version=\"{version}\"".format(version=version) in archetype_metadata_request.text: | |||||
return createTableRow(traffic_light.format(color="green"), "Check archetype metadata: <a href='{url}'>metadata is correct for {url}</a>".format(url=archetypeMetadataUrl)) | return createTableRow(traffic_light.format(color="green"), "Check archetype metadata: <a href='{url}'>metadata is correct for {url}</a>".format(url=archetypeMetadataUrl)) | ||||
else: | else: | ||||
return createTableRow(traffic_light.format(color="red"), "Check archetype metadata: <a href='{url}'>metadata seems to be incorrect for {url}</a>".format(url=archetypeMetadataUrl)) | return createTableRow(traffic_light.format(color="red"), "Check archetype metadata: <a href='{url}'>metadata seems to be incorrect for {url}</a>".format(url=archetypeMetadataUrl)) | ||||
content += "</table></body></html>" | content += "</table></body></html>" | ||||
with open("result/report.html", "wb") as f: | |||||
with open("result/report.html", "w") as f: | |||||
f.write(content) | f.write(content) |
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||||
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0 | Bundle-License: http://www.apache.org/licenses/LICENSE-2.0 | ||||
Import-Package: com.vaadin.sass.*;resolution:=optional,\ | Import-Package: com.vaadin.sass.*;resolution:=optional,\ | ||||
com.liferay.portal.kernel.util;resolution:=optional;version='[7.0.0,13.0.0)',\ | |||||
com.liferay.portal.kernel.util;resolution:=optional;version='[7.0.0,17.0.0)',\ | |||||
javax.portlet*;resolution:=optional,\ | javax.portlet*;resolution:=optional,\ | ||||
javax.validation*;resolution:=optional;version='${javax.validation.version}',\ | javax.validation*;resolution:=optional;version='${javax.validation.version}',\ | ||||
org.atmosphere*;resolution:=optional;version='${atmosphere.runtime.version}',\ | org.atmosphere*;resolution:=optional;version='${atmosphere.runtime.version}',\ |
/** | /** | ||||
* Sets the field value by invoking the getter function on the given | * Sets the field value by invoking the getter function on the given | ||||
* bean. The default listener attached to the field will be removed for | |||||
* the duration of this update. | |||||
* bean. | |||||
* | * | ||||
* @param bean | * @param bean | ||||
* the bean to fetch the property value from | * the bean to fetch the property value from | ||||
*/ | */ | ||||
private void initFieldValue(BEAN bean, boolean writeBackChangedValues) { | private void initFieldValue(BEAN bean, boolean writeBackChangedValues) { | ||||
assert bean != null; | assert bean != null; | ||||
assert onValueChange != null; | |||||
valueInit = true; | valueInit = true; | ||||
try { | try { | ||||
TARGET originalValue = getter.apply(bean); | TARGET originalValue = getter.apply(bean); | ||||
convertAndSetFieldValue(originalValue); | convertAndSetFieldValue(originalValue); | ||||
if (writeBackChangedValues && setter != null) { | |||||
if (writeBackChangedValues && setter != null && !readOnly) { | |||||
doConversion().ifOk(convertedValue -> { | doConversion().ifOk(convertedValue -> { | ||||
if (!Objects.equals(originalValue, convertedValue)) { | if (!Objects.equals(originalValue, convertedValue)) { | ||||
setter.accept(bean, convertedValue); | setter.accept(bean, convertedValue); | ||||
if (bean == null) { | if (bean == null) { | ||||
clearFields(); | clearFields(); | ||||
} else { | } else { | ||||
changedBindings.clear(); | |||||
getBindings().forEach(binding -> { | getBindings().forEach(binding -> { | ||||
// Some bindings may have been removed from binder | // Some bindings may have been removed from binder | ||||
// during readBean. We should skip those bindings to | // during readBean. We should skip those bindings to | ||||
binding.initFieldValue(bean, false); | binding.initFieldValue(bean, false); | ||||
} | } | ||||
}); | }); | ||||
changedBindings.clear(); | |||||
getValidationStatusHandler().statusChange( | getValidationStatusHandler().statusChange( | ||||
BinderValidationStatus.createUnresolvedStatus(this)); | BinderValidationStatus.createUnresolvedStatus(this)); | ||||
fireStatusChangeEvent(false); | fireStatusChangeEvent(false); | ||||
* updated, {@code false} otherwise | * updated, {@code false} otherwise | ||||
*/ | */ | ||||
public boolean writeBeanIfValid(BEAN bean) { | public boolean writeBeanIfValid(BEAN bean) { | ||||
return doWriteIfValid(bean, new ArrayList<>(bindings)).isOk(); | |||||
return doWriteIfValid(bean, bindings).isOk(); | |||||
} | } | ||||
/** | /** | ||||
Objects.requireNonNull(bean, "bean cannot be null"); | Objects.requireNonNull(bean, "bean cannot be null"); | ||||
List<ValidationResult> binderResults = Collections.emptyList(); | List<ValidationResult> binderResults = Collections.emptyList(); | ||||
// make a copy of the incoming bindings to avoid their modifications | |||||
// during validation | |||||
Collection<Binding<BEAN, ?>> currentBindings = new ArrayList<>( | |||||
bindings); | |||||
// First run fields level validation, if no validation errors then | // First run fields level validation, if no validation errors then | ||||
// update bean | // update bean | ||||
List<BindingValidationStatus<?>> bindingResults = bindings.stream() | |||||
.map(b -> b.validate(false)).collect(Collectors.toList()); | |||||
List<BindingValidationStatus<?>> bindingResults = currentBindings | |||||
.stream().map(b -> b.validate(false)) | |||||
.collect(Collectors.toList()); | |||||
if (bindingResults.stream() | if (bindingResults.stream() | ||||
.noneMatch(BindingValidationStatus::isError)) { | .noneMatch(BindingValidationStatus::isError)) { | ||||
// Store old bean values so we can restore them if validators fail | // Store old bean values so we can restore them if validators fail | ||||
Map<Binding<BEAN, ?>, Object> oldValues = getBeanState(bean, | Map<Binding<BEAN, ?>, Object> oldValues = getBeanState(bean, | ||||
bindings); | |||||
currentBindings); | |||||
bindings.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding) | |||||
.writeFieldValue(bean)); | |||||
currentBindings | |||||
.forEach(binding -> ((BindingImpl<BEAN, ?, ?>) binding) | |||||
.writeFieldValue(bean)); | |||||
// Now run bean level validation against the updated bean | // Now run bean level validation against the updated bean | ||||
binderResults = validateBean(bean); | binderResults = validateBean(bean); | ||||
if (binderResults.stream().anyMatch(ValidationResult::isError)) { | if (binderResults.stream().anyMatch(ValidationResult::isError)) { | ||||
* Changes have been successfully saved. The set is only cleared | * Changes have been successfully saved. The set is only cleared | ||||
* when the changes are stored in the currently set bean. | * when the changes are stored in the currently set bean. | ||||
*/ | */ | ||||
bindings.clear(); | |||||
changedBindings.clear(); | |||||
} else if (getBean() == null) { | } else if (getBean() == null) { | ||||
/* | /* | ||||
* When using readBean and writeBean there is no knowledge of | * When using readBean and writeBean there is no knowledge of |
public class DataCommunicator<T> extends AbstractExtension { | public class DataCommunicator<T> extends AbstractExtension { | ||||
private Registration dataProviderUpdateRegistration; | private Registration dataProviderUpdateRegistration; | ||||
private static final int MAXIMUM_ALLOWED_ROWS = 500; | |||||
private int maximumAllowedRows = 500; | |||||
/** | /** | ||||
* Simple implementation of collection data provider communication. All data | * Simple implementation of collection data provider communication. All data | ||||
} | } | ||||
/** | /** | ||||
* Set the maximum allowed rows to be fetched in one query. | |||||
* Get the maximum allowed rows to be fetched in one query. | |||||
* | * | ||||
* @return Maximum allowed rows for one query. | * @return Maximum allowed rows for one query. | ||||
* @since 8.14.1 | * @since 8.14.1 | ||||
*/ | */ | ||||
protected int getMaximumAllowedRows() { | protected int getMaximumAllowedRows() { | ||||
return MAXIMUM_ALLOWED_ROWS; | |||||
} | |||||
return maximumAllowedRows; | |||||
} | |||||
/** | |||||
* Set the maximum allowed rows to be fetched in one query. | |||||
* | |||||
* @param maximumAllowedRows Maximum allowed rows for one query. | |||||
* @since | |||||
*/ | |||||
public void setMaximumAllowedRows(int maximumAllowedRows) { | |||||
this.maximumAllowedRows = maximumAllowedRows; | |||||
} | |||||
/** | /** | ||||
* Triggered when rows have been dropped from the client side cache. | * Triggered when rows have been dropped from the client side cache. |
target.addText(css); | target.addText(css); | ||||
target.endTag("css-string"); | target.endTag("css-string"); | ||||
} | } | ||||
@Override | |||||
public boolean equals(Object obj) { | |||||
if (obj == this) { | |||||
return true; | |||||
} else if (obj instanceof InjectedStyleString) { | |||||
InjectedStyleString that = (InjectedStyleString) obj; | |||||
return css.equals(that.css); | |||||
} else { | |||||
return false; | |||||
} | |||||
} | |||||
@Override | |||||
public int hashCode() { | |||||
return css.hashCode(); | |||||
} | |||||
} | } | ||||
private static class InjectedStyleResource implements InjectedStyle { | private static class InjectedStyleResource implements InjectedStyle { | ||||
*/ | */ | ||||
public static class Styles implements Serializable { | public static class Styles implements Serializable { | ||||
private LinkedHashSet<InjectedStyle> injectedStyles = new LinkedHashSet<>(); | |||||
// For internal use only, visibility is package for enabling testing | |||||
LinkedHashSet<InjectedStyle> injectedStyles = new LinkedHashSet<>(); | |||||
private LinkedHashSet<InjectedStyle> pendingInjections = new LinkedHashSet<>(); | |||||
// For internal use only, visibility is package for enabling testing | |||||
LinkedHashSet<InjectedStyle> pendingInjections = new LinkedHashSet<>(); | |||||
private final UI ui; | private final UI ui; | ||||
"Cannot inject null CSS string"); | "Cannot inject null CSS string"); | ||||
} | } | ||||
pendingInjections.add(new InjectedStyleString(css)); | |||||
ui.markAsDirty(); | |||||
InjectedStyleString injectedStyleString = new InjectedStyleString( | |||||
css); | |||||
if (!injectedStyles.contains(injectedStyleString) | |||||
&& pendingInjections.add(injectedStyleString)) { | |||||
ui.markAsDirty(); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Sets the page title. The page title is displayed by the browser e.g. as | * Sets the page title. The page title is displayed by the browser e.g. as | ||||
* the title of the browser window or as the title of the tab. | * the title of the browser window or as the title of the tab. | ||||
* <p> | * <p> | ||||
* If the title is set to null, it will not left as-is. Set to empty string | |||||
* to clear the title. | |||||
* If this value is set to null, the previously set page title will be left | |||||
* as-is. Set to empty string to clear the title. | |||||
* | * | ||||
* @param title | * @param title | ||||
* the page title to set | * the page title to set |
import static org.junit.Assert.assertTrue; | import static org.junit.Assert.assertTrue; | ||||
import static org.junit.Assert.fail; | import static org.junit.Assert.fail; | ||||
import java.io.Serializable; | |||||
import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
import java.text.DecimalFormat; | import java.text.DecimalFormat; | ||||
import java.text.NumberFormat; | import java.text.NumberFormat; | ||||
assertEquals(new Double(2000), item.getSalaryDouble()); | assertEquals(new Double(2000), item.getSalaryDouble()); | ||||
} | } | ||||
// See: https://github.com/vaadin/framework/issues/9581 | |||||
@Test | |||||
public void withConverter_hasChangesFalse() { | |||||
TextField nameField = new TextField(); | |||||
nameField.setValue(""); | |||||
TextField rentField = new TextField(); | |||||
rentField.setValue(""); | |||||
rentField.addValueChangeListener(event -> { | |||||
nameField.setValue("Name"); | |||||
}); | |||||
item.setRent(BigDecimal.valueOf(10)); | |||||
binder.forField(nameField).bind(Person::getFirstName, Person::setFirstName); | |||||
binder.forField(rentField).withConverter(new EuroConverter("")) | |||||
.withNullRepresentation(BigDecimal.valueOf(0d)) | |||||
.bind(Person::getRent, Person::setRent); | |||||
binder.readBean(item); | |||||
assertFalse(binder.hasChanges()); | |||||
assertEquals("€ 10.00", rentField.getValue()); | |||||
assertEquals("Name", nameField.getValue()); | |||||
} | |||||
@Test | |||||
public void invalidUsage_modifyFieldsInsideValidator_binderDoesNotThrow() { | |||||
TextField field = new TextField(); | |||||
AtomicBoolean validatorIsExecuted = new AtomicBoolean(); | |||||
binder.forField(field).asRequired().withValidator((val, context) -> { | |||||
nameField.setValue("foo"); | |||||
ageField.setValue("bar"); | |||||
validatorIsExecuted.set(true); | |||||
return ValidationResult.ok(); | |||||
}).bind(Person::getEmail, Person::setEmail); | |||||
binder.forField(nameField).bind(Person::getFirstName, | |||||
Person::setFirstName); | |||||
binder.forField(ageField).bind(Person::getLastName, | |||||
Person::setLastName); | |||||
binder.setBean(new Person()); | |||||
field.setValue("baz"); | |||||
// mostly self control, the main check is: not exception is thrown | |||||
assertTrue(validatorIsExecuted.get()); | |||||
} | |||||
public void setBean_readOnlyBinding_propertyBinding_valueIsNotUpdated() { | |||||
Binder<ExampleBean> binder = new Binder<>(ExampleBean.class); | |||||
binder.forField(nameField).withNullRepresentation("") | |||||
.withConverter(new TestConverter()).bind("vals") | |||||
.setReadOnly(true); | |||||
ExampleBean bean = new ExampleBean(); | |||||
SubPropClass val = new SubPropClass(); | |||||
bean.setVals(val); | |||||
binder.setBean(bean); | |||||
assertSame(val, bean.getVals()); | |||||
} | |||||
@Test | |||||
public void setBean_readOnlyBinding_accessorsBiding_valueIsNotUpdated() { | |||||
Binder<ExampleBean> binder = new Binder<>(ExampleBean.class); | |||||
binder.forField(nameField).withNullRepresentation("") | |||||
.withConverter(new TestConverter()) | |||||
.bind(ExampleBean::getVals, ExampleBean::setVals) | |||||
.setReadOnly(true); | |||||
ExampleBean bean = new ExampleBean(); | |||||
SubPropClass val = new SubPropClass(); | |||||
bean.setVals(val); | |||||
binder.setBean(bean); | |||||
assertSame(val, bean.getVals()); | |||||
} | |||||
public static class ExampleBean implements Serializable { | |||||
private SubPropClass vals; | |||||
public SubPropClass getVals() { | |||||
return vals; | |||||
} | |||||
public void setVals(SubPropClass vals) { | |||||
this.vals = vals; | |||||
} | |||||
} | |||||
public static class SubPropClass implements Serializable { | |||||
private String val1 = "Val1"; | |||||
@Override | |||||
public String toString() { | |||||
return val1; | |||||
} | |||||
} | |||||
public static class TestConverter | |||||
implements Converter<String, SubPropClass> { | |||||
@Override | |||||
public Result<SubPropClass> convertToModel(String value, | |||||
ValueContext context) { | |||||
return Result.ok(null); | |||||
} | |||||
@Override | |||||
public String convertToPresentation(SubPropClass value, | |||||
ValueContext context) { | |||||
return value != null ? value.toString() : null; | |||||
} | |||||
}; | |||||
private TextField createNullAnd42RejectingFieldWithEmptyValue( | private TextField createNullAnd42RejectingFieldWithEmptyValue( | ||||
String emptyValue) { | String emptyValue) { | ||||
return new TextField() { | return new TextField() { |
communicator.onRequestRows(0, communicator.getMaximumAllowedRows() + 10, | communicator.onRequestRows(0, communicator.getMaximumAllowedRows() + 10, | ||||
0, 0); | 0, 0); | ||||
} | } | ||||
@Test | |||||
public void requestTooMuchRowsOverride() { | |||||
TestDataCommunicator communicator = new TestDataCommunicator(); | |||||
int maxRows = communicator.getMaximumAllowedRows(); | |||||
communicator.setMaximumAllowedRows(maxRows + 100); | |||||
communicator.onRequestRows(0, maxRows + 10, 0, 0); | |||||
} | |||||
} | } |
package com.vaadin.server; | package com.vaadin.server; | ||||
import static org.junit.Assert.assertEquals; | |||||
import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertFalse; | ||||
import java.io.Writer; | |||||
import org.easymock.EasyMock; | import org.easymock.EasyMock; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
page.getState(false).hasResizeListeners); | page.getState(false).hasResizeListeners); | ||||
} | } | ||||
@Test | |||||
public void cssStringInjectedTwice() throws PaintException { | |||||
TestPage page = new TestPage(EasyMock.createMock(UI.class), | |||||
EasyMock.createMock(PageState.class)); | |||||
JsonPaintTarget paintTarget = new JsonPaintTarget( | |||||
EasyMock.createMock(LegacyCommunicationManager.class), | |||||
EasyMock.createMock(Writer.class), true); | |||||
page.getStyles().add(".my-style { color: red; }"); | |||||
assertEquals(page.getStyles().pendingInjections.size(), 1); | |||||
page.paintContent(paintTarget); | |||||
assertEquals(page.getStyles().pendingInjections.size(), 0); | |||||
assertEquals(page.getStyles().injectedStyles.size(), 1); | |||||
page.getStyles().add(".my-style { color: red; }"); | |||||
assertEquals(page.getStyles().pendingInjections.size(), 0); | |||||
page.paintContent(paintTarget); | |||||
assertEquals(page.getStyles().pendingInjections.size(), 0); | |||||
assertEquals(page.getStyles().injectedStyles.size(), 1); | |||||
} | |||||
private static class TestPage extends Page { | private static class TestPage extends Page { | ||||
public TestPage(UI uI, PageState state) { | public TestPage(UI uI, PageState state) { |
<packaging>war</packaging> | <packaging>war</packaging> | ||||
<properties> | <properties> | ||||
<jetty.skip>false</jetty.skip> | <jetty.skip>false</jetty.skip> | ||||
<jetty.version>9.3.21.v20170918</jetty.version> | |||||
<jetty.version>9.4.38.v20210224</jetty.version> | |||||
<server.name>jetty9</server.name> | <server.name>jetty9</server.name> | ||||
</properties> | </properties> | ||||
* | * | ||||
* @group table | * @group table | ||||
*/ | */ | ||||
$v-table-row-height: $v-unit-size !default; | |||||
$v-table-border-width: first-number($v-border) !default; | |||||
/** | /** | ||||
* | * | ||||
* @group table | * @group table | ||||
*/ | */ | ||||
$v-table-border-width: first-number($v-border) !default; | |||||
$v-table-row-height: $v-unit-size !default; | |||||
$v-table-body-row-height: round($v-table-row-height + $v-table-border-width) !default; | |||||
/** | /** | ||||
* | * | ||||
.#{$primary-stylename}-cell-content { | .#{$primary-stylename}-cell-content { | ||||
border-left: $v-table-border-width solid $border-color; | border-left: $v-table-border-width solid $border-color; | ||||
overflow: hidden; | overflow: hidden; | ||||
height: $v-table-row-height; | |||||
height: $v-table-body-row-height; | |||||
vertical-align: middle; | vertical-align: middle; | ||||
&:first-child { | &:first-child { | ||||
.#{$primary-stylename}-table td { | .#{$primary-stylename}-table td { | ||||
border-top: $v-table-border-width solid $border-color; | border-top: $v-table-border-width solid $border-color; | ||||
box-sizing: border-box; | |||||
} | } | ||||
.#{$primary-stylename}-table tr:first-child > td { | .#{$primary-stylename}-table tr:first-child > td { | ||||
height: $v-table-row-height; | |||||
border-top: none; | border-top: none; | ||||
} | } | ||||
.#{$primary-stylename}-row-drag-bottom td.#{$primary-stylename}-cell-content { | .#{$primary-stylename}-row-drag-bottom td.#{$primary-stylename}-cell-content { | ||||
border-bottom: 2px solid $v-focus-color; | border-bottom: 2px solid $v-focus-color; | ||||
height: $v-table-row-height - 2px; | |||||
height: $v-table-body-row-height - 2px; | |||||
} | } | ||||
.#{$primary-stylename}-row-drag-bottom .#{$primary-stylename}-cell-wrapper { | .#{$primary-stylename}-row-drag-bottom .#{$primary-stylename}-cell-wrapper { | ||||
.#{$primary-stylename}-row-drag-top td.#{$primary-stylename}-cell-content { | .#{$primary-stylename}-row-drag-top td.#{$primary-stylename}-cell-content { | ||||
border-top: 2px solid $v-focus-color; | border-top: 2px solid $v-focus-color; | ||||
height: $v-table-row-height - 2px + $v-table-border-width; | |||||
height: $v-table-body-row-height - 2px + $v-table-border-width; | |||||
} | } | ||||
.#{$primary-stylename}-row-drag-top .#{$primary-stylename}-cell-wrapper { | .#{$primary-stylename}-row-drag-top .#{$primary-stylename}-cell-wrapper { | ||||
.#{$primary-stylename}-row-drag-top .#{$primary-stylename}-cell-content, | .#{$primary-stylename}-row-drag-top .#{$primary-stylename}-cell-content, | ||||
.#{$primary-stylename}-row-drag-bottom .#{$primary-stylename}-cell-content { | .#{$primary-stylename}-row-drag-bottom .#{$primary-stylename}-cell-content { | ||||
height: $v-table-row-height - 1px; | |||||
height: $v-table-body-row-height - 1px; | |||||
} | } | ||||
} | } | ||||