Author: doll
Date: Fri Jan 11 18:08:32 2008
New Revision: 611350
URL: http://svn.apache.org/viewvc?rev=611350&view=rev
Log:
Improved more of the opensocial - caja integration code. Gadgets cajoled with
the latest caja server should now work with the excpetion of 2 bugs on their
side.
This change includes html sanitization as well as a proper definition of
emitHtml.
Added:
incubator/shindig/trunk/features/caja/html-sanitizer.js
Modified:
incubator/shindig/trunk/features/caja/feature.xml
incubator/shindig/trunk/features/opensocial-reference/container.js
Modified: incubator/shindig/trunk/features/caja/feature.xml
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/caja/feature.xml?rev=611350&r1=611349&r2=611350&view=diff
==============================================================================
--- incubator/shindig/trunk/features/caja/feature.xml (original)
+++ incubator/shindig/trunk/features/caja/feature.xml Fri Jan 11 18:08:32 2008
@@ -23,6 +23,7 @@
<name>caja</name>
<gadget>
<script src="caja.js"></script>
+ <script src="html-sanitizer.js"></script>
<!--Be default permissive.js should not be included.
Including this file turns off all caja security rules. -->
<!--<script src="permissive.js"></script>-->
Added: incubator/shindig/trunk/features/caja/html-sanitizer.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/caja/html-sanitizer.js?rev=611350&view=auto
==============================================================================
--- incubator/shindig/trunk/features/caja/html-sanitizer.js (added)
+++ incubator/shindig/trunk/features/caja/html-sanitizer.js Fri Jan 11 18:08:32
2008
@@ -0,0 +1,420 @@
+// Copyright (C) 2006 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.
+
+// [EMAIL PROTECTED]
+
+/**
+ * Strips unsafe tags and attributes from html.
+ * @param {String} html to sanitize
+ * @param {Function} opt_urlXform : String -> String -- a transform to apply to
+ * url attribute values.
+ * @param {Function} opt_nmTokenXform : String -> String -- a transform to
apply
+ * to name attribute values.
+ * @return {String} html
+ */
+var html_sanitize = (function () {
+
+ // hide all the whitelists and other state so they can't be interfered with
+
+ /** token definitions. */
+ var TOK_ENTITY = /^&(?:\#[0-9]+|\#x[0-9a-f]+|\w+);/i;
+ var TOK_COMMENT = /^<!--[\s\S]*?-->/;
+ var TOK_TAG_BEGIN = /^<\/?[a-z][a-z0-9]*/i;
+ var TOK_TAG_END = /^\/?>/;
+ var TOK_ATTRIB = /^\w+(\s*=\s*(?:\"[^\"]*\"|\'[^\']*\'|[^>\"\'\s]*))?/;
+ var TOK_SPACE = /^\s+/;
+ var TOK_OTHER = /^[^&<]+/;
+ var TOK_CRUFT = /^[<&]/;
+ var TOK_IGNORABLE_CRUFT = /^[^\w\s>]+/;
+
+ /** the token definitions used when we are outside a tag. */
+ var TOKS_NOTTAG = [
+ TOK_ENTITY,
+ TOK_COMMENT,
+ TOK_TAG_BEGIN,
+ TOK_OTHER,
+ TOK_CRUFT
+ ];
+ /** token definitions used inside a tag. */
+ var TOKS_INTAG = [
+ TOK_SPACE,
+ TOK_ATTRIB,
+ TOK_TAG_END,
+ TOK_IGNORABLE_CRUFT
+ ];
+
+ /**
+ * split html into tokens using the regexps above.
+ * This also does some normalization of tokens, escaping specials that don't
+ * appear to be part of a larger token.
+ */
+ var lex = function (html) {
+ var tokens = [];
+ var inTag = false; // 0 outside tag, 1 inside tag
+ while (html) {
+ var m = null;
+ var tok = null;
+ if (!inTag) {
+ for (var i = 0; i < TOKS_NOTTAG.length; ++i) {
+ m = html.match(TOKS_NOTTAG[i]);
+ if (m) {
+ tok = TOKS_NOTTAG[i];
+ break;
+ }
+ }
+ if (tok === TOK_TAG_BEGIN) { inTag = true; }
+ } else {
+ for (var i = 0; i < TOKS_INTAG.length; ++i) {
+ m = html.match(TOKS_INTAG[i]);
+ if (m) {
+ tok = TOKS_INTAG[i];
+ break;
+ }
+ }
+ if (tok === TOK_TAG_END) { inTag = false; }
+ }
+ var tokstr = m[0];
+ html = html.substring(tokstr.length);
+ if (tok === TOK_CRUFT) {
+ tokstr = tokstr == '<' ? '<' : '&';
+ } else if (tok === TOK_OTHER) {
+ tokstr = tokstr.replace(/>/g, '>');
+ } else if (tok == TOK_SPACE) {
+ tokstr = ' ';
+ } else if (tok === TOK_ATTRIB) {
+ tokstr = tokstr.replace(/^(\w+)\s*=\s*/, '$1=');
+ }
+ if (tok !== TOK_IGNORABLE_CRUFT && tok != TOK_COMMENT) {
+ tokens.push(tokstr, tok);
+ }
+ }
+ return tokens;
+ };
+
+ // whitelists of elements and attributes
+
+ /** element flags. */
+ var OPTIONAL_ENDTAG = 1,
+ BREAKS_FLOW = 2,
+ EMPTY = 4,
+ UNSAFE = 8;
+
+ /** attribute flags */
+ var SCRIPT_TYPE = 1,
+ STYLE_TYPE = 2,
+ NMTOKEN_TYPE = 4,
+ URI_TYPE = 8;
+
+ /**
+ * All the HTML4 elements.
+ * U - unsafe, E - empty, B - breaks flow, O - optional endtag
+ */
+ var ELEMENTS = {
+ A : 0,
+ ABBR : 0,
+ ACRONYM : 0,
+ ADDRESS : 0,
+ APPLET : UNSAFE,
+ AREA : EMPTY,
+ B : 0,
+ BASE : UNSAFE|EMPTY,
+ BASEFONT : UNSAFE|EMPTY,
+ BDO : 0,
+ BIG : 0,
+ BLOCKQUOTE : BREAKS_FLOW,
+ BODY : UNSAFE|OPTIONAL_ENDTAG,
+ BR : EMPTY|BREAKS_FLOW,
+ BUTTON : 0,
+ CAPTION : 0,
+ CENTER : BREAKS_FLOW,
+ CITE : 0,
+ CODE : 0,
+ COL : EMPTY,
+ COLGROUP : OPTIONAL_ENDTAG,
+ DD : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ DEL : 0,
+ DFN : 0,
+ DIR : BREAKS_FLOW,
+ DIV : BREAKS_FLOW,
+ DL : BREAKS_FLOW,
+ DT : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ EM : 0,
+ FIELDSET : 0,
+ FONT : 0,
+ FORM : BREAKS_FLOW,
+ FRAME : UNSAFE|EMPTY,
+ FRAMESET : UNSAFE,
+ H1 : BREAKS_FLOW,
+ H2 : BREAKS_FLOW,
+ H3 : BREAKS_FLOW,
+ H4 : BREAKS_FLOW,
+ H5 : BREAKS_FLOW,
+ H6 : BREAKS_FLOW,
+ HEAD : UNSAFE|OPTIONAL_ENDTAG|BREAKS_FLOW,
+ HR : EMPTY|BREAKS_FLOW,
+ HTML : UNSAFE|OPTIONAL_ENDTAG|BREAKS_FLOW,
+ I : 0,
+ IFRAME : UNSAFE,
+ IMG : EMPTY,
+ INPUT : EMPTY,
+ INS : 0,
+ ISINDEX : UNSAFE|EMPTY|BREAKS_FLOW,
+ KBD : 0,
+ LABEL : 0,
+ LEGEND : 0,
+ LI : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ LINK : UNSAFE|EMPTY,
+ MAP : 0,
+ MENU : BREAKS_FLOW,
+ META : UNSAFE|EMPTY,
+ NOFRAMES : UNSAFE|BREAKS_FLOW,
+ NOSCRIPT : UNSAFE,
+ OBJECT : UNSAFE,
+ OL : BREAKS_FLOW,
+ OPTGROUP : 0,
+ OPTION : OPTIONAL_ENDTAG,
+ P : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ PARAM : UNSAFE|EMPTY,
+ PRE : BREAKS_FLOW,
+ Q : 0,
+ S : 0,
+ SAMP : 0,
+ SCRIPT : UNSAFE,
+ SELECT : 0,
+ SMALL : 0,
+ SPAN : 0,
+ STRIKE : 0,
+ STRONG : 0,
+ STYLE : UNSAFE,
+ SUB : 0,
+ SUP : 0,
+ TABLE : BREAKS_FLOW,
+ TBODY : OPTIONAL_ENDTAG,
+ TD : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ TEXTAREA : 0,
+ TFOOT : OPTIONAL_ENDTAG,
+ TH : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ THEAD : OPTIONAL_ENDTAG,
+ TITLE : UNSAFE|BREAKS_FLOW,
+ TR : OPTIONAL_ENDTAG|BREAKS_FLOW,
+ TT : 0,
+ U : 0,
+ UL : BREAKS_FLOW,
+ VAR : 0
+ };
+
+ /**
+ * All the HTML4 attributes
+ */
+ var ATTRIBS = {
+ ABBR : 0,
+ ACCEPT : 0,
+ 'ACCEPT-CHARSET': 0,
+ ACCESSKEY : 0,
+ ACTION : URI_TYPE,
+ ALIGN : 0,
+ ALINK : 0,
+ ALT : 0,
+ ARCHIVE : URI_TYPE,
+ AXIS : 0,
+ BACKGROUND : URI_TYPE,
+ BGCOLOR : 0,
+ BORDER : 0,
+ CELLPADDING : 0,
+ CELLSPACING : 0,
+ CHAR : 0,
+ CHAROFF : 0,
+ CHARSET : 0,
+ CHECKED : 0,
+ CITE : URI_TYPE,
+ CLASS : NMTOKEN_TYPE,
+ CLASSID : URI_TYPE,
+ CLEAR : 0,
+ CODE : 0,
+ CODEBASE : URI_TYPE,
+ CODETYPE : 0,
+ COLOR : 0,
+ COLS : 0,
+ COLSPAN : 0,
+ COMPACT : 0,
+ CONTENT : 0,
+ COORDS : 0,
+ DATA : URI_TYPE,
+ DATETIME : 0,
+ DECLARE : 0,
+ DEFER : 0,
+ DIR : 0,
+ DISABLED : 0,
+ ENCTYPE : 0,
+ FACE : 0,
+ FOR : NMTOKEN_TYPE,
+ FRAME : 0,
+ FRAMEBORDER : 0,
+ HEADERS : 0,
+ HEIGHT : 0,
+ HREF : URI_TYPE,
+ HREFLANG : 0,
+ HSPACE : 0,
+ 'HTTP-EQUIV' : 0,
+ ID : NMTOKEN_TYPE,
+ ISMAP : 0,
+ LABEL : 0,
+ LANG : 0,
+ LANGUAGE : 0,
+ LINK : 0,
+ LONGDESC : URI_TYPE,
+ MARGINHEIGHT : 0,
+ MARGINWIDTH : 0,
+ MAXLENGTH : 0,
+ MEDIA : 0,
+ METHOD : 0,
+ MULTIPLE : 0,
+ NAME : NMTOKEN_TYPE, // but not really for inputs
+ NOHREF : 0,
+ NORESIZE : 0,
+ NOSHADE : 0,
+ NOWRAP : 0,
+ OBJECT : 0,
+ ONBLUR : SCRIPT_TYPE,
+ ONCHANGE : SCRIPT_TYPE,
+ ONCLICK : SCRIPT_TYPE,
+ ONDBLCLICK : SCRIPT_TYPE,
+ ONFOCUS : SCRIPT_TYPE,
+ ONKEYDOWN : SCRIPT_TYPE,
+ ONKEYPRESS : SCRIPT_TYPE,
+ ONKEYUP : SCRIPT_TYPE,
+ ONLOAD : SCRIPT_TYPE,
+ ONMOUSEDOWN : SCRIPT_TYPE,
+ ONMOUSEMOVE : SCRIPT_TYPE,
+ ONMOUSEOUT : SCRIPT_TYPE,
+ ONMOUSEOVER : SCRIPT_TYPE,
+ ONMOUSEUP : SCRIPT_TYPE,
+ ONRESET : SCRIPT_TYPE,
+ ONSELECT : SCRIPT_TYPE,
+ ONSUBMIT : SCRIPT_TYPE,
+ ONUNLOAD : SCRIPT_TYPE,
+ PROFILE : URI_TYPE,
+ PROMPT : 0,
+ READONLY : 0,
+ REL : 0,
+ REV : 0,
+ ROWS : 0,
+ ROWSPAN : 0,
+ RULES : 0,
+ SCHEME : 0,
+ SCOPE : 0,
+ SCROLLING : 0,
+ SELECTED : 0,
+ SHAPE : 0,
+ SIZE : 0,
+ SPAN : 0,
+ SRC : URI_TYPE,
+ STANDBY : 0,
+ START : 0,
+ STYLE : STYLE_TYPE,
+ SUMMARY : 0,
+ TABINDEX : 0,
+ TARGET : 0,
+ TEXT : 0,
+ TITLE : 0,
+ TYPE : 0,
+ USEMAP : URI_TYPE,
+ VALIGN : 0,
+ VALUE : 0,
+ VALUETYPE : 0,
+ VERSION : 0,
+ VLINK : 0,
+ VSPACE : 0,
+ WIDTH : 0
+ };
+
+ var ENTITIES = {
+ LT : '<',
+ GT : '>',
+ AMP : '&',
+ NBSP : '\240',
+ QUOT : '"',
+ APOS : '\''
+ };
+
+ function escapeOneEntity(m) {
+ var name = m[1].toUpperCase();
+ if (ENTITIES.hasOwnProperty(s)) { return ENTITIES[name]; }
+ m = name.match(/^#(\d+)$/);
+ if (m) {
+ return String.fromCharCode(parseInt(m[1], 10));
+ } else if (!!(m = name.match(/^#x([0-9A-F]+)$/))) {
+ return String.fromCharCode(parseInt(m[1], 16));
+ }
+ return '';
+ }
+
+ function unescapeEntities(s) {
+ return s.replace(/&(#\d+|#x[\da-f]+|\w+);/g, escapeOneEntity);
+ }
+
+ function unescapedValueForAttrib(s) {
+ var m = s.match(/=\s*([\"\']?)?(.*)\1/);
+ if (m) {
+ return unescapeEntities(m[2]);
+ } else {
+ return null;
+ }
+ }
+
+ function escapeAttrib(s) {
+ return s.replace(/&/g, '&').replace(/</g, '<').replace(/&/g, '>')
+ .replace(/\"/g, '"');
+ }
+
+ /** actually does the sanitizing. */
+ return function html_sanitize(html, opt_urlXform, opt_nmTokenXform) {
+ var toks = lex(html);
+ var out = [];
+
+ var ignoring = false;
+ for (var i = 0; i < toks.length; ++i) {
+ var tok = toks[i], type = toks[++i];
+ //alert('tok=' + tok + ', type=' + type + ', ignoring=' + ignoring);
+ if (TOK_TAG_BEGIN === type) {
+ var name = tok.replace(/^[<\/]+/, '').toUpperCase();
+ ignoring = !ELEMENTS.hasOwnProperty(name) || (ELEMENTS[name] & UNSAFE);
+ } else if (TOK_ATTRIB === type && !ignoring) {
+ var name = tok.match(/\w+/)[0].toUpperCase();
+ if (!ATTRIBS.hasOwnProperty(name)) { continue; }
+ var flags = ATTRIBS[name];
+ if (flags & (SCRIPT_TYPE | STYLE_TYPE)) { continue; }
+ if (flags) {
+ // apply transforms
+ // unescape value, transform it. skip if null, otherwise reescape.
+ var value = unescapedValueForAttrib(tok);
+ if (null == value) { continue; }
+ if ((flags & URI_TYPE) && opt_urlXform) {
+ value = opt_urlXform(value);
+ }
+ if ((flags & NMTOKEN_TYPE) && opt_nmTokenXform) {
+ value = opt_nmTokenXForm(value);
+ }
+ if (null == value) { continue; }
+ tok = name + '="' + escapeAttrib(value) + '"';
+ }
+ }
+ if (!ignoring) { out.push(tok); }
+ // TODO: some way of enforcing attribute constraints
+ if (TOK_TAG_END === type) { ignoring = false; }
+ }
+ return out.join('');
+ };
+
+})();
Modified: incubator/shindig/trunk/features/opensocial-reference/container.js
URL:
http://svn.apache.org/viewvc/incubator/shindig/trunk/features/opensocial-reference/container.js?rev=611350&r1=611349&r2=611350&view=diff
==============================================================================
--- incubator/shindig/trunk/features/opensocial-reference/container.js
(original)
+++ incubator/shindig/trunk/features/opensocial-reference/container.js Fri Jan
11 18:08:32 2008
@@ -21,9 +21,7 @@
* @constructor
* @private
*/
-opensocial.Container = function() {
- this.cajaEnabled_ = false;
-};
+opensocial.Container = function() {};
/**
@@ -290,8 +288,7 @@
*/
opensocial.Container.prototype.newCollection = function(array, opt_offset,
opt_totalSize) {
- return this.wrapCollectionWithCaja_(new opensocial.Collection(array,
- opt_offset, opt_totalSize));
+ return new opensocial.Collection(array, opt_offset, opt_totalSize);
};
@@ -302,8 +299,7 @@
*/
opensocial.Container.prototype.newPerson = function(opt_params, opt_isOwner,
opt_isViewer) {
- return this.wrapPersonWithCaja_(new opensocial.Person(opt_params,
opt_isOwner,
- opt_isViewer));
+ return new opensocial.Person(opt_params, opt_isOwner, opt_isViewer);
};
@@ -321,7 +317,7 @@
*/
opensocial.Container.prototype.newActivity = function(title,
opt_params) {
- return this.wrapActivityWithCaja_(new opensocial.Activity(title,
opt_params));
+ return new opensocial.Activity(title, opt_params);
};
@@ -340,8 +336,7 @@
*/
opensocial.Container.prototype.newActivityMediaItem = function(mimeType, url,
opt_params) {
- return this.wrapActivityMediaItemWithCaja_(
- new opensocial.Activity.MediaItem(mimeType, url, opt_params));
+ return new opensocial.Activity.MediaItem(mimeType, url, opt_params);
};
@@ -352,8 +347,8 @@
*/
opensocial.Container.prototype.newResponseItem = function(originalDataRequest,
data, opt_errorCode, opt_errorMessage) {
- return this.wrapResponseItemWithCaja_(new opensocial.ResponseItem(
- originalDataRequest, data, opt_errorCode, opt_errorMessage));
+ return new opensocial.ResponseItem(originalDataRequest, data, opt_errorCode,
+ opt_errorMessage);
};
@@ -364,8 +359,7 @@
*/
opensocial.Container.prototype.newDataResponse = function(responseItems,
opt_globalError) {
- return this.wrapDataResponseWithCaja_(new opensocial.DataResponse(
- responseItems, opt_globalError));
+ return new opensocial.DataResponse(responseItems, opt_globalError);
};
@@ -377,7 +371,7 @@
* @private
*/
opensocial.Container.prototype.newDataRequest = function() {
- return this.wrapDataRequestWithCaja_(new opensocial.DataRequest());
+ return new opensocial.DataRequest();
};
@@ -389,8 +383,8 @@
*/
opensocial.Container.prototype.newEnvironment = function(domain, surface,
supportedSurfaces, supportedFields, opt_params) {
- return this.wrapEnvironmentWithCaja_(new opensocial.Environment(domain,
- surface, supportedSurfaces, supportedFields, opt_params));
+ return new opensocial.Environment(domain, surface, supportedSurfaces,
+ supportedFields, opt_params);
};
@@ -402,8 +396,7 @@
*/
opensocial.Container.prototype.newSurface = function(name,
opt_isPrimaryContent) {
- return this.wrapSurfaceWithCaja_(new opensocial.Surface(name,
- opt_isPrimaryContent));
+ return new opensocial.Surface(name, opt_isPrimaryContent);
};
@@ -439,38 +432,34 @@
var outers = caja.copy(___.sharedOuters);
- // TODO(doll): Is this the way all containers should do this?
+ // TODO(doll): We need to add caja allows for the gadgets namespace so that
+ // this works properly. It does not belong in gadgets.
var igOnload = window["_IG_RegisterOnloadHandler"];
if (igOnload) {
outers._IG_RegisterOnloadHandler = ___.simpleFunc(igOnload);
}
- // TODO(doll): Remove need for this
- outers.expose = function expose(name, func) {
- // TODO(benl): we should check that name does not contain
- // anything except numbers and letters.
- eval(name + ' = func;');
- };
-
- outers.emitHtml___ = function emitHtml(html) {
- // TODO(doll): This only works for the sample container. Really emitHtml
- // should be a passed in function
- var oldHtml = document.getElementById("gadgetContent").innerHTML;
- document.getElementById("gadgetContent").innerHTML = oldHtml + html;
+ outers.emitHtml___ = function emitHtml(var_args) {
+ var html = Array.prototype.slice.call(arguments, 0).join('');
+ document.write(html);
};
-
outers.document = function() {};
outers.document.getElementById = function(id) {
// TODO(benl): namespace-ize id.
- var element = document.getElementById(id);
- // TODO(benl): replace innerHTML with hidden getter/setter
- ___.allowSet(element, 'innerHTML');
+ var element = document.getElementById("DOM-PREFIX-" + id);
+ if (element !== null) {
+ ___.useSetHandler(element, 'innerHTML', function(html) {
+ var temp = html_sanitize(html);
+ return this.innerHTML = temp;
+ });
+ }
return element;
};
___.allowCall(outers.document, 'getElementById');
+ // Adding all of the available opensocial calls as defined in the spec
outers.opensocial = opensocial;
___.allowCall(outers.opensocial, 'requestCreateActivity');
___.allowCall(outers.opensocial, 'hasPermission');
@@ -481,122 +470,74 @@
___.allowCall(outers.opensocial, 'newActivity');
___.allowCall(outers.opensocial, 'newActivityMediaItem');
+ ___.allowCall(opensocial.Collection.prototype, 'getById');
+ ___.allowCall(opensocial.Collection.prototype, 'size');
+ ___.allowCall(opensocial.Collection.prototype, 'each');
+ ___.allowCall(opensocial.Collection.prototype, 'asArray');
+ ___.allowCall(opensocial.Collection.prototype, 'getTotalSize');
+ ___.allowCall(opensocial.Collection.prototype, 'getOffset');
+
+ // TODO(doll): Call caja method to support all array calls once it exists
+ ___.allowCall(Array.prototype, 'push');
+ ___.allowCall(Array.prototype, 'sort');
+
+ ___.allowCall(opensocial.Person.prototype, 'getId');
+ ___.allowCall(opensocial.Person.prototype, 'getDisplayName');
+ ___.allowCall(opensocial.Person.prototype, 'getField');
+ ___.allowCall(opensocial.Person.prototype, 'isViewer');
+ ___.allowCall(opensocial.Person.prototype, 'isOwner');
+
+ ___.allowCall(opensocial.Activity.prototype, 'getId');
+ ___.allowCall(opensocial.Activity.prototype, 'getField');
+
+ ___.allowCall(opensocial.Activity.MediaItem.prototype, 'getField');
+
+ ___.allowCall(opensocial.ResponseItem.prototype, 'hadError');
+ ___.allowCall(opensocial.ResponseItem.prototype, 'getError');
+ ___.allowCall(opensocial.ResponseItem.prototype, 'getOriginalDataRequest');
+ ___.allowCall(opensocial.ResponseItem.prototype, 'getData');
+
+ ___.allowCall(opensocial.DataResponse.prototype, 'hadError');
+ ___.allowCall(opensocial.DataResponse.prototype, 'get');
+
+ ___.allowCall(opensocial.DataRequest.prototype, 'getRequestObjects');
+ ___.allowCall(opensocial.DataRequest.prototype, 'add');
+ ___.allowCall(opensocial.DataRequest.prototype, 'send');
+ ___.allowCall(opensocial.DataRequest.prototype, 'newFetchPersonRequest');
+ ___.allowCall(opensocial.DataRequest.prototype, 'newFetchPeopleRequest');
+ ___.allowCall(opensocial.DataRequest.prototype,
'newFetchGlobalAppDataRequest');
+ ___.allowCall(opensocial.DataRequest.prototype,
'newFetchInstanceAppDataRequest');
+ ___.allowCall(opensocial.DataRequest.prototype,
'newUpdateInstanceAppDataRequest');
+ ___.allowCall(opensocial.DataRequest.prototype,
'newFetchPersonAppDataRequest');
+ ___.allowCall(opensocial.DataRequest.prototype,
'newUpdatePersonAppDataRequest');
+ ___.allowCall(opensocial.DataRequest.prototype, 'newFetchActivitiesRequest');
+
+ ___.allowCall(opensocial.Environment.prototype, 'getDomain');
+ ___.allowCall(opensocial.Environment.prototype, 'getSurface');
+ ___.allowCall(opensocial.Environment.prototype, 'getSupportedSurfaces');
+ ___.allowCall(opensocial.Environment.prototype, 'getParams');
+ ___.allowCall(opensocial.Environment.prototype, 'supportsField');
+ ___.allowCall(opensocial.Environment.prototype, 'hasCapability');
+
+ ___.allowCall(opensocial.Surface.prototype, 'getName');
+ ___.allowCall(opensocial.Surface.prototype, 'isPrimaryContent');
+
var moduleHandler = ___.freeze({
getOuters: ___.simpleFunc(function() { return outers; }),
handle: ___.simpleFunc(function(newModule) { newModule(outers); })
});
-
- this.cajaEnabled_ = true;
___.setNewModuleHandler(moduleHandler);
};
-
-opensocial.Container.prototype.wrapCollectionWithCaja_ = function(collection) {
- if (this.cajaEnabled_) {
- ___.allowCall(collection, 'getById');
- ___.allowCall(collection, 'size');
- ___.allowCall(collection, 'each');
- ___.allowCall(collection, 'asArray');
- ___.allowCall(collection, 'getTotalSize');
- ___.allowCall(collection, 'getOffset');
-
- // TODO(doll): Call caja method to support all array calls once it exists
- ___.allowCall(collection.asArray(), 'push');
- ___.allowCall(collection.asArray(), 'sort');
- }
- return collection;
-};
-
-
-opensocial.Container.prototype.wrapPersonWithCaja_ = function(person) {
- if (this.cajaEnabled_) {
- ___.allowCall(person, 'getId');
- ___.allowCall(person, 'getDisplayName');
- ___.allowCall(person, 'getField');
- ___.allowCall(person, 'isViewer');
- ___.allowCall(person, 'isOwner');
- }
- return person;
-};
-
-
-opensocial.Container.prototype.wrapActivityWithCaja_ = function(activity) {
- if (this.cajaEnabled_) {
- ___.allowCall(activity, 'getId');
- ___.allowCall(activity, 'getField');
- }
- return activity;
-};
-
-
-opensocial.Container.prototype.wrapActivityMediaItemWithCaja_ = function(
- mediaItem) {
- if (this.cajaEnabled_) {
- ___.allowCall(mediaItem, 'getField');
- }
- return mediaItem;
-};
-
-
-opensocial.Container.prototype.wrapResponseItemWithCaja_ = function(
- responseItem) {
- if (this.cajaEnabled_) {
- ___.allowCall(responseItem, 'hadError');
- ___.allowCall(responseItem, 'getError');
- ___.allowCall(responseItem, 'getOriginalDataRequest');
- ___.allowCall(responseItem, 'getData');
- }
- return responseItem;
-};
-
-
-opensocial.Container.prototype.wrapDataResponseWithCaja_ = function(
- dataResponse) {
- if (this.cajaEnabled_) {
- ___.allowCall(dataResponse, 'hadError');
- ___.allowCall(dataResponse, 'get');
- }
- return dataResponse;
-};
-
-
-opensocial.Container.prototype.wrapDataRequestWithCaja_ = function(request) {
- if (this.cajaEnabled_) {
- ___.allowCall(request, 'getRequestObjects');
- ___.allowCall(request, 'add');
- ___.allowCall(request, 'send');
- ___.allowCall(request, 'newFetchPersonRequest');
- ___.allowCall(request, 'newFetchPeopleRequest');
- ___.allowCall(request, 'newFetchGlobalAppDataRequest');
- ___.allowCall(request, 'newFetchInstanceAppDataRequest');
- ___.allowCall(request, 'newUpdateInstanceAppDataRequest');
- ___.allowCall(request, 'newFetchPersonAppDataRequest');
- ___.allowCall(request, 'newUpdatePersonAppDataRequest');
- ___.allowCall(request, 'newFetchActivitiesRequest');
- }
- return request;
-};
-
-
-opensocial.Container.prototype.wrapEnvironmentWithCaja_ = function(
- environment) {
- if (this.cajaEnabled_) {
- ___.allowCall(environment, 'getDomain');
- ___.allowCall(environment, 'getSurface');
- ___.allowCall(environment, 'getSupportedSurfaces');
- ___.allowCall(environment, 'getParams');
- ___.allowCall(environment, 'supportsField');
- ___.allowCall(environment, 'hasCapability');
- }
- return environment;
-};
-
-
-opensocial.Container.prototype.wrapSurfaceWithCaja_ = function(surface) {
- if (this.cajaEnabled_) {
- ___.allowCall(surface, 'getName');
- ___.allowCall(surface, 'isPrimaryContent');
- }
- return surface;
-};
+/**
+ * Default taming is to return obj itself. Depending on
+ * other taming decisions, it may be more appropriate to
+ * return an interposed wrapper.
+ */
+function plugin_tamed(obj) { return obj; }
+
+function plugin_dispatchEvent___(thisNode, event, pluginId, handlerName) {
+ return ___.getOuters(pluginId)[handlerName](plugin_tamed(thisNode),
+ plugin_tamed(event));
+}
\ No newline at end of file