зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1181239 - Enable eslint 'use strict' function rule for Loop's content code. r/rs=dmose
This commit is contained in:
Родитель
07eae88d8c
Коммит
38138f860a
|
@ -61,7 +61,7 @@
|
|||
"object-curly-spacing": 0, // [2, "always"],
|
||||
"quotes": [2, "double", "avoid-escape"],
|
||||
"spaced-comment": [2, "always"],
|
||||
"strict": 0, // [2, "function"],
|
||||
"strict": [2, "function"],
|
||||
// eslint-plugin-react rules. These are documented at
|
||||
// <https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules>
|
||||
"react/jsx-quotes": [2, "double", "avoid-escape"],
|
||||
|
|
|
@ -10,6 +10,8 @@ loop.store = loop.store || {};
|
|||
* the window data and store the window type.
|
||||
*/
|
||||
loop.store.ConversationAppStore = (function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
var loop = loop || {};
|
||||
loop.conversationViews = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var CALL_STATES = loop.store.CALL_STATES;
|
||||
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
var loop = loop || {};
|
||||
loop.conversationViews = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var CALL_STATES = loop.store.CALL_STATES;
|
||||
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
|
||||
|
|
|
@ -6,6 +6,8 @@ var loop = loop || {};
|
|||
loop.store = loop.store || {};
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
var CALL_TYPES = loop.shared.utils.CALL_TYPES;
|
||||
var REST_ERRNOS = loop.shared.utils.REST_ERRNOS;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
var loop = loop || {};
|
||||
loop.Dispatcher = (function() {
|
||||
"use strict";
|
||||
|
||||
function Dispatcher() {
|
||||
this._eventData = {};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
var loop = loop || {};
|
||||
loop.OTSdkDriver = (function() {
|
||||
"use strict";
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
|
||||
|
|
|
@ -113,6 +113,8 @@ loop.store.createStore = (function() {
|
|||
* });
|
||||
*/
|
||||
loop.store.StoreMixin = (function() {
|
||||
"use strict";
|
||||
|
||||
var _stores = {};
|
||||
function StoreMixin(id) {
|
||||
function _getStore() {
|
||||
|
|
|
@ -6,6 +6,8 @@ var loop = loop || {};
|
|||
loop.shared = loop.shared || {};
|
||||
loop.shared.views = loop.shared.views || {};
|
||||
loop.shared.views.chat = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
var sharedViews = loop.shared.views;
|
||||
|
|
|
@ -6,6 +6,8 @@ var loop = loop || {};
|
|||
loop.shared = loop.shared || {};
|
||||
loop.shared.views = loop.shared.views || {};
|
||||
loop.shared.views.chat = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
var sharedViews = loop.shared.views;
|
||||
|
|
|
@ -83,6 +83,8 @@ app.use("/test", express.static(__dirname + "/../test"));
|
|||
// As we don't have hashes on the urls, the best way to serve the index files
|
||||
// appears to be to be to closely filter the url and match appropriately.
|
||||
function serveIndex(req, res) {
|
||||
"use strict";
|
||||
|
||||
return res.sendfile(__dirname + "/content/index.html");
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
describe("loop.store.ConversationAppStore", function () {
|
||||
"use strict";
|
||||
|
||||
var expect = chai.expect;
|
||||
var sharedActions = loop.shared.actions;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
describe("loop.store.StandaloneAppStore", function () {
|
||||
"use strict";
|
||||
|
||||
var expect = chai.expect;
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedUtils = loop.shared.utils;
|
||||
|
|
|
@ -2,30 +2,33 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* /!\ FIXME: THIS IS A HORRID HACK which fakes both the mozL10n and webL10n
|
||||
* objects and makes them returning the string id and serialized vars if any,
|
||||
* for any requested string id.
|
||||
* @type {Object}
|
||||
*/
|
||||
navigator.mozL10n = document.mozL10n = {
|
||||
initialize: function(){},
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
getDirection: function(){},
|
||||
/**
|
||||
* /!\ FIXME: THIS IS A HORRID HACK which fakes both the mozL10n and webL10n
|
||||
* objects and makes them returning the string id and serialized vars if any,
|
||||
* for any requested string id.
|
||||
* @type {Object}
|
||||
*/
|
||||
navigator.mozL10n = document.mozL10n = {
|
||||
initialize: function(){},
|
||||
|
||||
get: function(stringId, vars) {
|
||||
getDirection: function(){},
|
||||
|
||||
// upcase the first letter
|
||||
var readableStringId = stringId.replace(/^./, function(match) {
|
||||
"use strict";
|
||||
return match.toUpperCase();
|
||||
}).replace(/_/g, " "); // and convert _ chars to spaces
|
||||
get: function(stringId, vars) {
|
||||
|
||||
return "" + readableStringId + (vars ? ";" + JSON.stringify(vars) : "");
|
||||
},
|
||||
// upcase the first letter
|
||||
var readableStringId = stringId.replace(/^./, function(match) {
|
||||
return match.toUpperCase();
|
||||
}).replace(/_/g, " "); // and convert _ chars to spaces
|
||||
|
||||
/* For timestamp formatting reasons. */
|
||||
language: {
|
||||
code: "en-US"
|
||||
}
|
||||
};
|
||||
return "" + readableStringId + (vars ? ";" + JSON.stringify(vars) : "");
|
||||
},
|
||||
|
||||
/* For timestamp formatting reasons. */
|
||||
language: {
|
||||
code: "en-US"
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -114,52 +114,56 @@ var fakeContacts = [{
|
|||
updated: 1406798311748
|
||||
}];
|
||||
|
||||
/**
|
||||
* Faking the mozLoop object which doesn't exist in regular web pages.
|
||||
* @type {Object}
|
||||
*/
|
||||
navigator.mozLoop = {
|
||||
ensureRegistered: function() {},
|
||||
getAudioBlob: function(){},
|
||||
getLoopPref: function(pref) {
|
||||
switch(pref) {
|
||||
// Ensure we skip FTE completely.
|
||||
case "gettingStarted.seen":
|
||||
case "contacts.gravatars.promo":
|
||||
case "contextInConversations.enabled":
|
||||
return true;
|
||||
case "contacts.gravatars.show":
|
||||
return false;
|
||||
}
|
||||
},
|
||||
hasEncryptionKey: true,
|
||||
setLoopPref: function(){},
|
||||
releaseCallData: function() {},
|
||||
copyString: function() {},
|
||||
getUserAvatar: function(emailAddress) {
|
||||
return "http://www.gravatar.com/avatar/" + (Math.ceil(Math.random() * 3) === 2 ?
|
||||
"0a996f0fe2727ef1668bdb11897e4459" : "foo") + ".jpg?default=blank&s=40";
|
||||
},
|
||||
getSelectedTabMetadata: function(callback) {
|
||||
callback({
|
||||
previews: ["chrome://branding/content/about-logo.png"],
|
||||
description: "sample webpage description",
|
||||
url: "https://www.example.com"
|
||||
});
|
||||
},
|
||||
contacts: {
|
||||
getAll: function(callback) {
|
||||
callback(null, [].concat(fakeContacts));
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Faking the mozLoop object which doesn't exist in regular web pages.
|
||||
* @type {Object}
|
||||
*/
|
||||
navigator.mozLoop = {
|
||||
ensureRegistered: function() {},
|
||||
getAudioBlob: function(){},
|
||||
getLoopPref: function(pref) {
|
||||
switch(pref) {
|
||||
// Ensure we skip FTE completely.
|
||||
case "gettingStarted.seen":
|
||||
case "contacts.gravatars.promo":
|
||||
case "contextInConversations.enabled":
|
||||
return true;
|
||||
case "contacts.gravatars.show":
|
||||
return false;
|
||||
}
|
||||
},
|
||||
on: function() {}
|
||||
},
|
||||
rooms: {
|
||||
getAll: function(version, callback) {
|
||||
callback(null, [].concat(fakeRooms));
|
||||
hasEncryptionKey: true,
|
||||
setLoopPref: function(){},
|
||||
releaseCallData: function() {},
|
||||
copyString: function() {},
|
||||
getUserAvatar: function(emailAddress) {
|
||||
return "http://www.gravatar.com/avatar/" + (Math.ceil(Math.random() * 3) === 2 ?
|
||||
"0a996f0fe2727ef1668bdb11897e4459" : "foo") + ".jpg?default=blank&s=40";
|
||||
},
|
||||
on: function() {}
|
||||
},
|
||||
fxAEnabled: true,
|
||||
startAlerting: function() {},
|
||||
stopAlerting: function() {}
|
||||
};
|
||||
getSelectedTabMetadata: function(callback) {
|
||||
callback({
|
||||
previews: ["chrome://branding/content/about-logo.png"],
|
||||
description: "sample webpage description",
|
||||
url: "https://www.example.com"
|
||||
});
|
||||
},
|
||||
contacts: {
|
||||
getAll: function(callback) {
|
||||
callback(null, [].concat(fakeContacts));
|
||||
},
|
||||
on: function() {}
|
||||
},
|
||||
rooms: {
|
||||
getAll: function(version, callback) {
|
||||
callback(null, [].concat(fakeRooms));
|
||||
},
|
||||
on: function() {}
|
||||
},
|
||||
fxAEnabled: true,
|
||||
startAlerting: function() {},
|
||||
stopAlerting: function() {}
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -12,159 +12,163 @@
|
|||
*/
|
||||
window.queuedFrames = [];
|
||||
|
||||
/**
|
||||
* Renders this.props.children inside an <iframe>.
|
||||
*
|
||||
* Works by creating the iframe, waiting for that to finish, and then
|
||||
* rendering the children inside that. Waits for a while in the hopes that the
|
||||
* contents will have been rendered, and then fires a callback indicating that.
|
||||
*
|
||||
* @see onContentsRendered for the gory details about this.
|
||||
*
|
||||
* @type {ReactComponentFactory<P>}
|
||||
*/
|
||||
window.Frame = React.createClass({
|
||||
propTypes: {
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.element,
|
||||
React.PropTypes.arrayOf(React.PropTypes.element)
|
||||
]).isRequired,
|
||||
className: React.PropTypes.string,
|
||||
/* By default, <link rel="stylesheet> nodes from the containing frame's
|
||||
head will be cloned into this iframe. However, if the link also has
|
||||
a "class" attribute, we only clone it if that class attribute is the
|
||||
same as cssClass. This allows us to avoid injecting stylesheets that
|
||||
aren't intended for this rendering of this component. */
|
||||
cssClass: React.PropTypes.string,
|
||||
head: React.PropTypes.node,
|
||||
height: React.PropTypes.number,
|
||||
onContentsRendered: React.PropTypes.func,
|
||||
style: React.PropTypes.object,
|
||||
width: React.PropTypes.number
|
||||
},
|
||||
render: function() {
|
||||
return React.createElement("iframe", {
|
||||
style: this.props.style,
|
||||
head: this.props.head,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
className: this.props.className
|
||||
});
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.renderFrameContents();
|
||||
},
|
||||
renderFrameContents: function() {
|
||||
function isStyleSheet(node) {
|
||||
return node.tagName.toLowerCase() === "link" &&
|
||||
node.getAttribute("rel") === "stylesheet";
|
||||
}
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var childDoc = this.getDOMNode().contentDocument;
|
||||
if (childDoc && childDoc.readyState === "complete") {
|
||||
// Remove this from the queue.
|
||||
window.queuedFrames.splice(window.queuedFrames.indexOf(this), 1);
|
||||
/**
|
||||
* Renders this.props.children inside an <iframe>.
|
||||
*
|
||||
* Works by creating the iframe, waiting for that to finish, and then
|
||||
* rendering the children inside that. Waits for a while in the hopes that the
|
||||
* contents will have been rendered, and then fires a callback indicating that.
|
||||
*
|
||||
* @see onContentsRendered for the gory details about this.
|
||||
*
|
||||
* @type {ReactComponentFactory<P>}
|
||||
*/
|
||||
window.Frame = React.createClass({
|
||||
propTypes: {
|
||||
children: React.PropTypes.oneOfType([
|
||||
React.PropTypes.element,
|
||||
React.PropTypes.arrayOf(React.PropTypes.element)
|
||||
]).isRequired,
|
||||
className: React.PropTypes.string,
|
||||
/* By default, <link rel="stylesheet> nodes from the containing frame's
|
||||
head will be cloned into this iframe. However, if the link also has
|
||||
a "class" attribute, we only clone it if that class attribute is the
|
||||
same as cssClass. This allows us to avoid injecting stylesheets that
|
||||
aren't intended for this rendering of this component. */
|
||||
cssClass: React.PropTypes.string,
|
||||
head: React.PropTypes.node,
|
||||
height: React.PropTypes.number,
|
||||
onContentsRendered: React.PropTypes.func,
|
||||
style: React.PropTypes.object,
|
||||
width: React.PropTypes.number
|
||||
},
|
||||
render: function() {
|
||||
return React.createElement("iframe", {
|
||||
style: this.props.style,
|
||||
head: this.props.head,
|
||||
width: this.props.width,
|
||||
height: this.props.height,
|
||||
className: this.props.className
|
||||
});
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.renderFrameContents();
|
||||
},
|
||||
renderFrameContents: function() {
|
||||
function isStyleSheet(node) {
|
||||
return node.tagName.toLowerCase() === "link" &&
|
||||
node.getAttribute("rel") === "stylesheet";
|
||||
}
|
||||
|
||||
var iframeHead = childDoc.querySelector("head");
|
||||
var parentHeadChildren = document.querySelector("head").children;
|
||||
var childDoc = this.getDOMNode().contentDocument;
|
||||
if (childDoc && childDoc.readyState === "complete") {
|
||||
// Remove this from the queue.
|
||||
window.queuedFrames.splice(window.queuedFrames.indexOf(this), 1);
|
||||
|
||||
[].forEach.call(parentHeadChildren, function(parentHeadNode) {
|
||||
var iframeHead = childDoc.querySelector("head");
|
||||
var parentHeadChildren = document.querySelector("head").children;
|
||||
|
||||
// if this node is a CSS stylesheet...
|
||||
if (isStyleSheet(parentHeadNode)) {
|
||||
// and it has a class different from the one that this frame does,
|
||||
// return immediately instead of appending it. Note that this
|
||||
// explicitly does not check for cssClass existence, because
|
||||
// non-existence of cssClass will be different from a style
|
||||
// element that does have a class on it, and we want it to return
|
||||
// in that case.
|
||||
if (parentHeadNode.hasAttribute("class") &&
|
||||
parentHeadNode.getAttribute("class") !== this.props.cssClass) {
|
||||
return;
|
||||
[].forEach.call(parentHeadChildren, function(parentHeadNode) {
|
||||
|
||||
// if this node is a CSS stylesheet...
|
||||
if (isStyleSheet(parentHeadNode)) {
|
||||
// and it has a class different from the one that this frame does,
|
||||
// return immediately instead of appending it. Note that this
|
||||
// explicitly does not check for cssClass existence, because
|
||||
// non-existence of cssClass will be different from a style
|
||||
// element that does have a class on it, and we want it to return
|
||||
// in that case.
|
||||
if (parentHeadNode.hasAttribute("class") &&
|
||||
parentHeadNode.getAttribute("class") !== this.props.cssClass) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
iframeHead.appendChild(parentHeadNode.cloneNode(true));
|
||||
}.bind(this));
|
||||
|
||||
var contents = React.createElement("div",
|
||||
undefined,
|
||||
this.props.head,
|
||||
this.props.children
|
||||
);
|
||||
|
||||
React.render(contents, childDoc.body, this.fireOnContentsRendered);
|
||||
|
||||
// Set the RTL mode. We assume for now that rtl is the only query parameter.
|
||||
//
|
||||
// See also "ShowCase" in ui-showcase.jsx
|
||||
if (document.location.search === "?rtl=1") {
|
||||
childDoc.documentElement.setAttribute("lang", "ar");
|
||||
childDoc.documentElement.setAttribute("dir", "rtl");
|
||||
}
|
||||
} else {
|
||||
// Queue it, only if it isn't already. We do need to set the timeout
|
||||
// regardless, as this function can get re-entered several times.
|
||||
if (window.queuedFrames.indexOf(this) === -1) {
|
||||
window.queuedFrames.push(this);
|
||||
}
|
||||
setTimeout(this.renderFrameContents, 0);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Fires the onContentsRendered callback passed in via this.props,
|
||||
* with the first argument set to the window global used by the iframe.
|
||||
* This is useful in extracting things specific to that iframe (such as
|
||||
* the matchMedia function) for use by code running in that iframe. Once
|
||||
* React gets a more complete "context" feature:
|
||||
*
|
||||
* https://facebook.github.io/react/blog/2015/02/24/streamlining-react-elements.html#solution-make-context-parent-based-instead-of-owner-based
|
||||
*
|
||||
* we should be able to avoid reaching into the DOM like this.
|
||||
*
|
||||
* XXX wait a little while. After React has rendered this iframe (eg the
|
||||
* virtual DOM cache gets flushed to the browser), there's still more stuff
|
||||
* that needs to happen before layout completes. If onContentsRendered fires
|
||||
* before that happens, the wrong sizes (eg remote stream vertical height
|
||||
* of 0) are used to compute the position in the MediaSetupStream, resulting
|
||||
* in everything looking wonky. One high likelihood candidate for the delay
|
||||
* here involves loading/decode poster images, but even using link
|
||||
* rel=prefetch on those isn't enough to workaround this problem, so there
|
||||
* may be more.
|
||||
*
|
||||
* There doesn't appear to be a good cross-browser way to handle this
|
||||
* at the moment without gross violation of encapsulation (see
|
||||
* http://stackoverflow.com/questions/27241186/how-to-determine-when-document-has-loaded-after-loading-external-csshttp://stackoverflow.com/questions/27241186/how-to-determine-when-document-has-loaded-after-loading-external-css
|
||||
* for discussion of a related problem.
|
||||
*
|
||||
* For now, just wait for multiple seconds. Yuck.
|
||||
*/
|
||||
fireOnContentsRendered: function() {
|
||||
if (!this.props.onContentsRendered) {
|
||||
return;
|
||||
}
|
||||
|
||||
var contentWindow;
|
||||
try {
|
||||
contentWindow = this.getDOMNode().contentWindow;
|
||||
if (!contentWindow) {
|
||||
throw new Error("no content window returned");
|
||||
}
|
||||
|
||||
iframeHead.appendChild(parentHeadNode.cloneNode(true));
|
||||
}.bind(this));
|
||||
|
||||
var contents = React.createElement("div",
|
||||
undefined,
|
||||
this.props.head,
|
||||
this.props.children
|
||||
);
|
||||
|
||||
React.render(contents, childDoc.body, this.fireOnContentsRendered);
|
||||
|
||||
// Set the RTL mode. We assume for now that rtl is the only query parameter.
|
||||
//
|
||||
// See also "ShowCase" in ui-showcase.jsx
|
||||
if (document.location.search === "?rtl=1") {
|
||||
childDoc.documentElement.setAttribute("lang", "ar");
|
||||
childDoc.documentElement.setAttribute("dir", "rtl");
|
||||
}
|
||||
} else {
|
||||
// Queue it, only if it isn't already. We do need to set the timeout
|
||||
// regardless, as this function can get re-entered several times.
|
||||
if (window.queuedFrames.indexOf(this) === -1) {
|
||||
window.queuedFrames.push(this);
|
||||
}
|
||||
setTimeout(this.renderFrameContents, 0);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Fires the onContentsRendered callback passed in via this.props,
|
||||
* with the first argument set to the window global used by the iframe.
|
||||
* This is useful in extracting things specific to that iframe (such as
|
||||
* the matchMedia function) for use by code running in that iframe. Once
|
||||
* React gets a more complete "context" feature:
|
||||
*
|
||||
* https://facebook.github.io/react/blog/2015/02/24/streamlining-react-elements.html#solution-make-context-parent-based-instead-of-owner-based
|
||||
*
|
||||
* we should be able to avoid reaching into the DOM like this.
|
||||
*
|
||||
* XXX wait a little while. After React has rendered this iframe (eg the
|
||||
* virtual DOM cache gets flushed to the browser), there's still more stuff
|
||||
* that needs to happen before layout completes. If onContentsRendered fires
|
||||
* before that happens, the wrong sizes (eg remote stream vertical height
|
||||
* of 0) are used to compute the position in the MediaSetupStream, resulting
|
||||
* in everything looking wonky. One high likelihood candidate for the delay
|
||||
* here involves loading/decode poster images, but even using link
|
||||
* rel=prefetch on those isn't enough to workaround this problem, so there
|
||||
* may be more.
|
||||
*
|
||||
* There doesn't appear to be a good cross-browser way to handle this
|
||||
* at the moment without gross violation of encapsulation (see
|
||||
* http://stackoverflow.com/questions/27241186/how-to-determine-when-document-has-loaded-after-loading-external-csshttp://stackoverflow.com/questions/27241186/how-to-determine-when-document-has-loaded-after-loading-external-css
|
||||
* for discussion of a related problem.
|
||||
*
|
||||
* For now, just wait for multiple seconds. Yuck.
|
||||
*/
|
||||
fireOnContentsRendered: function() {
|
||||
if (!this.props.onContentsRendered) {
|
||||
return;
|
||||
}
|
||||
|
||||
var contentWindow;
|
||||
try {
|
||||
contentWindow = this.getDOMNode().contentWindow;
|
||||
if (!contentWindow) {
|
||||
throw new Error("no content window returned");
|
||||
} catch (ex) {
|
||||
console.error("exception getting content window", ex);
|
||||
}
|
||||
|
||||
} catch (ex) {
|
||||
console.error("exception getting content window", ex);
|
||||
// Using bind to construct a "partial function", where |this| is unchanged,
|
||||
// but the first parameter is guaranteed to be set. Details at
|
||||
// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Example.3A_Partial_Functions
|
||||
setTimeout(this.props.onContentsRendered.bind(undefined, contentWindow),
|
||||
3000);
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
this.renderFrameContents();
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
React.unmountComponentAtNode(React.findDOMNode(this).contentDocument.body);
|
||||
}
|
||||
|
||||
// Using bind to construct a "partial function", where |this| is unchanged,
|
||||
// but the first parameter is guaranteed to be set. Details at
|
||||
// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Example.3A_Partial_Functions
|
||||
setTimeout(this.props.onContentsRendered.bind(undefined, contentWindow),
|
||||
3000);
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
this.renderFrameContents();
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
React.unmountComponentAtNode(React.findDOMNode(this).contentDocument.body);
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
|
Загрузка…
Ссылка в новой задаче