Revision: 9956
Author: jlaba...@google.com
Date: Thu Apr 7 07:38:23 2011
Log: Cherry picking r9954 into releases/2.3 for issues 5971, 5993, and
6134.
http://code.google.com/p/google-web-toolkit/source/detail?r=9956
Added:
/releases/2.3/user/src/com/google/gwt/user/cellview/client/CellBasedWidgetImplStandardBase.java
Deleted:
/releases/2.3/user/src/com/google/gwt/user/cellview/client/CellBasedWidgetImplSafari.java
Modified:
/releases/2.3/tools/api-checker/config/gwt22_23userApi.conf
/releases/2.3/user/src/com/google/gwt/cell/client/CompositeCell.java
/releases/2.3/user/src/com/google/gwt/cell/client/EditTextCell.java
/releases/2.3/user/src/com/google/gwt/cell/client/TextInputCell.java
/releases/2.3/user/src/com/google/gwt/user/cellview/CellView.gwt.xml
/releases/2.3/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java
/releases/2.3/user/test/com/google/gwt/cell/client/CompositeCellTest.java
/releases/2.3/user/test/com/google/gwt/cell/client/EditTextCellTest.java
/releases/2.3/user/test/com/google/gwt/cell/client/TextInputCellTest.java
/releases/2.3/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java
=======================================
--- /dev/null
+++
/releases/2.3/user/src/com/google/gwt/user/cellview/client/CellBasedWidgetImplStandardBase.java
Thu Apr 7 07:38:23 2011
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * 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.google.gwt.user.cellview.client;
+
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;
+
+/**
+ * StandardBase implementation of {@link CellBasedWidgetImpl}.
+ */
+public class CellBasedWidgetImplStandardBase extends
CellBasedWidgetImplStandard {
+
+ @Override
+ public void resetFocus(ScheduledCommand command) {
+ // Some browsers will not focus an element that was created in this
event loop.
+ Scheduler.get().scheduleDeferred(command);
+ }
+}
=======================================
---
/releases/2.3/user/src/com/google/gwt/user/cellview/client/CellBasedWidgetImplSafari.java
Wed Oct 13 12:59:56 2010
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2010 Google Inc.
- *
- * 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.google.gwt.user.cellview.client;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-
-/**
- * Webkit specified Impl used by cell based widgets.
- */
-public class CellBasedWidgetImplSafari extends CellBasedWidgetImplStandard
{
-
- @Override
- public void resetFocus(ScheduledCommand command) {
- // Webkit will not focus an element that was created in this event
loop.
- Scheduler.get().scheduleDeferred(command);
- }
-}
=======================================
--- /releases/2.3/tools/api-checker/config/gwt22_23userApi.conf Thu Mar 3
07:14:17 2011
+++ /releases/2.3/tools/api-checker/config/gwt22_23userApi.conf Thu Apr 7
07:38:23 2011
@@ -123,3 +123,5 @@
# Overloaded SimplePanel constructor to accept a Widget.
com.google.gwt.user.client.ui.SimplePanel::SimplePanel(Lcom/google/gwt/dom/client/Element;)
OVERLOADED_METHOD_CALL
+# Renamed CellBasedWidgetImplSafari to CellBasedWidgetImplStandardBase.
+com.google.gwt.user.cellview.client.CellBasedWidgetImplSafari MISSING
=======================================
--- /releases/2.3/user/src/com/google/gwt/cell/client/CompositeCell.java
Wed Dec 1 05:40:20 2010
+++ /releases/2.3/user/src/com/google/gwt/cell/client/CompositeCell.java
Thu Apr 7 07:38:23 2011
@@ -111,6 +111,18 @@
public boolean handlesSelection() {
return handlesSelection;
}
+
+ @Override
+ public boolean isEditing(Context context, Element parent, C value) {
+ Element curChild = getContainerElement(parent).getFirstChildElement();
+ for (HasCell<C, ?> hasCell : hasCells) {
+ if (isEditingImpl(context, curChild, value, hasCell)) {
+ return true;
+ }
+ curChild = curChild.getNextSiblingElement();
+ }
+ return false;
+ }
@Override
public void onBrowserEvent(Context context, Element parent, C value,
@@ -198,6 +210,11 @@
cell.render(context, hasCell.getValue(value), sb);
sb.appendHtmlConstant("</span>");
}
+
+ private <X> boolean isEditingImpl(Context context, Element cellParent, C
object,
+ HasCell<C, X> hasCell) {
+ return hasCell.getCell().isEditing(context, cellParent,
hasCell.getValue(object));
+ }
private <X> void onBrowserEventImpl(Context context, Element parent,
final C object, NativeEvent event, final ValueUpdater<C>
valueUpdater,
=======================================
--- /releases/2.3/user/src/com/google/gwt/cell/client/EditTextCell.java Wed
Dec 1 05:40:20 2010
+++ /releases/2.3/user/src/com/google/gwt/cell/client/EditTextCell.java Thu
Apr 7 07:38:23 2011
@@ -30,10 +30,6 @@
/**
* An editable text cell. Click to edit, escape to cancel, return to
commit.
- *
- * Important TODO: This cell still treats its value as HTML for rendering
- * purposes, which is entirely wrong. It should be able to treat it as a
proper
- * string (especially since that's all the user can enter).
*/
public class EditTextCell extends
AbstractEditableCell<String, EditTextCell.ViewData> {
@@ -146,9 +142,11 @@
}
/**
- * Construct a new EditTextCell that will use a given {@link
SafeHtmlRenderer}.
+ * Construct a new EditTextCell that will use a given {@link
SafeHtmlRenderer}
+ * to render the value when not in edit mode.
*
- * @param renderer a {@link SafeHtmlRenderer SafeHtmlRenderer<String>}
instance
+ * @param renderer a {@link SafeHtmlRenderer SafeHtmlRenderer<String>}
+ * instance
*/
public EditTextCell(SafeHtmlRenderer<String> renderer) {
super("click", "keyup", "keydown", "blur");
@@ -206,17 +204,19 @@
if (viewData != null) {
String text = viewData.getText();
- SafeHtml html = renderer.render(text);
if (viewData.isEditing()) {
- // Note the template will not treat SafeHtml specially
- sb.append(template.input(html.asString()));
+ /*
+ * Do not use the renderer in edit mode because the value of a text
+ * input element is always treated as text. SafeHtml isn't valid
in the
+ * context of the value attribute.
+ */
+ sb.append(template.input(text));
} else {
// The user pressed enter, but view data still exists.
- sb.append(html);
+ sb.append(renderer.render(text));
}
} else if (value != null) {
- SafeHtml html = renderer.render(value);
- sb.append(html);
+ sb.append(renderer.render(value));
}
}
=======================================
--- /releases/2.3/user/src/com/google/gwt/cell/client/TextInputCell.java
Wed Dec 1 05:40:20 2010
+++ /releases/2.3/user/src/com/google/gwt/cell/client/TextInputCell.java
Thu Apr 7 07:38:23 2011
@@ -23,7 +23,6 @@
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.SafeHtmlRenderer;
-import com.google.gwt.text.shared.SimpleSafeHtmlRenderer;
/**
* An {@link AbstractCell} used to render a text input.
@@ -129,30 +128,26 @@
private static Template template;
- private final SafeHtmlRenderer<String> renderer;
-
/**
* Constructs a TextInputCell that renders its text without HTML markup.
*/
public TextInputCell() {
- this(SimpleSafeHtmlRenderer.getInstance());
+ super("change", "keyup");
+ if (template == null) {
+ template = GWT.create(Template.class);
+ }
}
/**
* Constructs a TextInputCell that renders its text using the given
* {@link SafeHtmlRenderer}.
*
- * @param renderer a non-null SafeHtmlRenderer
+ * @param renderer parameter is ignored
+ * @deprecated the value of a text input is never treated as html
*/
+ @Deprecated
public TextInputCell(SafeHtmlRenderer<String> renderer) {
- super("change", "keyup");
- if (template == null) {
- template = GWT.create(Template.class);
- }
- if (renderer == null) {
- throw new IllegalArgumentException("renderer == null");
- }
- this.renderer = renderer;
+ this();
}
@Override
@@ -194,9 +189,7 @@
String s = (viewData != null) ? viewData.getCurrentValue() : value;
if (s != null) {
- SafeHtml html = renderer.render(s);
- // Note: template will not treat SafeHtml specially
- sb.append(template.input(html.asString()));
+ sb.append(template.input(s));
} else {
sb.appendHtmlConstant("<input type=\"text\"
tabindex=\"-1\"></input>");
}
=======================================
--- /releases/2.3/user/src/com/google/gwt/user/cellview/CellView.gwt.xml
Fri Mar 11 09:47:37 2011
+++ /releases/2.3/user/src/com/google/gwt/user/cellview/CellView.gwt.xml
Thu Apr 7 07:38:23 2011
@@ -35,15 +35,15 @@
<any>
<when-property-is name="user.agent" value="ie6"/>
<when-property-is name="user.agent" value="ie8"/>
- <when-property-is name="user.agent" value="ie9"/>
</any>
</replace-with>
- <!-- Safari-specific CellBasedWidgetImpl implementation. -->
- <replace-with
class="com.google.gwt.user.cellview.client.CellBasedWidgetImplSafari">
+ <!-- StandardBase CellBasedWidgetImpl implementation. -->
+ <replace-with
class="com.google.gwt.user.cellview.client.CellBasedWidgetImplStandardBase">
<when-type-is
class="com.google.gwt.user.cellview.client.CellBasedWidgetImpl"/>
<any>
<when-property-is name="user.agent" value="safari"/>
+ <when-property-is name="user.agent" value="ie9"/>
</any>
</replace-with>
=======================================
---
/releases/2.3/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java
Tue Mar 1 12:21:09 2011
+++
/releases/2.3/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java
Thu Apr 7 07:38:23 2011
@@ -384,7 +384,7 @@
* Update the selection model based on a user selection event.
*
* @param selectionModel the selection model to update
- * @param row the selected row index relative to the page start
+ * @param row the absolute index of the selected row
* @param rowValue the selected row value
* @param action the {@link SelectAction} to apply
* @param selectRange true to select the range from the last selected row
@@ -621,9 +621,9 @@
// Get the list of values to select.
List<T> toUpdate = new ArrayList<T>();
int itemCount = display.getVisibleItemCount();
- int start = range.getStart();
- int end = start + range.getLength();
- for (int i = start; i < end && i < itemCount; i++) {
+ int relativeStart = range.getStart() -
display.getVisibleRange().getStart();
+ int relativeEnd = relativeStart + range.getLength();
+ for (int i = relativeStart; i < relativeEnd && i < itemCount; i++) {
toUpdate.add(display.getVisibleItem(i));
}
=======================================
---
/releases/2.3/user/test/com/google/gwt/cell/client/CompositeCellTest.java
Wed Dec 1 05:40:20 2010
+++
/releases/2.3/user/test/com/google/gwt/cell/client/CompositeCellTest.java
Thu Apr 7 07:38:23 2011
@@ -82,6 +82,42 @@
assertTrue(cell.getConsumedEvents().contains("click"));
assertFalse(cell.dependsOnSelection());
}
+
+ public void testIsEditingFalse() {
+ List<HasCell<String, ?>> cells = createHasCells(3);
+ CompositeCell<String> cell = new CompositeCell<String>(cells);
+ Element parent = Document.get().createDivElement();
+ parent.setInnerHTML(getExpectedInnerHtml());
+ assertFalse(cell.isEditing(new Context(0, 0, null), parent, "test"));
+ }
+
+ public void testIsEditingTrue() {
+ List<HasCell<String, ?>> cells = createHasCells(3);
+ // Add a cell that is being edited.
+ final MockCell<String> mock = new MockCell<String>(false, null) {
+ @Override
+ public boolean isEditing(Context context, Element parent, String
value) {
+ return true;
+ }
+ };
+ cells.add(new HasCell<String, String>() {
+ public Cell<String> getCell() {
+ return mock;
+ }
+
+ public FieldUpdater<String, String> getFieldUpdater() {
+ return null;
+ }
+
+ public String getValue(String object) {
+ return object;
+ }
+ });
+ CompositeCell<String> cell = new CompositeCell<String>(cells);
+ Element parent = Document.get().createDivElement();
+ parent.setInnerHTML(getExpectedInnerHtml());
+ assertTrue(cell.isEditing(new Context(0, 0, null), parent, "test"));
+ }
/**
* Fire an event to no cell in particular.
@@ -137,7 +173,7 @@
Cell<String> cell = createCell();
Element parent = Document.get().createDivElement();
parent.setInnerHTML(getExpectedInnerHtml());
- Context context = new Context( 0, 0, null);
+ Context context = new Context(0, 0, null);
cell.setValue(context, parent, "test");
assertEquals(3, parent.getChildCount());
=======================================
---
/releases/2.3/user/test/com/google/gwt/cell/client/EditTextCellTest.java
Wed Dec 1 05:40:20 2010
+++
/releases/2.3/user/test/com/google/gwt/cell/client/EditTextCellTest.java
Thu Apr 7 07:38:23 2011
@@ -136,6 +136,33 @@
cell.render(context, "originalValue", sb);
assertEquals("newValue", sb.toSafeHtml().asString());
}
+
+ /**
+ * Test rendering the cell with a malicious value.
+ */
+ public void testRenderUnsafeHtml() {
+ EditTextCell cell = createCell();
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ Context context = new Context(0, 0, null);
+ cell.render(context, "<script>malicious</script>", sb);
+ assertEquals("<script>malicious</script>",
sb.toSafeHtml().asString());
+ }
+
+ /**
+ * Test rendering the cell with a malicious value in edit mode.
+ */
+ public void testRenderUnsafeHtmlWhenEditing() {
+ EditTextCell cell = createCell();
+ ViewData viewData = new ViewData("originalValue");
+ viewData.setText("<script>malicious</script>");
+ viewData.setEditing(true);
+ cell.setViewData(DEFAULT_KEY, viewData);
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ Context context = new Context(0, 0, DEFAULT_KEY);
+ cell.render(context, "<script>malicious</script>", sb);
+ assertEquals("<input type=\"text\"
value=\"<script>malicious</script>\" "
+ + "tabindex=\"-1\"></input>", sb.toSafeHtml().asString());
+ }
public void testViewData() {
// Start in edit mode.
=======================================
---
/releases/2.3/user/test/com/google/gwt/cell/client/TextInputCellTest.java
Wed Sep 22 12:58:01 2010
+++
/releases/2.3/user/test/com/google/gwt/cell/client/TextInputCellTest.java
Thu Apr 7 07:38:23 2011
@@ -15,8 +15,10 @@
*/
package com.google.gwt.cell.client;
+import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
/**
* Tests for {@link TextInputCell}.
@@ -41,6 +43,19 @@
testOnBrowserEvent(getExpectedInnerHtml(), event, "oldValue", null,
null,
expected);
}
+
+ /**
+ * Test rendering the cell with a malicious value.
+ */
+ public void testRenderUnsafeHtml() {
+ Cell<String> cell = createCell();
+ SafeHtmlBuilder sb = new SafeHtmlBuilder();
+ Context context = new Context(0, 0, null);
+ cell.render(context, "<script>malicious</script>", sb);
+ assertEquals(
+ "<input type=\"text\"
value=\"<script>malicious</script>\" tabindex=\"-1\">"
+ + "</input>", sb.toSafeHtml().asString());
+ }
@Override
protected TextInputCell createCell() {
=======================================
---
/releases/2.3/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java
Tue Mar 1 12:21:09 2011
+++
/releases/2.3/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java
Thu Apr 7 07:38:23 2011
@@ -201,6 +201,24 @@
manager.doMultiSelection(model, display, 3, "test 3", null, false,
true);
assertSelected(model, "test 3");
}
+
+ /**
+ * Test that selecting a range works when the visible range doesn't
start at index 0.
+ */
+ public void testDoMultiSelectionRangeWithPaging() {
+ MultiSelectionModel<String> model = new MultiSelectionModel<String>();
+ display.setVisibleRange(10, 10);
+ display.setRowData(10, createData(10, 10));
+ display.setSelectionModel(model);
+
+ // Select range, but really only one value because nothing is selected.
+ manager.doMultiSelection(model, display, 13, "test 13", null, true,
false);
+ assertSelected(model, "test 13");
+
+ // Select a range.
+ manager.doMultiSelection(model, display, 15, "test 15", null, true,
false);
+ assertSelected(model, "test 13", "test 14", "test 15");
+ }
public void testDoMultiSelectionSelect() {
MultiSelectionModel<String> model = new MultiSelectionModel<String>();
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors