Author: scottbw
Date: Thu Apr 11 08:57:00 2013
New Revision: 1466799
URL: http://svn.apache.org/r1466799
Log:
Moved the default scripts injected into all widgets from a list of constants
within StartPageProcessor into its own "feature", making it easier for admins
to modify what gets injected into all widgets by modifying just the "widget"
feature, for example to add things like usage tracking, common CSS definitions,
swap out DWR for something else, etc. See WOOKIE-408.
Added:
wookie/trunk/features/widget/
wookie/trunk/features/widget/feature.xml
wookie/trunk/features/widget/wookie.js
Removed:
wookie/trunk/WebContent/shared/js/
Modified:
wookie/trunk/src/org/apache/wookie/util/html/StartPageProcessor.java
Added: wookie/trunk/features/widget/feature.xml
URL:
http://svn.apache.org/viewvc/wookie/trunk/features/widget/feature.xml?rev=1466799&view=auto
==============================================================================
--- wookie/trunk/features/widget/feature.xml (added)
+++ wookie/trunk/features/widget/feature.xml Thu Apr 11 08:57:00 2013
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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.
+-->
+<feature>
+
+ <!--
+ This is the default feature for all widgets; add more scripts here and
+ they will be automatically added when widgets are imported or updated
+ -->
+ <name>http://wookie.apache.org/feature/default</name>
+ <script src="dwr/util.js"/>
+ <script src="dwr/engine.js"/>
+ <script src="dwr/interface/WidgetImpl.js"/>
+ <script src="wookie.js"/>
+</feature>
\ No newline at end of file
Added: wookie/trunk/features/widget/wookie.js
URL:
http://svn.apache.org/viewvc/wookie/trunk/features/widget/wookie.js?rev=1466799&view=auto
==============================================================================
--- wookie/trunk/features/widget/wookie.js (added)
+++ wookie/trunk/features/widget/wookie.js Thu Apr 11 08:57:00 2013
@@ -0,0 +1,447 @@
+
+/*
+ * 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.
+ */
+
+var widget;
+
+/*
+ * WidgetPreferences, singleton class
+ * Calls to this object replace the legacy
setPreferenceForKey/preferenceForKey methods
+ * Implements HTML 5 Storage API
+ */
+
+var WidgetPreferences = new function WidgetPreferences() {
+
+ /*
+ * the internal preferences map
+ */
+ this.prefs = {};
+
+ /*
+ * the number of key/value pairs currently present in preferences
+ */
+ this.length = 0;
+
+ /**
+ * Resets the length attribute
+ */
+ this.calcLength = function () {
+ var x = 0;
+ for (var key in this.prefs) {
+ x++;
+ }
+ this.length = x;
+ return x;
+ };
+
+ /**
+ * Returns the tuple for the key
+ * @param key the key to return the tuple for
+ */
+ this.key = function (n) {
+ var x = 0;
+ for (var key in this.prefs) {
+ if (x == n) {
+ return key;
+ }
+ x++;
+ }
+ };
+
+ /**
+ * Returns the value of a key
+ * @param the key to return the value for
+ */
+ this.getItem = function (key) {
+ if (!this.prefs[key]) {
+ return null;
+ }
+ return this.prefs[key]["dvalue"];
+ };
+
+ /**
+ * Create getters and setters for a preference
+ * @param key the key to set
+ * @param value the value to set (for IE)
+ * @param pref the preference object to set (for IE)
+ */
+ this.createAccessorMethods = function (key, value, pref) {
+ try {
+ eval("Widget.preferences.__defineGetter__('" + key + "',
function(){return Widget.preferences.getItem('" + key + "')})");
+ eval("Widget.preferences.__defineSetter__('" + key + "',
function(v){return Widget.preferences.setItem('" + key + "',v)})");
+ eval("Widget.preferences.prefs[\"" + key + "\"]=pref;");
+ }
+ catch (err) {
+
+ //
+ // cant use __defineGetter__ so try to setup for IE9
+ //
+ try {
+ eval("Object.defineProperty(Widget.preferences,'" + key + "',
{get: function get() { return Widget.preferences.getItem('" + key + "');},set:
function set(value) {Widget.preferences.setItem('" + key + "',value)}});");
+ eval("Widget.preferences.prefs[\"" + key + "\"]=pref;");
+ }
+ catch (err2) {
+
+ //
+ // Catch IE 8 error. See WOOKIE-44
+ //
+ eval("Widget.preferences");
+
+ //
+ // If eval went fine, populate with data, See WOOKIE-151
+ //
+ if (typeof Widget.preferences != "undefined") {
+ widget.preferences[key] = value;
+ widget.preferences.prefs[key] = pref;
+ }
+ }
+ }
+ };
+
+ /**
+ * Sets a key to a value
+ * @param key the key to set
+ * @param value the value to set
+ */
+ this.setItem = function (key, value) {
+ //
+ // Make a preference object and set its properties
+ //
+ var pref = {};
+ var oldValue = null;
+ pref.dvalue = value;
+ pref.key = key;
+ pref.readOnly = false;
+
+ //
+ // Check if the preference already exists
+ //
+ var existing = this.prefs[key];
+
+ //
+ // If it does exist, check it isn't read-only
+ //
+ if (existing) {
+ oldValue = this.getItem(key);
+ if (existing["readOnly"] === true) {
+ window.DOMException.code =
DOMException.NO_MODIFICATION_ALLOWED_ERR;
+ throw (window.DOMException);
+ }
+ } else {
+ //
+ // Setup getters and setters for the new tuple
+ //
+ this.createAccessorMethods(key, value, pref);
+ }
+
+ //
+ // Set the pref in the preferences collection
+ // and persist it
+ //
+ this.prefs[key] = pref;
+ widget.setPreferenceForKey(key, value);
+ this.__raiseEvent(key, value, oldValue);
+ //
+ // Recalculate the length of the preferences collection
+ //
+ this.calcLength();
+ };
+
+
+ /**
+ * Removes a tuple from the preferences collection
+ * @param key the key of the tuple to remove
+ */
+ this.removeItem = function (key) {
+ this.__removeItem(key, true);
+ };
+
+ /**
+ * Internal delete function
+ * @param key the key of the tuple to remove
+ * @param fireEvent boolean; true to fire Storage Event on remove
+ */
+ this.__removeItem = function(key, fireEvent){
+ var existing = (this.prefs[key]);
+ if (existing) {
+ if (existing["readOnly"] === true) {
+ window.DOMException.code =
DOMException.NO_MODIFICATION_ALLOWED_ERR;
+ throw (window.DOMException);
+ } else {
+ var oldValue = this.getItem(key);
+ delete this.prefs[key];
+ widget.setPreferenceForKey(key, null);
+ if (fireEvent) this.__raiseEvent(key, null, oldValue);
+ this.calcLength();
+ }
+ }
+ };
+
+ /**
+ * Clears all tuples from the preferences collection
+ */
+ this.clear = function () {
+ for (var key in this.prefs) {
+ try {
+ if(this.prefs[key]["readOnly"] === false)
+ this.__removeItem(key, false);
+ } catch (e) {
+ // swallow errors, as this method must never throw them
according to spec.
+ }
+ }
+ this.__raiseEvent(null,null,null);
+ };
+
+ this.__raiseEvent = function(key, value, oldValue){
+ //
+ // Raise custom storage event
+ //
+ var evt;
+ if(document.createEvent){
+ evt = document.createEvent("Event");
+ } else { // IE before v 9
+ evt = document.createEventObject(window.event);
+ }
+ var evt = document.createEvent("Event");
+ evt.initEvent("storage", false,false);
+ evt.key = key;
+ evt.newValue = value;
+ evt.oldValue = oldValue;
+ evt.url = window.location;
+ evt.storageArea = widget.preferences;
+ //
+ // Dispatch to child frames
+ //
+ var frames = window.frames;
+ for (var i=0;i<frames.length;i++){
+ try{
+ if(document.createEvent){
+ frames[i].dispatchEvent(evt);
+ } else { // IE before v 9
+ frames[i].fireEvent("storage", evt);
+ }
+ } catch(err) {
+ if (typeof console != "undefined") {
+ console.warn("error dispatching storage event to child frame;
most likely this is due to same-origin restrictions");
+ }
+ }
+ }
+ }
+};
+
+/**
+ * Widget object
+ */
+var Widget = {
+
+ /**
+ * The ID key issued by wookie
+ */
+ instanceid_key : null,
+
+ /**
+ * The URL to the server-side proxy
+ */
+ proxyUrl : null,
+
+ /**
+ * Method called whenever widget shared data is updated. Used by Wave
feature to register its state change callback.
+ */
+ onSharedUpdate : null,
+
+ /**
+ * The preferences object; instantiated below
+ */
+ preferences: null,
+
+ /**
+ * Set up the widget object
+ */
+ init: function () {
+
+ //
+ // This page url will be called with e.g.
idkey=4j45j345jl353n5lfg09cw03f05
+ // so grab that key to use as authentication against the server.
+ // Also get the proxy address and store it.
+ //
+ var query = window.location.search.substring(1);
+ var pairs = query.split("&");
+ for (var i = 0; i < pairs.length; i++) {
+ var pos = pairs[i].indexOf('=');
+ if (pos >= 0) {
+ var argname = pairs[i].substring(0, pos);
+
+ //
+ // get the id_key and assign it to instanceid_key.
+ //
+ if (argname == "idkey") {
+ this.instanceid_key = pairs[i].substring(pos + 1);
+ }
+
+ //
+ // TODO - remove this & use a callback instead of having it in
the URL
+ //
+ if (argname == "proxy") {
+ this.proxyUrl = pairs[i].substring(pos + 1);
+ }
+ }
+ }
+
+ //
+ // Instantiate a Widget Preferences object, and load all values
+ // Note we do this synchronously, as widgets are likely
+ // to ask for a handle on this as an onLoad() event
+ //
+ this.preferences = WidgetPreferences;
+ dwr.engine.beginBatch();
+ WidgetImpl.preferences(this.instanceid_key, this.setPrefs);
+ WidgetImpl.metadata(this.instanceid_key, this.setMetadata);
+ dwr.engine.endBatch({async: false});
+ },
+
+ /**
+ * Set the metadata collection for this widget instance
+ * @param map the map of metadata items, consisting of a key and value
+ */
+ setMetadata: function (map) {
+ for (var key in map) {
+ Widget.setMetadataProperty(key, map[key]);
+ }
+ },
+
+ /**
+ * Set an individual metadata property.
+ * @param key the metadata key
+ * @param value the metadata value
+ */
+ setMetadataProperty: function (key, value) {
+
+ //
+ // The height and widget metadata items use Number values
+ //
+ if (key == "width" || key == "height") {
+ value = Number(value);
+ }
+
+ //
+ // Set up getters and setters; note that setters must return a
+ // NO_MODIFICATION_ALLOWED_ERR as metadata properties are read-only
+ //
+ try {
+ Widget.__defineSetter__(key, function () {
+ window.DOMException.code =
DOMException.NO_MODIFICATION_ALLOWED_ERR;
+ throw (window.DOMException);
+ });
+ Widget.__defineGetter__(key, function () {
+ return value;
+ });
+ } catch (err) {
+ try {
+ //
+ // cant use __defineGetter__ so try to setup for IE9
+ //
+ Object.defineProperty(Widget, key, {
+ set: function set() {
+ window.DOMException.code =
DOMException.NO_MODIFICATION_ALLOWED_ERR;
+ throw (window.DOMException);
+ },
+ get: function get() {
+ return value;
+ }
+ });
+ } catch (err2) {
+ //
+ // catch IE8
+ //
+ eval("Widget." + key + "='" + value + "';");
+ }
+ }
+ },
+
+ /**
+ * Set the preferences collection for this widget instance
+ * @param map the map of preference items, consisting of key, value and
readonly flag
+ */
+ setPrefs: function (map) {
+ this.preferences = WidgetPreferences;
+ this.preferences.prefs = {};
+ for (var i in map) {
+ var obj = map[i];
+ var key = obj["dkey"];
+
+ //
+ // Define getters and setters for each preference item
+ //
+ this.preferences.createAccessorMethods(key, obj["dvalue"], obj);
+
+ //
+ // Add the item to preferences collection
+ //
+ eval("this.preferences.prefs[\"" + key + "\"]=obj;");
+ }
+ this.preferences.calcLength();
+ Widget.setMetadataProperty("preferences",this.preferences);
+ },
+
+ /**
+ * Persist a preference object in the server backend
+ */
+ setPreferenceForKey : function (wName, wValue) {
+ WidgetImpl.setPreferenceForKey(this.instanceid_key, wName, wValue);
+ },
+
+ /**
+ * Get the instance id key for this instance
+ */
+ getInstanceKey : function () {
+ return this.instanceid_key;
+ },
+
+ /**
+ * Get the URL for the server-side proxy
+ */
+ getProxyUrl : function () {
+ return this.proxyUrl;
+ },
+
+ /**
+ * Convert a given URL into a proxified version
+ * @param url the URL to convert
+ */
+ proxify : function (url) {
+ return this.proxyUrl + "?instanceid_key=" + this.instanceid_key +
"&url=" + url;
+ },
+
+ /**
+ * Return Widget as the object type
+ */
+ toString: function () {
+ return "[object Widget]";
+ }
+};
+
+//
+// Initialize the widget object
+//
+Widget.init();
+
+//
+// Avoid lower/uppercase confusion for the widget object
+//
+widget = Widget;
+
+//
+// Add widget object to the window object
+//
+window.widget = Widget;
\ No newline at end of file
Modified: wookie/trunk/src/org/apache/wookie/util/html/StartPageProcessor.java
URL:
http://svn.apache.org/viewvc/wookie/trunk/src/org/apache/wookie/util/html/StartPageProcessor.java?rev=1466799&r1=1466798&r2=1466799&view=diff
==============================================================================
--- wookie/trunk/src/org/apache/wookie/util/html/StartPageProcessor.java
(original)
+++ wookie/trunk/src/org/apache/wookie/util/html/StartPageProcessor.java Thu
Apr 11 08:57:00 2013
@@ -19,7 +19,6 @@ import java.io.FileWriter;
import org.apache.wookie.feature.Features;
import org.apache.wookie.feature.IFeature;
-import org.apache.wookie.helpers.WidgetRuntimeHelper;
import org.apache.wookie.w3c.IContent;
import org.apache.wookie.w3c.IStartPageProcessor;
import org.apache.wookie.w3c.W3CWidget;
@@ -29,10 +28,7 @@ import org.apache.wookie.w3c.W3CWidget;
*/
public class StartPageProcessor implements IStartPageProcessor {
- static final String DWR_UTIL_SRC_VALUE =
WidgetRuntimeHelper.getWebContextPath() + "/dwr/util.js";
- static final String DWR_ENGINE_SRC_VALUE =
WidgetRuntimeHelper.getWebContextPath() + "/dwr/engine.js";
- static final String WIDGET_IMPL_SRC_VALUE =
WidgetRuntimeHelper.getWebContextPath() + "/dwr/interface/WidgetImpl.js";
- static final String WOOKIE_WRAPPER_SRC_VALUE =
WidgetRuntimeHelper.getWebContextPath() + "/shared/js/wookie-wrapper.js";
+ static final String DEFAULT_FEATURE =
"http://wookie.apache.org/feature/default";
/* (non-Javadoc)
* @see
org.apache.wookie.util.html.IStartPageProcessor#processStartFile(java.io.File,
org.apache.wookie.w3c.IManifestModel)
@@ -61,10 +57,12 @@ public class StartPageProcessor implemen
* @param engine
*/
private void addDefaultScripts(IHtmlProcessor engine){
- engine.injectScript(DWR_UTIL_SRC_VALUE);
- engine.injectScript(DWR_ENGINE_SRC_VALUE);
- engine.injectScript(WIDGET_IMPL_SRC_VALUE);
- engine.injectScript(WOOKIE_WRAPPER_SRC_VALUE);
+ for (IFeature theFeature: Features.getFeatures()){
+ if
(theFeature.getName().equals("http://wookie.apache.org/feature/default")){
+ addScripts(engine,theFeature);
+ addStylesheets(engine, theFeature);
+ }
+ }
}
/**