You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by hs...@apache.org on 2012/07/24 02:40:52 UTC
svn commit: r1364855 - in /shindig/trunk: config/
features/src/main/javascript/features/core.io/
features/src/main/javascript/features/core.util.base/
Author: hsaputra
Date: Tue Jul 24 00:40:52 2012
New Revision: 1364855
URL: http://svn.apache.org/viewvc?rev=1364855&view=rev
Log:
Fix memory leak in IE7 for Ajax call in core.io feature using polling technique to do the xhr state change handler. CR: https://reviews.apache.org/r/6070/.
Added:
shindig/trunk/features/src/main/javascript/features/core.util.base/taming.js
Modified:
shindig/trunk/config/container.js
shindig/trunk/features/src/main/javascript/features/core.io/io.js
shindig/trunk/features/src/main/javascript/features/core.util.base/base.js
shindig/trunk/features/src/main/javascript/features/core.util.base/feature.xml
Modified: shindig/trunk/config/container.js
URL: http://svn.apache.org/viewvc/shindig/trunk/config/container.js?rev=1364855&r1=1364854&r2=1364855&view=diff
==============================================================================
--- shindig/trunk/config/container.js (original)
+++ shindig/trunk/config/container.js Tue Jul 24 00:40:52 2012
@@ -162,7 +162,10 @@
"unparseableCruft" : "throw 1; < don't be evil' >",
// This variable is needed during the config init to parse config augmentation
- "jsPath" : "${Cur['gadgets.uri.js.path']}"
+ "jsPath" : "${Cur['gadgets.uri.js.path']}",
+
+ // interval in milliseconds used to poll xhr request for the readyState
+ "xhrPollIntervalMs" : 50
},
"views" : {
"profile" : {
Modified: shindig/trunk/features/src/main/javascript/features/core.io/io.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/core.io/io.js?rev=1364855&r1=1364854&r2=1364855&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/core.io/io.js (original)
+++ shindig/trunk/features/src/main/javascript/features/core.io/io.js Tue Jul 24 00:40:52 2012
@@ -30,6 +30,12 @@
*/
gadgets.io = function() {
+ // Ever incrementing Ajax transaction id
+ var ioTransactionId = 0;
+
+ // Object to store ids for the ajax poll to avoid IE memory leak
+ var ajaxPollQ = {};
+
/**
* Holds configuration-related data such as proxy urls.
*/
@@ -259,8 +265,17 @@ gadgets.io = function() {
xhr.open(method, proxyUrl, true);
if (callback) {
- xhr.onreadystatechange = gadgets.util.makeClosure(
- null, processResponseFunction, realUrl, callback, params, xhr);
+ var closureCallback = gadgets.util.makeClosure(null, processResponseFunction, realUrl,
+ callback, params, xhr);
+
+ // check for alternate ajax for onreadystatechange event handler
+ var shouldPoll = gadgets.util.shouldPollXhrReadyStateChange();
+ if(shouldPoll) {
+ handleReadyState(xhr, closureCallback);
+ }
+ else {
+ xhr.onreadystatechange = closureCallback;
+ }
}
if (typeof opt_headers === 'string') {
@@ -285,6 +300,38 @@ gadgets.io = function() {
}
/**
+ * Helper function to use poll setInterval to call the callback for Ajax to avoid
+ * memory leak in certain browsers (eg: IE7) due to circular linking.
+ *
+ * The function will create interval polling to poll the XHR object's readyState
+ * property instead of binding a callback to the onreadystatechange event.
+ *
+ * @param {xhr} The Ajax object
+ * @param {function} The callback function for the Ajax call
+ * @return void
+ */
+ function handleReadyState(xhr, callback) {
+ var tempTid = ioTransactionId;
+ var pollInterval = config['xhrPollIntervalMs'] || 50;
+ ajaxPollQ[tempTid] = window.setInterval(
+ function() {
+ if(xhr && xhr.readyState === 4) {
+ // Clear the polling interval for the transaction and remove
+ // the reference from ajaxPollQ
+ window.clearInterval(ajaxPollQ[tempTid]);
+ delete ajaxPollQ[tempTid];
+
+ // call the callback
+ if(callback) {
+ callback();
+ }
+ }
+ }, pollInterval);
+
+ ioTransactionId++;
+ }
+
+ /**
* Satisfy a request with data that is prefetched as per the gadget Preload
* directive. The preloader will only satisfy a request for a specific piece
* of content once.
Modified: shindig/trunk/features/src/main/javascript/features/core.util.base/base.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/core.util.base/base.js?rev=1364855&r1=1364854&r2=1364855&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/core.util.base/base.js (original)
+++ shindig/trunk/features/src/main/javascript/features/core.util.base/base.js Tue Jul 24 00:40:52 2012
@@ -75,3 +75,15 @@ gadgets.util.makeEnum = function(values)
return obj;
};
+/**
+ * Check if need to poll for Ajax ready state change to avoid browsers memory leak.
+ * The default implementation will check for IE7 browsers.
+ *
+ * @return true if we need to add polling to handle ready state change and false otherwise.
+ */
+gadgets.util.shouldPollXhrReadyStateChange = function() {
+ if (document.all && !document.querySelector) {
+ return true;
+ }
+ return false;
+}
Modified: shindig/trunk/features/src/main/javascript/features/core.util.base/feature.xml
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/core.util.base/feature.xml?rev=1364855&r1=1364854&r2=1364855&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/core.util.base/feature.xml (original)
+++ shindig/trunk/features/src/main/javascript/features/core.util.base/feature.xml Tue Jul 24 00:40:52 2012
@@ -21,9 +21,11 @@
<dependency>globals</dependency>
<all>
<script src="base.js"/>
+ <script src="taming.js" caja="1"/>
<api>
<exports type="js">gadgets.util.makeClosure</exports>
<exports type="js">gadgets.util.makeEnum</exports>
+ <exports type="js">gadgets.util.shouldPollXhrReadyStateChange</exports>
</api>
</all>
</feature>
Added: shindig/trunk/features/src/main/javascript/features/core.util.base/taming.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/core.util.base/taming.js?rev=1364855&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/core.util.base/taming.js (added)
+++ shindig/trunk/features/src/main/javascript/features/core.util.base/taming.js Tue Jul 24 00:40:52 2012
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/**
+ * @class
+ * Tame and expose core gadgets.* API to cajoled gadgets
+ */
+tamings___.push(function(imports) {
+ caja___.whitelistFuncs([
+ [gadgets.util, 'makeClosure'],
+ [gadgets.util, 'makeEnum'],
+ [gadgets.util, 'shouldPollXhrReadyStateChange']
+ ]);
+});