You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by jc...@apache.org on 2011/10/18 14:20:37 UTC
svn commit: r1185619 - in /incubator/rave/trunk:
rave-portal-resources/src/main/webapp/WEB-INF/views/
rave-portal-resources/src/main/webapp/script/
rave-portal-resources/src/test/javascript/
rave-providers/rave-opensocial-provider/src/main/java/org/apa...
Author: jcian
Date: Tue Oct 18 12:20:36 2011
New Revision: 1185619
URL: http://svn.apache.org/viewvc?rev=1185619&view=rev
Log:
RAVE-269 - Widget Render Order
https://issues.apache.org/jira/browse/RAVE-269
Modified:
incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/home.jsp
incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js
incubator/rave/trunk/rave-portal-resources/src/test/javascript/raveSpec.js
incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java
incubator/rave/trunk/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java
incubator/rave/trunk/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java
Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/home.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/home.jsp?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/home.jsp (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/WEB-INF/views/home.jsp Tue Oct 18 12:20:36 2011
@@ -197,9 +197,8 @@
</form>
</div>
<script>
- //Define the global widgets variable
- //This array will be populated by RegionWidgetRender providers.
- var widgets = [];
+ //Define the global widgets map. This map will be populated by RegionWidgetRender providers.
+ var widgetsByRegionIdMap = {};
</script>
<portal:render-script location="${'BEFORE_LIB'}" />
<script src="//cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
@@ -218,7 +217,7 @@
$(function() {
rave.setContext("<spring:url value="/app/" />");
rave.initProviders();
- rave.initWidgets(widgets);
+ rave.initWidgets(widgetsByRegionIdMap);
rave.initUI();
rave.layout.init();
});
Modified: incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js (original)
+++ incubator/rave/trunk/rave-portal-resources/src/main/webapp/script/rave.js Tue Oct 18 12:20:36 2011
@@ -488,6 +488,13 @@ var rave = rave || (function() {
})();
+ function registerWidget(widgetsByRegionIdMap, regionId, widget) {
+ if (!widgetsByRegionIdMap.hasOwnProperty(regionId)) {
+ widgetsByRegionIdMap[regionId] = [];
+ }
+ widgetsByRegionIdMap[regionId].push(widget);
+ }
+
function initializeProviders() {
//Current providers are rave.wookie and rave.opensocial.
//Providers register themselves when loaded, so
@@ -498,9 +505,33 @@ var rave = rave || (function() {
}
}
- function initializeWidgets(widgets) {
+ function initializeWidgets(widgetsByRegionIdMap) {
+ //We get the widget objects in a map keyed by region ID. The code below converts that map into a flat array
+ //of widgets with all the top widgets in each region first, then the seconds widgets in each region, then the
+ //third, etc until we have all widgets in the array. This allows us to render widgets from left to right and
+ //top to bottom to give the best user experience possible (rendering the top widgets first).
+ //Note that this strategy relies on the javascript implementation to enumerate object properties in order:
+ //http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop
+ //However this should at least get us to render the top "row" first, then the second "row", ... in any browser.
+ //If this turns out to be a major concern we can change the widgetsByRegionIdMap to a 2D array instead of a map.
+ var widgets = [];
+ for (var i = 0; ; i++) {
+ var foundGadgets = false;
+ for (var regionWidgets in widgetsByRegionIdMap) {
+ regionWidgets = widgetsByRegionIdMap[regionWidgets];
+ if (regionWidgets.length > i) {
+ foundGadgets = true;
+ widgets.push(regionWidgets[i]);
+ }
+ }
+
+ if (!foundGadgets) {
+ break;
+ }
+ }
+
//Initialize the widgets for supported providers
- for(var i=0; i<widgets.length; i++) {
+ for (var i = 0; i < widgets.length; i++) {
var widget = widgets[i];
initializeWidget(widget);
widgetByIdMap[widget.regionWidgetId] = widget;
@@ -524,22 +555,6 @@ var rave = rave || (function() {
}
}
- function mapWidgetsByType(widgets) {
- var map = {};
- for (var i = 0; i < widgets.length; i++) {
- var widget = widgets[i];
- var type = widget.type;
- if (!type) {
- type = "Unknown";
- }
- if (!map[type]) {
- map[type] = [];
- }
- map[type].push(widget);
- }
- return map;
- }
-
function extractObjectIdFromElementId(elementId) {
var tokens = elementId.split("-");
return tokens.length > 2 && tokens[0] == "widget" || tokens[0] == "region" ? tokens[1] : null;
@@ -580,13 +595,21 @@ var rave = rave || (function() {
*/
return {
/**
+ * Registers the specified widget into the widgetsByRegionIdMap under the specified regionId.
+ * @param widgetsByRegionIdMap The map.
+ * @param regionId The regionId.
+ * @param widget The widget.
+ */
+ registerWidget : registerWidget,
+
+ /**
* Initialize all of the registered providers
*/
initProviders : initializeProviders,
/**
* Initializes the given set of widgets
- * @param widgets a map of widgets by type
+ * @param widgets a map of widgets by regionId
*
* NOTE: widget object must have at a minimum the following properties:
* type,
@@ -600,13 +623,6 @@ var rave = rave || (function() {
initUI : ui.init,
/**
- * Creates a map of widgets by their type
- *
- * @param widgets list of widgets to map by type
- */
- createWidgetMap : mapWidgetsByType,
-
- /**
* Parses the given string conforming to a rave object's DOM element ID and return
* the RegionWidget id
*
Modified: incubator/rave/trunk/rave-portal-resources/src/test/javascript/raveSpec.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal-resources/src/test/javascript/raveSpec.js?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal-resources/src/test/javascript/raveSpec.js (original)
+++ incubator/rave/trunk/rave-portal-resources/src/test/javascript/raveSpec.js Tue Oct 18 12:20:36 2011
@@ -97,7 +97,8 @@ describe("Rave", function() {
}
it("calls the appropriate providers", function() {
- var widgetList = [
+ var widgetsByRegionIdMap = {};
+ widgetsByRegionIdMap[1] = [
{type:"FOO"},
{type:"BAR"},
{type:"FOO"},
@@ -107,12 +108,68 @@ describe("Rave", function() {
var provider2 = getMockProvider("BAR");
rave.registerProvider(provider1);
rave.registerProvider(provider2);
- rave.initWidgets(widgetList);
+ rave.initWidgets(widgetsByRegionIdMap);
expect(provider1.initWidgetsWasCalled(2)).toBeTruthy();
expect(provider2.initWidgetsWasCalled(2)).toBeTruthy();
});
+
+ it("renders widgets in the appropriate order (first 'row', second 'row', third 'row', ...)", function() {
+ var widgetsByRegionIdMap = {};
+ widgetsByRegionIdMap[1] = [
+ {type:"FOO", renderOrder:1},
+ {type:"FOO", renderOrder:4},
+ {type:"FOO", renderOrder:7},
+ {type:"FOO", renderOrder:9}
+ ];
+ widgetsByRegionIdMap[2] = [
+ {type:"FOO", renderOrder:2},
+ {type:"FOO", renderOrder:5},
+ {type:"FOO", renderOrder:8},
+ {type:"FOO", renderOrder:10},
+ {type:"FOO", renderOrder:11},
+ {type:"FOO", renderOrder:12}
+ ];
+ widgetsByRegionIdMap[3] = [
+ {type:"FOO", renderOrder:3},
+ {type:"FOO", renderOrder:6}
+ ];
+ var widgets = [];
+ var provider1 = getMockProvider("FOO");
+ var originalInitWidgetFunction = provider1.initWidget;
+ provider1.initWidget = function(widget) {
+ originalInitWidgetFunction(widget);
+ widgets.push(widget);
+ };
+ rave.registerProvider(provider1);
+ rave.initWidgets(widgetsByRegionIdMap);
+ expect(provider1.initWidgetsWasCalled(12)).toBeTruthy();
+
+ for (var i = 0; i < 12; i++) {
+ expect(widgets[i].renderOrder).toEqual(i+1);
+ }
+ });
+
+ it("puts widgets in buckets keyed by regionIds", function() {
+ var widgetsByRegionIdMap = {};
+ var regionOneKey = 1;
+ var regionTwoKey = 2;
+ rave.registerWidget(widgetsByRegionIdMap, regionOneKey, {arbitrary:"value"});
+ rave.registerWidget(widgetsByRegionIdMap, regionOneKey, {arbitrary:"value"});
+
+ rave.registerWidget(widgetsByRegionIdMap, regionTwoKey, {arbitrary:"value"});
+
+ rave.registerWidget(widgetsByRegionIdMap, regionOneKey, {arbitrary:"value"});
+ rave.registerWidget(widgetsByRegionIdMap, regionOneKey, {arbitrary:"value"});
+
+ rave.registerWidget(widgetsByRegionIdMap, regionTwoKey, {arbitrary:"value"});
+
+ expect(widgetsByRegionIdMap[regionOneKey].length).toEqual(4);
+ expect(widgetsByRegionIdMap[regionTwoKey].length).toEqual(2);
+ });
+
it("Renders an error gadget when invalid widget is provided", function(){
- var widgetList = [
+ var widgetsByRegionIdMap = {};
+ widgetsByRegionIdMap[1] = [
{type:"FOO", regionWidgetId:20},
{type:"BAR", regionWidgetId:21},
{type:"FOO", regionWidgetId:22},
@@ -124,7 +181,7 @@ describe("Rave", function() {
var provider2 = getMockProvider("BAR");
rave.registerProvider(provider1);
rave.registerProvider(provider2);
- rave.initWidgets(widgetList);
+ rave.initWidgets(widgetsByRegionIdMap);
expect($().expression()).toEqual("#widget-43-body");
expect($().html()).toEqual("This widget type is currently unsupported. Check with your administrator and be sure the correct provider is registered.");
expect(provider1.initWidgetsWasCalled(2)).toBeTruthy();
@@ -132,56 +189,6 @@ describe("Rave", function() {
});
});
- describe("createWidgetMap", function() {
-
- it("builds a map keyed by type", function() {
- var widgets = [
- {regionWidgetId: 0, type: "OpenSocial"},
- {regionWidgetId: 1, type: "OpenSocial"},
- {regionWidgetId: 2, type: "W3C"},
- {regionWidgetId: 3, type: "W3C"}
- ];
-
- var map = rave.createWidgetMap(widgets);
-
- expect(map["OpenSocial"].length).toEqual(2);
- expect(map["W3C"].length).toEqual(2);
- expect(map["OpenSocial"]).toContain(widgets[1]);
- expect(map["W3C"]).toContain(widgets[3]);
- });
-
- it("builds a map that has widgets under an Unknown key", function() {
- var widgets = [
- {regionWidgetId: 0, type: "OpenSocial"},
- {regionWidgetId: 1, type: "OpenSocial"},
- {regionWidgetId: 2, type: "W3C"},
- {regionWidgetId: 3, type: "W3C"},
- {regionWidgetId: 4 },
- {regionWidgetId: 5, type: null }
- ];
-
- var map = rave.createWidgetMap(widgets);
-
- expect(map["OpenSocial"].length).toEqual(2);
- expect(map["W3C"].length).toEqual(2);
- expect(map["Unknown"].length).toEqual(2);
- expect(map["OpenSocial"]).toContain(widgets[1]);
- expect(map["W3C"]).toContain(widgets[3]);
- expect(map["Unknown"]).toContain(widgets[4]);
- });
-
- it("builds a map with no entries", function() {
- var widgets = [];
- var map = rave.createWidgetMap(widgets);
- var count = 0;
- for (i in map) {
- count++;
- }
- expect(count).toEqual(0);
- });
-
- });
-
describe("initUI", function() {
function createMockJQuery() {
var sortableArgs = null;
Modified: incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java (original)
+++ incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/main/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRenderer.java Tue Oct 18 12:20:36 2011
@@ -62,13 +62,13 @@ public class OpenSocialWidgetRenderer im
//Note the widgets.push() call. This defines the widget objects, which are
//added to the widgets[] array in home.jsp.
private static final String SCRIPT_BLOCK =
- "<script>widgets.push({type: '%1$s'," +
- " regionWidgetId: %2$s," +
- " widgetUrl: '%3$s', " +
- " securityToken: '%4$s', " +
- " metadata: %5$s," +
- " userPrefs: %6$s," +
- " collapsed: %7$s});</script>";
+ "<script>rave.registerWidget(widgetsByRegionIdMap, %1$s, {type: '%2$s'," +
+ " regionWidgetId: %3$s," +
+ " widgetUrl: '%4$s', " +
+ " securityToken: '%5$s', " +
+ " metadata: %6$s," +
+ " userPrefs: %7$s," +
+ " collapsed: %8$s});</script>";
private static final String MARKUP = "<!-- RegionWidget %1$s placeholder -->";
@Override
@@ -110,8 +110,8 @@ public class OpenSocialWidgetRenderer im
}
}
- return String.format(SCRIPT_BLOCK, Constants.WIDGET_TYPE, item.getEntityId(), item.getWidget().getUrl(),
- securityTokenService.getEncryptedSecurityToken(item),
+ return String.format(SCRIPT_BLOCK, item.getRegion().getEntityId(), Constants.WIDGET_TYPE, item.getEntityId(),
+ item.getWidget().getUrl(), securityTokenService.getEncryptedSecurityToken(item),
openSocialService.getGadgetMetadata(item.getWidget().getUrl()), userPrefs.toString(), item.isCollapsed());
}
}
\ No newline at end of file
Modified: incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java (original)
+++ incubator/rave/trunk/rave-providers/rave-opensocial-provider/src/test/java/org/apache/rave/provider/opensocial/web/renderer/OpenSocialWidgetRendererTest.java Tue Oct 18 12:20:36 2011
@@ -20,6 +20,7 @@
package org.apache.rave.provider.opensocial.web.renderer;
import org.apache.rave.exception.NotSupportedException;
+import org.apache.rave.portal.model.Region;
import org.apache.rave.portal.model.RegionWidget;
import org.apache.rave.portal.model.RegionWidgetPreference;
import org.apache.rave.portal.model.Widget;
@@ -77,16 +78,18 @@ public class OpenSocialWidgetRendererTes
w.setEntityId(1L);
w.setType(Constants.WIDGET_TYPE);
w.setUrl(VALID_GADGET_URL);
+ Region region = new Region(1L);
RegionWidget rw = new RegionWidget();
rw.setEntityId(1L);
rw.setCollapsed(VALID_COLLAPSED);
rw.setWidget(w);
+ rw.setRegion(region);
rw.setPreferences(Arrays.asList(new RegionWidgetPreference(1L, 1L, "color", "blue"),
new RegionWidgetPreference(2L, 1L, "speed", "fast"),
new RegionWidgetPreference(3L, 1L, null, null)));
final String markup =
- "<script>widgets.push({type: 'OpenSocial'," +
+ "<script>rave.registerWidget(widgetsByRegionIdMap, 1, {type: 'OpenSocial'," +
" regionWidgetId: 1," +
" widgetUrl: '" + VALID_GADGET_URL +"', " +
" securityToken: '" + VALID_SECURITY_TOKEN + "', " +
@@ -111,13 +114,15 @@ public class OpenSocialWidgetRendererTes
public void render_null() {
Widget w = new Widget();
w.setType(Constants.WIDGET_TYPE);
+ Region region = new Region(1L);
RegionWidget rw = new RegionWidget();
rw.setWidget(w);
+ rw.setRegion(region);
String result = renderer.render(rw, null);
final String markup =
- "<script>widgets.push({type: 'OpenSocial'," +
+ "<script>rave.registerWidget(widgetsByRegionIdMap, 1, {type: 'OpenSocial'," +
" regionWidgetId: null," +
" widgetUrl: 'null', " +
" securityToken: '" + VALID_SECURITY_TOKEN + "', " +
Modified: incubator/rave/trunk/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java (original)
+++ incubator/rave/trunk/rave-providers/rave-w3c-provider/src/main/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRenderer.java Tue Oct 18 12:20:36 2011
@@ -38,9 +38,9 @@ import static org.apache.rave.provider.w
public class W3cWidgetRenderer implements RegionWidgetRenderer {
- private static final String IFRAME_MARKUP = "widgets.push({type: '%1$s'," +
- " regionWidgetId: %2$s," +
- " widgetUrl: '%3$s'});";
+ private static final String IFRAME_MARKUP = "<script>rave.registerWidget(widgetsByRegionIdMap, %1$s, {type: '%2$s'," +
+ " regionWidgetId: %3$s," +
+ " widgetUrl: '%4$s'});</script>";
private static final String INLINE_MARKUP = "";
@@ -71,6 +71,6 @@ public class W3cWidgetRenderer implement
}
Widget contextualizedWidget = widgetService.getWidget(null, null, widget);
String url = contextualizedWidget == null ? null : contextualizedWidget.getUrl();
- return String.format(IFRAME_MARKUP, WIDGET_TYPE, item.getEntityId(), url);
+ return String.format(IFRAME_MARKUP, item.getRegion().getEntityId(), WIDGET_TYPE, item.getEntityId(), url);
}
}
Modified: incubator/rave/trunk/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java?rev=1185619&r1=1185618&r2=1185619&view=diff
==============================================================================
--- incubator/rave/trunk/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java (original)
+++ incubator/rave/trunk/rave-providers/rave-w3c-provider/src/test/java/org/apache/rave/provider/w3c/web/renderer/W3cWidgetRendererTest.java Tue Oct 18 12:20:36 2011
@@ -20,6 +20,7 @@
package org.apache.rave.provider.w3c.web.renderer;
import org.apache.rave.exception.NotSupportedException;
+import org.apache.rave.portal.model.Region;
import org.apache.rave.portal.model.RegionWidget;
import org.apache.rave.portal.model.Widget;
import org.apache.rave.portal.service.WidgetProviderService;
@@ -58,9 +59,11 @@ public class W3cWidgetRendererTest {
Widget w = new Widget();
w.setType(Constants.WIDGET_TYPE);
w.setUrl("http://example.com/widgets/1");
+ Region region = new Region(1L);
RegionWidget rw = new RegionWidget();
rw.setEntityId(1L);
rw.setWidget(w);
+ rw.setRegion(region);
Widget wookieWidget = new Widget();
final String WIDGET_INSTANCE = "http://example.com/widgetinstances/1";
@@ -79,8 +82,10 @@ public class W3cWidgetRendererTest {
public void render_null() {
Widget w = new Widget();
w.setType(Constants.WIDGET_TYPE);
+ Region region = new Region(1L);
RegionWidget rw = new RegionWidget();
rw.setWidget(w);
+ rw.setRegion(region);
String result = renderer.render(rw, null);
assertThat(result.matches(".*regionWidgetId[ ]*:[ ]*null,.*"), is(true));