Merge mozilla-central to mozilla-inbound

This commit is contained in:
Carsten "Tomcat" Book 2015-06-24 16:04:10 +02:00
Родитель 6713cdfbc5 7fd037905e
Коммит db531ad50b
92 изменённых файлов: 1720 добавлений и 1192 удалений

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
@ -38,7 +38,7 @@
<project name="platform/bootable/recovery" path="bootable/recovery" revision="286354e69491f7cba5b9ec6b551831fe6f85ad0d"/>
<project name="platform/external/aac" path="external/aac" revision="fa3eba16446cc8f2f5e2dfc20d86a49dbd37299e"/>
<project name="platform/external/bison" path="external/bison" revision="c2418b886165add7f5a31fc5609f0ce2d004a90e"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="c8e99ca7e11c00f8124196fe1726a15e6e976587"/>
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="3e5570325187f5cd9f8a944cbe4a93822e8c6328"/>
<project name="platform/external/bsdiff" path="external/bsdiff" revision="23e322ab19fb7d74c2c37e40ce364d9f709bdcee"/>
<project name="platform/external/bzip2" path="external/bzip2" revision="1cb636bd8e9e5cdfd5d5b2909a122f6e80db62de"/>
<project name="platform/external/checkpolicy" path="external/checkpolicy" revision="0d73ef7049feee794f14cf1af88d05dae8139914"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

Просмотреть файл

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="87a2d8ab9248540910e56921654367b78a587095"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "311c4e59936a407e64509f54fecb440d8a78e3c8",
"git_revision": "eb0d4aefa62b20420d6fa0642515a110daca5d97",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "7e585532a2935425fcddb964cb9002b18b94b3ff",
"revision": "28b5133c0a062776dac8282abcc7810dc317a0bc",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="311c4e59936a407e64509f54fecb440d8a78e3c8"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="eb0d4aefa62b20420d6fa0642515a110daca5d97"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="3477513bcd385571aa01c0d074849e35bd5e2376"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="9515d87a841daaf28f2577e92edf5206070d2d51"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="35d2750e2e09e2b6ca00f7679ef15066856b8d15"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

Просмотреть файл

@ -841,6 +841,10 @@ input[type=button] {
max-height: 40px;
}
.newtab-intro-image-customize #newtab-customize-panel-anchor {
display: none;
}
.newtab-intro-image-customize .newtab-customize-panel-item:not([selected]):hover {
background-color: inherit;
color: #7A7A7A;

Просмотреть файл

@ -63,8 +63,8 @@
"react/jsx-quotes": [2, "double", "avoid-escape"],
"react/jsx-no-undef": 2,
// Need to fix instances where this is failing.
"react/jsx-sort-props": 0,
"react/jsx-sort-prop-types": 0,
"react/jsx-sort-props": 2,
"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.

Просмотреть файл

@ -135,8 +135,8 @@ loop.contacts = (function(_, mozL10n) {
React.createElement(ButtonGroup, null,
React.createElement(Button, {caption: mozL10n.get("gravatars_promo_button_nothanks"),
onClick: this.handleCloseButtonClick}),
React.createElement(Button, {caption: mozL10n.get("gravatars_promo_button_use"),
additionalClass: "button-accept",
React.createElement(Button, {additionalClass: "button-accept",
caption: mozL10n.get("gravatars_promo_button_use"),
onClick: this.handleUseButtonClick})
)
)
@ -146,8 +146,8 @@ 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 () {
@ -191,31 +191,35 @@ loop.contacts = (function(_, mozL10n) {
"dropdown-menu-up": this.state.openDirUp })},
React.createElement("li", {className: cx({ "dropdown-menu-item": true,
"disabled": this.props.blocked }),
onClick: this.onItemClick,
"data-action": "video-call"},
"data-action": "video-call",
onClick: this.onItemClick},
React.createElement("i", {className: "icon icon-video-call"}),
mozL10n.get("video_call_menu_button")
),
React.createElement("li", {className: cx({ "dropdown-menu-item": true,
"disabled": this.props.blocked }),
onClick: this.onItemClick, "data-action": "audio-call"},
"data-action": "audio-call",
onClick: this.onItemClick},
React.createElement("i", {className: "icon icon-audio-call"}),
mozL10n.get("audio_call_menu_button")
),
React.createElement("li", {className: cx({ "dropdown-menu-item": true,
"disabled": !this.props.canEdit }),
onClick: this.onItemClick, "data-action": "edit"},
"data-action": "edit",
onClick: this.onItemClick},
React.createElement("i", {className: "icon icon-edit"}),
mozL10n.get("edit_contact_menu_button")
),
React.createElement("li", {className: "dropdown-menu-item",
onClick: this.onItemClick, "data-action": blockAction},
"data-action": blockAction,
onClick: this.onItemClick},
React.createElement("i", {className: "icon icon-" + blockAction}),
mozL10n.get(blockLabel)
),
React.createElement("li", {className: cx({ "dropdown-menu-item": true,
"disabled": !this.props.canEdit }),
onClick: this.onItemClick, "data-action": "remove"},
"data-action": "remove",
onClick: this.onItemClick},
React.createElement("i", {className: "icon icon-remove"}),
mozL10n.get("remove_contact_menu_button2")
)
@ -232,8 +236,8 @@ loop.contacts = (function(_, mozL10n) {
},
propTypes: {
handleContactAction: React.PropTypes.func,
contact: React.PropTypes.object.isRequired
contact: React.PropTypes.object.isRequired,
handleContactAction: React.PropTypes.func
},
_onBodyClick: function() {
@ -312,9 +316,9 @@ loop.contacts = (function(_, mozL10n) {
onClick: this.showDropdownMenu})
),
this.state.showMenu
? React.createElement(ContactDropdown, {handleAction: this.handleAction,
? React.createElement(ContactDropdown, {blocked: this.props.contact.blocked,
canEdit: this.canEdit(),
blocked: this.props.contact.blocked})
handleAction: this.handleAction})
: null
)
@ -549,8 +553,9 @@ loop.contacts = (function(_, mozL10n) {
let viewForItem = item => {
return (
React.createElement(ContactDetail, {key: item._guid, contact: item,
handleContactAction: this.handleContactAction})
React.createElement(ContactDetail, {contact: item,
handleContactAction: this.handleContactAction,
key: item._guid})
);
};
@ -717,16 +722,23 @@ loop.contacts = (function(_, mozL10n) {
? mozL10n.get("add_contact_button")
: mozL10n.get("edit_contact_title")),
React.createElement("label", null, mozL10n.get("edit_contact_name_label")),
React.createElement("input", {ref: "name", required: true, pattern: "\\s*\\S.*", type: "text",
className: cx({pristine: this.state.pristine}),
React.createElement("input", {className: cx({pristine: this.state.pristine}),
pattern: "\\s*\\S.*",
ref: "name",
required: true,
type: "text",
valueLink: this.linkState("name")}),
React.createElement("label", null, mozL10n.get("edit_contact_email_label")),
React.createElement("input", {ref: "email", type: "email", required: phoneOrEmailRequired,
className: cx({pristine: this.state.pristine}),
React.createElement("input", {className: cx({pristine: this.state.pristine}),
ref: "email",
required: phoneOrEmailRequired,
type: "email",
valueLink: this.linkState("email")}),
React.createElement("label", null, mozL10n.get("new_contact_fxos_phone_placeholder")),
React.createElement("input", {ref: "tel", type: "tel", required: phoneOrEmailRequired,
className: cx({pristine: this.state.pristine}),
React.createElement("input", {className: cx({pristine: this.state.pristine}),
ref: "tel",
required: phoneOrEmailRequired,
type: "tel",
valueLink: this.linkState("tel")}),
React.createElement(ButtonGroup, null,
React.createElement(Button, {additionalClass: "button-cancel",

Просмотреть файл

@ -135,8 +135,8 @@ loop.contacts = (function(_, mozL10n) {
<ButtonGroup>
<Button caption={mozL10n.get("gravatars_promo_button_nothanks")}
onClick={this.handleCloseButtonClick}/>
<Button caption={mozL10n.get("gravatars_promo_button_use")}
additionalClass="button-accept"
<Button additionalClass="button-accept"
caption={mozL10n.get("gravatars_promo_button_use")}
onClick={this.handleUseButtonClick}/>
</ButtonGroup>
</div>
@ -146,8 +146,8 @@ loop.contacts = (function(_, mozL10n) {
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 () {
@ -191,31 +191,35 @@ loop.contacts = (function(_, mozL10n) {
"dropdown-menu-up": this.state.openDirUp })}>
<li className={cx({ "dropdown-menu-item": true,
"disabled": this.props.blocked })}
onClick={this.onItemClick}
data-action="video-call">
data-action="video-call"
onClick={this.onItemClick}>
<i className="icon icon-video-call" />
{mozL10n.get("video_call_menu_button")}
</li>
<li className={cx({ "dropdown-menu-item": true,
"disabled": this.props.blocked })}
onClick={this.onItemClick} data-action="audio-call">
data-action="audio-call"
onClick={this.onItemClick}>
<i className="icon icon-audio-call" />
{mozL10n.get("audio_call_menu_button")}
</li>
<li className={cx({ "dropdown-menu-item": true,
"disabled": !this.props.canEdit })}
onClick={this.onItemClick} data-action="edit">
data-action="edit"
onClick={this.onItemClick}>
<i className="icon icon-edit" />
{mozL10n.get("edit_contact_menu_button")}
</li>
<li className="dropdown-menu-item"
onClick={this.onItemClick} data-action={blockAction}>
data-action={blockAction}
onClick={this.onItemClick}>
<i className={"icon icon-" + blockAction} />
{mozL10n.get(blockLabel)}
</li>
<li className={cx({ "dropdown-menu-item": true,
"disabled": !this.props.canEdit })}
onClick={this.onItemClick} data-action="remove">
data-action="remove"
onClick={this.onItemClick}>
<i className="icon icon-remove" />
{mozL10n.get("remove_contact_menu_button2")}
</li>
@ -232,8 +236,8 @@ loop.contacts = (function(_, mozL10n) {
},
propTypes: {
handleContactAction: React.PropTypes.func,
contact: React.PropTypes.object.isRequired
contact: React.PropTypes.object.isRequired,
handleContactAction: React.PropTypes.func
},
_onBodyClick: function() {
@ -312,9 +316,9 @@ loop.contacts = (function(_, mozL10n) {
onClick={this.showDropdownMenu} />
</div>
{this.state.showMenu
? <ContactDropdown handleAction={this.handleAction}
? <ContactDropdown blocked={this.props.contact.blocked}
canEdit={this.canEdit()}
blocked={this.props.contact.blocked} />
handleAction={this.handleAction} />
: null
}
</li>
@ -549,8 +553,9 @@ loop.contacts = (function(_, mozL10n) {
let viewForItem = item => {
return (
<ContactDetail key={item._guid} contact={item}
handleContactAction={this.handleContactAction} />
<ContactDetail contact={item}
handleContactAction={this.handleContactAction}
key={item._guid} />
);
};
@ -717,16 +722,23 @@ loop.contacts = (function(_, mozL10n) {
? mozL10n.get("add_contact_button")
: mozL10n.get("edit_contact_title")}</header>
<label>{mozL10n.get("edit_contact_name_label")}</label>
<input ref="name" required pattern="\s*\S.*" type="text"
className={cx({pristine: this.state.pristine})}
<input className={cx({pristine: this.state.pristine})}
pattern="\s*\S.*"
ref="name"
required
type="text"
valueLink={this.linkState("name")} />
<label>{mozL10n.get("edit_contact_email_label")}</label>
<input ref="email" type="email" required={phoneOrEmailRequired}
className={cx({pristine: this.state.pristine})}
<input className={cx({pristine: this.state.pristine})}
ref="email"
required={phoneOrEmailRequired}
type="email"
valueLink={this.linkState("email")} />
<label>{mozL10n.get("new_contact_fxos_phone_placeholder")}</label>
<input ref="tel" type="tel" required={phoneOrEmailRequired}
className={cx({pristine: this.state.pristine})}
<input className={cx({pristine: this.state.pristine})}
ref="tel"
required={phoneOrEmailRequired}
type="tel"
valueLink={this.linkState("tel")} />
<ButtonGroup>
<Button additionalClass="button-cancel"

Просмотреть файл

@ -29,8 +29,8 @@ loop.conversation = (function(mozL10n) {
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() {
@ -158,10 +158,11 @@ loop.conversation = (function(mozL10n) {
dispatcher.dispatch(new sharedActions.WindowUnload());
});
React.render(React.createElement(AppControllerView, {
roomStore: roomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop}), document.querySelector("#main"));
React.render(
React.createElement(AppControllerView, {
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
roomStore: roomStore}), document.querySelector("#main"));
document.documentElement.setAttribute("lang", mozL10n.getLanguage());
document.documentElement.setAttribute("dir", mozL10n.getDirection());

Просмотреть файл

@ -29,8 +29,8 @@ loop.conversation = (function(mozL10n) {
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() {
@ -158,10 +158,11 @@ loop.conversation = (function(mozL10n) {
dispatcher.dispatch(new sharedActions.WindowUnload());
});
React.render(<AppControllerView
roomStore={roomStore}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop} />, document.querySelector("#main"));
React.render(
<AppControllerView
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
roomStore={roomStore} />, document.querySelector("#main"));
document.documentElement.setAttribute("lang", mozL10n.getLanguage());
document.documentElement.setAttribute("dir", mozL10n.getDirection());

Просмотреть файл

@ -232,9 +232,10 @@ loop.conversationViews = (function(mozL10n) {
return (
React.createElement("div", {className: "call-window"},
React.createElement(CallIdentifierView, {video: this.props.callType === CALL_TYPES.AUDIO_VIDEO,
React.createElement(CallIdentifierView, {
peerIdentifier: this.props.callerId,
showIcons: true}),
showIcons: true,
video: this.props.callType === CALL_TYPES.AUDIO_VIDEO}),
React.createElement("div", {className: "btn-group call-action-group"},
@ -361,9 +362,9 @@ loop.conversationViews = (function(mozL10n) {
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
},
@ -425,8 +426,8 @@ loop.conversationViews = (function(mozL10n) {
],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
contact: React.PropTypes.object.isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
// This is used by the UI showcase.
emailLinkError: React.PropTypes.bool,
outgoing: React.PropTypes.bool.isRequired
@ -553,8 +554,8 @@ loop.conversationViews = (function(mozL10n) {
mozL10n.get("retry_call_button")
),
React.createElement("button", {className: emailClasses,
onClick: this.emailLink,
disabled: this.state.emailLinkButtonDisabled},
disabled: this.state.emailLinkButtonDisabled,
onClick: this.emailLink},
mozL10n.get("share_button3")
)
)
@ -570,18 +571,18 @@ loop.conversationViews = (function(mozL10n) {
],
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() {
@ -654,24 +655,24 @@ loop.conversationViews = (function(mozL10n) {
React.createElement("div", {className: "video_wrapper remote_wrapper"},
React.createElement("div", {className: "video_inner remote focus-stream"},
React.createElement(sharedViews.MediaView, {displayAvatar: !this.shouldRenderRemoteVideo(),
posterUrl: this.props.remotePosterUrl,
mediaType: "remote",
posterUrl: this.props.remotePosterUrl,
srcVideoObject: this.state.remoteSrcVideoObject})
)
),
React.createElement("div", {className: localStreamClasses},
React.createElement(sharedViews.MediaView, {displayAvatar: !this.props.video.enabled,
posterUrl: this.props.localPosterUrl,
mediaType: "local",
posterUrl: this.props.localPosterUrl,
srcVideoObject: this.state.localSrcVideoObject})
)
),
React.createElement(loop.shared.views.ConversationToolbar, {
dispatcher: this.props.dispatcher,
video: this.props.video,
audio: this.props.audio,
dispatcher: this.props.dispatcher,
hangup: this.hangup,
publishStream: this.publishStream,
hangup: this.hangup})
video: this.props.video})
)
)
);
@ -729,11 +730,10 @@ loop.conversationViews = (function(mozL10n) {
// for any state that render() doesn't manage.
if (this.state.outgoing) {
return (React.createElement(PendingConversationView, {
dispatcher: this.props.dispatcher,
callState: this.state.callState,
contact: this.state.contact,
enableCancelButton: this._isCancellable()}
));
dispatcher: this.props.dispatcher,
enableCancelButton: this._isCancellable()}));
}
// For incoming calls that are in accepting state, display the
@ -768,20 +768,18 @@ loop.conversationViews = (function(mozL10n) {
}
case CALL_STATES.TERMINATED: {
return (React.createElement(CallFailedView, {
dispatcher: this.props.dispatcher,
contact: this.state.contact,
outgoing: this.state.outgoing}
));
dispatcher: this.props.dispatcher,
outgoing: this.state.outgoing}));
}
case CALL_STATES.ONGOING: {
return (React.createElement(OngoingConversationView, {
dispatcher: this.props.dispatcher,
video: {enabled: !this.state.videoMuted},
audio: {enabled: !this.state.audioMuted},
remoteVideoEnabled: this.state.remoteVideoEnabled,
dispatcher: this.props.dispatcher,
mediaConnected: this.state.mediaConnected,
remoteSrcVideoObject: this.state.remoteSrcVideoObject}
)
remoteSrcVideoObject: this.state.remoteSrcVideoObject,
remoteVideoEnabled: this.state.remoteVideoEnabled,
video: {enabled: !this.state.videoMuted}})
);
}
case CALL_STATES.FINISHED: {

Просмотреть файл

@ -232,9 +232,10 @@ loop.conversationViews = (function(mozL10n) {
return (
<div className="call-window">
<CallIdentifierView video={this.props.callType === CALL_TYPES.AUDIO_VIDEO}
<CallIdentifierView
peerIdentifier={this.props.callerId}
showIcons={true} />
showIcons={true}
video={this.props.callType === CALL_TYPES.AUDIO_VIDEO} />
<div className="btn-group call-action-group">
@ -361,9 +362,9 @@ loop.conversationViews = (function(mozL10n) {
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
},
@ -425,8 +426,8 @@ loop.conversationViews = (function(mozL10n) {
],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
contact: React.PropTypes.object.isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
// This is used by the UI showcase.
emailLinkError: React.PropTypes.bool,
outgoing: React.PropTypes.bool.isRequired
@ -553,8 +554,8 @@ loop.conversationViews = (function(mozL10n) {
{mozL10n.get("retry_call_button")}
</button>
<button className={emailClasses}
onClick={this.emailLink}
disabled={this.state.emailLinkButtonDisabled}>
disabled={this.state.emailLinkButtonDisabled}
onClick={this.emailLink}>
{mozL10n.get("share_button3")}
</button>
</div>
@ -570,18 +571,18 @@ loop.conversationViews = (function(mozL10n) {
],
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() {
@ -654,24 +655,24 @@ loop.conversationViews = (function(mozL10n) {
<div className="video_wrapper remote_wrapper">
<div className="video_inner remote focus-stream">
<sharedViews.MediaView displayAvatar={!this.shouldRenderRemoteVideo()}
posterUrl={this.props.remotePosterUrl}
mediaType="remote"
posterUrl={this.props.remotePosterUrl}
srcVideoObject={this.state.remoteSrcVideoObject} />
</div>
</div>
<div className={localStreamClasses}>
<sharedViews.MediaView displayAvatar={!this.props.video.enabled}
posterUrl={this.props.localPosterUrl}
mediaType="local"
posterUrl={this.props.localPosterUrl}
srcVideoObject={this.state.localSrcVideoObject} />
</div>
</div>
<loop.shared.views.ConversationToolbar
dispatcher={this.props.dispatcher}
video={this.props.video}
audio={this.props.audio}
dispatcher={this.props.dispatcher}
hangup={this.hangup}
publishStream={this.publishStream}
hangup={this.hangup} />
video={this.props.video} />
</div>
</div>
);
@ -729,11 +730,10 @@ loop.conversationViews = (function(mozL10n) {
// for any state that render() doesn't manage.
if (this.state.outgoing) {
return (<PendingConversationView
dispatcher={this.props.dispatcher}
callState={this.state.callState}
contact={this.state.contact}
enableCancelButton={this._isCancellable()}
/>);
dispatcher={this.props.dispatcher}
enableCancelButton={this._isCancellable()} />);
}
// For incoming calls that are in accepting state, display the
@ -768,20 +768,18 @@ loop.conversationViews = (function(mozL10n) {
}
case CALL_STATES.TERMINATED: {
return (<CallFailedView
dispatcher={this.props.dispatcher}
contact={this.state.contact}
outgoing={this.state.outgoing}
/>);
dispatcher={this.props.dispatcher}
outgoing={this.state.outgoing} />);
}
case CALL_STATES.ONGOING: {
return (<OngoingConversationView
dispatcher={this.props.dispatcher}
video={{enabled: !this.state.videoMuted}}
audio={{enabled: !this.state.audioMuted}}
remoteVideoEnabled={this.state.remoteVideoEnabled}
dispatcher={this.props.dispatcher}
mediaConnected={this.state.mediaConnected}
remoteSrcVideoObject={this.state.remoteSrcVideoObject}
/>
remoteVideoEnabled={this.state.remoteVideoEnabled}
video={{enabled: !this.state.videoMuted}} />
);
}
case CALL_STATES.FINISHED: {

Просмотреть файл

@ -20,9 +20,9 @@ loop.panel = (function(_, mozL10n) {
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() {
@ -82,14 +82,14 @@ loop.panel = (function(_, mozL10n) {
if (!tab.props.hidden) {
tabButtons.push(
React.createElement("li", {className: cx({selected: isSelected}),
key: i,
"data-tab-name": tabName,
title: mozL10n.get(tabName + "_tab_button_tooltip"),
onClick: this.handleSelectTab})
key: i,
onClick: this.handleSelectTab,
title: mozL10n.get(tabName + "_tab_button_tooltip")})
);
}
tabs.push(
React.createElement("div", {key: i, className: cx({tab: true, selected: isSelected})},
React.createElement("div", {className: cx({tab: true, selected: isSelected}), key: i},
tab.props.children
)
);
@ -164,13 +164,13 @@ loop.panel = (function(_, mozL10n) {
React.createElement("i", {className: availabilityStatus})
),
React.createElement("ul", {className: availabilityDropdown},
React.createElement("li", {onClick: this.changeAvailability("available"),
className: "dropdown-menu-item dnd-make-available"},
React.createElement("li", {className: "dropdown-menu-item dnd-make-available",
onClick: this.changeAvailability("available")},
React.createElement("i", {className: "status status-available"}),
React.createElement("span", null, mozL10n.get("display_name_available_status"))
),
React.createElement("li", {onClick: this.changeAvailability("do-not-disturb"),
className: "dropdown-menu-item dnd-make-unavailable"},
React.createElement("li", {className: "dropdown-menu-item dnd-make-unavailable",
onClick: this.changeAvailability("do-not-disturb")},
React.createElement("i", {className: "status status-dnd"}),
React.createElement("span", null, mozL10n.get("display_name_dnd_status"))
)
@ -202,9 +202,9 @@ loop.panel = (function(_, mozL10n) {
"clientShortname": mozL10n.get("clientShortname2")
})
),
React.createElement(Button, {htmlId: "fte-button",
onClick: this.handleButtonClick,
caption: mozL10n.get("first_time_experience_button_label")})
React.createElement(Button, {caption: mozL10n.get("first_time_experience_button_label"),
htmlId: "fte-button",
onClick: this.handleButtonClick})
)
);
}
@ -291,9 +291,9 @@ loop.panel = (function(_, mozL10n) {
var locale = mozL10n.getLanguage();
navigator.mozLoop.setLoopPref("showPartnerLogo", false);
return (
React.createElement("p", {id: "powered-by", className: "powered-by"},
React.createElement("p", {className: "powered-by", id: "powered-by"},
mozL10n.get("powered_by_beforeLogo"),
React.createElement("img", {id: "powered-by-logo", className: locale}),
React.createElement("img", {className: locale, id: "powered-by-logo"}),
mozL10n.get("powered_by_afterLogo")
)
);
@ -335,10 +335,10 @@ loop.panel = (function(_, mozL10n) {
*/
var SettingsDropdownEntry = React.createClass({displayName: "SettingsDropdownEntry",
propTypes: {
onClick: React.PropTypes.func.isRequired,
label: React.PropTypes.string.isRequired,
displayed: React.PropTypes.bool,
icon: React.PropTypes.string,
displayed: React.PropTypes.bool
label: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired
},
getDefaultProps: function() {
@ -350,7 +350,7 @@ loop.panel = (function(_, mozL10n) {
return null;
}
return (
React.createElement("li", {onClick: this.props.onClick, className: "dropdown-menu-item"},
React.createElement("li", {className: "dropdown-menu-item", onClick: this.props.onClick},
this.props.icon ?
React.createElement("i", {className: "icon icon-" + this.props.icon}) :
null,
@ -410,29 +410,29 @@ loop.panel = (function(_, mozL10n) {
React.createElement("div", {className: "settings-menu dropdown"},
React.createElement("a", {className: "button-settings",
onClick: this.toggleDropdownMenu,
title: mozL10n.get("settings_menu_button_tooltip"),
ref: "menu-button"}),
ref: "menu-button",
title: mozL10n.get("settings_menu_button_tooltip")}),
React.createElement("ul", {className: cx({"dropdown-menu": true, hide: !this.state.showMenu})},
React.createElement(SettingsDropdownEntry, {label: mozL10n.get("settings_menu_item_settings"),
onClick: this.handleClickSettingsEntry,
displayed: false,
icon: "settings"}),
React.createElement(SettingsDropdownEntry, {label: mozL10n.get("settings_menu_item_account"),
onClick: this.handleClickAccountEntry,
React.createElement(SettingsDropdownEntry, {displayed: false,
icon: "settings",
label: mozL10n.get("settings_menu_item_settings"),
onClick: this.handleClickSettingsEntry}),
React.createElement(SettingsDropdownEntry, {displayed: this._isSignedIn() && this.props.mozLoop.fxAEnabled,
icon: "account",
displayed: this._isSignedIn() && this.props.mozLoop.fxAEnabled}),
label: mozL10n.get("settings_menu_item_account"),
onClick: this.handleClickAccountEntry}),
React.createElement(SettingsDropdownEntry, {icon: "tour",
label: mozL10n.get("tour_label"),
onClick: this.openGettingStartedTour}),
React.createElement(SettingsDropdownEntry, {label: this._isSignedIn() ?
React.createElement(SettingsDropdownEntry, {displayed: this.props.mozLoop.fxAEnabled,
icon: this._isSignedIn() ? "signout" : "signin",
label: this._isSignedIn() ?
mozL10n.get("settings_menu_item_signout") :
mozL10n.get("settings_menu_item_signin"),
onClick: this.handleClickAuthEntry,
displayed: this.props.mozLoop.fxAEnabled,
icon: this._isSignedIn() ? "signout" : "signin"}),
React.createElement(SettingsDropdownEntry, {label: mozL10n.get("help_label"),
onClick: this.handleHelpEntry,
icon: "help"})
onClick: this.handleClickAuthEntry}),
React.createElement(SettingsDropdownEntry, {icon: "help",
label: mozL10n.get("help_label"),
onClick: this.handleHelpEntry})
)
)
);
@ -500,7 +500,7 @@ loop.panel = (function(_, mozL10n) {
return (
React.createElement("div", {className: "room-entry-context-item"},
React.createElement("a", {href: roomUrl.location, title: roomUrl.description, onClick: this.handleClick},
React.createElement("a", {href: roomUrl.location, onClick: this.handleClick, title: roomUrl.description},
React.createElement("img", {src: roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"})
)
)
@ -587,17 +587,17 @@ loop.panel = (function(_, mozL10n) {
});
return (
React.createElement("div", {className: roomClasses, onMouseLeave: this.handleMouseLeave,
onClick: this.handleClickEntry},
React.createElement("div", {className: roomClasses, onClick: this.handleClickEntry,
onMouseLeave: this.handleMouseLeave},
React.createElement("h2", null,
React.createElement("span", {className: "room-notification"}),
this.props.room.decryptedContext.roomName,
React.createElement("button", {className: copyButtonClasses,
title: mozL10n.get("rooms_list_copy_url_tooltip"),
onClick: this.handleCopyButtonClick}),
onClick: this.handleCopyButtonClick,
title: mozL10n.get("rooms_list_copy_url_tooltip")}),
React.createElement("button", {className: "delete-link",
title: mozL10n.get("rooms_list_delete_tooltip"),
onClick: this.handleDeleteButtonClick})
onClick: this.handleDeleteButtonClick,
title: mozL10n.get("rooms_list_delete_tooltip")})
),
React.createElement(RoomEntryContextItem, {mozLoop: this.props.mozLoop,
roomUrls: this.props.room.decryptedContext.urls})
@ -613,9 +613,9 @@ loop.panel = (function(_, mozL10n) {
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
},
@ -670,11 +670,10 @@ loop.panel = (function(_, mozL10n) {
this.state.rooms.map(function(room, i) {
return (
React.createElement(RoomEntry, {
key: room.roomToken,
dispatcher: this.props.dispatcher,
key: room.roomToken,
mozLoop: this.props.mozLoop,
room: room}
)
room: room})
);
}, this)
),
@ -788,8 +787,8 @@ loop.panel = (function(_, mozL10n) {
useDesktopPaths: true})
),
React.createElement("button", {className: "btn btn-info new-room-button",
onClick: this.handleCreateButtonClick,
disabled: this.props.pendingOperation},
disabled: this.props.pendingOperation,
onClick: this.handleCreateButtonClick},
mozL10n.get("rooms_new_room_button_label")
)
)
@ -802,16 +801,16 @@ loop.panel = (function(_, mozL10n) {
*/
var PanelView = React.createClass({displayName: "PanelView",
propTypes: {
notifications: React.PropTypes.object.isRequired,
// Mostly used for UI components showcase and unit tests
userProfile: React.PropTypes.object,
// 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,
notifications: React.PropTypes.object.isRequired,
roomStore:
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
selectedTab: React.PropTypes.string,
// Used only for unit tests.
showTabButtons: React.PropTypes.bool,
// Mostly used for UI components showcase and unit tests
userProfile: React.PropTypes.object
},
getInitialState: function() {
@ -923,8 +922,9 @@ loop.panel = (function(_, mozL10n) {
if (!this.state.gettingStartedSeen) {
return (
React.createElement("div", null,
React.createElement(NotificationListView, {notifications: this.props.notifications,
clearOnDocumentHidden: true}),
React.createElement(NotificationListView, {
clearOnDocumentHidden: true,
notifications: this.props.notifications}),
React.createElement(GettingStartedView, null),
React.createElement(ToSView, null)
)
@ -943,33 +943,44 @@ loop.panel = (function(_, mozL10n) {
return (
React.createElement("div", null,
React.createElement(NotificationListView, {notifications: this.props.notifications,
clearOnDocumentHidden: true}),
React.createElement(TabView, {ref: "tabView", selectedTab: this.props.selectedTab,
buttonsHidden: hideButtons, mozLoop: this.props.mozLoop},
React.createElement(NotificationListView, {
clearOnDocumentHidden: true,
notifications: this.props.notifications}),
React.createElement(TabView, {
buttonsHidden: hideButtons,
mozLoop: this.props.mozLoop,
ref: "tabView",
selectedTab: this.props.selectedTab},
React.createElement(Tab, {name: "rooms"},
React.createElement(RoomList, {dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
store: this.props.roomStore,
userDisplayName: this._getUserDisplayName(),
mozLoop: this.props.mozLoop}),
userDisplayName: this._getUserDisplayName()}),
React.createElement(ToSView, null)
),
React.createElement(Tab, {name: "contacts"},
React.createElement(ContactsList, {selectTab: this.selectTab,
startForm: this.startForm,
notifications: this.props.notifications})
React.createElement(ContactsList, {
notifications: this.props.notifications,
selectTab: this.selectTab,
startForm: this.startForm})
),
React.createElement(Tab, {name: "contacts_add", hidden: true},
React.createElement(ContactDetailsForm, {ref: "contacts_add", mode: "add",
selectTab: this.selectTab})
React.createElement(Tab, {hidden: true, name: "contacts_add"},
React.createElement(ContactDetailsForm, {
mode: "add",
ref: "contacts_add",
selectTab: this.selectTab})
),
React.createElement(Tab, {name: "contacts_edit", hidden: true},
React.createElement(ContactDetailsForm, {ref: "contacts_edit", mode: "edit",
selectTab: this.selectTab})
React.createElement(Tab, {hidden: true, name: "contacts_edit"},
React.createElement(ContactDetailsForm, {
mode: "edit",
ref: "contacts_edit",
selectTab: this.selectTab})
),
React.createElement(Tab, {name: "contacts_import", hidden: true},
React.createElement(ContactDetailsForm, {ref: "contacts_import", mode: "import",
selectTab: this.selectTab})
React.createElement(Tab, {hidden: true, name: "contacts_import"},
React.createElement(ContactDetailsForm, {
mode: "import",
ref: "contacts_import",
selectTab: this.selectTab})
)
),
React.createElement("div", {className: "footer"},
@ -1004,10 +1015,10 @@ loop.panel = (function(_, mozL10n) {
});
React.render(React.createElement(PanelView, {
notifications: notifications,
roomStore: roomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
dispatcher: dispatcher}), document.querySelector("#main"));
notifications: notifications,
roomStore: roomStore}), document.querySelector("#main"));
document.documentElement.setAttribute("lang", mozL10n.getLanguage());
document.documentElement.setAttribute("dir", mozL10n.getDirection());

Просмотреть файл

@ -20,9 +20,9 @@ loop.panel = (function(_, mozL10n) {
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() {
@ -82,14 +82,14 @@ loop.panel = (function(_, mozL10n) {
if (!tab.props.hidden) {
tabButtons.push(
<li className={cx({selected: isSelected})}
key={i}
data-tab-name={tabName}
title={mozL10n.get(tabName + "_tab_button_tooltip")}
onClick={this.handleSelectTab} />
key={i}
onClick={this.handleSelectTab}
title={mozL10n.get(tabName + "_tab_button_tooltip")} />
);
}
tabs.push(
<div key={i} className={cx({tab: true, selected: isSelected})}>
<div className={cx({tab: true, selected: isSelected})} key={i}>
{tab.props.children}
</div>
);
@ -164,13 +164,13 @@ loop.panel = (function(_, mozL10n) {
<i className={availabilityStatus}></i>
</p>
<ul className={availabilityDropdown}>
<li onClick={this.changeAvailability("available")}
className="dropdown-menu-item dnd-make-available">
<li className="dropdown-menu-item dnd-make-available"
onClick={this.changeAvailability("available")}>
<i className="status status-available"></i>
<span>{mozL10n.get("display_name_available_status")}</span>
</li>
<li onClick={this.changeAvailability("do-not-disturb")}
className="dropdown-menu-item dnd-make-unavailable">
<li className="dropdown-menu-item dnd-make-unavailable"
onClick={this.changeAvailability("do-not-disturb")}>
<i className="status status-dnd"></i>
<span>{mozL10n.get("display_name_dnd_status")}</span>
</li>
@ -202,9 +202,9 @@ loop.panel = (function(_, mozL10n) {
"clientShortname": mozL10n.get("clientShortname2")
})}
</header>
<Button htmlId="fte-button"
onClick={this.handleButtonClick}
caption={mozL10n.get("first_time_experience_button_label")} />
<Button caption={mozL10n.get("first_time_experience_button_label")}
htmlId="fte-button"
onClick={this.handleButtonClick} />
</div>
);
}
@ -291,9 +291,9 @@ loop.panel = (function(_, mozL10n) {
var locale = mozL10n.getLanguage();
navigator.mozLoop.setLoopPref("showPartnerLogo", false);
return (
<p id="powered-by" className="powered-by">
<p className="powered-by" id="powered-by">
{mozL10n.get("powered_by_beforeLogo")}
<img id="powered-by-logo" className={locale} />
<img className={locale} id="powered-by-logo" />
{mozL10n.get("powered_by_afterLogo")}
</p>
);
@ -335,10 +335,10 @@ loop.panel = (function(_, mozL10n) {
*/
var SettingsDropdownEntry = React.createClass({
propTypes: {
onClick: React.PropTypes.func.isRequired,
label: React.PropTypes.string.isRequired,
displayed: React.PropTypes.bool,
icon: React.PropTypes.string,
displayed: React.PropTypes.bool
label: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired
},
getDefaultProps: function() {
@ -350,7 +350,7 @@ loop.panel = (function(_, mozL10n) {
return null;
}
return (
<li onClick={this.props.onClick} className="dropdown-menu-item">
<li className="dropdown-menu-item" onClick={this.props.onClick}>
{this.props.icon ?
<i className={"icon icon-" + this.props.icon}></i> :
null}
@ -410,29 +410,29 @@ loop.panel = (function(_, mozL10n) {
<div className="settings-menu dropdown">
<a className="button-settings"
onClick={this.toggleDropdownMenu}
title={mozL10n.get("settings_menu_button_tooltip")}
ref="menu-button" />
ref="menu-button"
title={mozL10n.get("settings_menu_button_tooltip")} />
<ul className={cx({"dropdown-menu": true, hide: !this.state.showMenu})}>
<SettingsDropdownEntry label={mozL10n.get("settings_menu_item_settings")}
onClick={this.handleClickSettingsEntry}
displayed={false}
icon="settings" />
<SettingsDropdownEntry label={mozL10n.get("settings_menu_item_account")}
onClick={this.handleClickAccountEntry}
<SettingsDropdownEntry displayed={false}
icon="settings"
label={mozL10n.get("settings_menu_item_settings")}
onClick={this.handleClickSettingsEntry} />
<SettingsDropdownEntry displayed={this._isSignedIn() && this.props.mozLoop.fxAEnabled}
icon="account"
displayed={this._isSignedIn() && this.props.mozLoop.fxAEnabled} />
label={mozL10n.get("settings_menu_item_account")}
onClick={this.handleClickAccountEntry} />
<SettingsDropdownEntry icon="tour"
label={mozL10n.get("tour_label")}
onClick={this.openGettingStartedTour} />
<SettingsDropdownEntry label={this._isSignedIn() ?
<SettingsDropdownEntry displayed={this.props.mozLoop.fxAEnabled}
icon={this._isSignedIn() ? "signout" : "signin"}
label={this._isSignedIn() ?
mozL10n.get("settings_menu_item_signout") :
mozL10n.get("settings_menu_item_signin")}
onClick={this.handleClickAuthEntry}
displayed={this.props.mozLoop.fxAEnabled}
icon={this._isSignedIn() ? "signout" : "signin"} />
<SettingsDropdownEntry label={mozL10n.get("help_label")}
onClick={this.handleHelpEntry}
icon="help" />
onClick={this.handleClickAuthEntry} />
<SettingsDropdownEntry icon="help"
label={mozL10n.get("help_label")}
onClick={this.handleHelpEntry} />
</ul>
</div>
);
@ -500,7 +500,7 @@ loop.panel = (function(_, mozL10n) {
return (
<div className="room-entry-context-item">
<a href={roomUrl.location} title={roomUrl.description} onClick={this.handleClick}>
<a href={roomUrl.location} onClick={this.handleClick} title={roomUrl.description}>
<img src={roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"} />
</a>
</div>
@ -587,17 +587,17 @@ loop.panel = (function(_, mozL10n) {
});
return (
<div className={roomClasses} onMouseLeave={this.handleMouseLeave}
onClick={this.handleClickEntry}>
<div className={roomClasses} onClick={this.handleClickEntry}
onMouseLeave={this.handleMouseLeave}>
<h2>
<span className="room-notification" />
{this.props.room.decryptedContext.roomName}
<button className={copyButtonClasses}
title={mozL10n.get("rooms_list_copy_url_tooltip")}
onClick={this.handleCopyButtonClick} />
onClick={this.handleCopyButtonClick}
title={mozL10n.get("rooms_list_copy_url_tooltip")} />
<button className="delete-link"
title={mozL10n.get("rooms_list_delete_tooltip")}
onClick={this.handleDeleteButtonClick} />
onClick={this.handleDeleteButtonClick}
title={mozL10n.get("rooms_list_delete_tooltip")} />
</h2>
<RoomEntryContextItem mozLoop={this.props.mozLoop}
roomUrls={this.props.room.decryptedContext.urls} />
@ -613,9 +613,9 @@ loop.panel = (function(_, mozL10n) {
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
},
@ -670,11 +670,10 @@ loop.panel = (function(_, mozL10n) {
this.state.rooms.map(function(room, i) {
return (
<RoomEntry
key={room.roomToken}
dispatcher={this.props.dispatcher}
key={room.roomToken}
mozLoop={this.props.mozLoop}
room={room}
/>
room={room} />
);
}, this)
}</div>
@ -788,8 +787,8 @@ loop.panel = (function(_, mozL10n) {
useDesktopPaths={true} />
</div>
<button className="btn btn-info new-room-button"
onClick={this.handleCreateButtonClick}
disabled={this.props.pendingOperation}>
disabled={this.props.pendingOperation}
onClick={this.handleCreateButtonClick}>
{mozL10n.get("rooms_new_room_button_label")}
</button>
</div>
@ -802,16 +801,16 @@ loop.panel = (function(_, mozL10n) {
*/
var PanelView = React.createClass({
propTypes: {
notifications: React.PropTypes.object.isRequired,
// Mostly used for UI components showcase and unit tests
userProfile: React.PropTypes.object,
// 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,
notifications: React.PropTypes.object.isRequired,
roomStore:
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
selectedTab: React.PropTypes.string,
// Used only for unit tests.
showTabButtons: React.PropTypes.bool,
// Mostly used for UI components showcase and unit tests
userProfile: React.PropTypes.object
},
getInitialState: function() {
@ -923,8 +922,9 @@ loop.panel = (function(_, mozL10n) {
if (!this.state.gettingStartedSeen) {
return (
<div>
<NotificationListView notifications={this.props.notifications}
clearOnDocumentHidden={true} />
<NotificationListView
clearOnDocumentHidden={true}
notifications={this.props.notifications} />
<GettingStartedView />
<ToSView />
</div>
@ -943,33 +943,44 @@ loop.panel = (function(_, mozL10n) {
return (
<div>
<NotificationListView notifications={this.props.notifications}
clearOnDocumentHidden={true} />
<TabView ref="tabView" selectedTab={this.props.selectedTab}
buttonsHidden={hideButtons} mozLoop={this.props.mozLoop}>
<NotificationListView
clearOnDocumentHidden={true}
notifications={this.props.notifications} />
<TabView
buttonsHidden={hideButtons}
mozLoop={this.props.mozLoop}
ref="tabView"
selectedTab={this.props.selectedTab}>
<Tab name="rooms">
<RoomList dispatcher={this.props.dispatcher}
mozLoop={this.props.mozLoop}
store={this.props.roomStore}
userDisplayName={this._getUserDisplayName()}
mozLoop={this.props.mozLoop}/>
userDisplayName={this._getUserDisplayName()} />
<ToSView />
</Tab>
<Tab name="contacts">
<ContactsList selectTab={this.selectTab}
startForm={this.startForm}
notifications={this.props.notifications} />
<ContactsList
notifications={this.props.notifications}
selectTab={this.selectTab}
startForm={this.startForm} />
</Tab>
<Tab name="contacts_add" hidden={true}>
<ContactDetailsForm ref="contacts_add" mode="add"
selectTab={this.selectTab} />
<Tab hidden={true} name="contacts_add">
<ContactDetailsForm
mode="add"
ref="contacts_add"
selectTab={this.selectTab} />
</Tab>
<Tab name="contacts_edit" hidden={true}>
<ContactDetailsForm ref="contacts_edit" mode="edit"
selectTab={this.selectTab} />
<Tab hidden={true} name="contacts_edit">
<ContactDetailsForm
mode="edit"
ref="contacts_edit"
selectTab={this.selectTab} />
</Tab>
<Tab name="contacts_import" hidden={true}>
<ContactDetailsForm ref="contacts_import" mode="import"
selectTab={this.selectTab}/>
<Tab hidden={true} name="contacts_import">
<ContactDetailsForm
mode="import"
ref="contacts_import"
selectTab={this.selectTab}/>
</Tab>
</TabView>
<div className="footer">
@ -1004,10 +1015,10 @@ loop.panel = (function(_, mozL10n) {
});
React.render(<PanelView
notifications={notifications}
roomStore={roomStore}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
dispatcher={dispatcher} />, document.querySelector("#main"));
notifications={notifications}
roomStore={roomStore} />, document.querySelector("#main"));
document.documentElement.setAttribute("lang", mozL10n.getLanguage());
document.documentElement.setAttribute("dir", mozL10n.getDirection());

Просмотреть файл

@ -129,8 +129,8 @@ loop.roomViews = (function(mozL10n) {
this.props.socialShareProviders.map(function(provider, idx) {
return (
React.createElement("li", {className: "dropdown-menu-item",
key: "provider-" + idx,
"data-provider": provider.origin,
key: "provider-" + idx,
onClick: this.handleProviderClick},
React.createElement("img", {className: "icon", src: provider.iconURL}),
React.createElement("span", null, provider.name)
@ -249,25 +249,25 @@ loop.roomViews = (function(mozL10n) {
mozL10n.get("copy_url_button2")
),
React.createElement("button", {className: "btn btn-info btn-share",
ref: "anchor",
onClick: this.handleShareButtonClick},
onClick: this.handleShareButtonClick,
ref: "anchor"},
mozL10n.get("share_button3")
)
),
React.createElement(SocialShareDropdown, {
dispatcher: this.props.dispatcher,
ref: "menu",
roomUrl: this.props.roomData.roomUrl,
show: this.state.showMenu,
socialShareProviders: this.props.socialShareProviders,
ref: "menu"}),
socialShareProviders: this.props.socialShareProviders}),
React.createElement(DesktopRoomContextView, {
dispatcher: this.props.dispatcher,
editMode: this.state.editMode,
error: this.props.error,
savingContext: this.props.savingContext,
mozLoop: this.props.mozLoop,
onEditModeChange: this.handleEditModeChange,
roomData: this.props.roomData,
savingContext: this.props.savingContext,
show: this.props.showContext || this.state.editMode})
)
);
@ -519,18 +519,21 @@ loop.roomViews = (function(mozL10n) {
onChange: this.handleCheckboxChange,
value: location}),
React.createElement("form", {onSubmit: this.handleFormSubmit},
React.createElement("input", {type: "text", className: "room-context-name",
React.createElement("input", {className: "room-context-name",
onKeyDown: this.handleTextareaKeyDown,
placeholder: mozL10n.get("context_edit_name_placeholder"),
type: "text",
valueLink: this.linkState("newRoomName")}),
React.createElement("input", {type: "text", className: "room-context-url",
React.createElement("input", {className: "room-context-url",
disabled: availableContext && availableContext.url === this.state.newRoomURL,
onKeyDown: this.handleTextareaKeyDown,
placeholder: "https://",
disabled: availableContext && availableContext.url === this.state.newRoomURL,
type: "text",
valueLink: this.linkState("newRoomURL")}),
React.createElement("textarea", {rows: "3", type: "text", className: "room-context-comments",
React.createElement("textarea", {className: "room-context-comments",
onKeyDown: this.handleTextareaKeyDown,
placeholder: mozL10n.get("context_edit_comments_placeholder"),
rows: "3", type: "text",
valueLink: this.linkState("newRoomDescription")})
),
React.createElement("button", {className: "btn btn-info",
@ -587,9 +590,9 @@ loop.roomViews = (function(mozL10n) {
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
},
@ -769,35 +772,35 @@ loop.roomViews = (function(mozL10n) {
React.createElement("div", {className: "video_wrapper remote_wrapper"},
React.createElement("div", {className: "video_inner remote focus-stream"},
React.createElement(sharedViews.MediaView, {displayAvatar: !this.shouldRenderRemoteVideo(),
posterUrl: this.props.remotePosterUrl,
isLoading: this._shouldRenderRemoteLoading(),
mediaType: "remote",
posterUrl: this.props.remotePosterUrl,
srcVideoObject: this.state.remoteSrcVideoObject})
)
),
React.createElement("div", {className: localStreamClasses},
React.createElement(sharedViews.MediaView, {displayAvatar: this.state.videoMuted,
posterUrl: this.props.localPosterUrl,
isLoading: this._shouldRenderLocalLoading(),
mediaType: "local",
posterUrl: this.props.localPosterUrl,
srcVideoObject: this.state.localSrcVideoObject})
)
),
React.createElement(sharedViews.ConversationToolbar, {
dispatcher: this.props.dispatcher,
video: {enabled: !this.state.videoMuted, visible: true},
audio: {enabled: !this.state.audioMuted, visible: true},
publishStream: this.publishStream,
dispatcher: this.props.dispatcher,
hangup: this.leaveRoom,
screenShare: screenShareData})
publishStream: this.publishStream,
screenShare: screenShareData,
video: {enabled: !this.state.videoMuted, visible: true}})
)
),
React.createElement(DesktopRoomContextView, {
dispatcher: this.props.dispatcher,
error: this.state.error,
savingContext: this.state.savingContext,
mozLoop: this.props.mozLoop,
roomData: roomData,
savingContext: this.state.savingContext,
show: !shouldRenderInvitationOverlay && shouldRenderContextView}),
React.createElement(sharedViews.TextChatView, {
dispatcher: this.props.dispatcher,

Просмотреть файл

@ -129,8 +129,8 @@ loop.roomViews = (function(mozL10n) {
this.props.socialShareProviders.map(function(provider, idx) {
return (
<li className="dropdown-menu-item"
key={"provider-" + idx}
data-provider={provider.origin}
key={"provider-" + idx}
onClick={this.handleProviderClick}>
<img className="icon" src={provider.iconURL}/>
<span>{provider.name}</span>
@ -249,25 +249,25 @@ loop.roomViews = (function(mozL10n) {
mozL10n.get("copy_url_button2")}
</button>
<button className="btn btn-info btn-share"
ref="anchor"
onClick={this.handleShareButtonClick}>
onClick={this.handleShareButtonClick}
ref="anchor">
{mozL10n.get("share_button3")}
</button>
</div>
<SocialShareDropdown
dispatcher={this.props.dispatcher}
ref="menu"
roomUrl={this.props.roomData.roomUrl}
show={this.state.showMenu}
socialShareProviders={this.props.socialShareProviders}
ref="menu" />
socialShareProviders={this.props.socialShareProviders} />
<DesktopRoomContextView
dispatcher={this.props.dispatcher}
editMode={this.state.editMode}
error={this.props.error}
savingContext={this.props.savingContext}
mozLoop={this.props.mozLoop}
onEditModeChange={this.handleEditModeChange}
roomData={this.props.roomData}
savingContext={this.props.savingContext}
show={this.props.showContext || this.state.editMode} />
</div>
);
@ -519,18 +519,21 @@ loop.roomViews = (function(mozL10n) {
onChange={this.handleCheckboxChange}
value={location} />
<form onSubmit={this.handleFormSubmit}>
<input type="text" className="room-context-name"
<input className="room-context-name"
onKeyDown={this.handleTextareaKeyDown}
placeholder={mozL10n.get("context_edit_name_placeholder")}
type="text"
valueLink={this.linkState("newRoomName")} />
<input type="text" className="room-context-url"
<input className="room-context-url"
disabled={availableContext && availableContext.url === this.state.newRoomURL}
onKeyDown={this.handleTextareaKeyDown}
placeholder="https://"
disabled={availableContext && availableContext.url === this.state.newRoomURL}
type="text"
valueLink={this.linkState("newRoomURL")} />
<textarea rows="3" type="text" className="room-context-comments"
<textarea className="room-context-comments"
onKeyDown={this.handleTextareaKeyDown}
placeholder={mozL10n.get("context_edit_comments_placeholder")}
rows="3" type="text"
valueLink={this.linkState("newRoomDescription")} />
</form>
<button className="btn btn-info"
@ -587,9 +590,9 @@ loop.roomViews = (function(mozL10n) {
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
},
@ -769,35 +772,35 @@ loop.roomViews = (function(mozL10n) {
<div className="video_wrapper remote_wrapper">
<div className="video_inner remote focus-stream">
<sharedViews.MediaView displayAvatar={!this.shouldRenderRemoteVideo()}
posterUrl={this.props.remotePosterUrl}
isLoading={this._shouldRenderRemoteLoading()}
mediaType="remote"
posterUrl={this.props.remotePosterUrl}
srcVideoObject={this.state.remoteSrcVideoObject} />
</div>
</div>
<div className={localStreamClasses}>
<sharedViews.MediaView displayAvatar={this.state.videoMuted}
posterUrl={this.props.localPosterUrl}
isLoading={this._shouldRenderLocalLoading()}
mediaType="local"
posterUrl={this.props.localPosterUrl}
srcVideoObject={this.state.localSrcVideoObject} />
</div>
</div>
<sharedViews.ConversationToolbar
dispatcher={this.props.dispatcher}
video={{enabled: !this.state.videoMuted, visible: true}}
audio={{enabled: !this.state.audioMuted, visible: true}}
publishStream={this.publishStream}
dispatcher={this.props.dispatcher}
hangup={this.leaveRoom}
screenShare={screenShareData} />
publishStream={this.publishStream}
screenShare={screenShareData}
video={{enabled: !this.state.videoMuted, visible: true}} />
</div>
</div>
<DesktopRoomContextView
dispatcher={this.props.dispatcher}
error={this.state.error}
savingContext={this.state.savingContext}
mozLoop={this.props.mozLoop}
roomData={roomData}
savingContext={this.state.savingContext}
show={!shouldRenderInvitationOverlay && shouldRenderContextView} />
<sharedViews.TextChatView
dispatcher={this.props.dispatcher}

Просмотреть файл

@ -24,16 +24,17 @@ loop.shared.views.FeedbackView = (function(l10n) {
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", type: "button",
onClick: this.props.reset},
React.createElement("button", {className: "fx-embedded-btn-back",
onClick: this.props.reset,
type: "button"},
"« ", l10n.get("feedback_back_button")
)
);
@ -80,12 +81,15 @@ loop.shared.views.FeedbackView = (function(l10n) {
var categories = this._getCategories();
return Object.keys(categories).map(function(category, key) {
return (
React.createElement("label", {key: key, className: "feedback-category-label"},
React.createElement("input", {type: "radio", ref: "category", name: "category",
className: "feedback-category-radio",
value: category,
onChange: this.handleCategoryChange,
checked: this.state.category === category}),
React.createElement("label", {className: "feedback-category-label", key: key},
React.createElement("input", {
checked: this.state.category === category,
className: "feedback-category-radio",
name: "category",
onChange: this.handleCategoryChange,
ref: "category",
type: "radio",
value: category}),
categories[category]
)
);
@ -138,20 +142,24 @@ loop.shared.views.FeedbackView = (function(l10n) {
render: function() {
return (
React.createElement(FeedbackLayout, {title: l10n.get("feedback_category_list_heading"),
reset: this.props.reset},
React.createElement(FeedbackLayout, {
reset: this.props.reset,
title: l10n.get("feedback_category_list_heading")},
React.createElement("form", {onSubmit: this.handleFormSubmit},
this._getCategoryFields(),
React.createElement("p", null,
React.createElement("input", {type: "text", ref: "description", name: "description",
className: "feedback-description",
React.createElement("input", {className: "feedback-description",
name: "description",
onChange: this.handleDescriptionFieldChange,
value: this.state.description,
placeholder:
l10n.get("feedback_custom_category_text_placeholder")})
l10n.get("feedback_custom_category_text_placeholder"),
ref: "description",
type: "text",
value: this.state.description})
),
React.createElement("button", {type: "submit", className: "btn btn-success",
disabled: !this._isFormReady()},
React.createElement("button", {className: "btn btn-success",
disabled: !this._isFormReady(),
type: "submit"},
l10n.get("feedback_submit_button")
)
)
@ -229,10 +237,10 @@ loop.shared.views.FeedbackView = (function(l10n) {
],
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() {
@ -289,8 +297,8 @@ loop.shared.views.FeedbackView = (function(l10n) {
return (
React.createElement(FeedbackForm, {
feedbackStore: this.getStore(),
reset: this.reset,
pending: this.state.feedbackState === FEEDBACK_STATES.PENDING})
pending: this.state.feedbackState === FEEDBACK_STATES.PENDING,
reset: this.reset})
);
}
case FEEDBACK_STATES.PENDING:

Просмотреть файл

@ -24,16 +24,17 @@ loop.shared.views.FeedbackView = (function(l10n) {
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" type="button"
onClick={this.props.reset}>
<button className="fx-embedded-btn-back"
onClick={this.props.reset}
type="button" >
&laquo;&nbsp;{l10n.get("feedback_back_button")}
</button>
);
@ -80,12 +81,15 @@ loop.shared.views.FeedbackView = (function(l10n) {
var categories = this._getCategories();
return Object.keys(categories).map(function(category, key) {
return (
<label key={key} className="feedback-category-label">
<input type="radio" ref="category" name="category"
className="feedback-category-radio"
value={category}
onChange={this.handleCategoryChange}
checked={this.state.category === category} />
<label className="feedback-category-label" key={key}>
<input
checked={this.state.category === category}
className="feedback-category-radio"
name="category"
onChange={this.handleCategoryChange}
ref="category"
type="radio"
value={category} />
{categories[category]}
</label>
);
@ -138,20 +142,24 @@ loop.shared.views.FeedbackView = (function(l10n) {
render: function() {
return (
<FeedbackLayout title={l10n.get("feedback_category_list_heading")}
reset={this.props.reset}>
<FeedbackLayout
reset={this.props.reset}
title={l10n.get("feedback_category_list_heading")}>
<form onSubmit={this.handleFormSubmit}>
{this._getCategoryFields()}
<p>
<input type="text" ref="description" name="description"
className="feedback-description"
<input className="feedback-description"
name="description"
onChange={this.handleDescriptionFieldChange}
value={this.state.description}
placeholder={
l10n.get("feedback_custom_category_text_placeholder")} />
l10n.get("feedback_custom_category_text_placeholder")}
ref="description"
type="text"
value={this.state.description} />
</p>
<button type="submit" className="btn btn-success"
disabled={!this._isFormReady()}>
<button className="btn btn-success"
disabled={!this._isFormReady()}
type="submit">
{l10n.get("feedback_submit_button")}
</button>
</form>
@ -229,10 +237,10 @@ loop.shared.views.FeedbackView = (function(l10n) {
],
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() {
@ -289,8 +297,8 @@ loop.shared.views.FeedbackView = (function(l10n) {
return (
<FeedbackForm
feedbackStore={this.getStore()}
reset={this.reset}
pending={this.state.feedbackState === FEEDBACK_STATES.PENDING} />
pending={this.state.feedbackState === FEEDBACK_STATES.PENDING}
reset={this.reset} />
);
}
case FEEDBACK_STATES.PENDING:

Просмотреть файл

@ -107,7 +107,7 @@ loop.shared.views.TextChatView = (function(mozL10n) {
return React.createElement(TextChatRoomName, {key: i, message: entry.message});
case CHAT_CONTENT_TYPES.CONTEXT:
return (
React.createElement("div", {key: i, className: "context-url-view-wrapper"},
React.createElement("div", {className: "context-url-view-wrapper", key: i},
React.createElement(sharedViews.ContextUrlView, {
allowClick: true,
description: entry.message,
@ -125,10 +125,11 @@ loop.shared.views.TextChatView = (function(mozL10n) {
}
return (
React.createElement(TextChatEntry, {key: i,
contentType: entry.contentType,
message: entry.message,
type: entry.type})
React.createElement(TextChatEntry, {
contentType: entry.contentType,
key: i,
message: entry.message,
type: entry.type})
);
}, this)
@ -206,10 +207,11 @@ loop.shared.views.TextChatView = (function(mozL10n) {
return (
React.createElement("div", {className: "text-chat-box"},
React.createElement("form", {onSubmit: this.handleFormSubmit},
React.createElement("input", {type: "text",
placeholder: this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : "",
onKeyDown: this.handleKeyDown,
valueLink: this.linkState("messageDetail")})
React.createElement("input", {
onKeyDown: this.handleKeyDown,
placeholder: this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : "",
type: "text",
valueLink: this.linkState("messageDetail")})
)
)
);

Просмотреть файл

@ -107,7 +107,7 @@ loop.shared.views.TextChatView = (function(mozL10n) {
return <TextChatRoomName key={i} message={entry.message}/>;
case CHAT_CONTENT_TYPES.CONTEXT:
return (
<div key={i} className="context-url-view-wrapper">
<div className="context-url-view-wrapper" key={i}>
<sharedViews.ContextUrlView
allowClick={true}
description={entry.message}
@ -125,10 +125,11 @@ loop.shared.views.TextChatView = (function(mozL10n) {
}
return (
<TextChatEntry key={i}
contentType={entry.contentType}
message={entry.message}
type={entry.type} />
<TextChatEntry
contentType={entry.contentType}
key={i}
message={entry.message}
type={entry.type} />
);
}, this)
}
@ -206,10 +207,11 @@ loop.shared.views.TextChatView = (function(mozL10n) {
return (
<div className="text-chat-box">
<form onSubmit={this.handleFormSubmit}>
<input type="text"
placeholder={this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : ""}
onKeyDown={this.handleKeyDown}
valueLink={this.linkState("messageDetail")} />
<input
onKeyDown={this.handleKeyDown}
placeholder={this.props.showPlaceholder ? mozL10n.get("chat_textbox_placeholder") : ""}
type="text"
valueLink={this.linkState("messageDetail")} />
</form>
</div>
);

Просмотреть файл

@ -23,10 +23,10 @@ loop.shared.views = (function(_, l10n) {
*/
var MediaControlButton = React.createClass({displayName: "MediaControlButton",
propTypes: {
scope: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired,
action: React.PropTypes.func.isRequired,
enabled: React.PropTypes.bool.isRequired,
scope: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired,
visible: React.PropTypes.bool.isRequired
},
@ -63,8 +63,8 @@ loop.shared.views = (function(_, l10n) {
render: function() {
return (
React.createElement("button", {className: this._getClasses(),
title: this._getTitle(),
onClick: this.handleClick})
onClick: this.handleClick,
title: this._getTitle()})
);
}
});
@ -83,8 +83,8 @@ loop.shared.views = (function(_, l10n) {
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() {
@ -162,11 +162,11 @@ loop.shared.views = (function(_, l10n) {
title: this._getTitle()},
isActive ? null : React.createElement("span", {className: "chevron"})
),
React.createElement("ul", {ref: "menu", className: dropdownMenuClasses},
React.createElement("ul", {className: dropdownMenuClasses, ref: "menu"},
React.createElement("li", {onClick: this._handleShareTabs},
l10n.get("share_tabs_button_title2")
),
React.createElement("li", {onClick: this._handleShareWindows, className: windowSharingClasses},
React.createElement("li", {className: windowSharingClasses, onClick: this._handleShareWindows},
l10n.get("share_windows_button_title")
)
)
@ -189,14 +189,14 @@ loop.shared.views = (function(_, l10n) {
},
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
video: React.PropTypes.object.isRequired,
audio: React.PropTypes.object.isRequired,
screenShare: React.PropTypes.object,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
enableHangup: React.PropTypes.bool,
hangup: React.PropTypes.func.isRequired,
publishStream: React.PropTypes.func.isRequired,
hangupButtonLabel: React.PropTypes.string,
enableHangup: React.PropTypes.bool
publishStream: React.PropTypes.func.isRequired,
screenShare: React.PropTypes.object,
video: React.PropTypes.object.isRequired
},
handleClickHangup: function() {
@ -219,28 +219,29 @@ loop.shared.views = (function(_, l10n) {
return (
React.createElement("ul", {className: "conversation-toolbar"},
React.createElement("li", {className: "conversation-toolbar-btn-box btn-hangup-entry"},
React.createElement("button", {className: "btn btn-hangup", onClick: this.handleClickHangup,
title: l10n.get("hangup_button_title"),
disabled: !this.props.enableHangup},
React.createElement("button", {className: "btn btn-hangup",
disabled: !this.props.enableHangup,
onClick: this.handleClickHangup,
title: l10n.get("hangup_button_title")},
this._getHangupButtonLabel()
)
),
React.createElement("li", {className: "conversation-toolbar-btn-box"},
React.createElement(MediaControlButton, {action: this.handleToggleVideo,
enabled: this.props.video.enabled,
visible: this.props.video.visible,
scope: "local", type: "video"})
scope: "local", type: "video",
visible: this.props.video.visible})
),
React.createElement("li", {className: "conversation-toolbar-btn-box"},
React.createElement(MediaControlButton, {action: this.handleToggleAudio,
enabled: this.props.audio.enabled,
visible: this.props.audio.visible,
scope: "local", type: "audio"})
scope: "local", type: "audio",
visible: this.props.audio.visible})
),
React.createElement("li", {className: "conversation-toolbar-btn-box btn-screen-share-entry"},
React.createElement(ScreenShareControlButton, {dispatcher: this.props.dispatcher,
visible: this.props.screenShare.visible,
state: this.props.screenShare.state})
state: this.props.screenShare.state,
visible: this.props.screenShare.visible})
)
)
);
@ -258,11 +259,11 @@ loop.shared.views = (function(_, l10n) {
],
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() {
@ -455,10 +456,11 @@ loop.shared.views = (function(_, l10n) {
),
React.createElement("div", {className: localStreamClasses})
),
React.createElement(ConversationToolbar, {video: this.state.video,
audio: this.state.audio,
publishStream: this.publishStream,
hangup: this.hangup})
React.createElement(ConversationToolbar, {
audio: this.state.audio,
hangup: this.hangup,
publishStream: this.publishStream,
video: this.state.video})
)
)
);
@ -472,23 +474,23 @@ loop.shared.views = (function(_, l10n) {
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", {key: this.props.key,
className: "alert alert-" + notification.get("level")},
React.createElement("div", {className: "alert alert-" + notification.get("level"),
key: this.props.key},
React.createElement("span", {className: "message"}, notification.get("message"))
),
React.createElement("div", {className: "detailsBar details-" + notification.get("level"),
hidden: !notification.get("details")},
React.createElement("button", {className: "detailsButton btn-info",
onClick: notification.get("detailsButtonCallback"),
hidden: !notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback")},
hidden: !notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback"),
onClick: notification.get("detailsButtonCallback")},
notification.get("detailsButtonLabel")
),
React.createElement("span", {className: "details"}, notification.get("details"))
@ -505,8 +507,8 @@ loop.shared.views = (function(_, l10n) {
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() {
@ -553,11 +555,11 @@ loop.shared.views = (function(_, l10n) {
var Button = React.createClass({displayName: "Button",
propTypes: {
caption: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired,
disabled: React.PropTypes.bool,
additionalClass: React.PropTypes.string,
htmlId: React.PropTypes.string
caption: React.PropTypes.string.isRequired,
disabled: React.PropTypes.bool,
htmlId: React.PropTypes.string,
onClick: React.PropTypes.func.isRequired
},
getDefaultProps: function() {
@ -575,10 +577,10 @@ loop.shared.views = (function(_, l10n) {
classObject[this.props.additionalClass] = true;
}
return (
React.createElement("button", {onClick: this.props.onClick,
React.createElement("button", {className: cx(classObject),
disabled: this.props.disabled,
id: this.props.htmlId,
className: cx(classObject)},
onClick: this.props.onClick},
React.createElement("span", {className: "button-caption"}, this.props.caption),
this.props.children
)
@ -791,8 +793,8 @@ loop.shared.views = (function(_, l10n) {
React.createElement("span", {className: "context-description"},
this.props.description,
React.createElement("a", {className: "context-url",
onClick: this.handleLinkClick,
href: this.props.allowClick ? this.props.url : null,
onClick: this.handleLinkClick,
rel: "noreferrer",
target: "_blank"}, hostname)
)

Просмотреть файл

@ -23,10 +23,10 @@ loop.shared.views = (function(_, l10n) {
*/
var MediaControlButton = React.createClass({
propTypes: {
scope: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired,
action: React.PropTypes.func.isRequired,
enabled: React.PropTypes.bool.isRequired,
scope: React.PropTypes.string.isRequired,
type: React.PropTypes.string.isRequired,
visible: React.PropTypes.bool.isRequired
},
@ -63,8 +63,8 @@ loop.shared.views = (function(_, l10n) {
render: function() {
return (
<button className={this._getClasses()}
title={this._getTitle()}
onClick={this.handleClick}></button>
onClick={this.handleClick}
title={this._getTitle()}></button>
);
}
});
@ -83,8 +83,8 @@ loop.shared.views = (function(_, l10n) {
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() {
@ -162,11 +162,11 @@ loop.shared.views = (function(_, l10n) {
title={this._getTitle()}>
{isActive ? null : <span className="chevron"/>}
</button>
<ul ref="menu" className={dropdownMenuClasses}>
<ul className={dropdownMenuClasses} ref="menu">
<li onClick={this._handleShareTabs}>
{l10n.get("share_tabs_button_title2")}
</li>
<li onClick={this._handleShareWindows} className={windowSharingClasses}>
<li className={windowSharingClasses} onClick={this._handleShareWindows}>
{l10n.get("share_windows_button_title")}
</li>
</ul>
@ -189,14 +189,14 @@ loop.shared.views = (function(_, l10n) {
},
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
video: React.PropTypes.object.isRequired,
audio: React.PropTypes.object.isRequired,
screenShare: React.PropTypes.object,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
enableHangup: React.PropTypes.bool,
hangup: React.PropTypes.func.isRequired,
publishStream: React.PropTypes.func.isRequired,
hangupButtonLabel: React.PropTypes.string,
enableHangup: React.PropTypes.bool
publishStream: React.PropTypes.func.isRequired,
screenShare: React.PropTypes.object,
video: React.PropTypes.object.isRequired
},
handleClickHangup: function() {
@ -219,28 +219,29 @@ loop.shared.views = (function(_, l10n) {
return (
<ul className="conversation-toolbar">
<li className="conversation-toolbar-btn-box btn-hangup-entry">
<button className="btn btn-hangup" onClick={this.handleClickHangup}
title={l10n.get("hangup_button_title")}
disabled={!this.props.enableHangup}>
<button className="btn btn-hangup"
disabled={!this.props.enableHangup}
onClick={this.handleClickHangup}
title={l10n.get("hangup_button_title")}>
{this._getHangupButtonLabel()}
</button>
</li>
<li className="conversation-toolbar-btn-box">
<MediaControlButton action={this.handleToggleVideo}
enabled={this.props.video.enabled}
visible={this.props.video.visible}
scope="local" type="video" />
scope="local" type="video"
visible={this.props.video.visible} />
</li>
<li className="conversation-toolbar-btn-box">
<MediaControlButton action={this.handleToggleAudio}
enabled={this.props.audio.enabled}
visible={this.props.audio.visible}
scope="local" type="audio" />
scope="local" type="audio"
visible={this.props.audio.visible} />
</li>
<li className="conversation-toolbar-btn-box btn-screen-share-entry">
<ScreenShareControlButton dispatcher={this.props.dispatcher}
visible={this.props.screenShare.visible}
state={this.props.screenShare.state} />
state={this.props.screenShare.state}
visible={this.props.screenShare.visible} />
</li>
</ul>
);
@ -258,11 +259,11 @@ loop.shared.views = (function(_, l10n) {
],
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() {
@ -455,10 +456,11 @@ loop.shared.views = (function(_, l10n) {
</div>
<div className={localStreamClasses}></div>
</div>
<ConversationToolbar video={this.state.video}
audio={this.state.audio}
publishStream={this.publishStream}
hangup={this.hangup} />
<ConversationToolbar
audio={this.state.audio}
hangup={this.hangup}
publishStream={this.publishStream}
video={this.state.video} />
</div>
</div>
);
@ -472,23 +474,23 @@ loop.shared.views = (function(_, l10n) {
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 key={this.props.key}
className={"alert alert-" + notification.get("level")}>
<div className={"alert alert-" + notification.get("level")}
key={this.props.key}>
<span className="message">{notification.get("message")}</span>
</div>
<div className={"detailsBar details-" + notification.get("level")}
hidden={!notification.get("details")}>
<button className="detailsButton btn-info"
onClick={notification.get("detailsButtonCallback")}
hidden={!notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback")}>
hidden={!notification.get("detailsButtonLabel") || !notification.get("detailsButtonCallback")}
onClick={notification.get("detailsButtonCallback")}>
{notification.get("detailsButtonLabel")}
</button>
<span className="details">{notification.get("details")}</span>
@ -505,8 +507,8 @@ loop.shared.views = (function(_, l10n) {
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() {
@ -553,11 +555,11 @@ loop.shared.views = (function(_, l10n) {
var Button = React.createClass({
propTypes: {
caption: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired,
disabled: React.PropTypes.bool,
additionalClass: React.PropTypes.string,
htmlId: React.PropTypes.string
caption: React.PropTypes.string.isRequired,
disabled: React.PropTypes.bool,
htmlId: React.PropTypes.string,
onClick: React.PropTypes.func.isRequired
},
getDefaultProps: function() {
@ -575,10 +577,10 @@ loop.shared.views = (function(_, l10n) {
classObject[this.props.additionalClass] = true;
}
return (
<button onClick={this.props.onClick}
<button className={cx(classObject)}
disabled={this.props.disabled}
id={this.props.htmlId}
className={cx(classObject)}>
onClick={this.props.onClick}>
<span className="button-caption">{this.props.caption}</span>
{this.props.children}
</button>
@ -791,8 +793,8 @@ loop.shared.views = (function(_, l10n) {
<span className="context-description">
{this.props.description}
<a className="context-url"
onClick={this.handleLinkClick}
href={this.props.allowClick ? this.props.url : null}
onClick={this.handleLinkClick}
rel="noreferrer"
target="_blank">{hostname}</a>
</span>

Просмотреть файл

@ -16,7 +16,7 @@ loop.fxOSMarketplaceViews = (function() {
*/
var FxOSHiddenMarketplaceView = React.createClass({displayName: "FxOSHiddenMarketplaceView",
render: function() {
return React.createElement("iframe", {id: "marketplace", src: this.props.marketplaceSrc, hidden: true});
return React.createElement("iframe", {hidden: true, id: "marketplace", src: this.props.marketplaceSrc});
},
componentDidUpdate: function() {

Просмотреть файл

@ -16,7 +16,7 @@ loop.fxOSMarketplaceViews = (function() {
*/
var FxOSHiddenMarketplaceView = React.createClass({
render: function() {
return <iframe id="marketplace" src={this.props.marketplaceSrc} hidden/>;
return <iframe hidden id="marketplace" src={this.props.marketplaceSrc} />;
},
componentDidUpdate: function() {

Просмотреть файл

@ -16,11 +16,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
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() {
@ -33,7 +33,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
_renderCallToActionLink: function() {
if (this.props.isFirefox) {
return (
React.createElement("a", {href: loop.config.learnMoreUrl, className: "btn btn-info"},
React.createElement("a", {className: "btn btn-info", href: loop.config.learnMoreUrl},
mozL10n.get("rooms_room_full_call_to_action_label", {
clientShortname: mozL10n.get("clientShortname2")
})
@ -41,7 +41,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
);
}
return (
React.createElement("a", {href: loop.config.downloadFirefoxUrl, className: "btn btn-info"},
React.createElement("a", {className: "btn btn-info", href: loop.config.downloadFirefoxUrl},
mozL10n.get("rooms_room_full_call_to_action_nonFx_label", {
brandShortname: mozL10n.get("brandShortname")
})
@ -127,9 +127,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
return (
React.createElement("div", {className: "ended-conversation"},
React.createElement(sharedViews.FeedbackView, {
onAfterFeedbackReceived: this.onFeedbackSent,
noCloseText: true}
)
noCloseText: true,
onAfterFeedbackReceived: this.onFeedbackSent})
)
);
}
@ -432,11 +431,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
React.createElement("div", {className: "room-conversation-wrapper"},
React.createElement("div", {className: "beta-logo"}),
React.createElement(StandaloneRoomHeader, {dispatcher: this.props.dispatcher}),
React.createElement(StandaloneRoomInfoArea, {roomState: this.state.roomState,
React.createElement(StandaloneRoomInfoArea, {activeRoomStore: this.props.activeRoomStore,
failureReason: this.state.failureReason,
joinRoom: this.joinRoom,
isFirefox: this.props.isFirefox,
activeRoomStore: this.props.activeRoomStore,
joinRoom: this.joinRoom,
roomState: this.state.roomState,
roomUsed: this.state.used}),
React.createElement("div", {className: "media-layout"},
React.createElement("div", {className: mediaWrapperClasses},
@ -445,16 +444,16 @@ loop.standaloneRoomViews = (function(mozL10n) {
),
React.createElement("div", {className: remoteStreamClasses},
React.createElement(sharedViews.MediaView, {displayAvatar: !this.shouldRenderRemoteVideo(),
posterUrl: this.props.remotePosterUrl,
isLoading: this._shouldRenderRemoteLoading(),
mediaType: "remote",
posterUrl: this.props.remotePosterUrl,
srcVideoObject: this.state.remoteSrcVideoObject})
),
React.createElement("div", {className: screenShareStreamClasses},
React.createElement(sharedViews.MediaView, {displayAvatar: false,
posterUrl: this.props.screenSharePosterUrl,
isLoading: this._shouldRenderScreenShareLoading(),
mediaType: "screen-share",
posterUrl: this.props.screenSharePosterUrl,
srcVideoObject: this.state.screenShareVideoObject})
),
React.createElement(sharedViews.TextChatView, {
@ -463,22 +462,22 @@ loop.standaloneRoomViews = (function(mozL10n) {
showRoomName: true}),
React.createElement("div", {className: "local"},
React.createElement(sharedViews.MediaView, {displayAvatar: this.state.videoMuted,
posterUrl: this.props.localPosterUrl,
isLoading: this._shouldRenderLocalLoading(),
mediaType: "local",
posterUrl: this.props.localPosterUrl,
srcVideoObject: this.state.localSrcVideoObject})
)
),
React.createElement(sharedViews.ConversationToolbar, {
dispatcher: this.props.dispatcher,
video: {enabled: !this.state.videoMuted,
visible: this._roomIsActive()},
audio: {enabled: !this.state.audioMuted,
visible: this._roomIsActive()},
publishStream: this.publishStream,
dispatcher: this.props.dispatcher,
enableHangup: this._roomIsActive(),
hangup: this.leaveRoom,
hangupButtonLabel: mozL10n.get("rooms_leave_button_label"),
enableHangup: this._roomIsActive()})
publishStream: this.publishStream,
video: {enabled: !this.state.videoMuted,
visible: this._roomIsActive()}})
),
React.createElement(loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView, {
marketplaceSrc: this.state.marketplaceSrc,

Просмотреть файл

@ -16,11 +16,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
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() {
@ -33,7 +33,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
_renderCallToActionLink: function() {
if (this.props.isFirefox) {
return (
<a href={loop.config.learnMoreUrl} className="btn btn-info">
<a className="btn btn-info" href={loop.config.learnMoreUrl}>
{mozL10n.get("rooms_room_full_call_to_action_label", {
clientShortname: mozL10n.get("clientShortname2")
})}
@ -41,7 +41,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
);
}
return (
<a href={loop.config.downloadFirefoxUrl} className="btn btn-info">
<a className="btn btn-info" href={loop.config.downloadFirefoxUrl}>
{mozL10n.get("rooms_room_full_call_to_action_nonFx_label", {
brandShortname: mozL10n.get("brandShortname")
})}
@ -127,9 +127,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
return (
<div className="ended-conversation">
<sharedViews.FeedbackView
onAfterFeedbackReceived={this.onFeedbackSent}
noCloseText={true}
/>
onAfterFeedbackReceived={this.onFeedbackSent} />
</div>
);
}
@ -432,11 +431,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
<div className="room-conversation-wrapper">
<div className="beta-logo" />
<StandaloneRoomHeader dispatcher={this.props.dispatcher} />
<StandaloneRoomInfoArea roomState={this.state.roomState}
<StandaloneRoomInfoArea activeRoomStore={this.props.activeRoomStore}
failureReason={this.state.failureReason}
joinRoom={this.joinRoom}
isFirefox={this.props.isFirefox}
activeRoomStore={this.props.activeRoomStore}
joinRoom={this.joinRoom}
roomState={this.state.roomState}
roomUsed={this.state.used} />
<div className="media-layout">
<div className={mediaWrapperClasses}>
@ -445,16 +444,16 @@ loop.standaloneRoomViews = (function(mozL10n) {
</span>
<div className={remoteStreamClasses}>
<sharedViews.MediaView displayAvatar={!this.shouldRenderRemoteVideo()}
posterUrl={this.props.remotePosterUrl}
isLoading={this._shouldRenderRemoteLoading()}
mediaType="remote"
posterUrl={this.props.remotePosterUrl}
srcVideoObject={this.state.remoteSrcVideoObject} />
</div>
<div className={screenShareStreamClasses}>
<sharedViews.MediaView displayAvatar={false}
posterUrl={this.props.screenSharePosterUrl}
isLoading={this._shouldRenderScreenShareLoading()}
mediaType="screen-share"
posterUrl={this.props.screenSharePosterUrl}
srcVideoObject={this.state.screenShareVideoObject} />
</div>
<sharedViews.TextChatView
@ -463,22 +462,22 @@ loop.standaloneRoomViews = (function(mozL10n) {
showRoomName={true} />
<div className="local">
<sharedViews.MediaView displayAvatar={this.state.videoMuted}
posterUrl={this.props.localPosterUrl}
isLoading={this._shouldRenderLocalLoading()}
mediaType="local"
posterUrl={this.props.localPosterUrl}
srcVideoObject={this.state.localSrcVideoObject} />
</div>
</div>
<sharedViews.ConversationToolbar
dispatcher={this.props.dispatcher}
video={{enabled: !this.state.videoMuted,
visible: this._roomIsActive()}}
audio={{enabled: !this.state.audioMuted,
visible: this._roomIsActive()}}
publishStream={this.publishStream}
dispatcher={this.props.dispatcher}
enableHangup={this._roomIsActive()}
hangup={this.leaveRoom}
hangupButtonLabel={mozL10n.get("rooms_leave_button_label")}
enableHangup={this._roomIsActive()} />
publishStream={this.publishStream}
video={{enabled: !this.state.videoMuted,
visible: this._roomIsActive()}} />
</div>
<loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView
marketplaceSrc={this.state.marketplaceSrc}

Просмотреть файл

@ -248,11 +248,11 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
return (
React.createElement("div", {className: "standalone-footer container-box"},
React.createElement("div", {title: mozL10n.get("vendor_alttext",
{vendorShortname: mozL10n.get("vendorShortname")}),
className: "footer-logo"}),
React.createElement("div", {className: "footer-logo",
title: mozL10n.get("vendor_alttext",
{vendorShortname: mozL10n.get("vendorShortname")})}),
React.createElement("div", {className: "footer-external-links"},
React.createElement("a", {target: "_blank", href: loop.config.generalSupportUrl},
React.createElement("a", {href: loop.config.generalSupportUrl, target: "_blank"},
mozL10n.get("support_link")
)
)
@ -374,8 +374,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
React.createElement(PendingConversationView, {
callState: callState,
cancelCallback: this._cancelOutgoingCall}
)
cancelCallback: this._cancelOutgoingCall})
);
}
});
@ -385,8 +384,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -408,8 +407,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
React.createElement("div", {className: "btn-group-chevron"},
React.createElement("div", {className: "btn-group"},
React.createElement("button", {className: "btn btn-constrained btn-large btn-accept",
onClick: this.props.startCall("audio-video"),
disabled: this.props.disabled,
onClick: this.props.startCall("audio-video"),
title: mozL10n.get("initiate_audio_video_call_tooltip2")},
React.createElement("span", {className: "standalone-call-btn-text"},
this.props.caption
@ -423,8 +422,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
React.createElement("ul", {className: dropdownMenuClasses},
React.createElement("li", null,
React.createElement("button", {className: "start-audio-only-call",
onClick: this.props.startCall("audio"),
disabled: this.props.disabled},
disabled: this.props.disabled,
onClick: this.props.startCall("audio")},
mozL10n.get("initiate_audio_call_button2")
)
)
@ -442,15 +441,15 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -577,8 +576,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -588,15 +587,13 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
React.createElement("div", {className: "ended-conversation"},
React.createElement(sharedViews.FeedbackView, {
onAfterFeedbackReceived: this.props.onAfterFeedbackReceived}
),
onAfterFeedbackReceived: this.props.onAfterFeedbackReceived}),
React.createElement(sharedViews.ConversationView, {
initiate: false,
sdk: this.props.sdk,
model: this.props.conversation,
audio: {enabled: false, visible: false},
video: {enabled: false, visible: false}}
)
initiate: false,
model: this.props.conversation,
sdk: this.props.sdk,
video: {enabled: false, visible: false}})
)
);
}
@ -608,8 +605,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
React.createElement(InitiateConversationView, React.__spread({},
this.props,
{title: mozL10n.get("initiate_call_button_label2"),
callButtonLabel: mozL10n.get("initiate_audio_video_call_button2")}))
{callButtonLabel: mozL10n.get("initiate_audio_video_call_button2"),
title: mozL10n.get("initiate_call_button_label2")}))
);
}
});
@ -628,8 +625,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
React.createElement(InitiateConversationView, React.__spread({},
this.props,
{title: mozL10n.get("call_failed_title"),
callButtonLabel: mozL10n.get("retry_call_button")}))
{callButtonLabel: mozL10n.get("retry_call_button"),
title: mozL10n.get("call_failed_title")}))
);
}
});
@ -695,19 +692,17 @@ loop.webapp = (function($, _, OT, mozL10n) {
case "start": {
return (
React.createElement(StartConversationView, {
client: this.props.client,
conversation: this.props.conversation,
notifications: this.props.notifications,
client: this.props.client}
)
notifications: this.props.notifications})
);
}
case "failure": {
return (
React.createElement(FailedConversationView, {
client: this.props.client,
conversation: this.props.conversation,
notifications: this.props.notifications,
client: this.props.client}
)
notifications: this.props.notifications})
);
}
case "gumPrompt": {
@ -723,19 +718,17 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
React.createElement(sharedViews.ConversationView, {
initiate: true,
sdk: this.props.sdk,
model: this.props.conversation,
video: {enabled: this.props.conversation.hasVideoStream("outgoing")}}
)
sdk: this.props.sdk,
video: {enabled: this.props.conversation.hasVideoStream("outgoing")}})
);
}
case "end": {
return (
React.createElement(EndedConversationView, {
sdk: this.props.sdk,
conversation: this.props.conversation,
onAfterFeedbackReceived: this.resetCallStatus()}
)
onAfterFeedbackReceived: this.resetCallStatus(),
sdk: this.props.sdk})
);
}
case "expired": {
@ -939,23 +932,21 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -988,11 +979,10 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
React.createElement(OutgoingConversationView, {
client: this.props.client,
dispatcher: this.props.dispatcher,
conversation: this.props.conversation,
dispatcher: this.props.dispatcher,
notifications: this.props.notifications,
sdk: this.props.sdk}
)
sdk: this.props.sdk})
);
}
case "room": {
@ -1000,8 +990,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
React.createElement(loop.standaloneRoomViews.StandaloneRoomView, {
activeRoomStore: this.props.activeRoomStore,
dispatcher: this.props.dispatcher,
isFirefox: this.state.isFirefox}
)
isFirefox: this.state.isFirefox})
);
}
case "home": {
@ -1107,14 +1096,13 @@ loop.webapp = (function($, _, OT, mozL10n) {
});
React.render(React.createElement(WebappRootView, {
activeRoomStore: activeRoomStore,
client: client,
conversation: conversation,
dispatcher: dispatcher,
notifications: notifications,
sdk: OT,
standaloneAppStore: standaloneAppStore,
activeRoomStore: activeRoomStore,
dispatcher: dispatcher}
), document.querySelector("#main"));
standaloneAppStore: standaloneAppStore}), document.querySelector("#main"));
// Set the 'lang' and 'dir' attributes to <html> when the page is translated
document.documentElement.lang = mozL10n.language.code;

Просмотреть файл

@ -248,11 +248,11 @@ loop.webapp = (function($, _, OT, mozL10n) {
render: function() {
return (
<div className="standalone-footer container-box">
<div title={mozL10n.get("vendor_alttext",
{vendorShortname: mozL10n.get("vendorShortname")})}
className="footer-logo"></div>
<div className="footer-logo"
title={mozL10n.get("vendor_alttext",
{vendorShortname: mozL10n.get("vendorShortname")})} />
<div className="footer-external-links">
<a target="_blank" href={loop.config.generalSupportUrl}>
<a href={loop.config.generalSupportUrl} target="_blank">
{mozL10n.get("support_link")}
</a>
</div>
@ -374,8 +374,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
<PendingConversationView
callState={callState}
cancelCallback={this._cancelOutgoingCall}
/>
cancelCallback={this._cancelOutgoingCall} />
);
}
});
@ -385,8 +384,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -408,8 +407,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
<div className="btn-group-chevron">
<div className="btn-group">
<button className="btn btn-constrained btn-large btn-accept"
onClick={this.props.startCall("audio-video")}
disabled={this.props.disabled}
onClick={this.props.startCall("audio-video")}
title={mozL10n.get("initiate_audio_video_call_tooltip2")}>
<span className="standalone-call-btn-text">
{this.props.caption}
@ -423,8 +422,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
<ul className={dropdownMenuClasses}>
<li>
<button className="start-audio-only-call"
onClick={this.props.startCall("audio")}
disabled={this.props.disabled}>
disabled={this.props.disabled}
onClick={this.props.startCall("audio")}>
{mozL10n.get("initiate_audio_call_button2")}
</button>
</li>
@ -442,15 +441,15 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -577,8 +576,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -588,15 +587,13 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
<div className="ended-conversation">
<sharedViews.FeedbackView
onAfterFeedbackReceived={this.props.onAfterFeedbackReceived}
/>
onAfterFeedbackReceived={this.props.onAfterFeedbackReceived} />
<sharedViews.ConversationView
initiate={false}
sdk={this.props.sdk}
model={this.props.conversation}
audio={{enabled: false, visible: false}}
video={{enabled: false, visible: false}}
/>
initiate={false}
model={this.props.conversation}
sdk={this.props.sdk}
video={{enabled: false, visible: false}} />
</div>
);
}
@ -608,8 +605,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
<InitiateConversationView
{...this.props}
title={mozL10n.get("initiate_call_button_label2")}
callButtonLabel={mozL10n.get("initiate_audio_video_call_button2")}/>
callButtonLabel={mozL10n.get("initiate_audio_video_call_button2")}
title={mozL10n.get("initiate_call_button_label2")} />
);
}
});
@ -628,8 +625,8 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
<InitiateConversationView
{...this.props}
title={mozL10n.get("call_failed_title")}
callButtonLabel={mozL10n.get("retry_call_button")} />
callButtonLabel={mozL10n.get("retry_call_button")}
title={mozL10n.get("call_failed_title")} />
);
}
});
@ -695,19 +692,17 @@ loop.webapp = (function($, _, OT, mozL10n) {
case "start": {
return (
<StartConversationView
conversation={this.props.conversation}
notifications={this.props.notifications}
client={this.props.client}
/>
conversation={this.props.conversation}
notifications={this.props.notifications} />
);
}
case "failure": {
return (
<FailedConversationView
conversation={this.props.conversation}
notifications={this.props.notifications}
client={this.props.client}
/>
conversation={this.props.conversation}
notifications={this.props.notifications} />
);
}
case "gumPrompt": {
@ -723,19 +718,17 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
<sharedViews.ConversationView
initiate={true}
sdk={this.props.sdk}
model={this.props.conversation}
video={{enabled: this.props.conversation.hasVideoStream("outgoing")}}
/>
sdk={this.props.sdk}
video={{enabled: this.props.conversation.hasVideoStream("outgoing")}} />
);
}
case "end": {
return (
<EndedConversationView
sdk={this.props.sdk}
conversation={this.props.conversation}
onAfterFeedbackReceived={this.resetCallStatus()}
/>
sdk={this.props.sdk} />
);
}
case "expired": {
@ -939,23 +932,21 @@ loop.webapp = (function($, _, OT, mozL10n) {
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() {
@ -988,11 +979,10 @@ loop.webapp = (function($, _, OT, mozL10n) {
return (
<OutgoingConversationView
client={this.props.client}
dispatcher={this.props.dispatcher}
conversation={this.props.conversation}
dispatcher={this.props.dispatcher}
notifications={this.props.notifications}
sdk={this.props.sdk}
/>
sdk={this.props.sdk} />
);
}
case "room": {
@ -1000,8 +990,7 @@ loop.webapp = (function($, _, OT, mozL10n) {
<loop.standaloneRoomViews.StandaloneRoomView
activeRoomStore={this.props.activeRoomStore}
dispatcher={this.props.dispatcher}
isFirefox={this.state.isFirefox}
/>
isFirefox={this.state.isFirefox} />
);
}
case "home": {
@ -1107,14 +1096,13 @@ loop.webapp = (function($, _, OT, mozL10n) {
});
React.render(<WebappRootView
activeRoomStore={activeRoomStore}
client={client}
conversation={conversation}
dispatcher={dispatcher}
notifications={notifications}
sdk={OT}
standaloneAppStore={standaloneAppStore}
activeRoomStore={activeRoomStore}
dispatcher={dispatcher}
/>, document.querySelector("#main"));
standaloneAppStore={standaloneAppStore} />, document.querySelector("#main"));
// Set the 'lang' and 'dir' attributes to <html> when the page is translated
document.documentElement.lang = mozL10n.language.code;

Просмотреть файл

@ -25,18 +25,18 @@ window.queuedFrames = [];
*/
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", {

Просмотреть файл

@ -385,9 +385,9 @@
var sizeUnit = this.props.size.split("x");
return (
React.createElement("img", {className: "svg-icon",
height: sizeUnit[1],
src: "../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId,
width: sizeUnit[0],
height: sizeUnit[1]})
width: sizeUnit[0]})
);
}
});
@ -421,7 +421,7 @@
render: function() {
var icons = this.shapes[this.props.size].map(function(shapeId, i) {
return (
React.createElement("li", {key: this.props.size + "-" + i, className: "svg-icon-entry"},
React.createElement("li", {className: "svg-icon-entry", key: this.props.size + "-" + i},
React.createElement("p", null, React.createElement(SVGIcon, {shapeId: shapeId, size: this.props.size})),
React.createElement("p", null, shapeId)
)
@ -435,11 +435,11 @@
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) {
@ -464,10 +464,11 @@
React.createElement("a", {href: this.makeId("#")}, " ¶")
),
React.createElement("div", {className: "comp"},
React.createElement(Frame, {width: width, height: height,
React.createElement(Frame, {className: cx({dashed: this.props.dashed}),
cssClass: this.props.cssClass,
height: height,
onContentsRendered: this.props.onContentsRendered,
className: cx({dashed: this.props.dashed}),
cssClass: this.props.cssClass},
width: width},
this.props.children
)
)
@ -501,7 +502,7 @@
var Section = React.createClass({displayName: "Section",
render: function() {
return (
React.createElement("section", {id: this.props.name, className: this.props.className},
React.createElement("section", {className: this.props.className, id: this.props.name},
React.createElement("h1", null, this.props.name),
this.props.children
)
@ -544,7 +545,7 @@
React.createElement("div", {className: "showcase"},
React.createElement("header", null,
React.createElement("h1", null, "Loop UI Components Showcase"),
React.createElement(Checkbox, {label: "RTL mode?", checked: this.state.rtlMode,
React.createElement(Checkbox, {checked: this.state.rtlMode, label: "RTL mode?",
onChange: this._handleCheckboxChange}),
React.createElement("nav", {className: "showcase-menu"},
React.Children.map(this.props.children, function(section) {
@ -571,58 +572,63 @@
React.createElement("p", {className: "note"},
React.createElement("strong", null, "Note:"), " 332px wide."
),
React.createElement(Example, {summary: "Re-sign-in view", dashed: "true", style: {width: "332px"}},
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Re-sign-in view"},
React.createElement(SignInRequestView, {mozLoop: mockMozLoopRooms})
),
React.createElement(Example, {summary: "Room list tab", dashed: "true", style: {width: "332px"}},
React.createElement(PanelView, {client: mockClient, notifications: notifications,
userProfile: {email: "test@example.com"},
mozLoop: mockMozLoopRooms,
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Room list tab"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
roomStore: roomStore,
selectedTab: "rooms"})
),
React.createElement(Example, {summary: "Contact list tab", dashed: "true", style: {width: "332px"}},
React.createElement(PanelView, {client: mockClient, notifications: notifications,
userProfile: {email: "test@example.com"},
mozLoop: mockMozLoopRooms,
dispatcher: dispatcher,
notifications: notifications,
roomStore: roomStore,
selectedTab: "contacts"})
selectedTab: "rooms",
userProfile: {email: "test@example.com"}})
),
React.createElement(Example, {summary: "Error Notification", dashed: "true", style: {width: "332px"}},
React.createElement(PanelView, {client: mockClient, notifications: errNotifications,
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Contact list tab"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: mockMozLoopRooms,
notifications: notifications,
roomStore: roomStore,
selectedTab: "contacts",
userProfile: {email: "test@example.com"}})
),
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Error Notification"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
dispatcher: dispatcher,
notifications: errNotifications,
roomStore: roomStore})
),
React.createElement(Example, {summary: "Error Notification - authenticated", dashed: "true", style: {width: "332px"}},
React.createElement(PanelView, {client: mockClient, notifications: errNotifications,
userProfile: {email: "test@example.com"},
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Error Notification - authenticated"},
React.createElement(PanelView, {client: mockClient,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
dispatcher: dispatcher,
roomStore: roomStore})
),
React.createElement(Example, {summary: "Contact import success", dashed: "true", style: {width: "332px"}},
React.createElement(PanelView, {notifications: new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}]),
userProfile: {email: "test@example.com"},
mozLoop: mockMozLoopRooms,
dispatcher: dispatcher,
notifications: errNotifications,
roomStore: roomStore,
selectedTab: "contacts"})
userProfile: {email: "test@example.com"}})
),
React.createElement(Example, {summary: "Contact import error", dashed: "true", style: {width: "332px"}},
React.createElement(PanelView, {notifications: new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}]),
userProfile: {email: "test@example.com"},
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Contact import success"},
React.createElement(PanelView, {dispatcher: dispatcher,
mozLoop: mockMozLoopRooms,
dispatcher: dispatcher,
notifications: new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}]),
roomStore: roomStore,
selectedTab: "contacts"})
selectedTab: "contacts",
userProfile: {email: "test@example.com"}})
),
React.createElement(Example, {dashed: "true", style: {width: "332px"}, summary: "Contact import error"},
React.createElement(PanelView, {dispatcher: dispatcher,
mozLoop: mockMozLoopRooms,
notifications: new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}]),
roomStore: roomStore,
selectedTab: "contacts",
userProfile: {email: "test@example.com"}})
)
),
React.createElement(Section, {name: "AcceptCallView"},
React.createElement(Example, {summary: "Default / incoming video call", dashed: "true", style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true", style: {width: "300px", height: "272px"},
summary: "Default / incoming video call"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(AcceptCallView, {callType: CALL_TYPES.AUDIO_VIDEO,
callerId: "Mr Smith",
@ -631,7 +637,8 @@
)
),
React.createElement(Example, {summary: "Default / incoming audio only call", dashed: "true", style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true", style: {width: "300px", height: "272px"},
summary: "Default / incoming audio only call"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(AcceptCallView, {callType: CALL_TYPES.AUDIO_ONLY,
callerId: "Mr Smith",
@ -642,7 +649,8 @@
),
React.createElement(Section, {name: "AcceptCallView-ActiveState"},
React.createElement(Example, {summary: "Default", dashed: "true", style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true", style: {width: "300px", height: "272px"},
summary: "Default"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(AcceptCallView, {callType: CALL_TYPES.AUDIO_VIDEO,
callerId: "Mr Smith",
@ -656,52 +664,53 @@
React.createElement(Section, {name: "ConversationToolbar"},
React.createElement("h2", null, "Desktop Conversation Window"),
React.createElement("div", {className: "fx-embedded override-position"},
React.createElement(Example, {summary: "Default", style: {width: "300px", height: "26px"}},
React.createElement(ConversationToolbar, {video: {enabled: true},
audio: {enabled: true},
React.createElement(Example, {style: {width: "300px", height: "26px"}, summary: "Default"},
React.createElement(ConversationToolbar, {audio: {enabled: true},
hangup: noop,
publishStream: noop})
publishStream: noop,
video: {enabled: true}})
),
React.createElement(Example, {summary: "Video muted", style: {width: "300px", height: "26px"}},
React.createElement(ConversationToolbar, {video: {enabled: false},
audio: {enabled: true},
React.createElement(Example, {style: {width: "300px", height: "26px"}, summary: "Video muted"},
React.createElement(ConversationToolbar, {audio: {enabled: true},
hangup: noop,
publishStream: noop})
publishStream: noop,
video: {enabled: false}})
),
React.createElement(Example, {summary: "Audio muted", style: {width: "300px", height: "26px"}},
React.createElement(ConversationToolbar, {video: {enabled: true},
audio: {enabled: false},
React.createElement(Example, {style: {width: "300px", height: "26px"}, summary: "Audio muted"},
React.createElement(ConversationToolbar, {audio: {enabled: false},
hangup: noop,
publishStream: noop})
publishStream: noop,
video: {enabled: true}})
)
),
React.createElement("h2", null, "Standalone"),
React.createElement("div", {className: "standalone override-position"},
React.createElement(Example, {summary: "Default"},
React.createElement(ConversationToolbar, {video: {enabled: true},
audio: {enabled: true},
React.createElement(ConversationToolbar, {audio: {enabled: true},
hangup: noop,
publishStream: noop})
publishStream: noop,
video: {enabled: true}})
),
React.createElement(Example, {summary: "Video muted"},
React.createElement(ConversationToolbar, {video: {enabled: false},
audio: {enabled: true},
React.createElement(ConversationToolbar, {audio: {enabled: true},
hangup: noop,
publishStream: noop})
publishStream: noop,
video: {enabled: false}})
),
React.createElement(Example, {summary: "Audio muted"},
React.createElement(ConversationToolbar, {video: {enabled: true},
audio: {enabled: false},
React.createElement(ConversationToolbar, {audio: {enabled: false},
hangup: noop,
publishStream: noop})
publishStream: noop,
video: {enabled: true}})
)
)
),
React.createElement(Section, {name: "PendingConversationView (Desktop)"},
React.createElement(Example, {summary: "Connecting", dashed: "true",
style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Connecting"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopPendingConversationView, {callState: "gather",
contact: mockContact,
@ -711,24 +720,27 @@
),
React.createElement(Section, {name: "CallFailedView"},
React.createElement(Example, {summary: "Call Failed - Incoming", dashed: "true",
style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Call Failed - Incoming"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(CallFailedView, {dispatcher: dispatcher,
outgoing: false,
store: conversationStore})
)
),
React.createElement(Example, {summary: "Call Failed - Outgoing", dashed: "true",
style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Call Failed - Outgoing"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(CallFailedView, {dispatcher: dispatcher,
outgoing: true,
store: conversationStore})
)
),
React.createElement(Example, {summary: "Call Failed — with call URL error", dashed: "true",
style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Call Failed — with call URL error"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true,
outgoing: true,
@ -738,57 +750,61 @@
),
React.createElement(Section, {name: "OngoingConversationView"},
React.createElement(FramedExample, {width: 298, height: 254,
summary: "Desktop ongoing conversation window"},
React.createElement(FramedExample, {height: 254,
summary: "Desktop ongoing conversation window",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
dispatcher: dispatcher,
video: {enabled: true},
audio: {enabled: true},
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mediaConnected: true,
remotePosterUrl: "sample-img/video-screen-remote.png",
remoteVideoEnabled: true,
mediaConnected: true})
video: {enabled: true}})
)
),
React.createElement(FramedExample, {width: 800, height: 600,
summary: "Desktop ongoing conversation window large"},
React.createElement(FramedExample, {height: 600,
summary: "Desktop ongoing conversation window large",
width: 800},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
dispatcher: dispatcher,
video: {enabled: true},
audio: {enabled: true},
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mediaConnected: true,
remotePosterUrl: "sample-img/video-screen-remote.png",
remoteVideoEnabled: true,
mediaConnected: true})
video: {enabled: true}})
)
),
React.createElement(FramedExample, {width: 298, height: 254,
summary: "Desktop ongoing conversation window - local face mute"},
React.createElement(FramedExample, {height: 254,
summary: "Desktop ongoing conversation window - local face mute",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
dispatcher: dispatcher,
video: {enabled: false},
audio: {enabled: true},
remoteVideoEnabled: true,
dispatcher: dispatcher,
mediaConnected: true,
remotePosterUrl: "sample-img/video-screen-remote.png",
mediaConnected: true})
remoteVideoEnabled: true,
video: {enabled: false}})
)
),
React.createElement(FramedExample, {width: 298, height: 254,
summary: "Desktop ongoing conversation window - remote face mute"},
React.createElement(FramedExample, {height: 254,
summary: "Desktop ongoing conversation window - remote face mute",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(OngoingConversationView, {
dispatcher: dispatcher,
video: {enabled: true},
audio: {enabled: true},
remoteVideoEnabled: false,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mediaConnected: true})
mediaConnected: true,
remoteVideoEnabled: false,
video: {enabled: true}})
)
)
@ -799,14 +815,20 @@
React.createElement("strong", null, "Note:"), " For the useable demo, you can access submitted data at ",
React.createElement("a", {href: "https://input.allizom.org/"}, "input.allizom.org"), "."
),
React.createElement(Example, {summary: "Default (useable demo)", dashed: "true", style: {width: "300px", height: "272px"}},
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Default (useable demo)"},
React.createElement(FeedbackView, {feedbackStore: feedbackStore})
),
React.createElement(Example, {summary: "Detailed form", dashed: "true", style: {width: "300px", height: "272px"}},
React.createElement(FeedbackView, {feedbackStore: feedbackStore, feedbackState: FEEDBACK_STATES.DETAILS})
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Detailed form"},
React.createElement(FeedbackView, {feedbackState: FEEDBACK_STATES.DETAILS, feedbackStore: feedbackStore})
),
React.createElement(Example, {summary: "Thank you!", dashed: "true", style: {width: "300px", height: "272px"}},
React.createElement(FeedbackView, {feedbackStore: feedbackStore, feedbackState: FEEDBACK_STATES.SENT})
React.createElement(Example, {dashed: "true",
style: {width: "300px", height: "272px"},
summary: "Thank you!"},
React.createElement(FeedbackView, {feedbackState: FEEDBACK_STATES.SENT, feedbackStore: feedbackStore})
)
),
@ -845,287 +867,330 @@
),
React.createElement(Section, {name: "DesktopRoomConversationView"},
React.createElement(FramedExample, {width: 298, height: 254,
summary: "Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)"},
React.createElement(FramedExample, {
height: 254,
summary: "Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
roomStore: invitationRoomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
localPosterUrl: "sample-img/video-screen-local.png",
roomState: ROOM_STATES.INIT})
mozLoop: navigator.mozLoop,
roomState: ROOM_STATES.INIT,
roomStore: invitationRoomStore})
)
),
React.createElement(FramedExample, {width: 298, height: 394, dashed: true,
summary: "Desktop room conversation (loading)"},
React.createElement(FramedExample, {
dashed: true,
height: 394,
summary: "Desktop room conversation (loading)",
width: 298},
/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */
React.createElement("div", {className: "fx-embedded overflow-hidden"},
React.createElement(DesktopRoomConversationView, {
roomStore: desktopRoomStoreLoading,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS})
roomState: ROOM_STATES.HAS_PARTICIPANTS,
roomStore: desktopRoomStoreLoading})
)
),
React.createElement(FramedExample, {width: 298, height: 254,
summary: "Desktop room conversation"},
React.createElement(FramedExample, {height: 254,
summary: "Desktop room conversation"},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
roomStore: roomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS})
roomState: ROOM_STATES.HAS_PARTICIPANTS,
roomStore: roomStore})
)
),
React.createElement(FramedExample, {width: 298, height: 394, dashed: true,
summary: "Desktop room conversation local face-mute"},
React.createElement(FramedExample, {dashed: true,
height: 394,
summary: "Desktop room conversation local face-mute",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
roomStore: desktopLocalFaceMuteRoomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
remotePosterUrl: "sample-img/video-screen-remote.png"})
remotePosterUrl: "sample-img/video-screen-remote.png",
roomStore: desktopLocalFaceMuteRoomStore})
)
),
React.createElement(FramedExample, {width: 298, height: 394, dashed: true,
summary: "Desktop room conversation remote face-mute"},
React.createElement(FramedExample, {dashed: true, height: 394,
summary: "Desktop room conversation remote face-mute",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(DesktopRoomConversationView, {
roomStore: desktopRemoteFaceMuteRoomStore,
dispatcher: dispatcher,
localPosterUrl: "sample-img/video-screen-local.png",
mozLoop: navigator.mozLoop,
localPosterUrl: "sample-img/video-screen-local.png"})
roomStore: desktopRemoteFaceMuteRoomStore})
)
)
),
React.createElement(Section, {name: "StandaloneRoomView"},
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
summary: "Standalone room conversation (ready)"},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
summary: "Standalone room conversation (ready)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: readyRoomStore,
roomState: ROOM_STATES.READY,
isFirefox: true})
dispatcher: dispatcher,
isFirefox: true,
roomState: ROOM_STATES.READY})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
summary: "Standalone room conversation (joined)",
cssClass: "standalone",
onContentsRendered: joinedRoomStore.forcedUpdate},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
onContentsRendered: joinedRoomStore.forcedUpdate,
summary: "Standalone room conversation (joined)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: joinedRoomStore,
localPosterUrl: "sample-img/video-screen-local.png",
isFirefox: true})
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png"})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
summary: "Standalone room conversation (loading remote)",
cssClass: "standalone",
onContentsRendered: loadingRemoteVideoRoomStore.forcedUpdate},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
onContentsRendered: loadingRemoteVideoRoomStore.forcedUpdate,
summary: "Standalone room conversation (loading remote)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: loadingRemoteVideoRoomStore,
localPosterUrl: "sample-img/video-screen-local.png",
isFirefox: true})
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png"})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
onContentsRendered: updatingActiveRoomStore.forcedUpdate,
summary: "Standalone room conversation (has-participants, 644x483)"},
summary: "Standalone room conversation (has-participants, 644x483)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: updatingActiveRoomStore,
roomState: ROOM_STATES.HAS_PARTICIPANTS,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png"})
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
onContentsRendered: localFaceMuteRoomStore.forcedUpdate,
summary: "Standalone room conversation (local face mute, has-participants, 644x483)"},
React.createElement(FramedExample, {
cssClass: "standalone",
dashed: true,
height: 483,
onContentsRendered: localFaceMuteRoomStore.forcedUpdate,
summary: "Standalone room conversation (local face mute, has-participants, 644x483)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: localFaceMuteRoomStore,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png"})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
onContentsRendered: remoteFaceMuteRoomStore.forcedUpdate,
summary: "Standalone room conversation (remote face mute, has-participants, 644x483)"},
React.createElement(FramedExample, {
cssClass: "standalone",
dashed: true,
height: 483,
onContentsRendered: remoteFaceMuteRoomStore.forcedUpdate,
summary: "Standalone room conversation (remote face mute, has-participants, 644x483)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: remoteFaceMuteRoomStore,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png"})
)
),
React.createElement(FramedExample, {width: 800, height: 660, dashed: true,
cssClass: "standalone",
onContentsRendered: loadingRemoteLoadingScreenStore.forcedUpdate,
summary: "Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)"},
React.createElement(FramedExample, {
cssClass: "standalone",
dashed: true,
height: 660,
onContentsRendered: loadingRemoteLoadingScreenStore.forcedUpdate,
summary: "Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)",
width: 800},
/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */
React.createElement("div", {className: "standalone overflow-hidden"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: loadingRemoteLoadingScreenStore,
roomState: ROOM_STATES.HAS_PARTICIPANTS,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png",
screenSharePosterUrl: "sample-img/video-screen-baz.png"}
)
roomState: ROOM_STATES.HAS_PARTICIPANTS,
screenSharePosterUrl: "sample-img/video-screen-baz.png"})
)
),
React.createElement(FramedExample, {width: 800, height: 660, dashed: true,
cssClass: "standalone",
onContentsRendered: loadingScreenSharingRoomStore.forcedUpdate,
summary: "Standalone room convo (has-participants, loading screen share, 800x660)"},
React.createElement(FramedExample, {
cssClass: "standalone",
dashed: true,
height: 660,
onContentsRendered: loadingScreenSharingRoomStore.forcedUpdate,
summary: "Standalone room convo (has-participants, loading screen share, 800x660)",
width: 800},
/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */
React.createElement("div", {className: "standalone overflow-hidden"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: loadingScreenSharingRoomStore,
roomState: ROOM_STATES.HAS_PARTICIPANTS,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png",
screenSharePosterUrl: "sample-img/video-screen-baz.png"}
)
roomState: ROOM_STATES.HAS_PARTICIPANTS,
screenSharePosterUrl: "sample-img/video-screen-baz.png"})
)
),
React.createElement(FramedExample, {width: 800, height: 660, dashed: true,
cssClass: "standalone",
onContentsRendered: updatingSharingRoomStore.forcedUpdate,
summary: "Standalone room convo (has-participants, receivingScreenShare, 800x660)"},
React.createElement(FramedExample, {
cssClass: "standalone",
dashed: true,
height: 660,
onContentsRendered: updatingSharingRoomStore.forcedUpdate,
summary: "Standalone room convo (has-participants, receivingScreenShare, 800x660)",
width: 800},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: updatingSharingRoomStore,
roomState: ROOM_STATES.HAS_PARTICIPANTS,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png",
screenSharePosterUrl: "sample-img/video-screen-terminal.png"}
)
roomState: ROOM_STATES.HAS_PARTICIPANTS,
screenSharePosterUrl: "sample-img/video-screen-terminal.png"})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
summary: "Standalone room conversation (full - FFx user)"},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
summary: "Standalone room conversation (full - FFx user)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: fullActiveRoomStore,
dispatcher: dispatcher,
isFirefox: true})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
summary: "Standalone room conversation (full - non FFx user)"},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
summary: "Standalone room conversation (full - non FFx user)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: fullActiveRoomStore,
dispatcher: dispatcher,
isFirefox: false})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
summary: "Standalone room conversation (feedback)"},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
summary: "Standalone room conversation (feedback)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: endedRoomStore,
dispatcher: dispatcher,
feedbackStore: feedbackStore,
isFirefox: false})
)
),
React.createElement(FramedExample, {width: 644, height: 483, dashed: true,
cssClass: "standalone",
summary: "Standalone room conversation (failed)"},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 483,
summary: "Standalone room conversation (failed)",
width: 644},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: failedRoomStore,
dispatcher: dispatcher,
isFirefox: false})
)
)
),
React.createElement(Section, {name: "StandaloneRoomView (Mobile)"},
React.createElement(FramedExample, {width: 600, height: 480, cssClass: "standalone",
dashed: true,
onContentsRendered: updatingActiveRoomStore.forcedUpdate,
summary: "Standalone room conversation (has-participants, 600x480)"},
React.createElement(FramedExample, {
cssClass: "standalone",
dashed: true,
height: 480,
onContentsRendered: updatingActiveRoomStore.forcedUpdate,
summary: "Standalone room conversation (has-participants, 600x480)",
width: 600},
React.createElement("div", {className: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: updatingActiveRoomStore,
roomState: ROOM_STATES.HAS_PARTICIPANTS,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png"})
)
),
React.createElement(FramedExample, {width: 600, height: 480,
onContentsRendered: updatingSharingRoomStore.forcedUpdate,
summary: "Standalone room convo (has-participants, receivingScreenShare, 600x480)"},
React.createElement("div", {className: "standalone", cssClass: "standalone"},
React.createElement(StandaloneRoomView, {
dispatcher: dispatcher,
activeRoomStore: updatingSharingRoomStore,
roomState: ROOM_STATES.HAS_PARTICIPANTS,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS})
)
),
React.createElement(FramedExample, {
height: 480,
onContentsRendered: updatingSharingRoomStore.forcedUpdate,
summary: "Standalone room convo (has-participants, receivingScreenShare, 600x480)",
width: 600},
React.createElement("div", {className: "standalone", cssClass: "standalone"},
React.createElement(StandaloneRoomView, {
activeRoomStore: updatingSharingRoomStore,
dispatcher: dispatcher,
isFirefox: true,
localPosterUrl: "sample-img/video-screen-local.png",
remotePosterUrl: "sample-img/video-screen-remote.png",
roomState: ROOM_STATES.HAS_PARTICIPANTS,
screenSharePosterUrl: "sample-img/video-screen-terminal.png"})
)
)
),
React.createElement(Section, {name: "TextChatView"},
React.createElement(FramedExample, {width: 298, height: 160, dashed: true,
summary: "TextChatView: desktop embedded"},
React.createElement(FramedExample, {dashed: true,
height: 160,
summary: "TextChatView: desktop embedded",
width: 298},
React.createElement("div", {className: "fx-embedded"},
React.createElement(TextChatView, {dispatcher: dispatcher,
showAlways: false,
@ -1133,9 +1198,11 @@
)
),
React.createElement(FramedExample, {width: 200, height: 400, dashed: true,
cssClass: "standalone",
summary: "Standalone Text Chat conversation (200x400)"},
React.createElement(FramedExample, {cssClass: "standalone",
dashed: true,
height: 400,
summary: "Standalone Text Chat conversation (200x400)",
width: 200},
React.createElement("div", {className: "standalone text-chat-example"},
React.createElement("div", {className: "media-wrapper"},
React.createElement(TextChatView, {
@ -1147,7 +1214,7 @@
)
),
React.createElement(Section, {name: "SVG icons preview", className: "svg-icons"},
React.createElement(Section, {className: "svg-icons", name: "SVG icons preview"},
React.createElement(Example, {summary: "10x10"},
React.createElement(SVGIcons, {size: "10x10"})
),

Просмотреть файл

@ -385,9 +385,9 @@
var sizeUnit = this.props.size.split("x");
return (
<img className="svg-icon"
height={sizeUnit[1]}
src={"../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId}
width={sizeUnit[0]}
height={sizeUnit[1]} />
width={sizeUnit[0]} />
);
}
});
@ -421,7 +421,7 @@
render: function() {
var icons = this.shapes[this.props.size].map(function(shapeId, i) {
return (
<li key={this.props.size + "-" + i} className="svg-icon-entry">
<li className="svg-icon-entry" key={this.props.size + "-" + i}>
<p><SVGIcon shapeId={shapeId} size={this.props.size} /></p>
<p>{shapeId}</p>
</li>
@ -435,11 +435,11 @@
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) {
@ -464,10 +464,11 @@
<a href={this.makeId("#")}>&nbsp;</a>
</h3>
<div className="comp">
<Frame width={width} height={height}
<Frame className={cx({dashed: this.props.dashed})}
cssClass={this.props.cssClass}
height={height}
onContentsRendered={this.props.onContentsRendered}
className={cx({dashed: this.props.dashed})}
cssClass={this.props.cssClass}>
width={width}>
{this.props.children}
</Frame>
</div>
@ -501,7 +502,7 @@
var Section = React.createClass({
render: function() {
return (
<section id={this.props.name} className={this.props.className}>
<section className={this.props.className} id={this.props.name}>
<h1>{this.props.name}</h1>
{this.props.children}
</section>
@ -544,7 +545,7 @@
<div className="showcase">
<header>
<h1>Loop UI Components Showcase</h1>
<Checkbox label="RTL mode?" checked={this.state.rtlMode}
<Checkbox checked={this.state.rtlMode} label="RTL mode?"
onChange={this._handleCheckboxChange} />
<nav className="showcase-menu">{
React.Children.map(this.props.children, function(section) {
@ -571,58 +572,63 @@
<p className="note">
<strong>Note:</strong> 332px wide.
</p>
<Example summary="Re-sign-in view" dashed="true" style={{width: "332px"}}>
<Example dashed="true" style={{width: "332px"}} summary="Re-sign-in view">
<SignInRequestView mozLoop={mockMozLoopRooms} />
</Example>
<Example summary="Room list tab" dashed="true" style={{width: "332px"}}>
<PanelView client={mockClient} notifications={notifications}
userProfile={{email: "test@example.com"}}
mozLoop={mockMozLoopRooms}
<Example dashed="true" style={{width: "332px"}} summary="Room list tab">
<PanelView client={mockClient}
dispatcher={dispatcher}
roomStore={roomStore}
selectedTab="rooms" />
</Example>
<Example summary="Contact list tab" dashed="true" style={{width: "332px"}}>
<PanelView client={mockClient} notifications={notifications}
userProfile={{email: "test@example.com"}}
mozLoop={mockMozLoopRooms}
dispatcher={dispatcher}
notifications={notifications}
roomStore={roomStore}
selectedTab="contacts" />
selectedTab="rooms"
userProfile={{email: "test@example.com"}} />
</Example>
<Example summary="Error Notification" dashed="true" style={{width: "332px"}}>
<PanelView client={mockClient} notifications={errNotifications}
<Example dashed="true" style={{width: "332px"}} summary="Contact list tab">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={mockMozLoopRooms}
notifications={notifications}
roomStore={roomStore}
selectedTab="contacts"
userProfile={{email: "test@example.com"}} />
</Example>
<Example dashed="true" style={{width: "332px"}} summary="Error Notification">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
dispatcher={dispatcher}
notifications={errNotifications}
roomStore={roomStore} />
</Example>
<Example summary="Error Notification - authenticated" dashed="true" style={{width: "332px"}}>
<PanelView client={mockClient} notifications={errNotifications}
userProfile={{email: "test@example.com"}}
<Example dashed="true" style={{width: "332px"}} summary="Error Notification - authenticated">
<PanelView client={mockClient}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
dispatcher={dispatcher}
roomStore={roomStore} />
</Example>
<Example summary="Contact import success" dashed="true" style={{width: "332px"}}>
<PanelView notifications={new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}])}
userProfile={{email: "test@example.com"}}
mozLoop={mockMozLoopRooms}
dispatcher={dispatcher}
notifications={errNotifications}
roomStore={roomStore}
selectedTab="contacts" />
userProfile={{email: "test@example.com"}} />
</Example>
<Example summary="Contact import error" dashed="true" style={{width: "332px"}}>
<PanelView notifications={new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}])}
userProfile={{email: "test@example.com"}}
<Example dashed="true" style={{width: "332px"}} summary="Contact import success">
<PanelView dispatcher={dispatcher}
mozLoop={mockMozLoopRooms}
dispatcher={dispatcher}
notifications={new loop.shared.models.NotificationCollection([{level: "success", message: "Import success"}])}
roomStore={roomStore}
selectedTab="contacts" />
selectedTab="contacts"
userProfile={{email: "test@example.com"}} />
</Example>
<Example dashed="true" style={{width: "332px"}} summary="Contact import error">
<PanelView dispatcher={dispatcher}
mozLoop={mockMozLoopRooms}
notifications={new loop.shared.models.NotificationCollection([{level: "error", message: "Import error"}])}
roomStore={roomStore}
selectedTab="contacts"
userProfile={{email: "test@example.com"}} />
</Example>
</Section>
<Section name="AcceptCallView">
<Example summary="Default / incoming video call" dashed="true" style={{width: "300px", height: "272px"}}>
<Example dashed="true" style={{width: "300px", height: "272px"}}
summary="Default / incoming video call">
<div className="fx-embedded">
<AcceptCallView callType={CALL_TYPES.AUDIO_VIDEO}
callerId="Mr Smith"
@ -631,7 +637,8 @@
</div>
</Example>
<Example summary="Default / incoming audio only call" dashed="true" style={{width: "300px", height: "272px"}}>
<Example dashed="true" style={{width: "300px", height: "272px"}}
summary="Default / incoming audio only call">
<div className="fx-embedded">
<AcceptCallView callType={CALL_TYPES.AUDIO_ONLY}
callerId="Mr Smith"
@ -642,7 +649,8 @@
</Section>
<Section name="AcceptCallView-ActiveState">
<Example summary="Default" dashed="true" style={{width: "300px", height: "272px"}}>
<Example dashed="true" style={{width: "300px", height: "272px"}}
summary="Default">
<div className="fx-embedded" >
<AcceptCallView callType={CALL_TYPES.AUDIO_VIDEO}
callerId="Mr Smith"
@ -656,52 +664,53 @@
<Section name="ConversationToolbar">
<h2>Desktop Conversation Window</h2>
<div className="fx-embedded override-position">
<Example summary="Default" style={{width: "300px", height: "26px"}}>
<ConversationToolbar video={{enabled: true}}
audio={{enabled: true}}
<Example style={{width: "300px", height: "26px"}} summary="Default">
<ConversationToolbar audio={{enabled: true}}
hangup={noop}
publishStream={noop} />
publishStream={noop}
video={{enabled: true}} />
</Example>
<Example summary="Video muted" style={{width: "300px", height: "26px"}}>
<ConversationToolbar video={{enabled: false}}
audio={{enabled: true}}
<Example style={{width: "300px", height: "26px"}} summary="Video muted">
<ConversationToolbar audio={{enabled: true}}
hangup={noop}
publishStream={noop} />
publishStream={noop}
video={{enabled: false}} />
</Example>
<Example summary="Audio muted" style={{width: "300px", height: "26px"}}>
<ConversationToolbar video={{enabled: true}}
audio={{enabled: false}}
<Example style={{width: "300px", height: "26px"}} summary="Audio muted">
<ConversationToolbar audio={{enabled: false}}
hangup={noop}
publishStream={noop} />
publishStream={noop}
video={{enabled: true}} />
</Example>
</div>
<h2>Standalone</h2>
<div className="standalone override-position">
<Example summary="Default">
<ConversationToolbar video={{enabled: true}}
audio={{enabled: true}}
<ConversationToolbar audio={{enabled: true}}
hangup={noop}
publishStream={noop} />
publishStream={noop}
video={{enabled: true}} />
</Example>
<Example summary="Video muted">
<ConversationToolbar video={{enabled: false}}
audio={{enabled: true}}
<ConversationToolbar audio={{enabled: true}}
hangup={noop}
publishStream={noop} />
publishStream={noop}
video={{enabled: false}} />
</Example>
<Example summary="Audio muted">
<ConversationToolbar video={{enabled: true}}
audio={{enabled: false}}
<ConversationToolbar audio={{enabled: false}}
hangup={noop}
publishStream={noop} />
publishStream={noop}
video={{enabled: true}} />
</Example>
</div>
</Section>
<Section name="PendingConversationView (Desktop)">
<Example summary="Connecting" dashed="true"
style={{width: "300px", height: "272px"}}>
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Connecting">
<div className="fx-embedded">
<DesktopPendingConversationView callState={"gather"}
contact={mockContact}
@ -711,24 +720,27 @@
</Section>
<Section name="CallFailedView">
<Example summary="Call Failed - Incoming" dashed="true"
style={{width: "300px", height: "272px"}}>
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Call Failed - Incoming">
<div className="fx-embedded">
<CallFailedView dispatcher={dispatcher}
outgoing={false}
store={conversationStore} />
</div>
</Example>
<Example summary="Call Failed - Outgoing" dashed="true"
style={{width: "300px", height: "272px"}}>
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Call Failed - Outgoing">
<div className="fx-embedded">
<CallFailedView dispatcher={dispatcher}
outgoing={true}
store={conversationStore} />
</div>
</Example>
<Example summary="Call Failed — with call URL error" dashed="true"
style={{width: "300px", height: "272px"}}>
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Call Failed — with call URL error">
<div className="fx-embedded">
<CallFailedView dispatcher={dispatcher} emailLinkError={true}
outgoing={true}
@ -738,57 +750,61 @@
</Section>
<Section name="OngoingConversationView">
<FramedExample width={298} height={254}
summary="Desktop ongoing conversation window">
<FramedExample height={254}
summary="Desktop ongoing conversation window"
width={298}>
<div className="fx-embedded">
<OngoingConversationView
dispatcher={dispatcher}
video={{enabled: true}}
audio={{enabled: true}}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mediaConnected={true}
remotePosterUrl="sample-img/video-screen-remote.png"
remoteVideoEnabled={true}
mediaConnected={true} />
video={{enabled: true}} />
</div>
</FramedExample>
<FramedExample width={800} height={600}
summary="Desktop ongoing conversation window large">
<FramedExample height={600}
summary="Desktop ongoing conversation window large"
width={800}>
<div className="fx-embedded">
<OngoingConversationView
dispatcher={dispatcher}
video={{enabled: true}}
audio={{enabled: true}}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mediaConnected={true}
remotePosterUrl="sample-img/video-screen-remote.png"
remoteVideoEnabled={true}
mediaConnected={true} />
video={{enabled: true}} />
</div>
</FramedExample>
<FramedExample width={298} height={254}
summary="Desktop ongoing conversation window - local face mute">
<FramedExample height={254}
summary="Desktop ongoing conversation window - local face mute"
width={298} >
<div className="fx-embedded">
<OngoingConversationView
dispatcher={dispatcher}
video={{enabled: false}}
audio={{enabled: true}}
remoteVideoEnabled={true}
dispatcher={dispatcher}
mediaConnected={true}
remotePosterUrl="sample-img/video-screen-remote.png"
mediaConnected={true} />
remoteVideoEnabled={true}
video={{enabled: false}} />
</div>
</FramedExample>
<FramedExample width={298} height={254}
summary="Desktop ongoing conversation window - remote face mute">
<FramedExample height={254}
summary="Desktop ongoing conversation window - remote face mute"
width={298} >
<div className="fx-embedded">
<OngoingConversationView
dispatcher={dispatcher}
video={{enabled: true}}
audio={{enabled: true}}
remoteVideoEnabled={false}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mediaConnected={true} />
mediaConnected={true}
remoteVideoEnabled={false}
video={{enabled: true}} />
</div>
</FramedExample>
@ -799,14 +815,20 @@
<strong>Note:</strong> For the useable demo, you can access submitted data at&nbsp;
<a href="https://input.allizom.org/">input.allizom.org</a>.
</p>
<Example summary="Default (useable demo)" dashed="true" style={{width: "300px", height: "272px"}}>
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Default (useable demo)">
<FeedbackView feedbackStore={feedbackStore} />
</Example>
<Example summary="Detailed form" dashed="true" style={{width: "300px", height: "272px"}}>
<FeedbackView feedbackStore={feedbackStore} feedbackState={FEEDBACK_STATES.DETAILS} />
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Detailed form">
<FeedbackView feedbackState={FEEDBACK_STATES.DETAILS} feedbackStore={feedbackStore} />
</Example>
<Example summary="Thank you!" dashed="true" style={{width: "300px", height: "272px"}}>
<FeedbackView feedbackStore={feedbackStore} feedbackState={FEEDBACK_STATES.SENT} />
<Example dashed="true"
style={{width: "300px", height: "272px"}}
summary="Thank you!">
<FeedbackView feedbackState={FEEDBACK_STATES.SENT} feedbackStore={feedbackStore}/>
</Example>
</Section>
@ -845,287 +867,330 @@
</Section>
<Section name="DesktopRoomConversationView">
<FramedExample width={298} height={254}
summary="Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)">
<FramedExample
height={254}
summary="Desktop room conversation (invitation, text-chat inclusion/scrollbars don't happen in real client)"
width={298}>
<div className="fx-embedded">
<DesktopRoomConversationView
roomStore={invitationRoomStore}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
localPosterUrl="sample-img/video-screen-local.png"
roomState={ROOM_STATES.INIT} />
mozLoop={navigator.mozLoop}
roomState={ROOM_STATES.INIT}
roomStore={invitationRoomStore} />
</div>
</FramedExample>
<FramedExample width={298} height={394} dashed={true}
summary="Desktop room conversation (loading)">
<FramedExample
dashed={true}
height={394}
summary="Desktop room conversation (loading)"
width={298}>
{/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */}
<div className="fx-embedded overflow-hidden">
<DesktopRoomConversationView
roomStore={desktopRoomStoreLoading}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS} />
roomState={ROOM_STATES.HAS_PARTICIPANTS}
roomStore={desktopRoomStoreLoading} />
</div>
</FramedExample>
<FramedExample width={298} height={254}
summary="Desktop room conversation">
<FramedExample height={254}
summary="Desktop room conversation">
<div className="fx-embedded">
<DesktopRoomConversationView
roomStore={roomStore}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS} />
roomState={ROOM_STATES.HAS_PARTICIPANTS}
roomStore={roomStore} />
</div>
</FramedExample>
<FramedExample width={298} height={394} dashed={true}
summary="Desktop room conversation local face-mute">
<FramedExample dashed={true}
height={394}
summary="Desktop room conversation local face-mute"
width={298}>
<div className="fx-embedded">
<DesktopRoomConversationView
roomStore={desktopLocalFaceMuteRoomStore}
dispatcher={dispatcher}
mozLoop={navigator.mozLoop}
remotePosterUrl="sample-img/video-screen-remote.png" />
remotePosterUrl="sample-img/video-screen-remote.png"
roomStore={desktopLocalFaceMuteRoomStore} />
</div>
</FramedExample>
<FramedExample width={298} height={394} dashed={true}
summary="Desktop room conversation remote face-mute">
<FramedExample dashed={true} height={394}
summary="Desktop room conversation remote face-mute"
width={298} >
<div className="fx-embedded">
<DesktopRoomConversationView
roomStore={desktopRemoteFaceMuteRoomStore}
dispatcher={dispatcher}
localPosterUrl="sample-img/video-screen-local.png"
mozLoop={navigator.mozLoop}
localPosterUrl="sample-img/video-screen-local.png" />
roomStore={desktopRemoteFaceMuteRoomStore} />
</div>
</FramedExample>
</Section>
<Section name="StandaloneRoomView">
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
summary="Standalone room conversation (ready)">
<FramedExample cssClass="standalone"
dashed={true}
height={483}
summary="Standalone room conversation (ready)"
width={644} >
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={readyRoomStore}
roomState={ROOM_STATES.READY}
isFirefox={true} />
dispatcher={dispatcher}
isFirefox={true}
roomState={ROOM_STATES.READY} />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
summary="Standalone room conversation (joined)"
cssClass="standalone"
onContentsRendered={joinedRoomStore.forcedUpdate}>
<FramedExample cssClass="standalone"
dashed={true}
height={483}
onContentsRendered={joinedRoomStore.forcedUpdate}
summary="Standalone room conversation (joined)"
width={644}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={joinedRoomStore}
localPosterUrl="sample-img/video-screen-local.png"
isFirefox={true} />
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png" />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
summary="Standalone room conversation (loading remote)"
cssClass="standalone"
onContentsRendered={loadingRemoteVideoRoomStore.forcedUpdate}>
<FramedExample cssClass="standalone"
dashed={true}
height={483}
onContentsRendered={loadingRemoteVideoRoomStore.forcedUpdate}
summary="Standalone room conversation (loading remote)"
width={644}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={loadingRemoteVideoRoomStore}
localPosterUrl="sample-img/video-screen-local.png"
isFirefox={true} />
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png" />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
<FramedExample cssClass="standalone"
dashed={true}
height={483}
onContentsRendered={updatingActiveRoomStore.forcedUpdate}
summary="Standalone room conversation (has-participants, 644x483)">
summary="Standalone room conversation (has-participants, 644x483)"
width={644} >
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={updatingActiveRoomStore}
roomState={ROOM_STATES.HAS_PARTICIPANTS}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png" />
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS} />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
onContentsRendered={localFaceMuteRoomStore.forcedUpdate}
summary="Standalone room conversation (local face mute, has-participants, 644x483)">
<FramedExample
cssClass="standalone"
dashed={true}
height={483}
onContentsRendered={localFaceMuteRoomStore.forcedUpdate}
summary="Standalone room conversation (local face mute, has-participants, 644x483)"
width={644}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={localFaceMuteRoomStore}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png" />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
onContentsRendered={remoteFaceMuteRoomStore.forcedUpdate}
summary="Standalone room conversation (remote face mute, has-participants, 644x483)">
<FramedExample
cssClass="standalone"
dashed={true}
height={483}
onContentsRendered={remoteFaceMuteRoomStore.forcedUpdate}
summary="Standalone room conversation (remote face mute, has-participants, 644x483)"
width={644}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={remoteFaceMuteRoomStore}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png" />
</div>
</FramedExample>
<FramedExample width={800} height={660} dashed={true}
cssClass="standalone"
onContentsRendered={loadingRemoteLoadingScreenStore.forcedUpdate}
summary="Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)">
<FramedExample
cssClass="standalone"
dashed={true}
height={660}
onContentsRendered={loadingRemoteLoadingScreenStore.forcedUpdate}
summary="Standalone room convo (has-participants, loading screen share, loading remote video, 800x660)"
width={800}>
{/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */}
<div className="standalone overflow-hidden">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={loadingRemoteLoadingScreenStore}
roomState={ROOM_STATES.HAS_PARTICIPANTS}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png"
screenSharePosterUrl="sample-img/video-screen-baz.png"
/>
roomState={ROOM_STATES.HAS_PARTICIPANTS}
screenSharePosterUrl="sample-img/video-screen-baz.png" />
</div>
</FramedExample>
<FramedExample width={800} height={660} dashed={true}
cssClass="standalone"
onContentsRendered={loadingScreenSharingRoomStore.forcedUpdate}
summary="Standalone room convo (has-participants, loading screen share, 800x660)">
<FramedExample
cssClass="standalone"
dashed={true}
height={660}
onContentsRendered={loadingScreenSharingRoomStore.forcedUpdate}
summary="Standalone room convo (has-participants, loading screen share, 800x660)"
width={800}>
{/* Hide scrollbars here. Rotating loading div overflows and causes
scrollbars to appear */}
<div className="standalone overflow-hidden">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={loadingScreenSharingRoomStore}
roomState={ROOM_STATES.HAS_PARTICIPANTS}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png"
screenSharePosterUrl="sample-img/video-screen-baz.png"
/>
roomState={ROOM_STATES.HAS_PARTICIPANTS}
screenSharePosterUrl="sample-img/video-screen-baz.png" />
</div>
</FramedExample>
<FramedExample width={800} height={660} dashed={true}
cssClass="standalone"
onContentsRendered={updatingSharingRoomStore.forcedUpdate}
summary="Standalone room convo (has-participants, receivingScreenShare, 800x660)">
<FramedExample
cssClass="standalone"
dashed={true}
height={660}
onContentsRendered={updatingSharingRoomStore.forcedUpdate}
summary="Standalone room convo (has-participants, receivingScreenShare, 800x660)"
width={800}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={updatingSharingRoomStore}
roomState={ROOM_STATES.HAS_PARTICIPANTS}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png"
screenSharePosterUrl="sample-img/video-screen-terminal.png"
/>
roomState={ROOM_STATES.HAS_PARTICIPANTS}
screenSharePosterUrl="sample-img/video-screen-terminal.png" />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
summary="Standalone room conversation (full - FFx user)">
<FramedExample cssClass="standalone"
dashed={true}
height={483}
summary="Standalone room conversation (full - FFx user)"
width={644} >
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={fullActiveRoomStore}
dispatcher={dispatcher}
isFirefox={true} />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
summary="Standalone room conversation (full - non FFx user)">
<FramedExample cssClass="standalone"
dashed={true}
height={483}
summary="Standalone room conversation (full - non FFx user)"
width={644} >
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={fullActiveRoomStore}
dispatcher={dispatcher}
isFirefox={false} />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
summary="Standalone room conversation (feedback)">
<FramedExample cssClass="standalone"
dashed={true}
height={483}
summary="Standalone room conversation (feedback)"
width={644}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={endedRoomStore}
dispatcher={dispatcher}
feedbackStore={feedbackStore}
isFirefox={false} />
</div>
</FramedExample>
<FramedExample width={644} height={483} dashed={true}
cssClass="standalone"
summary="Standalone room conversation (failed)">
<FramedExample cssClass="standalone"
dashed={true}
height={483}
summary="Standalone room conversation (failed)"
width={644} >
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={failedRoomStore}
dispatcher={dispatcher}
isFirefox={false} />
</div>
</FramedExample>
</Section>
<Section name="StandaloneRoomView (Mobile)">
<FramedExample width={600} height={480} cssClass="standalone"
dashed={true}
onContentsRendered={updatingActiveRoomStore.forcedUpdate}
summary="Standalone room conversation (has-participants, 600x480)">
<FramedExample
cssClass="standalone"
dashed={true}
height={480}
onContentsRendered={updatingActiveRoomStore.forcedUpdate}
summary="Standalone room conversation (has-participants, 600x480)"
width={600}>
<div className="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={updatingActiveRoomStore}
roomState={ROOM_STATES.HAS_PARTICIPANTS}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png" />
</div>
</FramedExample>
<FramedExample width={600} height={480}
onContentsRendered={updatingSharingRoomStore.forcedUpdate}
summary="Standalone room convo (has-participants, receivingScreenShare, 600x480)">
<div className="standalone" cssClass="standalone">
<StandaloneRoomView
dispatcher={dispatcher}
activeRoomStore={updatingSharingRoomStore}
roomState={ROOM_STATES.HAS_PARTICIPANTS}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS} />
</div>
</FramedExample>
<FramedExample
height={480}
onContentsRendered={updatingSharingRoomStore.forcedUpdate}
summary="Standalone room convo (has-participants, receivingScreenShare, 600x480)"
width={600} >
<div className="standalone" cssClass="standalone">
<StandaloneRoomView
activeRoomStore={updatingSharingRoomStore}
dispatcher={dispatcher}
isFirefox={true}
localPosterUrl="sample-img/video-screen-local.png"
remotePosterUrl="sample-img/video-screen-remote.png"
roomState={ROOM_STATES.HAS_PARTICIPANTS}
screenSharePosterUrl="sample-img/video-screen-terminal.png" />
</div>
</FramedExample>
</Section>
<Section name="TextChatView">
<FramedExample width={298} height={160} dashed={true}
summary="TextChatView: desktop embedded">
<FramedExample dashed={true}
height={160}
summary="TextChatView: desktop embedded"
width={298}>
<div className="fx-embedded">
<TextChatView dispatcher={dispatcher}
showAlways={false}
@ -1133,9 +1198,11 @@
</div>
</FramedExample>
<FramedExample width={200} height={400} dashed={true}
cssClass="standalone"
summary="Standalone Text Chat conversation (200x400)">
<FramedExample cssClass="standalone"
dashed={true}
height={400}
summary="Standalone Text Chat conversation (200x400)"
width={200}>
<div className="standalone text-chat-example">
<div className="media-wrapper">
<TextChatView
@ -1147,7 +1214,7 @@
</FramedExample>
</Section>
<Section name="SVG icons preview" className="svg-icons">
<Section className="svg-icons" name="SVG icons preview">
<Example summary="10x10">
<SVGIcons size="10x10"/>
</Example>

Просмотреть файл

@ -1208,7 +1208,7 @@ SourceScripts.prototype = {
connect: function() {
dumpn("SourceScripts is connecting...");
this.debuggerClient.addListener("newGlobal", this._onNewGlobal);
this.debuggerClient.addListener("newSource", this._onNewSource);
this.activeThread.addListener("newSource", this._onNewSource);
this.activeThread.addListener("blackboxchange", this._onBlackBoxChange);
this.activeThread.addListener("prettyprintchange", this._onPrettyPrintChange);
this.handleTabNavigation();
@ -1223,7 +1223,7 @@ SourceScripts.prototype = {
}
dumpn("SourceScripts is disconnecting...");
this.debuggerClient.removeListener("newGlobal", this._onNewGlobal);
this.debuggerClient.removeListener("newSource", this._onNewSource);
this.activeThread.removeListener("newSource", this._onNewSource);
this.activeThread.removeListener("blackboxchange", this._onBlackBoxChange);
this.activeThread.addListener("prettyprintchange", this._onPrettyPrintChange);
},

Просмотреть файл

@ -45,12 +45,12 @@ function test() {
function testChromeActor() {
gClient.getProcess().then(aResponse => {
gClient.addListener("newGlobal", onNewGlobal);
gClient.addListener("newSource", onNewSource);
let actor = aResponse.form.actor;
gClient.attachTab(actor, (response, tabClient) => {
tabClient.attachThread(null, (aResponse, aThreadClient) => {
gThreadClient = aThreadClient;
gThreadClient.addListener("newSource", onNewSource);
if (aResponse.error) {
ok(false, "Couldn't attach to the chrome debugger.");
@ -78,7 +78,7 @@ function onNewSource(aEvent, aPacket) {
if (aPacket.source.url.startsWith("chrome:")) {
ok(true, "Received a new chrome source: " + aPacket.source.url);
gClient.removeListener("newSource", onNewSource);
gThreadClient.removeListener("newSource", onNewSource);
gNewChromeSource.resolve();
}
}

Просмотреть файл

@ -143,6 +143,46 @@ const TEST_DATA = [
is(Math.floor(bottomY1), points[2][1], "Bottom guide's y1 is correct");
is(Math.ceil(leftX1), points[3][0], "Left guide's x1 is correct");
}
},
{
desc: "When showOnly is used, other regions can be faded",
options: {showOnly: "margin", onlyRegionArea: true},
checkHighlighter: function*(toolbox) {
let h = toolbox.highlighter;
for (let region of ["margin", "border", "padding", "content"]) {
let {d} = yield getHighlighterRegionPath(region, h);
ok(d, "Region " + region + " is shown (it has a d attribute)");
let faded = yield getHighlighterNodeAttribute(h,
"box-model-" + region, "faded");
if (region === "margin") {
ok(!faded, "The margin region is not faded");
} else {
is(faded, "true", "Region " + region + " is faded");
}
}
}
},
{
desc: "When showOnly is used, other regions can be faded (2)",
options: {showOnly: "padding", onlyRegionArea: true},
checkHighlighter: function*(toolbox) {
let h = toolbox.highlighter;
for (let region of ["margin", "border", "padding", "content"]) {
let {d} = yield getHighlighterRegionPath(region, h);
ok(d, "Region " + region + " is shown (it has a d attribute)");
let faded = yield getHighlighterNodeAttribute(h,
"box-model-" + region, "faded");
if (region === "padding") {
ok(!faded, "The padding region is not faded");
} else {
is(faded, "true", "Region " + region + " is faded");
}
}
}
}
];

Просмотреть файл

@ -553,7 +553,11 @@ let onmouseover = function(e) {
return false;
}
this.layoutview.showBoxModel({region});
this.layoutview.showBoxModel({
region,
showOnly: region,
onlyRegionArea: true
});
return false;
}.bind(window);

Просмотреть файл

@ -1543,7 +1543,7 @@ Scope.prototype = {
*
* @param string a
* @param string b
* @return number
* @return number
* -1 if a is less than b, 0 if no change in order, +1 if a is greater than 0
*/
_naturalSort: function(a,b) {

Просмотреть файл

@ -342,6 +342,10 @@ ConsoleOutput.prototype = {
this.owner.owner.openLink.apply(this.owner.owner, arguments);
},
openLocationInDebugger: function ({url, line}) {
return this.owner.owner.viewSourceInDebugger(url, line);
},
/**
* Open the variables view to inspect an object actor.
* @see JSTerm.openVariablesView() in webconsole.js
@ -2496,6 +2500,8 @@ Widgets.JSObject.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
options.onClick = options.href ? this._onClickAnchor : this._onClick;
}
options.onContextMenu = options.onContextMenu || this._onContextMenu;
let anchor = this.el("a", {
class: options.className,
draggable: false,
@ -2504,6 +2510,8 @@ Widgets.JSObject.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
this.message._addLinkCallback(anchor, options.onClick);
anchor.addEventListener("contextmenu", options.onContextMenu.bind(this));
if (options.appendTo) {
options.appendTo.appendChild(anchor);
} else if (!("appendTo" in options) && this.element) {
@ -2513,16 +2521,38 @@ Widgets.JSObject.prototype = Heritage.extend(Widgets.BaseWidget.prototype,
return anchor;
},
openObjectInVariablesView: function()
{
this.output.openVariablesView({
label: VariablesView.getString(this.objectActor, { concise: true }),
objectActor: this.objectActor,
autofocus: true,
});
},
/**
* The click event handler for objects shown inline.
* @private
*/
_onClick: function()
{
this.output.openVariablesView({
label: VariablesView.getString(this.objectActor, { concise: true }),
objectActor: this.objectActor,
autofocus: true,
this.openObjectInVariablesView();
},
_onContextMenu: function(ev) {
// TODO offer a nice API for the context menu.
// Probably worth to take a look at Firebug's way
// https://github.com/firebug/firebug/blob/master/extension/content/firebug/chrome/menu.js
let doc = ev.target.ownerDocument;
let cmPopup = doc.getElementById("output-contextmenu");
let openInVarViewCmd = doc.getElementById("menu_openInVarView");
let openVarView = this.openObjectInVariablesView.bind(this);
openInVarViewCmd.addEventListener("command", openVarView);
openInVarViewCmd.removeAttribute("disabled");
cmPopup.addEventListener("popuphiding", function onPopupHiding() {
cmPopup.removeEventListener("popuphiding", onPopupHiding);
openInVarViewCmd.removeEventListener("command", openVarView);
openInVarViewCmd.setAttribute("disabled", "true");
});
},
@ -2690,6 +2720,16 @@ Widgets.ObjectRenderers.add({
this._text(")");
},
_onClick: function () {
let location = this.objectActor.location;
if (location) {
this.output.openLocationInDebugger(location);
}
else {
this.openObjectInVariablesView();
}
}
}); // Widgets.ObjectRenderers.byClass.Function
/**

Просмотреть файл

@ -124,6 +124,8 @@ support-files =
test-bug-609872-cd-iframe-parent.html
test-bug-609872-cd-iframe-child.html
test-bug-989025-iframe-parent.html
test-bug_1050691_click_function_to_source.html
test-bug_1050691_click_function_to_source.js
test-console-api-stackframe.html
test_bug_1010953_cspro.html^headers^
test_bug_1010953_cspro.html
@ -387,3 +389,5 @@ skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
[browser_webconsole_bug_922212_console_dirxml.js]
[browser_webconsole_shows_reqs_in_netmonitor.js]
[browser_netmonitor_shows_reqs_in_webconsole.js]
[browser_webconsole_bug_1050691_click_function_to_source.js]
[browser_webconsole_context_menu_open_in_var_view.js]

Просмотреть файл

@ -0,0 +1,60 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
// Tests that clicking on a function displays its source in the debugger.
"use strict";
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/test-bug_1050691_click_function_to_source.html";
let test = asyncTest(function*() {
yield loadTab(TEST_URI);
let hud = yield openConsole();
yield testWithoutDebuggerOpen(hud);
// Open the Debugger panel.
let debuggerPanel = yield openDebugger();
// And right after come back to the Console panel.
yield openConsole();
yield testWithDebuggerOpen(hud, debuggerPanel);
});
function* testWithoutDebuggerOpen(hud) {
let clickable = yield printFunction(hud);
let onVariablesViewOpen = hud.jsterm.once("variablesview-fetched");
synthesizeClick(clickable, hud);
return onVariablesViewOpen;
}
function* testWithDebuggerOpen(hud, debuggerPanel) {
let clickable = yield printFunction(hud);
let panelWin = debuggerPanel.panelWin;
let onEditorLocationSet = panelWin.once(panelWin.EVENTS.EDITOR_LOCATION_SET);
synthesizeClick(clickable, hud);
yield onEditorLocationSet;
ok(isDebuggerCaretPos(debuggerPanel, 7),
"Clicking on a function should go to its source in the debugger view");
}
function synthesizeClick(clickable, hud) {
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
}
let printFunction = Task.async(function* (hud) {
hud.jsterm.clearOutput();
content.wrappedJSObject.foo();
let [result] = yield waitForMessages({
webconsole: hud,
messages: [{
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
}],
});
let msg = [...result.matched][0];
let clickable = msg.querySelector("a");
ok(clickable, "clickable item for object should exist");
return clickable;
});

Просмотреть файл

@ -39,7 +39,7 @@ function test()
return deferred.promise;
});
})
});
});
}
@ -65,7 +65,15 @@ function onExecuteGetName(aResults)
ok(clickable, "clickable object found");
gJSTerm.once("variablesview-fetched", onGetNameFetch);
EventUtils.synthesizeMouse(clickable, 2, 2, {}, gWebConsole.iframeWindow);
let contextMenu =
gWebConsole.iframeWindow.document.getElementById("output-contextmenu");
waitForContextMenu(contextMenu, clickable, () => {
let openInVarView = contextMenu.querySelector("#menu_openInVarView");
ok(openInVarView.disabled === false,
"the \"Open In Variables View\" context menu item should be clickable");
// EventUtils.synthesizeMouseAtCenter seems to fail here in Mac OSX
openInVarView.click();
});
}
function onGetNameFetch(aEvent, aVar)

Просмотреть файл

@ -0,0 +1,51 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
// Tests that the "Open in Variables View" context menu item is enabled
// only for objects.
"use strict";
const TEST_URI = `data:text/html,<script>
console.log("foo");
console.log("foo", window);
</script>`;
let test = asyncTest(function*() {
yield loadTab(TEST_URI);
let hud = yield openConsole();
let [result] = yield waitForMessages({
webconsole: hud,
messages: [{
category: CATEGORY_WEBDEV,
severity: SEVERITY_LOG,
count: 2,
text: /foo/
}],
});
let [msgWithText, msgWithObj] = [...result.matched];
ok(msgWithText && msgWithObj, "Two messages should have appeared");
let contextMenu = hud.iframeWindow.
document.getElementById("output-contextmenu");
let openInVarViewItem = contextMenu.querySelector("#menu_openInVarView");
let obj = msgWithObj.querySelector(".cm-variable");
let text = msgWithText.querySelector(".console-string");
yield waitForContextMenu(contextMenu, obj, () => {
ok(openInVarViewItem.disabled === false, "The \"Open In Variables View\" " +
"context menu item should be available for objects");
}, () => {
ok(openInVarViewItem.disabled === true, "The \"Open In Variables View\" " +
"context menu item should be disabled on popup hiding");
});
yield waitForContextMenu(contextMenu, text, () => {
ok(openInVarViewItem.disabled === true, "The \"Open In Variables View\" " +
"context menu item should be disabled for texts");
});
});

Просмотреть файл

@ -226,6 +226,8 @@ let closeConsole = Task.async(function* (aTab) {
*/
function waitForContextMenu(aPopup, aButton, aOnShown, aOnHidden)
{
let deferred = promise.defer();
function onPopupShown() {
info("onPopupShown");
aPopup.removeEventListener("popupshown", onPopupShown);
@ -245,11 +247,10 @@ function waitForContextMenu(aPopup, aButton, aOnShown, aOnHidden)
deferred.resolve(aPopup);
}
let deferred = promise.defer();
aPopup.addEventListener("popupshown", onPopupShown);
info("wait for the context menu to open");
let eventDetails = { type: "contextmenu", button: 2};
let eventDetails = {type: "contextmenu", button: 2};
EventUtils.synthesizeMouse(aButton, 2, 2, eventDetails,
aButton.ownerDocument.defaultView);
return deferred.promise;
@ -825,7 +826,7 @@ function openDebugger(aOptions = {})
let target = TargetFactory.forTab(aOptions.tab);
let toolbox = gDevTools.getToolbox(target);
let dbgPanelAlreadyOpen = toolbox.getPanel("jsdebugger");
let dbgPanelAlreadyOpen = toolbox && toolbox.getPanel("jsdebugger");
gDevTools.showToolbox(target, "jsdebugger").then(function onSuccess(aToolbox) {
let panel = aToolbox.getCurrentPanel();
@ -856,6 +857,24 @@ function openDebugger(aOptions = {})
return deferred.promise;
}
/**
* Returns true if the caret in the debugger editor is placed at the specified
* position.
* @param aPanel The debugger panel.
* @param {number} aLine The line number.
* @param {number} [aCol] The column number.
* @returns {boolean}
*/
function isDebuggerCaretPos(aPanel, aLine, aCol = 1) {
let editor = aPanel.panelWin.DebuggerView.editor;
let cursor = editor.getCursor();
// Source editor starts counting line and column numbers from 0.
info("Current editor caret position: " + (cursor.line + 1) + ", " +
(cursor.ch + 1));
return cursor.line == (aLine - 1) && cursor.ch == (aCol - 1);
}
/**
* Wait for messages in the Web Console output.
*

Просмотреть файл

@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<meta charset="utf-8">
<title>Click on function should point to source</title>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<script type="text/javascript" src="test-bug_1050691_click_function_to_source.js"></script>
</head>
<body></body>
</html>

Просмотреть файл

@ -0,0 +1,10 @@
/**
* this
* is
* a
* function
*/
function foo() {
console.log(foo);
}

Просмотреть файл

@ -76,6 +76,8 @@ function goUpdateConsoleCommands() {
<menuitem id="menu_copyURL" label="&copyURLCmd.label;"
accesskey="&copyURLCmd.accesskey;" command="consoleCmd_copyURL"
selection="network" selectionType="single"/>
<menuitem id="menu_openInVarView" label="&openInVarViewCmd.label;"
accesskey="&openInVarViewCmd.accesskey;" disabled="true"/>
<menuitem id="cMenu_copy"/>
<menuitem id="cMenu_selectAll"/>
</menupopup>

Просмотреть файл

@ -107,3 +107,5 @@
<!ENTITY closeCmd.key "W">
<!ENTITY findCmd.key "F">
<!ENTITY clearOutputCtrl.key "L">
<!ENTITY openInVarViewCmd.label "Open in Variables View">
<!ENTITY openInVarViewCmd.accesskey "V">

Просмотреть файл

@ -3,7 +3,11 @@
- 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/. -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- We disable AlwaysShowAction because we interpret the menu
attributes ourselves and thus the warning isn't relevant to us. -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item android:id="@+id/reload"
android:icon="@drawable/new_tablet_ic_menu_reload"

Просмотреть файл

@ -3,7 +3,11 @@
- 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/. -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- We disable AlwaysShowAction because we interpret the menu
attributes ourselves and thus the warning isn't relevant to us. -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item android:id="@+id/back"
android:icon="@drawable/ic_menu_back"

Просмотреть файл

@ -3,7 +3,11 @@
- 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/. -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- We disable AlwaysShowAction because we interpret the menu
attributes ourselves and thus the warning isn't relevant to us. -->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="AlwaysShowAction">
<item android:id="@+id/reload"
android:icon="@drawable/new_tablet_ic_menu_reload"

Просмотреть файл

@ -31,7 +31,7 @@
<h1 class="showNormal">&privatebrowsingpage.title.normal;</h1>
<div class="contentSection">
<p class="showPrivate">&privatebrowsingpage.description.private;</p>
<p class="showPrivate">&privatebrowsingpage.description.private2;</p>
<p class="showNormal">&privatebrowsingpage.description.normal;</p>
<p class="showPrivate"><a href="https://support.mozilla.org/kb/private-browsing-firefox-android">&privatebrowsingpage.link.private;</a></p>

Просмотреть файл

@ -10,7 +10,7 @@
<!ENTITY privatebrowsingpage.description2 "Bookmarks you add and files you download will still be saved on your device.">
<!ENTITY privatebrowsingpage.description.normal "&privatebrowsingpage.issueDesc.normal2; &privatebrowsingpage.description2;">
<!ENTITY privatebrowsingpage.description.private "&privatebrowsingpage.issueDesc.private2; &privatebrowsingpage.description2;">
<!ENTITY privatebrowsingpage.description.private2 "&privatebrowsingpage.issueDesc.private2; &privatebrowsingpage.description2;">
<!ENTITY privatebrowsingpage.link.private "Want to learn more?">
<!ENTITY privatebrowsingpage.link.normal "Open a new private tab">

Просмотреть файл

@ -128,7 +128,7 @@ this.SearchSuggestionController.prototype = {
if (!this.maxLocalResults && !this.maxRemoteResults) {
throw new Error("Zero results expected, what are you trying to do?");
}
if (this.maxLocalResults < 0 || this.remoteResult < 0) {
if (this.maxLocalResults < 0 || this.maxRemoteResults < 0) {
throw new Error("Number of requested results must be positive");
}

Просмотреть файл

@ -50,7 +50,7 @@ exports.reportException = function reportException(aWho, aException) {
dump(msg + "\n");
if (Cu.reportError) {
if (Cu && Cu.reportError) {
/*
* Note that the xpcshell test harness registers an observer for
* console messages, so when we're running tests, this will cause

Просмотреть файл

@ -224,7 +224,6 @@ const UnsolicitedNotifications = {
"networkEventUpdate": "networkEventUpdate",
"newGlobal": "newGlobal",
"newScript": "newScript",
"newSource": "newSource",
"tabDetached": "tabDetached",
"tabListChanged": "tabListChanged",
"reflowActivity": "reflowActivity",
@ -1623,7 +1622,6 @@ function ThreadClient(aClient, aActor) {
this._pauseGrips = {};
this._threadGrips = {};
this.request = this.client.request;
this.events = [];
}
ThreadClient.prototype = {
@ -2170,7 +2168,9 @@ ThreadClient.prototype = {
actors: args(0)
}, {
telemetry: "PROTOTYPESANDPROPERTIES"
})
}),
events: ["newSource"]
};
eventSource(ThreadClient.prototype);

Просмотреть файл

@ -25,7 +25,7 @@ function BrowserAddonActor(aConnection, aAddon) {
this._addon = aAddon;
this._contextPool = new ActorPool(this.conn);
this.conn.addActorPool(this._contextPool);
this._threadActor = null;
this.threadActor = null;
this._global = null;
this._shouldAddNewGlobalAsDebuggee = this._shouldAddNewGlobalAsDebuggee.bind(this);
@ -55,7 +55,7 @@ BrowserAddonActor.prototype = {
},
get attached() {
return this._threadActor;
return this.threadActor;
},
get global() {
@ -65,7 +65,7 @@ BrowserAddonActor.prototype = {
get sources() {
if (!this._sources) {
dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
this._sources = new TabSources(this._threadActor, this._allowSource);
this._sources = new TabSources(this.threadActor, this._allowSource);
}
return this._sources;
},
@ -135,11 +135,11 @@ BrowserAddonActor.prototype = {
}
if (!this.attached) {
this._threadActor = new AddonThreadActor(this.conn, this);
this._contextPool.addActor(this._threadActor);
this.threadActor = new AddonThreadActor(this.conn, this);
this._contextPool.addActor(this.threadActor);
}
return { type: "tabAttached", threadActor: this._threadActor.actorID };
return { type: "tabAttached", threadActor: this.threadActor.actorID };
},
onDetach: function BAA_onDetach() {
@ -147,9 +147,9 @@ BrowserAddonActor.prototype = {
return { error: "wrongState" };
}
this._contextPool.removeActor(this._threadActor);
this._contextPool.removeActor(this.threadActor);
this._threadActor = null;
this.threadActor = null;
this._sources = null;
return { type: "detached" };

Просмотреть файл

@ -18,7 +18,7 @@ function ChildProcessActor(aConnection) {
this.conn = aConnection;
this._contextPool = new ActorPool(this.conn);
this.conn.addActorPool(this._contextPool);
this._threadActor = null;
this.threadActor = null;
// Use a see-everything debugger
this.makeDebugger = makeDebugger.bind(null, {
@ -56,8 +56,8 @@ ChildProcessActor.prototype = {
get sources() {
if (!this._sources) {
dbg_assert(this._threadActor, "threadActor should exist when creating sources.");
this._sources = new TabSources(this._threadActor);
dbg_assert(this.threadActor, "threadActor should exist when creating sources.");
this._sources = new TabSources(this.threadActor);
}
return this._sources;
},
@ -68,9 +68,9 @@ ChildProcessActor.prototype = {
this._contextPool.addActor(this._consoleActor);
}
if (!this._threadActor) {
this._threadActor = new ChromeDebuggerActor(this.conn, this);
this._contextPool.addActor(this._threadActor);
if (!this.threadActor) {
this.threadActor = new ChromeDebuggerActor(this.conn, this);
this._contextPool.addActor(this.threadActor);
}
return {
@ -78,7 +78,7 @@ ChildProcessActor.prototype = {
name: "Content process",
consoleActor: this._consoleActor.actorID,
chromeDebugger: this._threadActor.actorID,
chromeDebugger: this.threadActor.actorID,
traits: {
highlightable: false,

Просмотреть файл

@ -35,6 +35,12 @@
opacity: 0.6;
}
/* Box model regions can be faded (see the onlyRegionArea option in
highlighter.js) in order to only display certain regions. */
:-moz-native-anonymous .box-model-regions [faded] {
display: none;
}
:-moz-native-anonymous .box-model-content {
fill: #87ceeb;
}

Просмотреть файл

@ -234,7 +234,8 @@ let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
region: Option(1),
hideInfoBar: Option(1),
hideGuides: Option(1),
showOnly: Option(1)
showOnly: Option(1),
onlyRegionArea: Option(1)
}
}),
@ -1045,7 +1046,12 @@ AutoRefreshHighlighter.prototype = {
* Defaults to false
* - showOnly {String}
* "content", "padding", "border" or "margin"
* If set, only this region will be highlighted
* If set, only this region will be highlighted. Use with onlyRegionArea to
* only highlight the area of the region.
* - onlyRegionArea {Boolean}
* This can be set to true to make each region's box only highlight the area
* of the corresponding region rather than the area of nested regions too.
* This is useful when used with showOnly.
*
* Structure:
* <div class="highlighter-container">
@ -1427,49 +1433,90 @@ BoxModelHighlighter.prototype = Heritage.extend(AutoRefreshHighlighter.prototype
* True if the current node has a box model to be highlighted
*/
_updateBoxModel: function() {
this.options.region = this.options.region || "content";
let options = this.options;
options.region = options.region || "content";
if (this._nodeNeedsHighlighting()) {
for (let boxType of BOX_MODEL_REGIONS) {
let box = this.getElement(boxType);
if (!this._nodeNeedsHighlighting()) {
this._hideBoxModel();
return false;
}
if (this.regionFill[boxType]) {
box.setAttribute("style", "fill:" + this.regionFill[boxType]);
} else {
box.setAttribute("style", "");
}
for (let i = 0; i < BOX_MODEL_REGIONS.length; i++) {
let boxType = BOX_MODEL_REGIONS[i];
let nextBoxType = BOX_MODEL_REGIONS[i + 1];
let box = this.getElement(boxType);
if (!this.options.showOnly || this.options.showOnly === boxType) {
// Highlighting all quads.
let path = [];
for (let {p1, p2, p3, p4} of this.currentQuads[boxType]) {
path.push("M" + p1.x + "," + p1.y + " " +
"L" + p2.x + "," + p2.y + " " +
"L" + p3.x + "," + p3.y + " " +
"L" + p4.x + "," + p4.y);
}
if (this.regionFill[boxType]) {
box.setAttribute("style", "fill:" + this.regionFill[boxType]);
} else {
box.setAttribute("style", "");
}
box.setAttribute("d", path.join(" "));
// Highlight all quads for this region by setting the "d" attribute of the
// corresponding <path>.
let path = [];
for (let j = 0; j < this.currentQuads[boxType].length; j++) {
let boxQuad = this.currentQuads[boxType][j];
let nextBoxQuad = this.currentQuads[nextBoxType]
? this.currentQuads[nextBoxType][j]
: null;
path.push(this._getBoxPathCoordinates(boxQuad, nextBoxQuad));
}
box.setAttribute("d", path.join(" "));
box.removeAttribute("faded");
// If showOnly is defined, either hide the other regions, or fade them out
// if onlyRegionArea is set too.
if (options.showOnly && options.showOnly !== boxType) {
if (options.onlyRegionArea) {
box.setAttribute("faded", "true");
} else {
box.removeAttribute("d");
}
if (boxType === this.options.region && !this.options.hideGuides) {
this._showGuides(boxType);
} else if (this.options.hideGuides) {
this._hideGuides();
}
}
// Un-zoom the root wrapper if the page was zoomed.
let rootId = this.ID_CLASS_PREFIX + "root";
this.markup.scaleRootElement(this.currentNode, rootId);
return true;
if (boxType === options.region && !options.hideGuides) {
this._showGuides(boxType);
} else if (options.hideGuides) {
this._hideGuides();
}
}
this._hideBoxModel();
return false;
// Un-zoom the root wrapper if the page was zoomed.
let rootId = this.ID_CLASS_PREFIX + "root";
this.markup.scaleRootElement(this.currentNode, rootId);
return true;
},
_getBoxPathCoordinates: function(boxQuad, nextBoxQuad) {
let {p1, p2, p3, p4} = boxQuad;
let path;
if (!nextBoxQuad || !this.options.onlyRegionArea) {
// If this is the content box (inner-most box) or if we're not being asked
// to highlight only region areas, then draw a simple rectangle.
path = "M" + p1.x + "," + p1.y + " " +
"L" + p2.x + "," + p2.y + " " +
"L" + p3.x + "," + p3.y + " " +
"L" + p4.x + "," + p4.y;
} else {
// Otherwise, just draw the region itself, not a filled rectangle.
let {p1: np1, p2: np2, p3: np3, p4: np4} = nextBoxQuad;
path = "M" + p1.x + "," + p1.y + " " +
"L" + p2.x + "," + p2.y + " " +
"L" + p3.x + "," + p3.y + " " +
"L" + p4.x + "," + p4.y + " " +
"L" + p1.x + "," + p1.y + " " +
"L" + np1.x + "," + np1.y + " " +
"L" + np4.x + "," + np4.y + " " +
"L" + np3.x + "," + np3.y + " " +
"L" + np2.x + "," + np2.y + " " +
"L" + np1.x + "," + np1.y;
}
return path;
},
_nodeNeedsHighlighting: function() {

Просмотреть файл

@ -42,6 +42,8 @@ const OBJECT_PREVIEW_MAX_ITEMS = 10;
* Increment the actor's grip depth
* - decrementGripDepth
* Decrement the actor's grip depth
* - globalDebugObject
* The Debuggee Global Object as given by the ThreadActor
*/
function ObjectActor(obj, {
createValueGrip,
@ -49,7 +51,8 @@ function ObjectActor(obj, {
createEnvironmentActor,
getGripDepth,
incrementGripDepth,
decrementGripDepth
decrementGripDepth,
getGlobalDebugObject
}) {
dbg_assert(!obj.optimizedOut,
"Should not create object actors for optimized out values!");
@ -60,7 +63,8 @@ function ObjectActor(obj, {
createEnvironmentActor,
getGripDepth,
incrementGripDepth,
decrementGripDepth
decrementGripDepth,
getGlobalDebugObject
};
this.iterators = new Set();
}
@ -804,6 +808,17 @@ DebuggerServer.ObjectActorPreviewers = {
grip.userDisplayName = hooks.createValueGrip(userDisplayName.value);
}
let dbgGlobal = hooks.getGlobalDebugObject();
if (dbgGlobal) {
let script = dbgGlobal.makeDebuggeeValue(obj.unsafeDereference()).script;
if (script) {
grip.location = {
url: script.url,
line: script.startLine
};
}
}
return true;
}],

Просмотреть файл

@ -145,7 +145,9 @@ let PromisesActor = protocol.ActorClass({
sources: () => DevToolsUtils.reportException("PromisesActor",
Error("sources not yet implemented")),
createEnvironmentActor: () => DevToolsUtils.reportException(
"PromisesActor", Error("createEnvironmentActor not yet implemented"))
"PromisesActor", Error("createEnvironmentActor not yet implemented")),
getGlobalDebugObject: () => DevToolsUtils.reportException(
"PromisesActor", Error("getGlobalDebugObject not yet implemented")),
});
this._navigationLifetimePool.addActor(actor);

Просмотреть файл

@ -462,6 +462,9 @@ ThreadActor.prototype = {
},
get globalDebugObject() {
if (!this._parent.window) {
return null;
}
return this.dbg.makeGlobalObjectReference(this._parent.window);
},
@ -1676,7 +1679,8 @@ ThreadActor.prototype = {
this.createEnvironmentActor(env, pool),
promote: () => this.threadObjectGrip(actor),
isThreadLifetimePool: () =>
actor.registeredPool !== this.threadLifetimePool
actor.registeredPool !== this.threadLifetimePool,
getGlobalDebugObject: () => this.globalDebugObject
});
aPool.addActor(actor);
aPool.objectActors.set(aValue, actor);

Просмотреть файл

@ -305,6 +305,10 @@ WebConsoleActor.prototype =
actorPrefix: "console",
get globalDebugObject() {
return this.parentActor.threadActor.globalDebugObject;
},
grip: function WCA_grip()
{
return { actor: this.actorID };
@ -450,7 +454,8 @@ WebConsoleActor.prototype =
createValueGrip: v => this.createValueGrip(v),
sources: () => DevToolsUtils.reportException("WebConsoleActor",
Error("sources not yet implemented")),
createEnvironmentActor: (env) => this.createEnvironmentActor(env)
createEnvironmentActor: (env) => this.createEnvironmentActor(env),
getGlobalDebugObject: () => this.globalDebugObject
});
aPool.addActor(actor);
return actor.grip();

Просмотреть файл

@ -75,9 +75,9 @@ function attachTab(client, tab) {
return rdpRequest(client, client.attachTab, tab.actor);
}
function waitForNewSource(client, url) {
function waitForNewSource(threadClient, url) {
dump("Waiting for new source with url '" + url + "'.\n");
return waitForEvent(client, "newSource", function (packet) {
return waitForEvent(threadClient, "newSource", function (packet) {
return packet.source.url === url;
});
}

Просмотреть файл

@ -31,7 +31,7 @@ function run_test() {
}
function test_executable_lines() {
gClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
gThreadClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
do_check_eq(evt, "newSource");
gThreadClient.getSources(function ({error, sources}) {

Просмотреть файл

@ -31,7 +31,7 @@ function run_test() {
}
function test_executable_lines() {
gClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
gThreadClient.addOneTimeListener("newSource", function _onNewSource(evt, packet) {
do_check_eq(evt, "newSource");
gThreadClient.getSources(function ({error, sources}) {
@ -52,4 +52,4 @@ function test_executable_lines() {
function arrays_equal(a,b) {
return !(a<b || b<a);
}
}

Просмотреть файл

@ -25,7 +25,7 @@ function run_test()
function test_simple_new_source()
{
gClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
gThreadClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
do_check_eq(aEvent, "newSource");
do_check_eq(aPacket.type, "newSource");
do_check_true(!!aPacket.source);

Просмотреть файл

@ -21,7 +21,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -21,7 +21,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -21,7 +21,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -21,7 +21,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -22,7 +22,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -22,7 +22,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -21,7 +21,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -21,7 +21,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -22,7 +22,7 @@ function run_test() {
let [, threadClient] = yield attachThread(tabClient);
yield resume(threadClient);
let promise = waitForNewSource(client, SOURCE_URL);
let promise = waitForNewSource(threadClient, SOURCE_URL);
loadSubScript(SOURCE_URL, global);
let { source } = yield promise;
let sourceClient = threadClient.source(source);

Просмотреть файл

@ -33,7 +33,7 @@ function test_simple_source_map()
"http://example.com/www/js/b.js",
"http://example.com/www/js/c.js"]);
gClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
gThreadClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
do_check_eq(aEvent, "newSource");
do_check_eq(aPacket.type, "newSource");
do_check_true(!!aPacket.source);

Просмотреть файл

@ -94,12 +94,12 @@ function test_simple_source_map()
"http://example.com/www/js/c.js"
]);
gClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
gThreadClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
expectedSources.delete(aPacket.source.url);
if (expectedSources.size > 0) {
return;
}
gClient.removeListener("newSource", _onNewSource);
gThreadClient.removeListener("newSource", _onNewSource);
testBreakpointMapping("a", function () {
testBreakpointMapping("b", function () {

Просмотреть файл

@ -27,7 +27,7 @@ function run_test()
function test_absolute_source_map()
{
gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
gThreadClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
do_check_eq(aEvent, "newSource");
do_check_eq(aPacket.type, "newSource");
do_check_true(!!aPacket.source);

Просмотреть файл

@ -27,7 +27,7 @@ function run_test()
function test_relative_source_map()
{
gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
gThreadClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
do_check_eq(aEvent, "newSource");
do_check_eq(aPacket.type, "newSource");
do_check_true(!!aPacket.source);

Просмотреть файл

@ -30,11 +30,11 @@ function test_source_content()
{
let numNewSources = 0;
gClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
gThreadClient.addListener("newSource", function _onNewSource(aEvent, aPacket) {
if (++numNewSources !== 3) {
return;
}
gClient.removeListener("newSource", _onNewSource);
gThreadClient.removeListener("newSource", _onNewSource);
gThreadClient.getSources(function (aResponse) {
do_check_true(!aResponse.error, "Should not get an error");

Просмотреть файл

@ -29,7 +29,7 @@ function test_cached_original_sources()
{
writeFile("temp.js", "initial content");
gClient.addOneTimeListener("newSource", onNewSource);
gThreadClient.addOneTimeListener("newSource", onNewSource);
let node = new SourceNode(1, 0,
getFileUrl("temp.js"),

Просмотреть файл

@ -28,7 +28,7 @@ function run_test()
function test_source_maps()
{
gClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
gThreadClient.addOneTimeListener("newSource", function (aEvent, aPacket) {
let sourceClient = gThreadClient.source(aPacket.source);
sourceClient.source(function ({error, source}) {
do_check_true(!error, "should be able to grab the source");

Просмотреть файл

@ -29,7 +29,7 @@ function test_minified()
{
let newSourceFired = false;
gClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
gThreadClient.addOneTimeListener("newSource", function _onNewSource(aEvent, aPacket) {
do_check_eq(aEvent, "newSource");
do_check_eq(aPacket.type, "newSource");
do_check_true(!!aPacket.source);

Просмотреть файл

@ -77,7 +77,7 @@ function setup_new_code() {
code += "\n//# sourceMappingURL=" + getFileUrl(MAP_FILE_NAME, true);
writeFile(MAP_FILE_NAME, map.toString());
gClient.addOneTimeListener("newSource", test_new_sources);
gThreadClient.addOneTimeListener("newSource", test_new_sources);
Cu.evalInSandbox(code,
gDebuggee,
"1.8",

Просмотреть файл

@ -95,7 +95,7 @@ TestTabActor.prototype = {
actorPrefix: "TestTabActor",
get window() {
return { wrappedJSObject: this._global };
return this._global;
},
get url() {