Bug 1176780 - Enable jsx-sort-props-types eslint rule for Loop. rs=dmose
authorMark Banner <standard8@mozilla.com>
Tue, 23 Jun 2015 23:11:48 -0700
changeset 250092 572593f71b17ed287241d217e9caf79a5182086f
parent 250091 2b391a831518764b800381e8eda7a8a6d58cbc6a
child 250093 3ae7fd12f53fa7955ab952273870f205a82de527
push id61434
push usercbook@mozilla.com
push dateWed, 24 Jun 2015 14:04:25 +0000
treeherdermozilla-inbound@d12f46ccb758 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmose
bugs1176780
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1176780 - Enable jsx-sort-props-types eslint rule for Loop. rs=dmose
browser/components/loop/.eslintrc
browser/components/loop/content/js/contacts.js
browser/components/loop/content/js/contacts.jsx
browser/components/loop/content/js/conversation.js
browser/components/loop/content/js/conversation.jsx
browser/components/loop/content/js/conversationViews.js
browser/components/loop/content/js/conversationViews.jsx
browser/components/loop/content/js/panel.js
browser/components/loop/content/js/panel.jsx
browser/components/loop/content/js/roomViews.js
browser/components/loop/content/js/roomViews.jsx
browser/components/loop/content/shared/js/feedbackViews.js
browser/components/loop/content/shared/js/feedbackViews.jsx
browser/components/loop/content/shared/js/views.js
browser/components/loop/content/shared/js/views.jsx
browser/components/loop/standalone/content/js/standaloneRoomViews.js
browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
browser/components/loop/standalone/content/js/webapp.js
browser/components/loop/standalone/content/js/webapp.jsx
browser/components/loop/ui/react-frame-component.js
browser/components/loop/ui/ui-showcase.js
browser/components/loop/ui/ui-showcase.jsx
--- a/browser/components/loop/.eslintrc
+++ b/browser/components/loop/.eslintrc
@@ -59,17 +59,17 @@
     "quotes": [2, "double", "avoid-escape"],
     "strict": 0,                  // [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"],
     "react/jsx-no-undef": 2,
     // Need to fix instances where this is failing.
     "react/jsx-sort-props": 2,
-    "react/jsx-sort-prop-types": 0,
+    "react/jsx-sort-prop-types": 2,
     "react/jsx-uses-vars": 2,
     // Need to fix the couple of instances which don't
     // currently pass this rule.
     "react/no-did-mount-set-state": 0,
     "react/no-did-update-set-state": 2,
     "react/no-unknown-property": 2,
     // Need to fix instances where this is currently failing
     "react/prop-types": 0,
--- a/browser/components/loop/content/js/contacts.js
+++ b/browser/components/loop/content/js/contacts.js
@@ -141,18 +141,18 @@ loop.contacts = (function(_, mozL10n) {
           )
         )
       );
     }
   });
 
   const ContactDropdown = React.createClass({displayName: "ContactDropdown",
     propTypes: {
-      handleAction: React.PropTypes.func.isRequired,
-      canEdit: React.PropTypes.bool
+      canEdit: React.PropTypes.bool,
+      handleAction: React.PropTypes.func.isRequired
     },
 
     getInitialState: function () {
       return {
         openDirUp: false
       };
     },
 
@@ -231,18 +231,18 @@ loop.contacts = (function(_, mozL10n) {
   const ContactDetail = React.createClass({displayName: "ContactDetail",
     getInitialState: function() {
       return {
         showMenu: false
       };
     },
 
     propTypes: {
-      handleContactAction: React.PropTypes.func,
-      contact: React.PropTypes.object.isRequired
+      contact: React.PropTypes.object.isRequired,
+      handleContactAction: React.PropTypes.func
     },
 
     _onBodyClick: function() {
       // Hide the menu after other click handlers have been invoked.
       setTimeout(this.hideDropdownMenu, 10);
     },
 
     showDropdownMenu: function() {
--- a/browser/components/loop/content/js/contacts.jsx
+++ b/browser/components/loop/content/js/contacts.jsx
@@ -141,18 +141,18 @@ loop.contacts = (function(_, mozL10n) {
           </ButtonGroup>
         </div>
       );
     }
   });
 
   const ContactDropdown = React.createClass({
     propTypes: {
-      handleAction: React.PropTypes.func.isRequired,
-      canEdit: React.PropTypes.bool
+      canEdit: React.PropTypes.bool,
+      handleAction: React.PropTypes.func.isRequired
     },
 
     getInitialState: function () {
       return {
         openDirUp: false
       };
     },
 
@@ -231,18 +231,18 @@ loop.contacts = (function(_, mozL10n) {
   const ContactDetail = React.createClass({
     getInitialState: function() {
       return {
         showMenu: false
       };
     },
 
     propTypes: {
-      handleContactAction: React.PropTypes.func,
-      contact: React.PropTypes.object.isRequired
+      contact: React.PropTypes.object.isRequired,
+      handleContactAction: React.PropTypes.func
     },
 
     _onBodyClick: function() {
       // Hide the menu after other click handlers have been invoked.
       setTimeout(this.hideDropdownMenu, 10);
     },
 
     showDropdownMenu: function() {
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -24,18 +24,18 @@ loop.conversation = (function(mozL10n) {
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationAppStore"),
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore),
-      mozLoop: React.PropTypes.object.isRequired
+      mozLoop: React.PropTypes.object.isRequired,
+      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore)
     },
 
     getInitialState: function() {
       return this.getStoreState();
     },
 
     render: function() {
       switch(this.state.windowType) {
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -24,18 +24,18 @@ loop.conversation = (function(mozL10n) {
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationAppStore"),
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore),
-      mozLoop: React.PropTypes.object.isRequired
+      mozLoop: React.PropTypes.object.isRequired,
+      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore)
     },
 
     getInitialState: function() {
       return this.getStoreState();
     },
 
     render: function() {
       switch(this.state.windowType) {
--- a/browser/components/loop/content/js/conversationViews.js
+++ b/browser/components/loop/content/js/conversationViews.js
@@ -357,19 +357,19 @@ loop.conversationViews = (function(mozL1
   /**
    * View for pending conversations. Displays a cancel button and appropriate
    * pending/ringing strings.
    */
   var PendingConversationView = React.createClass({displayName: "PendingConversationView",
     mixins: [sharedMixins.AudioMixin],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       callState: React.PropTypes.string,
       contact: React.PropTypes.object,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       enableCancelButton: React.PropTypes.bool
     },
 
     getDefaultProps: function() {
       return {
         enableCancelButton: false
       };
     },
@@ -421,18 +421,18 @@ loop.conversationViews = (function(mozL1
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.AudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
+      contact: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      contact: React.PropTypes.object.isRequired,
       // This is used by the UI showcase.
       emailLinkError: React.PropTypes.bool,
       outgoing: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       return {
         emailLinkError: this.props.emailLinkError,
@@ -566,28 +566,28 @@ loop.conversationViews = (function(mozL1
 
   var OngoingConversationView = React.createClass({displayName: "OngoingConversationView",
     mixins: [
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      // local
-      video: React.PropTypes.object,
       // local
       audio: React.PropTypes.object,
-      remoteVideoEnabled: React.PropTypes.bool,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      // The poster URLs are for UI-showcase testing and development.
+      localPosterUrl: React.PropTypes.string,
       // This is used from the props rather than the state to make it easier for
       // the ui-showcase.
       mediaConnected: React.PropTypes.bool,
-      // The poster URLs are for UI-showcase testing and development.
-      localPosterUrl: React.PropTypes.string,
-      remotePosterUrl: React.PropTypes.string
+      remotePosterUrl: React.PropTypes.string,
+      remoteVideoEnabled: React.PropTypes.bool,
+      // local
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
       };
     },
--- a/browser/components/loop/content/js/conversationViews.jsx
+++ b/browser/components/loop/content/js/conversationViews.jsx
@@ -357,19 +357,19 @@ loop.conversationViews = (function(mozL1
   /**
    * View for pending conversations. Displays a cancel button and appropriate
    * pending/ringing strings.
    */
   var PendingConversationView = React.createClass({
     mixins: [sharedMixins.AudioMixin],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       callState: React.PropTypes.string,
       contact: React.PropTypes.object,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       enableCancelButton: React.PropTypes.bool
     },
 
     getDefaultProps: function() {
       return {
         enableCancelButton: false
       };
     },
@@ -421,18 +421,18 @@ loop.conversationViews = (function(mozL1
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.AudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
+      contact: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      contact: React.PropTypes.object.isRequired,
       // This is used by the UI showcase.
       emailLinkError: React.PropTypes.bool,
       outgoing: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       return {
         emailLinkError: this.props.emailLinkError,
@@ -566,28 +566,28 @@ loop.conversationViews = (function(mozL1
 
   var OngoingConversationView = React.createClass({
     mixins: [
       loop.store.StoreMixin("conversationStore"),
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      // local
-      video: React.PropTypes.object,
       // local
       audio: React.PropTypes.object,
-      remoteVideoEnabled: React.PropTypes.bool,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      // The poster URLs are for UI-showcase testing and development.
+      localPosterUrl: React.PropTypes.string,
       // This is used from the props rather than the state to make it easier for
       // the ui-showcase.
       mediaConnected: React.PropTypes.bool,
-      // The poster URLs are for UI-showcase testing and development.
-      localPosterUrl: React.PropTypes.string,
-      remotePosterUrl: React.PropTypes.string
+      remotePosterUrl: React.PropTypes.string,
+      remoteVideoEnabled: React.PropTypes.bool,
+      // local
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
       };
     },
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -15,19 +15,19 @@ loop.panel = (function(_, mozL10n) {
   var ButtonGroup = sharedViews.ButtonGroup;
   var Checkbox = sharedViews.Checkbox;
   var ContactsList = loop.contacts.ContactsList;
   var ContactDetailsForm = loop.contacts.ContactDetailsForm;
 
   var TabView = React.createClass({displayName: "TabView",
     propTypes: {
       buttonsHidden: React.PropTypes.array,
+      mozLoop: React.PropTypes.object,
       // The selectedTab prop is used by the UI showcase.
-      selectedTab: React.PropTypes.string,
-      mozLoop: React.PropTypes.object
+      selectedTab: React.PropTypes.string
     },
 
     getDefaultProps: function() {
       return {
         buttonsHidden: []
       };
     },
 
@@ -330,20 +330,20 @@ loop.panel = (function(_, mozL10n) {
     }
   });
 
   /**
    * Panel settings (gear) menu entry.
    */
   var SettingsDropdownEntry = React.createClass({displayName: "SettingsDropdownEntry",
     propTypes: {
-      onClick: React.PropTypes.func.isRequired,
+      displayed: React.PropTypes.bool,
+      icon: React.PropTypes.string,
       label: React.PropTypes.string.isRequired,
-      icon: React.PropTypes.string,
-      displayed: React.PropTypes.bool
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {displayed: true};
     },
 
     render: function() {
       if (!this.props.displayed) {
@@ -608,19 +608,19 @@ loop.panel = (function(_, mozL10n) {
 
   /**
    * Room list.
    */
   var RoomList = React.createClass({displayName: "RoomList",
     mixins: [Backbone.Events, sharedMixins.WindowCloseMixin],
 
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       mozLoop: React.PropTypes.object.isRequired,
       store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       userDisplayName: React.PropTypes.string.isRequired  // for room creation
     },
 
     getInitialState: function() {
       return this.props.store.getStoreState();
     },
 
     componentDidMount: function() {
@@ -796,26 +796,26 @@ loop.panel = (function(_, mozL10n) {
     }
   });
 
   /**
    * Panel view.
    */
   var PanelView = React.createClass({displayName: "PanelView",
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      mozLoop: React.PropTypes.object.isRequired,
       notifications: React.PropTypes.object.isRequired,
-      // Mostly used for UI components showcase and unit tests
-      userProfile: React.PropTypes.object,
+      roomStore:
+        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
+      selectedTab: React.PropTypes.string,
       // Used only for unit tests.
       showTabButtons: React.PropTypes.bool,
-      selectedTab: React.PropTypes.string,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
-      roomStore:
-        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
+      // Mostly used for UI components showcase and unit tests
+      userProfile: React.PropTypes.object
     },
 
     getInitialState: function() {
       return {
         hasEncryptionKey: this.props.mozLoop.hasEncryptionKey,
         userProfile: this.props.userProfile || this.props.mozLoop.userProfile,
         gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
       };
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -15,19 +15,19 @@ loop.panel = (function(_, mozL10n) {
   var ButtonGroup = sharedViews.ButtonGroup;
   var Checkbox = sharedViews.Checkbox;
   var ContactsList = loop.contacts.ContactsList;
   var ContactDetailsForm = loop.contacts.ContactDetailsForm;
 
   var TabView = React.createClass({
     propTypes: {
       buttonsHidden: React.PropTypes.array,
+      mozLoop: React.PropTypes.object,
       // The selectedTab prop is used by the UI showcase.
-      selectedTab: React.PropTypes.string,
-      mozLoop: React.PropTypes.object
+      selectedTab: React.PropTypes.string
     },
 
     getDefaultProps: function() {
       return {
         buttonsHidden: []
       };
     },
 
@@ -330,20 +330,20 @@ loop.panel = (function(_, mozL10n) {
     }
   });
 
   /**
    * Panel settings (gear) menu entry.
    */
   var SettingsDropdownEntry = React.createClass({
     propTypes: {
-      onClick: React.PropTypes.func.isRequired,
+      displayed: React.PropTypes.bool,
+      icon: React.PropTypes.string,
       label: React.PropTypes.string.isRequired,
-      icon: React.PropTypes.string,
-      displayed: React.PropTypes.bool
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {displayed: true};
     },
 
     render: function() {
       if (!this.props.displayed) {
@@ -608,19 +608,19 @@ loop.panel = (function(_, mozL10n) {
 
   /**
    * Room list.
    */
   var RoomList = React.createClass({
     mixins: [Backbone.Events, sharedMixins.WindowCloseMixin],
 
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       mozLoop: React.PropTypes.object.isRequired,
       store: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       userDisplayName: React.PropTypes.string.isRequired  // for room creation
     },
 
     getInitialState: function() {
       return this.props.store.getStoreState();
     },
 
     componentDidMount: function() {
@@ -796,26 +796,26 @@ loop.panel = (function(_, mozL10n) {
     }
   });
 
   /**
    * Panel view.
    */
   var PanelView = React.createClass({
     propTypes: {
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
+      mozLoop: React.PropTypes.object.isRequired,
       notifications: React.PropTypes.object.isRequired,
-      // Mostly used for UI components showcase and unit tests
-      userProfile: React.PropTypes.object,
+      roomStore:
+        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
+      selectedTab: React.PropTypes.string,
       // Used only for unit tests.
       showTabButtons: React.PropTypes.bool,
-      selectedTab: React.PropTypes.string,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
-      roomStore:
-        React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
+      // Mostly used for UI components showcase and unit tests
+      userProfile: React.PropTypes.object
     },
 
     getInitialState: function() {
       return {
         hasEncryptionKey: this.props.mozLoop.hasEncryptionKey,
         userProfile: this.props.userProfile || this.props.mozLoop.userProfile,
         gettingStartedSeen: this.props.mozLoop.getLoopPref("gettingStarted.seen")
       };
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -585,19 +585,19 @@ loop.roomViews = (function(mozL10n) {
       sharedMixins.DocumentTitleMixin,
       sharedMixins.MediaSetupMixin,
       sharedMixins.RoomsAudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
       // The poster URLs are for UI-showcase testing and development.
       localPosterUrl: React.PropTypes.string,
+      mozLoop: React.PropTypes.object.isRequired,
       remotePosterUrl: React.PropTypes.string
     },
 
     componentWillUpdate: function(nextProps, nextState) {
       // The SDK needs to know about the configuration and the elements to use
       // for display. So the best way seems to pass the information here - ideally
       // the sdk wouldn't need to know this, but we can't change that.
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -585,19 +585,19 @@ loop.roomViews = (function(mozL10n) {
       sharedMixins.DocumentTitleMixin,
       sharedMixins.MediaSetupMixin,
       sharedMixins.RoomsAudioMixin,
       sharedMixins.WindowCloseMixin
     ],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      mozLoop: React.PropTypes.object.isRequired,
       // The poster URLs are for UI-showcase testing and development.
       localPosterUrl: React.PropTypes.string,
+      mozLoop: React.PropTypes.object.isRequired,
       remotePosterUrl: React.PropTypes.string
     },
 
     componentWillUpdate: function(nextProps, nextState) {
       // The SDK needs to know about the configuration and the elements to use
       // for display. So the best way seems to pass the information here - ideally
       // the sdk wouldn't need to know this, but we can't change that.
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
--- a/browser/components/loop/content/shared/js/feedbackViews.js
+++ b/browser/components/loop/content/shared/js/feedbackViews.js
@@ -19,18 +19,18 @@ loop.shared.views.FeedbackView = (functi
    * Feedback outer layout.
    *
    * Props:
    * -
    */
   var FeedbackLayout = React.createClass({displayName: "FeedbackLayout",
     propTypes: {
       children: React.PropTypes.component.isRequired,
-      title: React.PropTypes.string.isRequired,
-      reset: React.PropTypes.func // if not specified, no Back btn is shown
+      reset: React.PropTypes.func, // if not specified, no Back btn is shown
+      title: React.PropTypes.string.isRequired
     },
 
     render: function() {
       var backButton = React.createElement("div", null);
       if (this.props.reset) {
         backButton = (
           React.createElement("button", {className: "fx-embedded-btn-back", 
             onClick: this.props.reset, 
@@ -232,20 +232,20 @@ loop.shared.views.FeedbackView = (functi
    */
   var FeedbackView = React.createClass({displayName: "FeedbackView",
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("feedbackStore")
     ],
 
     propTypes: {
-      onAfterFeedbackReceived: React.PropTypes.func,
       // Used by the UI showcase.
       feedbackState: React.PropTypes.string,
-      noCloseText: React.PropTypes.bool
+      noCloseText: React.PropTypes.bool,
+      onAfterFeedbackReceived: React.PropTypes.func
     },
 
     getInitialState: function() {
       var storeState = this.getStoreState();
       return _.extend({}, storeState, {
         feedbackState: this.props.feedbackState || storeState.feedbackState
       });
     },
--- a/browser/components/loop/content/shared/js/feedbackViews.jsx
+++ b/browser/components/loop/content/shared/js/feedbackViews.jsx
@@ -19,18 +19,18 @@ loop.shared.views.FeedbackView = (functi
    * Feedback outer layout.
    *
    * Props:
    * -
    */
   var FeedbackLayout = React.createClass({
     propTypes: {
       children: React.PropTypes.component.isRequired,
-      title: React.PropTypes.string.isRequired,
-      reset: React.PropTypes.func // if not specified, no Back btn is shown
+      reset: React.PropTypes.func, // if not specified, no Back btn is shown
+      title: React.PropTypes.string.isRequired
     },
 
     render: function() {
       var backButton = <div />;
       if (this.props.reset) {
         backButton = (
           <button className="fx-embedded-btn-back"
             onClick={this.props.reset}
@@ -232,20 +232,20 @@ loop.shared.views.FeedbackView = (functi
    */
   var FeedbackView = React.createClass({
     mixins: [
       Backbone.Events,
       loop.store.StoreMixin("feedbackStore")
     ],
 
     propTypes: {
-      onAfterFeedbackReceived: React.PropTypes.func,
       // Used by the UI showcase.
       feedbackState: React.PropTypes.string,
-      noCloseText: React.PropTypes.bool
+      noCloseText: React.PropTypes.bool,
+      onAfterFeedbackReceived: React.PropTypes.func
     },
 
     getInitialState: function() {
       var storeState = this.getStoreState();
       return _.extend({}, storeState, {
         feedbackState: this.props.feedbackState || storeState.feedbackState
       });
     },
--- a/browser/components/loop/content/shared/js/views.js
+++ b/browser/components/loop/content/shared/js/views.js
@@ -18,20 +18,20 @@ loop.shared.views = (function(_, l10n) {
    * Required props:
    * - {String}   scope   Media scope, can be "local" or "remote".
    * - {String}   type    Media type, can be "audio" or "video".
    * - {Function} action  Function to be executed on click.
    * - {Enabled}  enabled Stream activation status (default: true).
    */
   var MediaControlButton = React.createClass({displayName: "MediaControlButton",
     propTypes: {
+      action: React.PropTypes.func.isRequired,
+      enabled: React.PropTypes.bool.isRequired,
       scope: React.PropTypes.string.isRequired,
       type: React.PropTypes.string.isRequired,
-      action: React.PropTypes.func.isRequired,
-      enabled: React.PropTypes.bool.isRequired,
       visible: React.PropTypes.bool.isRequired
     },
 
     getDefaultProps: function() {
       return {enabled: true, visible: true};
     },
 
     handleClick: function() {
@@ -78,18 +78,18 @@ loop.shared.views = (function(_, l10n) {
    * - {String}          state       One of the screen sharing states, see
    *                                 loop.shared.utils.SCREEN_SHARE_STATES
    */
   var ScreenShareControlButton = React.createClass({displayName: "ScreenShareControlButton",
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      visible: React.PropTypes.bool.isRequired,
-      state: React.PropTypes.string.isRequired
+      state: React.PropTypes.string.isRequired,
+      visible: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       var os = loop.shared.utils.getOS();
       var osVersion = loop.shared.utils.getOSVersion();
       // Disable screensharing on older OSX and Windows versions.
       if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
           (os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
@@ -184,24 +184,24 @@ loop.shared.views = (function(_, l10n) {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true},
         screenShare: {state: SCREEN_SHARE_STATES.INACTIVE, visible: false},
         enableHangup: true
       };
     },
 
     propTypes: {
+      audio: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      video: React.PropTypes.object.isRequired,
-      audio: React.PropTypes.object.isRequired,
+      enableHangup: React.PropTypes.bool,
+      hangup: React.PropTypes.func.isRequired,
+      hangupButtonLabel: React.PropTypes.string,
+      publishStream: React.PropTypes.func.isRequired,
       screenShare: React.PropTypes.object,
-      hangup: React.PropTypes.func.isRequired,
-      publishStream: React.PropTypes.func.isRequired,
-      hangupButtonLabel: React.PropTypes.string,
-      enableHangup: React.PropTypes.bool
+      video: React.PropTypes.object.isRequired
     },
 
     handleClickHangup: function() {
       this.props.hangup();
     },
 
     handleToggleVideo: function() {
       this.props.publishStream("video", !this.props.video.enabled);
@@ -254,21 +254,21 @@ loop.shared.views = (function(_, l10n) {
   var ConversationView = React.createClass({displayName: "ConversationView",
     mixins: [
       Backbone.Events,
       sharedMixins.AudioMixin,
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      sdk: React.PropTypes.object.isRequired,
-      video: React.PropTypes.object,
       audio: React.PropTypes.object,
       initiate: React.PropTypes.bool,
-      isDesktop: React.PropTypes.bool
+      isDesktop: React.PropTypes.bool,
+      sdk: React.PropTypes.object.isRequired,
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         initiate: true,
         isDesktop: false,
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
@@ -469,18 +469,18 @@ loop.shared.views = (function(_, l10n) {
 
   /**
    * Notification view.
    */
   var NotificationView = React.createClass({displayName: "NotificationView",
     mixins: [Backbone.Events],
 
     propTypes: {
-      notification: React.PropTypes.object.isRequired,
-      key: React.PropTypes.number.isRequired
+      key: React.PropTypes.number.isRequired,
+      notification: React.PropTypes.object.isRequired
     },
 
     render: function() {
       var notification = this.props.notification;
       return (
         React.createElement("div", {className: "notificationContainer"}, 
           React.createElement("div", {className: "alert alert-" + notification.get("level"), 
             key: this.props.key}, 
@@ -502,18 +502,18 @@ loop.shared.views = (function(_, l10n) {
 
   /**
    * Notification list view.
    */
   var NotificationListView = React.createClass({displayName: "NotificationListView",
     mixins: [Backbone.Events, sharedMixins.DocumentVisibilityMixin],
 
     propTypes: {
-      notifications: React.PropTypes.object.isRequired,
-      clearOnDocumentHidden: React.PropTypes.bool
+      clearOnDocumentHidden: React.PropTypes.bool,
+      notifications: React.PropTypes.object.isRequired
     },
 
     getDefaultProps: function() {
       return {clearOnDocumentHidden: false};
     },
 
     componentDidMount: function() {
       this.listenTo(this.props.notifications, "reset add remove", function() {
@@ -550,21 +550,21 @@ loop.shared.views = (function(_, l10n) {
         
         )
       );
     }
   });
 
   var Button = React.createClass({displayName: "Button",
     propTypes: {
+      additionalClass: React.PropTypes.string,
       caption: React.PropTypes.string.isRequired,
-      onClick: React.PropTypes.func.isRequired,
       disabled: React.PropTypes.bool,
-      additionalClass: React.PropTypes.string,
-      htmlId: React.PropTypes.string
+      htmlId: React.PropTypes.string,
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {
         disabled: false,
         additionalClass: "",
         htmlId: ""
       };
--- a/browser/components/loop/content/shared/js/views.jsx
+++ b/browser/components/loop/content/shared/js/views.jsx
@@ -18,20 +18,20 @@ loop.shared.views = (function(_, l10n) {
    * Required props:
    * - {String}   scope   Media scope, can be "local" or "remote".
    * - {String}   type    Media type, can be "audio" or "video".
    * - {Function} action  Function to be executed on click.
    * - {Enabled}  enabled Stream activation status (default: true).
    */
   var MediaControlButton = React.createClass({
     propTypes: {
+      action: React.PropTypes.func.isRequired,
+      enabled: React.PropTypes.bool.isRequired,
       scope: React.PropTypes.string.isRequired,
       type: React.PropTypes.string.isRequired,
-      action: React.PropTypes.func.isRequired,
-      enabled: React.PropTypes.bool.isRequired,
       visible: React.PropTypes.bool.isRequired
     },
 
     getDefaultProps: function() {
       return {enabled: true, visible: true};
     },
 
     handleClick: function() {
@@ -78,18 +78,18 @@ loop.shared.views = (function(_, l10n) {
    * - {String}          state       One of the screen sharing states, see
    *                                 loop.shared.utils.SCREEN_SHARE_STATES
    */
   var ScreenShareControlButton = React.createClass({
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      visible: React.PropTypes.bool.isRequired,
-      state: React.PropTypes.string.isRequired
+      state: React.PropTypes.string.isRequired,
+      visible: React.PropTypes.bool.isRequired
     },
 
     getInitialState: function() {
       var os = loop.shared.utils.getOS();
       var osVersion = loop.shared.utils.getOSVersion();
       // Disable screensharing on older OSX and Windows versions.
       if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
           (os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
@@ -184,24 +184,24 @@ loop.shared.views = (function(_, l10n) {
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true},
         screenShare: {state: SCREEN_SHARE_STATES.INACTIVE, visible: false},
         enableHangup: true
       };
     },
 
     propTypes: {
+      audio: React.PropTypes.object.isRequired,
       dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
-      video: React.PropTypes.object.isRequired,
-      audio: React.PropTypes.object.isRequired,
+      enableHangup: React.PropTypes.bool,
+      hangup: React.PropTypes.func.isRequired,
+      hangupButtonLabel: React.PropTypes.string,
+      publishStream: React.PropTypes.func.isRequired,
       screenShare: React.PropTypes.object,
-      hangup: React.PropTypes.func.isRequired,
-      publishStream: React.PropTypes.func.isRequired,
-      hangupButtonLabel: React.PropTypes.string,
-      enableHangup: React.PropTypes.bool
+      video: React.PropTypes.object.isRequired
     },
 
     handleClickHangup: function() {
       this.props.hangup();
     },
 
     handleToggleVideo: function() {
       this.props.publishStream("video", !this.props.video.enabled);
@@ -254,21 +254,21 @@ loop.shared.views = (function(_, l10n) {
   var ConversationView = React.createClass({
     mixins: [
       Backbone.Events,
       sharedMixins.AudioMixin,
       sharedMixins.MediaSetupMixin
     ],
 
     propTypes: {
-      sdk: React.PropTypes.object.isRequired,
-      video: React.PropTypes.object,
       audio: React.PropTypes.object,
       initiate: React.PropTypes.bool,
-      isDesktop: React.PropTypes.bool
+      isDesktop: React.PropTypes.bool,
+      sdk: React.PropTypes.object.isRequired,
+      video: React.PropTypes.object
     },
 
     getDefaultProps: function() {
       return {
         initiate: true,
         isDesktop: false,
         video: {enabled: true, visible: true},
         audio: {enabled: true, visible: true}
@@ -469,18 +469,18 @@ loop.shared.views = (function(_, l10n) {
 
   /**
    * Notification view.
    */
   var NotificationView = React.createClass({
     mixins: [Backbone.Events],
 
     propTypes: {
-      notification: React.PropTypes.object.isRequired,
-      key: React.PropTypes.number.isRequired
+      key: React.PropTypes.number.isRequired,
+      notification: React.PropTypes.object.isRequired
     },
 
     render: function() {
       var notification = this.props.notification;
       return (
         <div className="notificationContainer">
           <div className={"alert alert-" + notification.get("level")}
             key={this.props.key}>
@@ -502,18 +502,18 @@ loop.shared.views = (function(_, l10n) {
 
   /**
    * Notification list view.
    */
   var NotificationListView = React.createClass({
     mixins: [Backbone.Events, sharedMixins.DocumentVisibilityMixin],
 
     propTypes: {
-      notifications: React.PropTypes.object.isRequired,
-      clearOnDocumentHidden: React.PropTypes.bool
+      clearOnDocumentHidden: React.PropTypes.bool,
+      notifications: React.PropTypes.object.isRequired
     },
 
     getDefaultProps: function() {
       return {clearOnDocumentHidden: false};
     },
 
     componentDidMount: function() {
       this.listenTo(this.props.notifications, "reset add remove", function() {
@@ -550,21 +550,21 @@ loop.shared.views = (function(_, l10n) {
         }
         </div>
       );
     }
   });
 
   var Button = React.createClass({
     propTypes: {
+      additionalClass: React.PropTypes.string,
       caption: React.PropTypes.string.isRequired,
-      onClick: React.PropTypes.func.isRequired,
       disabled: React.PropTypes.bool,
-      additionalClass: React.PropTypes.string,
-      htmlId: React.PropTypes.string
+      htmlId: React.PropTypes.string,
+      onClick: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {
         disabled: false,
         additionalClass: "",
         htmlId: ""
       };
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.js
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
@@ -11,21 +11,21 @@ loop.standaloneRoomViews = (function(moz
   var ROOM_STATES = loop.store.ROOM_STATES;
   var sharedActions = loop.shared.actions;
   var sharedMixins = loop.shared.mixins;
   var sharedUtils = loop.shared.utils;
   var sharedViews = loop.shared.views;
 
   var StandaloneRoomInfoArea = React.createClass({displayName: "StandaloneRoomInfoArea",
     propTypes: {
-      isFirefox: React.PropTypes.bool.isRequired,
       activeRoomStore: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
         React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired
+      ]).isRequired,
+      isFirefox: React.PropTypes.bool.isRequired
     },
 
     onFeedbackSent: function() {
       // We pass a tick to prevent React warnings regarding nested updates.
       setTimeout(function() {
         this.props.activeRoomStore.dispatchAction(new sharedActions.FeedbackComplete());
       }.bind(this));
     },
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
@@ -11,21 +11,21 @@ loop.standaloneRoomViews = (function(moz
   var ROOM_STATES = loop.store.ROOM_STATES;
   var sharedActions = loop.shared.actions;
   var sharedMixins = loop.shared.mixins;
   var sharedUtils = loop.shared.utils;
   var sharedViews = loop.shared.views;
 
   var StandaloneRoomInfoArea = React.createClass({
     propTypes: {
-      isFirefox: React.PropTypes.bool.isRequired,
       activeRoomStore: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
         React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired
+      ]).isRequired,
+      isFirefox: React.PropTypes.bool.isRequired
     },
 
     onFeedbackSent: function() {
       // We pass a tick to prevent React warnings regarding nested updates.
       setTimeout(function() {
         this.props.activeRoomStore.dispatchAction(new sharedActions.FeedbackComplete());
       }.bind(this));
     },
--- a/browser/components/loop/standalone/content/js/webapp.js
+++ b/browser/components/loop/standalone/content/js/webapp.js
@@ -379,18 +379,18 @@ loop.webapp = (function($, _, OT, mozL10
     }
   });
 
   var InitiateCallButton = React.createClass({displayName: "InitiateCallButton",
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       caption: React.PropTypes.string.isRequired,
-      startCall: React.PropTypes.func.isRequired,
-      disabled: React.PropTypes.bool
+      disabled: React.PropTypes.bool,
+      startCall: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {disabled: false};
     },
 
     render: function() {
       var dropdownMenuClasses = React.addons.classSet({
@@ -436,25 +436,25 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Initiate conversation view.
    */
   var InitiateConversationView = React.createClass({displayName: "InitiateConversationView",
     mixins: [Backbone.Events],
 
     propTypes: {
+      callButtonLabel: React.PropTypes.string.isRequired,
+      client: React.PropTypes.object.isRequired,
       conversation: React.PropTypes.oneOfType([
                       React.PropTypes.instanceOf(sharedModels.ConversationModel),
                       React.PropTypes.instanceOf(FxOSConversationModel)
                     ]).isRequired,
       // XXX Check more tightly here when we start injecting window.loop.*
       notifications: React.PropTypes.object.isRequired,
-      client: React.PropTypes.object.isRequired,
-      title: React.PropTypes.string.isRequired,
-      callButtonLabel: React.PropTypes.string.isRequired
+      title: React.PropTypes.string.isRequired
     },
 
     getInitialState: function() {
       return {
         urlCreationDateString: "",
         disableCallButton: false
       };
     },
@@ -571,18 +571,18 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Ended conversation view.
    */
   var EndedConversationView = React.createClass({displayName: "EndedConversationView",
     propTypes: {
       conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel)
                          .isRequired,
-      sdk: React.PropTypes.object.isRequired,
-      onAfterFeedbackReceived: React.PropTypes.func.isRequired
+      onAfterFeedbackReceived: React.PropTypes.func.isRequired,
+      sdk: React.PropTypes.object.isRequired
     },
 
     render: function() {
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get("status_conversation_ended")});
       return (
         React.createElement("div", {className: "ended-conversation"}, 
@@ -927,33 +927,31 @@ loop.webapp = (function($, _, OT, mozL10
    */
   var WebappRootView = React.createClass({displayName: "WebappRootView",
 
     mixins: [sharedMixins.UrlHashChangeMixin,
              sharedMixins.DocumentLocationMixin,
              Backbone.Events],
 
     propTypes: {
+      activeRoomStore: React.PropTypes.oneOfType([
+        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
+        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
+      ]).isRequired,
       client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
       conversation: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(sharedModels.ConversationModel),
         React.PropTypes.instanceOf(FxOSConversationModel)
       ]).isRequired,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection)
                           .isRequired,
       sdk: React.PropTypes.object.isRequired,
-
-      // XXX New types for flux style
       standaloneAppStore: React.PropTypes.instanceOf(
-        loop.store.StandaloneAppStore).isRequired,
-      activeRoomStore: React.PropTypes.oneOfType([
-        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
-        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
+        loop.store.StandaloneAppStore).isRequired
     },
 
     getInitialState: function() {
       return this.props.standaloneAppStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.standaloneAppStore, "change", function() {
--- a/browser/components/loop/standalone/content/js/webapp.jsx
+++ b/browser/components/loop/standalone/content/js/webapp.jsx
@@ -379,18 +379,18 @@ loop.webapp = (function($, _, OT, mozL10
     }
   });
 
   var InitiateCallButton = React.createClass({
     mixins: [sharedMixins.DropdownMenuMixin()],
 
     propTypes: {
       caption: React.PropTypes.string.isRequired,
-      startCall: React.PropTypes.func.isRequired,
-      disabled: React.PropTypes.bool
+      disabled: React.PropTypes.bool,
+      startCall: React.PropTypes.func.isRequired
     },
 
     getDefaultProps: function() {
       return {disabled: false};
     },
 
     render: function() {
       var dropdownMenuClasses = React.addons.classSet({
@@ -436,25 +436,25 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Initiate conversation view.
    */
   var InitiateConversationView = React.createClass({
     mixins: [Backbone.Events],
 
     propTypes: {
+      callButtonLabel: React.PropTypes.string.isRequired,
+      client: React.PropTypes.object.isRequired,
       conversation: React.PropTypes.oneOfType([
                       React.PropTypes.instanceOf(sharedModels.ConversationModel),
                       React.PropTypes.instanceOf(FxOSConversationModel)
                     ]).isRequired,
       // XXX Check more tightly here when we start injecting window.loop.*
       notifications: React.PropTypes.object.isRequired,
-      client: React.PropTypes.object.isRequired,
-      title: React.PropTypes.string.isRequired,
-      callButtonLabel: React.PropTypes.string.isRequired
+      title: React.PropTypes.string.isRequired
     },
 
     getInitialState: function() {
       return {
         urlCreationDateString: "",
         disableCallButton: false
       };
     },
@@ -571,18 +571,18 @@ loop.webapp = (function($, _, OT, mozL10
 
   /**
    * Ended conversation view.
    */
   var EndedConversationView = React.createClass({
     propTypes: {
       conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel)
                          .isRequired,
-      sdk: React.PropTypes.object.isRequired,
-      onAfterFeedbackReceived: React.PropTypes.func.isRequired
+      onAfterFeedbackReceived: React.PropTypes.func.isRequired,
+      sdk: React.PropTypes.object.isRequired
     },
 
     render: function() {
       document.title = mozL10n.get("standalone_title_with_status",
                                    {clientShortname: mozL10n.get("clientShortname2"),
                                     currentStatus: mozL10n.get("status_conversation_ended")});
       return (
         <div className="ended-conversation">
@@ -927,33 +927,31 @@ loop.webapp = (function($, _, OT, mozL10
    */
   var WebappRootView = React.createClass({
 
     mixins: [sharedMixins.UrlHashChangeMixin,
              sharedMixins.DocumentLocationMixin,
              Backbone.Events],
 
     propTypes: {
+      activeRoomStore: React.PropTypes.oneOfType([
+        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
+        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
+      ]).isRequired,
       client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
       conversation: React.PropTypes.oneOfType([
         React.PropTypes.instanceOf(sharedModels.ConversationModel),
         React.PropTypes.instanceOf(FxOSConversationModel)
       ]).isRequired,
+      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
       notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection)
                           .isRequired,
       sdk: React.PropTypes.object.isRequired,
-
-      // XXX New types for flux style
       standaloneAppStore: React.PropTypes.instanceOf(
-        loop.store.StandaloneAppStore).isRequired,
-      activeRoomStore: React.PropTypes.oneOfType([
-        React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
-        React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
-      ]).isRequired,
-      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
+        loop.store.StandaloneAppStore).isRequired
     },
 
     getInitialState: function() {
       return this.props.standaloneAppStore.getStoreState();
     },
 
     componentWillMount: function() {
       this.listenTo(this.props.standaloneAppStore, "change", function() {
--- a/browser/components/loop/ui/react-frame-component.js
+++ b/browser/components/loop/ui/react-frame-component.js
@@ -20,28 +20,28 @@ window.queuedFrames = [];
  * 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: {
-    style: React.PropTypes.object,
-    head: React.PropTypes.node,
-    width: React.PropTypes.number,
-    height: React.PropTypes.number,
-    onContentsRendered: React.PropTypes.func,
     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
+    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
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -430,21 +430,21 @@
       return (
         React.createElement("ul", {className: "svg-icon-list"}, icons)
       );
     }
   });
 
   var FramedExample = React.createClass({displayName: "FramedExample",
     propTypes: {
-      width: React.PropTypes.number,
+      cssClass: React.PropTypes.string,
+      dashed: React.PropTypes.bool,
       height: React.PropTypes.number,
       onContentsRendered: React.PropTypes.func,
-      dashed: React.PropTypes.bool,
-      cssClass: React.PropTypes.string
+      width: React.PropTypes.number
     },
 
     makeId: function(prefix) {
       return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-");
     },
 
     render: function() {
       var height = this.props.height;
--- a/browser/components/loop/ui/ui-showcase.jsx
+++ b/browser/components/loop/ui/ui-showcase.jsx
@@ -430,21 +430,21 @@
       return (
         <ul className="svg-icon-list">{icons}</ul>
       );
     }
   });
 
   var FramedExample = React.createClass({
     propTypes: {
-      width: React.PropTypes.number,
+      cssClass: React.PropTypes.string,
+      dashed: React.PropTypes.bool,
       height: React.PropTypes.number,
       onContentsRendered: React.PropTypes.func,
-      dashed: React.PropTypes.bool,
-      cssClass: React.PropTypes.string
+      width: React.PropTypes.number
     },
 
     makeId: function(prefix) {
       return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-");
     },
 
     render: function() {
       var height = this.props.height;