зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to b2g-i
This commit is contained in:
Коммит
681941a240
|
@ -683,7 +683,7 @@ getRoleCB(AtkObject *aAtkObj)
|
|||
else if (aAtkObj->role == ATK_ROLE_TABLE_ROW && !IsAtkVersionAtLeast(2, 1))
|
||||
aAtkObj->role = ATK_ROLE_LIST_ITEM;
|
||||
else if (aAtkObj->role == ATK_ROLE_MATH && !IsAtkVersionAtLeast(2, 12))
|
||||
aAtkObj->role = ATK_ROLE_PANEL;
|
||||
aAtkObj->role = ATK_ROLE_SECTION;
|
||||
else if (aAtkObj->role == ATK_ROLE_STATIC && !IsAtkVersionAtLeast(2, 16))
|
||||
aAtkObj->role = ATK_ROLE_TEXT;
|
||||
else if ((aAtkObj->role == ATK_ROLE_MATH_FRACTION ||
|
||||
|
|
|
@ -1067,7 +1067,7 @@ ROLE(SWITCH,
|
|||
ROLE(MATHML_MATH,
|
||||
"math",
|
||||
ATK_ROLE_MATH,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
ROLE_SYSTEM_EQUATION,
|
||||
ROLE_SYSTEM_EQUATION,
|
||||
eNoNameRule)
|
||||
|
@ -1075,7 +1075,7 @@ ROLE(MATHML_MATH,
|
|||
ROLE(MATHML_IDENTIFIER,
|
||||
"mathml identifier",
|
||||
ATK_ROLE_STATIC,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNameFromSubtreeRule)
|
||||
|
@ -1083,7 +1083,7 @@ ROLE(MATHML_IDENTIFIER,
|
|||
ROLE(MATHML_NUMBER,
|
||||
"mathml number",
|
||||
ATK_ROLE_STATIC,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNameFromSubtreeRule)
|
||||
|
@ -1091,7 +1091,7 @@ ROLE(MATHML_NUMBER,
|
|||
ROLE(MATHML_OPERATOR,
|
||||
"mathml operator",
|
||||
ATK_ROLE_STATIC,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNameFromSubtreeRule)
|
||||
|
@ -1099,7 +1099,7 @@ ROLE(MATHML_OPERATOR,
|
|||
ROLE(MATHML_TEXT,
|
||||
"mathml text",
|
||||
ATK_ROLE_STATIC,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNameFromSubtreeRule)
|
||||
|
@ -1107,7 +1107,7 @@ ROLE(MATHML_TEXT,
|
|||
ROLE(MATHML_STRING_LITERAL,
|
||||
"mathml string literal",
|
||||
ATK_ROLE_STATIC,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNameFromSubtreeRule)
|
||||
|
@ -1115,15 +1115,15 @@ ROLE(MATHML_STRING_LITERAL,
|
|||
ROLE(MATHML_GLYPH,
|
||||
"mathml glyph",
|
||||
ATK_ROLE_IMAGE,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNameFromSubtreeRule)
|
||||
|
||||
ROLE(MATHML_ROW,
|
||||
"mathml row",
|
||||
ATK_ROLE_PANEL,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1131,7 +1131,7 @@ ROLE(MATHML_ROW,
|
|||
ROLE(MATHML_FRACTION,
|
||||
"mathml fraction",
|
||||
ATK_ROLE_MATH_FRACTION,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1139,7 +1139,7 @@ ROLE(MATHML_FRACTION,
|
|||
ROLE(MATHML_SQUARE_ROOT,
|
||||
"mathml square root",
|
||||
ATK_ROLE_MATH_ROOT,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1147,87 +1147,87 @@ ROLE(MATHML_SQUARE_ROOT,
|
|||
ROLE(MATHML_ROOT,
|
||||
"mathml root",
|
||||
ATK_ROLE_MATH_ROOT,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_FENCED,
|
||||
"mathml fenced",
|
||||
ATK_ROLE_PANEL,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_ENCLOSED,
|
||||
"mathml enclosed",
|
||||
ATK_ROLE_PANEL,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_STYLE,
|
||||
"mathml style",
|
||||
ATK_ROLE_PANEL,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_SUB,
|
||||
"mathml sub",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_SUP,
|
||||
"mathml sup",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_SUB_SUP,
|
||||
"mathml sub sup",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_UNDER,
|
||||
"mathml under",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_OVER,
|
||||
"mathml over",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_UNDER_OVER,
|
||||
"mathml under over",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_MULTISCRIPTS,
|
||||
"mathml multiscripts",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1235,7 +1235,7 @@ ROLE(MATHML_MULTISCRIPTS,
|
|||
ROLE(MATHML_TABLE,
|
||||
"mathml table",
|
||||
ATK_ROLE_TABLE,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1243,7 +1243,7 @@ ROLE(MATHML_TABLE,
|
|||
ROLE(MATHML_LABELED_ROW,
|
||||
"mathml labeled row",
|
||||
ATK_ROLE_TABLE_ROW,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1251,7 +1251,7 @@ ROLE(MATHML_LABELED_ROW,
|
|||
ROLE(MATHML_TABLE_ROW,
|
||||
"mathml table row",
|
||||
ATK_ROLE_TABLE_ROW,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1259,23 +1259,23 @@ ROLE(MATHML_TABLE_ROW,
|
|||
ROLE(MATHML_CELL,
|
||||
"mathml cell",
|
||||
ATK_ROLE_TABLE_CELL,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_ACTION,
|
||||
"mathml action",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
||||
ROLE(MATHML_ERROR,
|
||||
"mathml error",
|
||||
ATK_ROLE_PANEL,
|
||||
NSAccessibilityUnknownRole,
|
||||
ATK_ROLE_SECTION,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1283,7 +1283,7 @@ ROLE(MATHML_ERROR,
|
|||
ROLE(MATHML_STACK,
|
||||
"mathml stack",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1291,7 +1291,7 @@ ROLE(MATHML_STACK,
|
|||
ROLE(MATHML_LONG_DIVISION,
|
||||
"mathml long division",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1299,7 +1299,7 @@ ROLE(MATHML_LONG_DIVISION,
|
|||
ROLE(MATHML_STACK_GROUP,
|
||||
"mathml stack group",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1307,7 +1307,7 @@ ROLE(MATHML_STACK_GROUP,
|
|||
ROLE(MATHML_STACK_ROW,
|
||||
"mathml stack row",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1315,7 +1315,7 @@ ROLE(MATHML_STACK_ROW,
|
|||
ROLE(MATHML_STACK_CARRIES,
|
||||
"mathml stack carries",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1323,7 +1323,7 @@ ROLE(MATHML_STACK_CARRIES,
|
|||
ROLE(MATHML_STACK_CARRY,
|
||||
"mathml stack carry",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
@ -1331,7 +1331,7 @@ ROLE(MATHML_STACK_CARRY,
|
|||
ROLE(MATHML_STACK_LINE,
|
||||
"mathml stack line",
|
||||
ATK_ROLE_UNKNOWN,
|
||||
NSAccessibilityUnknownRole,
|
||||
NSAccessibilityGroupRole,
|
||||
0,
|
||||
IA2_ROLE_UNKNOWN,
|
||||
eNoNameRule)
|
||||
|
|
|
@ -503,6 +503,66 @@ GetClosestInterestingAccessible(id anObject)
|
|||
case roles::DEFINITION:
|
||||
return @"AXDefinition";
|
||||
|
||||
case roles::MATHML_MATH:
|
||||
return @"AXDocumentMath";
|
||||
|
||||
case roles::MATHML_FRACTION:
|
||||
return @"AXMathFraction";
|
||||
|
||||
case roles::MATHML_FENCED:
|
||||
// XXX This should be AXMathFence, but doing so without implementing the
|
||||
// whole fence interface seems to make VoiceOver crash, so we present it
|
||||
// as a row for now.
|
||||
return @"AXMathRow";
|
||||
|
||||
case roles::MATHML_SUB:
|
||||
case roles::MATHML_SUP:
|
||||
case roles::MATHML_SUB_SUP:
|
||||
return @"AXMathSubscriptSuperscript";
|
||||
|
||||
case roles::MATHML_ROW:
|
||||
return @"AXMathRow";
|
||||
|
||||
case roles::MATHML_UNDER:
|
||||
case roles::MATHML_OVER:
|
||||
case roles::MATHML_UNDER_OVER:
|
||||
return @"AXMathUnderOver";
|
||||
|
||||
case roles::MATHML_SQUARE_ROOT:
|
||||
return @"AXMathSquareRoot";
|
||||
|
||||
case roles::MATHML_ROOT:
|
||||
return @"AXMathRoot";
|
||||
|
||||
case roles::MATHML_TEXT:
|
||||
return @"AXMathText";
|
||||
|
||||
case roles::MATHML_NUMBER:
|
||||
return @"AXMathNumber";
|
||||
|
||||
case roles::MATHML_IDENTIFIER:
|
||||
return @"AXMathIdentifier";
|
||||
|
||||
case roles::MATHML_TABLE:
|
||||
return @"AXMathTable";
|
||||
|
||||
case roles::MATHML_TABLE_ROW:
|
||||
return @"AXMathTableRow";
|
||||
|
||||
case roles::MATHML_CELL:
|
||||
return @"AXMathTableCell";
|
||||
|
||||
// XXX: NSAccessibility also uses subroles AXMathSeparatorOperator and
|
||||
// AXMathFenceOperator. We should use the NS_MATHML_OPERATOR_FENCE and
|
||||
// NS_MATHML_OPERATOR_SEPARATOR bits of nsOperatorFlags, but currently they
|
||||
// are only available from the MathML layout code. Hence we just fallback
|
||||
// to subrole AXMathOperator for now.
|
||||
case roles::MATHML_OPERATOR:
|
||||
return @"AXMathOperator";
|
||||
|
||||
case roles::MATHML_MULTISCRIPTS:
|
||||
return @"AXMathMultiscript";
|
||||
|
||||
case roles::SWITCH:
|
||||
return @"AXSwitch";
|
||||
|
||||
|
|
|
@ -305,7 +305,6 @@
|
|||
@RESPATH@/components/plugin.xpt
|
||||
@RESPATH@/components/pref.xpt
|
||||
@RESPATH@/components/prefetch.xpt
|
||||
@RESPATH@/components/profile.xpt
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
@RESPATH@/components/profiler.xpt
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -475,6 +475,7 @@ skip-if = e10s # Bug 1100687 - test directly manipulates content (content.docume
|
|||
[browser_e10s_chrome_process.js]
|
||||
[browser_e10s_javascript.js]
|
||||
[browser_blockHPKP.js]
|
||||
tags = psm
|
||||
skip-if = e10s # bug 1100687 - test directly manipulates content (content.document.getElementById)
|
||||
[browser_mcb_redirect.js]
|
||||
[browser_windowactivation.js]
|
||||
|
|
|
@ -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" >
|
||||
« {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("#")}> ¶</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
|
||||
<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="©URLCmd.label;"
|
||||
accesskey="©URLCmd.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>
|
||||
|
|
|
@ -306,7 +306,6 @@
|
|||
@RESPATH@/components/plugin.xpt
|
||||
@RESPATH@/components/pref.xpt
|
||||
@RESPATH@/components/prefetch.xpt
|
||||
@RESPATH@/components/profile.xpt
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
@RESPATH@/components/profiler.xpt
|
||||
#endif
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -98,6 +98,8 @@ public:
|
|||
|
||||
Element* GetOwnerElement(ErrorResult& aRv);
|
||||
|
||||
bool IsNSAware() const { return mNsAware; }
|
||||
|
||||
protected:
|
||||
virtual Element* GetNameSpaceElement() override
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/NamedNodeMapBinding.h"
|
||||
#include "mozilla/dom/NodeInfoInlines.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "nsAttrName.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsError.h"
|
||||
|
@ -271,6 +272,21 @@ nsDOMAttributeMap::SetNamedItemInternal(Attr& aAttr,
|
|||
{
|
||||
NS_ENSURE_TRUE(mContent, nullptr);
|
||||
|
||||
if (!aAttr.IsNSAware() &&
|
||||
!mContent->IsHTMLElement() &&
|
||||
aAttr.OwnerDoc()->IsHTMLDocument()) {
|
||||
// Check whether we have a non-lowercase name, and if so log some telemetry.
|
||||
// We check whether the attr's document is HTML _before_ the adopt we do
|
||||
// below, because we're trying to figure out whether we could lowercase the
|
||||
// attr name at creation time. We restrict this to the !IsNSAware() case,
|
||||
// because we only care about Attr nodes created via createAttribute.
|
||||
nsIAtom* nameAtom = aAttr.NodeInfo()->NameAtom();
|
||||
if (nsContentUtils::StringContainsASCIIUpper(nsDependentAtomString(nameAtom))) {
|
||||
Telemetry::Accumulate(Telemetry::NONLOWERCASE_NONHTML_ATTR_NODE_SET,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX should check same-origin between mContent and aAttr however
|
||||
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet
|
||||
|
||||
|
|
|
@ -7590,18 +7590,6 @@ nsGlobalWindow::ClearInterval(int32_t aHandle)
|
|||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::SetTimeout(int32_t *_retval)
|
||||
{
|
||||
return SetTimeoutOrInterval(false, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::SetInterval(int32_t *_retval)
|
||||
{
|
||||
return SetTimeoutOrInterval(true, _retval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::SetResizable(bool aResizable)
|
||||
{
|
||||
|
@ -11945,50 +11933,6 @@ nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
|
|||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, int32_t *aReturn)
|
||||
{
|
||||
// This needs to forward to the inner window, but since the current
|
||||
// inner may not be the inner in the calling scope, we need to treat
|
||||
// this specially here as we don't want timeouts registered in a
|
||||
// dying inner window to get registered and run on the current inner
|
||||
// window. To get this right, we need to forward this call to the
|
||||
// inner window that's calling window.setTimeout().
|
||||
|
||||
if (IsOuterWindow()) {
|
||||
nsGlobalWindow* callerInner = CallerInnerWindow();
|
||||
NS_ENSURE_TRUE(callerInner || nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// If the caller and the callee share the same outer window,
|
||||
// forward to the callee inner. Else, we forward to the current
|
||||
// inner (e.g. someone is calling setTimeout() on a reference to
|
||||
// some other window).
|
||||
|
||||
if (callerInner &&
|
||||
callerInner->GetOuterWindow() == this &&
|
||||
callerInner->IsInnerWindow()) {
|
||||
return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn);
|
||||
}
|
||||
|
||||
FORWARD_TO_INNER(SetTimeoutOrInterval, (aIsInterval, aReturn),
|
||||
NS_ERROR_NOT_INITIALIZED);
|
||||
}
|
||||
|
||||
int32_t interval = 0;
|
||||
bool isInterval = aIsInterval;
|
||||
nsCOMPtr<nsIScriptTimeoutHandler> handler;
|
||||
nsresult rv = NS_CreateJSTimeoutHandler(this,
|
||||
&isInterval,
|
||||
&interval,
|
||||
getter_AddRefs(handler));
|
||||
if (!handler) {
|
||||
*aReturn = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
return SetTimeoutOrInterval(handler, interval, isInterval, aReturn);
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsGlobalWindow::SetTimeoutOrInterval(Function& aFunction, int32_t aTimeout,
|
||||
const Sequence<JS::Value>& aArguments,
|
||||
|
|
|
@ -129,12 +129,6 @@ class VRHMDInfo;
|
|||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
extern nsresult
|
||||
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
||||
bool *aIsInterval,
|
||||
int32_t *aInterval,
|
||||
nsIScriptTimeoutHandler **aRet);
|
||||
|
||||
extern already_AddRefed<nsIScriptTimeoutHandler>
|
||||
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
||||
mozilla::dom::Function& aFunction,
|
||||
|
@ -1335,7 +1329,6 @@ public:
|
|||
}
|
||||
|
||||
// JS specific timeout functions (JS args grabbed from context).
|
||||
nsresult SetTimeoutOrInterval(bool aIsInterval, int32_t* aReturn);
|
||||
nsresult ResetTimersForNonBackgroundWindow();
|
||||
|
||||
// The timeout implementation functions.
|
||||
|
|
|
@ -58,9 +58,6 @@ public:
|
|||
return mArgs;
|
||||
}
|
||||
|
||||
nsresult Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
||||
int32_t *aInterval, bool* aAllowEval);
|
||||
|
||||
void ReleaseJSObjects();
|
||||
|
||||
private:
|
||||
|
@ -248,136 +245,6 @@ nsJSScriptTimeoutHandler::ReleaseJSObjects()
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
||||
int32_t *aInterval, bool *aAllowEval)
|
||||
{
|
||||
if (!aWindow->GetContextInternal() || !aWindow->FastGetGlobalJSObject()) {
|
||||
// This window was already closed, or never properly initialized,
|
||||
// don't let a timer be scheduled on such a window.
|
||||
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsAXPCNativeCallContext *ncc = nullptr;
|
||||
nsresult rv = nsContentUtils::XPConnect()->
|
||||
GetCurrentNativeCallContext(&ncc);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!ncc)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
JSContext *cx = nullptr;
|
||||
|
||||
rv = ncc->GetJSContext(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t argc;
|
||||
JS::Value *argv = nullptr;
|
||||
|
||||
ncc->GetArgc(&argc);
|
||||
ncc->GetArgvPtr(&argv);
|
||||
|
||||
JS::Rooted<JSFlatString*> expr(cx);
|
||||
JS::Rooted<JSObject*> funobj(cx);
|
||||
|
||||
if (argc < 1) {
|
||||
::JS_ReportError(cx, "Function %s requires at least 2 parameter",
|
||||
*aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
int32_t interval = 0;
|
||||
if (argc > 1) {
|
||||
JS::Rooted<JS::Value> arg(cx, argv[1]);
|
||||
|
||||
if (!JS::ToInt32(cx, arg, &interval)) {
|
||||
::JS_ReportError(cx,
|
||||
"Second argument to %s must be a millisecond interval",
|
||||
aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
// If no interval was specified, treat this like a timeout, to avoid
|
||||
// setting an interval of 0 milliseconds.
|
||||
*aIsInterval = false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> arg(cx, argv[0]);
|
||||
switch (::JS_TypeOfValue(cx, arg)) {
|
||||
case JSTYPE_FUNCTION:
|
||||
funobj = &arg.toObject();
|
||||
break;
|
||||
|
||||
case JSTYPE_STRING:
|
||||
case JSTYPE_OBJECT:
|
||||
{
|
||||
JSString *str = JS::ToString(cx, arg);
|
||||
if (!str)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
expr = ::JS_FlattenString(cx, str);
|
||||
if (!expr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
argv[0] = JS::StringValue(str);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
::JS_ReportError(cx, "useless %s call (missing quotes around argument?)",
|
||||
*aIsInterval ? kSetIntervalStr : kSetTimeoutStr);
|
||||
|
||||
// Return an error that nsGlobalWindow can recognize and turn into NS_OK.
|
||||
return NS_ERROR_DOM_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (expr) {
|
||||
// if CSP is enabled, and setTimeout/setInterval was called with a string,
|
||||
// disable the registration and log an error
|
||||
ErrorResult error;
|
||||
*aAllowEval = CheckCSPForEval(cx, aWindow, error);
|
||||
if (error.Failed() || !*aAllowEval) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mExpr.IsEmpty());
|
||||
AssignJSFlatString(mExpr, expr);
|
||||
|
||||
// Get the calling location.
|
||||
nsJSUtils::GetCallingLocation(cx, mFileName, &mLineNo);
|
||||
} else if (funobj) {
|
||||
*aAllowEval = true;
|
||||
|
||||
mozilla::HoldJSObjects(this);
|
||||
|
||||
mFunction = new Function(funobj, GetIncumbentGlobal());
|
||||
|
||||
// Create our arg array. argc is the number of arguments passed
|
||||
// to setTimeout or setInterval; the first two are our callback
|
||||
// and the delay, so only arguments after that need to go in our
|
||||
// array.
|
||||
// std::max(argc - 2, 0) wouldn't work right because argc is unsigned.
|
||||
uint32_t argCount = std::max(argc, 2u) - 2;
|
||||
|
||||
FallibleTArray<JS::Heap<JS::Value> > args;
|
||||
if (!args.SetCapacity(argCount, fallible)) {
|
||||
// No need to drop here, since we already have a non-null mFunction
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
for (uint32_t idx = 0; idx < argCount; ++idx) {
|
||||
*args.AppendElement(fallible) = argv[idx + 2];
|
||||
}
|
||||
args.SwapElements(mArgs);
|
||||
} else {
|
||||
NS_WARNING("No func and no expr - why are we here?");
|
||||
}
|
||||
*aInterval = interval;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const char16_t *
|
||||
nsJSScriptTimeoutHandler::GetHandlerText()
|
||||
{
|
||||
|
@ -385,24 +252,6 @@ nsJSScriptTimeoutHandler::GetHandlerText()
|
|||
return mExpr.get();
|
||||
}
|
||||
|
||||
nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
||||
bool *aIsInterval,
|
||||
int32_t *aInterval,
|
||||
nsIScriptTimeoutHandler **aRet)
|
||||
{
|
||||
*aRet = nullptr;
|
||||
nsRefPtr<nsJSScriptTimeoutHandler> handler = new nsJSScriptTimeoutHandler();
|
||||
bool allowEval;
|
||||
nsresult rv = handler->Init(aWindow, aIsInterval, aInterval, &allowEval);
|
||||
if (NS_FAILED(rv) || !allowEval) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
handler.forget(aRet);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIScriptTimeoutHandler>
|
||||
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow, Function& aFunction,
|
||||
const Sequence<JS::Value>& aArguments,
|
||||
|
|
|
@ -678,13 +678,18 @@ nsXMLHttpRequest::AppendToResponseText(const char * aSrcBuffer,
|
|||
&destBufferLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mResponseText.SetCapacity(mResponseText.Length() + destBufferLen, fallible)) {
|
||||
uint32_t size = mResponseText.Length() + destBufferLen;
|
||||
if (size < (uint32_t)destBufferLen) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!mResponseText.SetCapacity(size, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
char16_t* destBuffer = mResponseText.BeginWriting() + mResponseText.Length();
|
||||
|
||||
int32_t totalChars = mResponseText.Length();
|
||||
CheckedInt32 totalChars = mResponseText.Length();
|
||||
|
||||
// This code here is basically a copy of a similar thing in
|
||||
// nsScanner::Append(const char* aBuffer, uint32_t aLen).
|
||||
|
@ -697,9 +702,11 @@ nsXMLHttpRequest::AppendToResponseText(const char * aSrcBuffer,
|
|||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
totalChars += destlen;
|
||||
if (!totalChars.isValid()) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mResponseText.SetLength(totalChars);
|
||||
|
||||
mResponseText.SetLength(totalChars.value());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -756,6 +756,11 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
|
|||
JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject);
|
||||
|
||||
request = IDBOpenDBRequest::CreateForJS(this, scriptOwner);
|
||||
if (!request) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
aRv.ThrowUncatchableException();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(request);
|
||||
|
|
|
@ -442,11 +442,19 @@ class IDBOpenDBRequest::WorkerFeature final
|
|||
: public mozilla::dom::workers::WorkerFeature
|
||||
{
|
||||
WorkerPrivate* mWorkerPrivate;
|
||||
#ifdef DEBUG
|
||||
// This is only here so that assertions work in the destructor even if
|
||||
// NoteAddFeatureFailed was called.
|
||||
WorkerPrivate* mWorkerPrivateDEBUG;
|
||||
#endif
|
||||
|
||||
public:
|
||||
explicit
|
||||
WorkerFeature(WorkerPrivate* aWorkerPrivate)
|
||||
: mWorkerPrivate(aWorkerPrivate)
|
||||
#ifdef DEBUG
|
||||
, mWorkerPrivateDEBUG(aWorkerPrivate)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(aWorkerPrivate);
|
||||
aWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
@ -456,11 +464,24 @@ public:
|
|||
|
||||
~WorkerFeature()
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
#ifdef DEBUG
|
||||
mWorkerPrivateDEBUG->AssertIsOnWorkerThread();
|
||||
#endif
|
||||
|
||||
MOZ_COUNT_DTOR(IDBOpenDBRequest::WorkerFeature);
|
||||
|
||||
mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this);
|
||||
if (mWorkerPrivate) {
|
||||
mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NoteAddFeatureFailed()
|
||||
{
|
||||
MOZ_ASSERT(mWorkerPrivate);
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
|
||||
mWorkerPrivate = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -527,6 +548,7 @@ IDBOpenDBRequest::CreateForJS(IDBFactory* aFactory,
|
|||
|
||||
nsAutoPtr<WorkerFeature> feature(new WorkerFeature(workerPrivate));
|
||||
if (NS_WARN_IF(!workerPrivate->AddFeature(cx, feature))) {
|
||||
feature->NoteAddFeatureFailed();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,20 +5,11 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(4237c376-d637-4b6e-9f8a-1da57e867834)]
|
||||
[scriptable, uuid(e0f739e3-47e2-4007-af30-181939e97a51)]
|
||||
interface nsIDOMJSWindow : nsISupports
|
||||
{
|
||||
void dump(in DOMString str);
|
||||
|
||||
/**
|
||||
* These methods take typeless arguments and optional arguments, the
|
||||
* first argument is either a function or a string, the second
|
||||
* argument must be a number (ms) and the rest of the arguments (2
|
||||
* ... n) are passed to the callback function
|
||||
*/
|
||||
long setTimeout();
|
||||
long setInterval();
|
||||
|
||||
/**
|
||||
* These methods take one optional argument that's the timer ID to
|
||||
* clear. Often in existing code these methods are passed undefined,
|
||||
|
|
|
@ -104,13 +104,12 @@ void InitPreferredSampleRate()
|
|||
cubeb* GetCubebContextUnlocked()
|
||||
{
|
||||
sMutex.AssertCurrentThreadOwns();
|
||||
if (!sCubebContext) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (cubeb_init(&sCubebContext, "CubebUtils") != CUBEB_OK) {
|
||||
NS_WARNING("cubeb_init failed");
|
||||
}
|
||||
if (sCubebContext ||
|
||||
cubeb_init(&sCubebContext, "CubebUtils") == CUBEB_OK) {
|
||||
return sCubebContext;
|
||||
}
|
||||
return sCubebContext;
|
||||
NS_WARNING("cubeb_init failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t GetCubebLatency()
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <limits>
|
||||
#include "nsIObserver.h"
|
||||
#include "nsTArray.h"
|
||||
#include "CubebUtils.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "MediaDecoderStateMachine.h"
|
||||
#include "ImageContainer.h"
|
||||
|
@ -402,11 +401,6 @@ bool MediaDecoder::Init(MediaDecoderOwner* aOwner)
|
|||
mOwner = aOwner;
|
||||
mVideoFrameContainer = aOwner->GetVideoFrameContainer();
|
||||
MediaShutdownManager::Instance().Register(this);
|
||||
// We don't use the cubeb context yet, but need to ensure it is created on
|
||||
// the main thread.
|
||||
if (!CubebUtils::GetCubebContext()) {
|
||||
NS_WARNING("Audio backend initialization failed.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -286,6 +286,11 @@ public:
|
|||
|
||||
class EncryptionInfo {
|
||||
public:
|
||||
EncryptionInfo()
|
||||
: mEncrypted(false)
|
||||
{
|
||||
}
|
||||
|
||||
struct InitData {
|
||||
template<typename AInitDatas>
|
||||
InitData(const nsAString& aType, AInitDatas&& aInitData)
|
||||
|
@ -305,22 +310,26 @@ public:
|
|||
// True if the stream has encryption metadata
|
||||
bool IsEncrypted() const
|
||||
{
|
||||
return !mInitDatas.IsEmpty();
|
||||
return mEncrypted;
|
||||
}
|
||||
|
||||
template<typename AInitDatas>
|
||||
void AddInitData(const nsAString& aType, AInitDatas&& aInitData)
|
||||
{
|
||||
mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData)));
|
||||
mEncrypted = true;
|
||||
}
|
||||
|
||||
void AddInitData(const EncryptionInfo& aInfo)
|
||||
{
|
||||
mInitDatas.AppendElements(aInfo.mInitDatas);
|
||||
mEncrypted = !!mInitDatas.Length();
|
||||
}
|
||||
|
||||
// One 'InitData' per encrypted buffer.
|
||||
InitDatas mInitDatas;
|
||||
private:
|
||||
bool mEncrypted;
|
||||
};
|
||||
|
||||
class MediaInfo {
|
||||
|
|
|
@ -31,6 +31,7 @@ using mozilla::dom::CrashReporterParent;
|
|||
using mozilla::ipc::GeckoChildProcessHost;
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsPrintfCString.h"
|
||||
using CrashReporter::AnnotationTable;
|
||||
using CrashReporter::GetIDFromMinidump;
|
||||
#endif
|
||||
|
@ -196,6 +197,11 @@ AbortWaitingForGMPAsyncShutdown(nsITimer* aTimer, void* aClosure)
|
|||
{
|
||||
NS_WARNING("Timed out waiting for GMP async shutdown!");
|
||||
GMPParent* parent = reinterpret_cast<GMPParent*>(aClosure);
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", parent->GetDisplayName().get(), parent),
|
||||
NS_LITERAL_CSTRING("Timed out waiting for async shutdown"));
|
||||
#endif
|
||||
nsRefPtr<GeckoMediaPluginServiceParent> service =
|
||||
GeckoMediaPluginServiceParent::GetSingleton();
|
||||
if (service) {
|
||||
|
@ -239,8 +245,20 @@ GMPParent::RecvPGMPContentChildDestroyed()
|
|||
{
|
||||
--mGMPContentChildCount;
|
||||
if (!IsUsed()) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
NS_LITERAL_CSTRING("Content children destroyed"));
|
||||
#endif
|
||||
CloseIfUnused();
|
||||
}
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
else {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
nsPrintfCString("Content child destroyed, remaining: %u", mGMPContentChildCount));
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -262,9 +280,19 @@ GMPParent::CloseIfUnused()
|
|||
if (mAsyncShutdownRequired) {
|
||||
if (!mAsyncShutdownInProgress) {
|
||||
LOGD("%s: sending async shutdown notification", __FUNCTION__);
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
NS_LITERAL_CSTRING("Sent BeginAsyncShutdown"));
|
||||
#endif
|
||||
mAsyncShutdownInProgress = true;
|
||||
if (!SendBeginAsyncShutdown() ||
|
||||
NS_FAILED(EnsureAsyncShutdownTimeoutSet())) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
NS_LITERAL_CSTRING("Could not send BeginAsyncShutdown - Aborting"));
|
||||
#endif
|
||||
AbortAsyncShutdown();
|
||||
}
|
||||
}
|
||||
|
@ -313,6 +341,11 @@ GMPParent::CloseActive(bool aDieWhenUnloaded)
|
|||
mState = GMPStateUnloading;
|
||||
}
|
||||
if (mState != GMPStateNotLoaded && IsUsed()) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
nsPrintfCString("Sent CloseActive, content children to close: %u", mGMPContentChildCount));
|
||||
#endif
|
||||
unused << SendCloseActive();
|
||||
}
|
||||
}
|
||||
|
@ -568,6 +601,11 @@ GMPParent::ActorDestroy(ActorDestroyReason aWhy)
|
|||
if (AbnormalShutdown == aWhy) {
|
||||
nsRefPtr<GMPParent> self(this);
|
||||
if (mAsyncShutdownRequired) {
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
NS_LITERAL_CSTRING("Actor destroyed"));
|
||||
#endif
|
||||
mService->AsyncShutdownComplete(this);
|
||||
mAsyncShutdownRequired = false;
|
||||
}
|
||||
|
@ -870,6 +908,11 @@ GMPParent::RecvAsyncShutdownComplete()
|
|||
LOGD("%s", __FUNCTION__);
|
||||
|
||||
MOZ_ASSERT(mAsyncShutdownRequired);
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsPrintfCString("AsyncPluginShutdown-%s@%p", GetDisplayName().get(), this),
|
||||
NS_LITERAL_CSTRING("Received AsyncShutdownComplete"));
|
||||
#endif
|
||||
AbortAsyncShutdown();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -316,7 +316,7 @@ SourceBuffer::SourceBuffer(MediaSource* aMediaSource, const nsACString& aType)
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aMediaSource);
|
||||
mEvictionThreshold = Preferences::GetUint("media.mediasource.eviction_threshold",
|
||||
75 * (1 << 20));
|
||||
100 * (1 << 20));
|
||||
mContentManager =
|
||||
SourceBufferContentManager::CreateManager(this,
|
||||
aMediaSource->GetDecoder(),
|
||||
|
@ -581,7 +581,7 @@ SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult&
|
|||
// See if we have enough free space to append our new data.
|
||||
// As we can only evict once we have playable data, we must give a chance
|
||||
// to the DASH player to provide a complete media segment.
|
||||
if (aLength > mEvictionThreshold ||
|
||||
if (aLength > mEvictionThreshold || evicted == Result::BUFFER_FULL ||
|
||||
((!mIsUsingFormatReader &&
|
||||
mContentManager->GetSize() > mEvictionThreshold - aLength) &&
|
||||
evicted != Result::CANT_EVICT)) {
|
||||
|
@ -594,7 +594,6 @@ SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult&
|
|||
aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
// TODO: Test buffer full flag.
|
||||
return data.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
NO_DATA_EVICTED,
|
||||
DATA_EVICTED,
|
||||
CANT_EVICT,
|
||||
BUFFER_FULL,
|
||||
};
|
||||
|
||||
// Evicts data up to aPlaybackTime. aThreshold is used to
|
||||
|
|
|
@ -39,6 +39,34 @@ AppendStateToStr(TrackBuffersManager::AppendState aState)
|
|||
|
||||
static Atomic<uint32_t> sStreamSourceID(0u);
|
||||
|
||||
#ifdef MOZ_EME
|
||||
class DispatchKeyNeededEvent : public nsRunnable {
|
||||
public:
|
||||
DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
|
||||
nsTArray<uint8_t>& aInitData,
|
||||
const nsString& aInitDataType)
|
||||
: mDecoder(aDecoder)
|
||||
, mInitData(aInitData)
|
||||
, mInitDataType(aInitDataType)
|
||||
{
|
||||
}
|
||||
NS_IMETHOD Run() {
|
||||
// Note: Null check the owner, as the decoder could have been shutdown
|
||||
// since this event was dispatched.
|
||||
MediaDecoderOwner* owner = mDecoder->GetOwner();
|
||||
if (owner) {
|
||||
owner->DispatchEncrypted(mInitData, mInitDataType);
|
||||
}
|
||||
mDecoder = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<AbstractMediaDecoder> mDecoder;
|
||||
nsTArray<uint8_t> mInitData;
|
||||
nsString mInitDataType;
|
||||
};
|
||||
#endif // MOZ_EME
|
||||
|
||||
TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType)
|
||||
: mInputBuffer(new MediaByteBuffer)
|
||||
, mAppendState(AppendState::WAITING_FOR_SEGMENT)
|
||||
|
@ -55,6 +83,9 @@ TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSource
|
|||
, mMediaSourceDemuxer(mParentDecoder->GetDemuxer())
|
||||
, mMediaSourceDuration(mTaskQueue, Maybe<double>(), "TrackBuffersManager::mMediaSourceDuration (Mirror)")
|
||||
, mAbort(false)
|
||||
, mEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold",
|
||||
100 * (1 << 20)))
|
||||
, mEvictionOccurred(false)
|
||||
, mMonitor("TrackBuffersManager")
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Must be instanciated on the main thread");
|
||||
|
@ -176,6 +207,11 @@ TrackBuffersManager::EvictData(TimeUnit aPlaybackTime,
|
|||
// Don't bother evicting less than 512KB.
|
||||
return EvictDataResult::CANT_EVICT;
|
||||
}
|
||||
|
||||
if (mBufferFull && mEvictionOccurred) {
|
||||
return EvictDataResult::BUFFER_FULL;
|
||||
}
|
||||
|
||||
MSE_DEBUG("Reaching our size limit, schedule eviction of %lld bytes", toEvict);
|
||||
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
|
@ -345,12 +381,12 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
|||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
|
||||
// Remove any data we've already played, up to 5s behind.
|
||||
TimeUnit lowerLimit = aPlaybackTime - TimeUnit::FromSeconds(5);
|
||||
TimeUnit to;
|
||||
// Video is what takes the most space, only evict there if we have video.
|
||||
const auto& track = HasVideo() ? mVideoTracks : mAudioTracks;
|
||||
const auto& buffer = track.mBuffers.LastElement();
|
||||
// Remove any data we've already played, or before the next sample to be
|
||||
// demuxed whichever is lowest.
|
||||
TimeUnit lowerLimit = std::min(track.mNextSampleTime, aPlaybackTime);
|
||||
uint32_t lastKeyFrameIndex = 0;
|
||||
int64_t toEvict = aSizeToEvict;
|
||||
uint32_t partialEvict = 0;
|
||||
|
@ -369,18 +405,29 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
|||
}
|
||||
partialEvict += sizeof(*frame) + frame->mSize;
|
||||
}
|
||||
|
||||
int64_t finalSize = mSizeSourceBuffer - aSizeToEvict;
|
||||
|
||||
if (lastKeyFrameIndex > 0) {
|
||||
MSE_DEBUG("Step1. Evicting %u bytes prior currentTime",
|
||||
aSizeToEvict - toEvict);
|
||||
CodedFrameRemoval(
|
||||
TimeInterval(TimeUnit::FromMicroseconds(0),
|
||||
TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex-1]->mTime)));
|
||||
TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex]->mTime - 1)));
|
||||
}
|
||||
if (toEvict <= 0) {
|
||||
|
||||
if (mSizeSourceBuffer <= finalSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Still some to remove. Remove data starting from the end, up to 5s ahead
|
||||
// of our playtime.
|
||||
TimeUnit upperLimit = aPlaybackTime + TimeUnit::FromSeconds(5);
|
||||
toEvict = mSizeSourceBuffer - finalSize;
|
||||
|
||||
// Still some to remove. Remove data starting from the end, up to 30s ahead
|
||||
// of the later of the playback time or the next sample to be demuxed.
|
||||
// 30s is a value chosen as it appears to work with YouTube.
|
||||
TimeUnit upperLimit =
|
||||
std::max(aPlaybackTime, track.mNextSampleTime) + TimeUnit::FromSeconds(30);
|
||||
lastKeyFrameIndex = buffer.Length();
|
||||
for (int32_t i = buffer.Length() - 1; i >= 0; i--) {
|
||||
const auto& frame = buffer[i];
|
||||
if (frame->mKeyframe) {
|
||||
|
@ -396,9 +443,11 @@ TrackBuffersManager::DoEvictData(const TimeUnit& aPlaybackTime,
|
|||
}
|
||||
partialEvict += sizeof(*frame) + frame->mSize;
|
||||
}
|
||||
if (lastKeyFrameIndex + 1 < buffer.Length()) {
|
||||
if (lastKeyFrameIndex < buffer.Length()) {
|
||||
MSE_DEBUG("Step2. Evicting %u bytes from trailing data",
|
||||
mSizeSourceBuffer - finalSize);
|
||||
CodedFrameRemoval(
|
||||
TimeInterval(TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex+1]->mTime),
|
||||
TimeInterval(TimeUnit::FromMicroseconds(buffer[lastKeyFrameIndex]->GetEndTime() + 1),
|
||||
TimeUnit::FromInfinity()));
|
||||
}
|
||||
}
|
||||
|
@ -559,9 +608,7 @@ TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval)
|
|||
// This will be done by the MDSM during playback.
|
||||
// TODO properly, so it works even if paused.
|
||||
}
|
||||
// 4. If buffer full flag equals true and this object is ready to accept more bytes, then set the buffer full flag to false.
|
||||
// TODO.
|
||||
mBufferFull = false;
|
||||
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mVideoBufferedRanges = mVideoTracks.mBufferedRanges;
|
||||
|
@ -580,6 +627,12 @@ TrackBuffersManager::CodedFrameRemoval(TimeInterval aInterval)
|
|||
// Update our reported total size.
|
||||
mSizeSourceBuffer = mVideoTracks.mSizeBuffer + mAudioTracks.mSizeBuffer;
|
||||
|
||||
// 4. If buffer full flag equals true and this object is ready to accept more bytes, then set the buffer full flag to false.
|
||||
if (mBufferFull && mSizeSourceBuffer < mEvictionThreshold) {
|
||||
mBufferFull = false;
|
||||
}
|
||||
mEvictionOccurred = true;
|
||||
|
||||
// Tell our demuxer that data was removed.
|
||||
mMediaSourceDemuxer->NotifyTimeRangesChanged();
|
||||
|
||||
|
@ -953,17 +1006,19 @@ TrackBuffersManager::OnDemuxerInitDone(nsresult)
|
|||
mVideoTracks.mLastInfo = new SharedTrackInfo(info.mVideo, streamID);
|
||||
}
|
||||
|
||||
// TODO CHECK ENCRYPTION
|
||||
UniquePtr<EncryptionInfo> crypto = mInputDemuxer->GetCrypto();
|
||||
if (crypto && crypto->IsEncrypted()) {
|
||||
#ifdef MOZ_EME
|
||||
// Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
|
||||
for (uint32_t i = 0; i < crypto->mInitDatas.Length(); i++) {
|
||||
// NS_DispatchToMainThread(
|
||||
// new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
|
||||
NS_DispatchToMainThread(
|
||||
new DispatchKeyNeededEvent(mParentDecoder, crypto->mInitDatas[i].mInitData, NS_LITERAL_STRING("cenc")));
|
||||
}
|
||||
#endif // MOZ_EME
|
||||
info.mCrypto = *crypto;
|
||||
// We clear our crypto init data array, so the MediaFormatReader will
|
||||
// not emit an encrypted event for the same init data again.
|
||||
info.mCrypto.mInitDatas.Clear();
|
||||
mEncrypted = true;
|
||||
}
|
||||
|
||||
|
@ -1180,8 +1235,10 @@ TrackBuffersManager::CompleteCodedFrameProcessing()
|
|||
|
||||
// Return to step 6.4 of Segment Parser Loop algorithm
|
||||
// 4. If this SourceBuffer is full and cannot accept more media data, then set the buffer full flag to true.
|
||||
// TODO
|
||||
mBufferFull = false;
|
||||
if (mSizeSourceBuffer >= mEvictionThreshold) {
|
||||
mBufferFull = true;
|
||||
mEvictionOccurred = false;
|
||||
}
|
||||
|
||||
// 5. If the input buffer does not contain a complete media segment, then jump to the need more data step below.
|
||||
if (mParser->MediaSegmentRange().IsNull()) {
|
||||
|
@ -1360,78 +1417,84 @@ TrackBuffersManager::ProcessFrame(MediaRawData* aSample,
|
|||
Maybe<uint32_t> firstRemovedIndex;
|
||||
TimeInterval removedInterval;
|
||||
TrackBuffer& data = trackBuffer.mBuffers.LastElement();
|
||||
if (trackBuffer.mBufferedRanges.ContainsStrict(presentationTimestamp)) {
|
||||
bool removeCodedFrames =
|
||||
trackBuffer.mHighestEndTimestamp.isSome()
|
||||
? trackBuffer.mHighestEndTimestamp.ref() <= presentationTimestamp
|
||||
: true;
|
||||
if (removeCodedFrames) {
|
||||
TimeUnit lowerBound =
|
||||
trackBuffer.mHighestEndTimestamp.valueOr(presentationTimestamp);
|
||||
for (uint32_t i = 0; i < data.Length();) {
|
||||
MediaRawData* sample = data[i].get();
|
||||
if (sample->mTime >= lowerBound.ToMicroseconds() &&
|
||||
sample->mTime < frameEndTimestamp.ToMicroseconds()) {
|
||||
if (firstRemovedIndex.isNothing()) {
|
||||
removedInterval =
|
||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime()));
|
||||
firstRemovedIndex = Some(i);
|
||||
} else {
|
||||
removedInterval = removedInterval.Span(
|
||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime())));
|
||||
}
|
||||
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
|
||||
MSE_DEBUGV("Overlapping frame:%u ([%f, %f))",
|
||||
i,
|
||||
TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime()).ToSeconds());
|
||||
data.RemoveElementAt(i);
|
||||
|
||||
if (trackBuffer.mNextGetSampleIndex.isSome()) {
|
||||
if (trackBuffer.mNextGetSampleIndex.ref() == i) {
|
||||
MSE_DEBUG("Next sample to be played got evicted");
|
||||
trackBuffer.mNextGetSampleIndex.reset();
|
||||
} else if (trackBuffer.mNextGetSampleIndex.ref() > i) {
|
||||
trackBuffer.mNextGetSampleIndex.ref()--;
|
||||
if (trackBuffer.mBufferedRanges.ContainsStrict(lowerBound)) {
|
||||
for (uint32_t i = 0; i < data.Length();) {
|
||||
MediaRawData* sample = data[i].get();
|
||||
if (sample->mTime >= lowerBound.ToMicroseconds() &&
|
||||
sample->mTime < frameEndTimestamp.ToMicroseconds()) {
|
||||
if (firstRemovedIndex.isNothing()) {
|
||||
removedInterval =
|
||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime()));
|
||||
firstRemovedIndex = Some(i);
|
||||
} else {
|
||||
removedInterval = removedInterval.Span(
|
||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime())));
|
||||
}
|
||||
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
|
||||
MSE_DEBUGV("Overlapping frame:%u ([%f, %f))",
|
||||
i,
|
||||
TimeUnit::FromMicroseconds(sample->mTime).ToSeconds(),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime()).ToSeconds());
|
||||
data.RemoveElementAt(i);
|
||||
|
||||
if (trackBuffer.mNextGetSampleIndex.isSome()) {
|
||||
if (trackBuffer.mNextGetSampleIndex.ref() == i) {
|
||||
MSE_DEBUG("Next sample to be played got evicted");
|
||||
trackBuffer.mNextGetSampleIndex.reset();
|
||||
} else if (trackBuffer.mNextGetSampleIndex.ref() > i) {
|
||||
trackBuffer.mNextGetSampleIndex.ref()--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 15. Remove decoding dependencies of the coded frames removed in the previous step:
|
||||
// Remove all coded frames between the coded frames removed in the previous step and the next random access point after those removed frames.
|
||||
if (firstRemovedIndex.isSome()) {
|
||||
uint32_t start = firstRemovedIndex.ref();
|
||||
uint32_t end = start;
|
||||
for (;end < data.Length(); end++) {
|
||||
MediaRawData* sample = data[end].get();
|
||||
if (sample->mKeyframe) {
|
||||
break;
|
||||
// 15. Remove decoding dependencies of the coded frames removed in the previous step:
|
||||
// Remove all coded frames between the coded frames removed in the previous step and the next random access point after those removed frames.
|
||||
if (firstRemovedIndex.isSome()) {
|
||||
uint32_t start = firstRemovedIndex.ref();
|
||||
uint32_t end = start;
|
||||
for (;end < data.Length(); end++) {
|
||||
MediaRawData* sample = data[end].get();
|
||||
if (sample->mKeyframe) {
|
||||
break;
|
||||
}
|
||||
removedInterval = removedInterval.Span(
|
||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime())));
|
||||
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
|
||||
}
|
||||
removedInterval = removedInterval.Span(
|
||||
TimeInterval(TimeUnit::FromMicroseconds(sample->mTime),
|
||||
TimeUnit::FromMicroseconds(sample->GetEndTime())));
|
||||
trackBuffer.mSizeBuffer -= sizeof(*sample) + sample->mSize;
|
||||
}
|
||||
data.RemoveElementsAt(start, end - start);
|
||||
data.RemoveElementsAt(start, end - start);
|
||||
|
||||
MSE_DEBUG("Removing undecodable frames from:%u (frames:%u) ([%f, %f))",
|
||||
start, end - start,
|
||||
removedInterval.mStart.ToSeconds(), removedInterval.mEnd.ToSeconds());
|
||||
MSE_DEBUG("Removing undecodable frames from:%u (frames:%u) ([%f, %f))",
|
||||
start, end - start,
|
||||
removedInterval.mStart.ToSeconds(), removedInterval.mEnd.ToSeconds());
|
||||
|
||||
if (trackBuffer.mNextGetSampleIndex.isSome()) {
|
||||
if (trackBuffer.mNextGetSampleIndex.ref() >= start &&
|
||||
trackBuffer.mNextGetSampleIndex.ref() < end) {
|
||||
MSE_DEBUG("Next sample to be played got evicted");
|
||||
trackBuffer.mNextGetSampleIndex.reset();
|
||||
} else if (trackBuffer.mNextGetSampleIndex.ref() >= end) {
|
||||
trackBuffer.mNextGetSampleIndex.ref() -= end - start;
|
||||
if (trackBuffer.mNextGetSampleIndex.isSome()) {
|
||||
if (trackBuffer.mNextGetSampleIndex.ref() >= start &&
|
||||
trackBuffer.mNextGetSampleIndex.ref() < end) {
|
||||
MSE_DEBUG("Next sample to be played got evicted");
|
||||
trackBuffer.mNextGetSampleIndex.reset();
|
||||
} else if (trackBuffer.mNextGetSampleIndex.ref() >= end) {
|
||||
trackBuffer.mNextGetSampleIndex.ref() -= end - start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update our buffered range to exclude the range just removed.
|
||||
trackBuffer.mBufferedRanges -= removedInterval;
|
||||
MOZ_ASSERT(trackBuffer.mNextInsertionIndex.isNothing() ||
|
||||
trackBuffer.mNextInsertionIndex.ref() <= start);
|
||||
// Update our buffered range to exclude the range just removed.
|
||||
trackBuffer.mBufferedRanges -= removedInterval;
|
||||
MOZ_ASSERT(trackBuffer.mNextInsertionIndex.isNothing() ||
|
||||
trackBuffer.mNextInsertionIndex.ref() <= start);
|
||||
}
|
||||
}
|
||||
|
||||
// 16. Add the coded frame with the presentation timestamp, decode timestamp, and frame duration to the track buffer.
|
||||
|
@ -1564,11 +1627,11 @@ TrackBuffersManager::RestoreCachedVariables()
|
|||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
if (mTimestampOffset != mLastTimestampOffset) {
|
||||
nsRefPtr<TrackBuffersManager> self = this;
|
||||
nsCOMPtr<nsIRunnable> task =
|
||||
NS_NewRunnableMethodWithArg<TimeUnit>(
|
||||
mParent.get(),
|
||||
static_cast<void (dom::SourceBuffer::*)(const TimeUnit&)>(&dom::SourceBuffer::SetTimestampOffset), /* beauty uh? :) */
|
||||
mTimestampOffset);
|
||||
NS_NewRunnableFunction([self] {
|
||||
self->mParent->SetTimestampOffset(self->mTimestampOffset);
|
||||
});
|
||||
AbstractThread::MainThread()->Dispatch(task.forget());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -310,6 +310,8 @@ private:
|
|||
|
||||
// Global size of this source buffer content.
|
||||
Atomic<int64_t> mSizeSourceBuffer;
|
||||
uint32_t mEvictionThreshold;
|
||||
Atomic<bool> mEvictionOccurred;
|
||||
|
||||
// Monitor to protect following objects accessed across multipple threads.
|
||||
mutable Monitor mMonitor;
|
||||
|
|
|
@ -110,11 +110,6 @@ AudioContext::AudioContext(nsPIDOMWindow* aWindow,
|
|||
// call them after mDestination has been set up.
|
||||
mDestination->CreateAudioChannelAgent();
|
||||
mDestination->SetIsOnlyNodeForContext(true);
|
||||
// We don't use the cubeb context yet, but need to ensure it is created on
|
||||
// the main thread.
|
||||
if (!aIsOffline && !CubebUtils::GetCubebContext()) {
|
||||
NS_WARNING("Audio backend initialization failed.");
|
||||
}
|
||||
}
|
||||
|
||||
AudioContext::~AudioContext()
|
||||
|
|
|
@ -771,8 +771,11 @@ DOMStorageCache::StartDatabase()
|
|||
|
||||
sDatabase = db.forget();
|
||||
} else {
|
||||
// Use DOMLocalStorageManager::Ensure in case we're called from
|
||||
// DOMSessionStorageManager's initializer and we haven't yet initialized the
|
||||
// local storage manager.
|
||||
nsRefPtr<DOMStorageDBChild> db = new DOMStorageDBChild(
|
||||
DOMLocalStorageManager::Self());
|
||||
DOMLocalStorageManager::Ensure());
|
||||
|
||||
nsresult rv = db->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -628,6 +628,21 @@ DOMLocalStorageManager::~DOMLocalStorageManager()
|
|||
sSelf = nullptr;
|
||||
}
|
||||
|
||||
DOMLocalStorageManager*
|
||||
DOMLocalStorageManager::Ensure()
|
||||
{
|
||||
if (sSelf) {
|
||||
return sSelf;
|
||||
}
|
||||
|
||||
// Cause sSelf to be populated.
|
||||
nsCOMPtr<nsIDOMStorageManager> initializer =
|
||||
do_GetService("@mozilla.org/dom/localStorage-manager;1");
|
||||
MOZ_ASSERT(sSelf, "Didn't initialize?");
|
||||
|
||||
return sSelf;
|
||||
}
|
||||
|
||||
// DOMSessionStorageManager
|
||||
|
||||
DOMSessionStorageManager::DOMSessionStorageManager()
|
||||
|
|
|
@ -126,6 +126,9 @@ public:
|
|||
// Global getter of localStorage manager service
|
||||
static DOMLocalStorageManager* Self() { return sSelf; }
|
||||
|
||||
// Like Self, but creates an instance if we're not yet initialized.
|
||||
static DOMLocalStorageManager* Ensure();
|
||||
|
||||
private:
|
||||
static DOMLocalStorageManager* sSelf;
|
||||
};
|
||||
|
|
|
@ -379,6 +379,7 @@ NS_INTERFACE_MAP_END
|
|||
|
||||
ServiceWorkerManager::ServiceWorkerManager()
|
||||
: mActor(nullptr)
|
||||
, mShuttingDown(false)
|
||||
{
|
||||
// Register this component to PBackground.
|
||||
MOZ_ALWAYS_TRUE(BackgroundChild::GetOrCreateForCurrentThread(this));
|
||||
|
@ -388,19 +389,19 @@ ServiceWorkerManager::~ServiceWorkerManager()
|
|||
{
|
||||
// The map will assert if it is not empty when destroyed.
|
||||
mRegistrationInfos.Clear();
|
||||
|
||||
if (mActor) {
|
||||
mActor->ManagerShuttingDown();
|
||||
|
||||
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
MOZ_ASSERT(!mActor);
|
||||
}
|
||||
|
||||
void
|
||||
ServiceWorkerManager::Init()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
DebugOnly<nsresult> rv;
|
||||
rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
nsRefPtr<ServiceWorkerRegistrar> swr = ServiceWorkerRegistrar::Get();
|
||||
MOZ_ASSERT(swr);
|
||||
|
@ -409,11 +410,8 @@ ServiceWorkerManager::Init()
|
|||
swr->GetRegistrations(data);
|
||||
LoadRegistrations(data);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
DebugOnly<nsresult> rv;
|
||||
rv = obs->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = obs->AddObserver(this, PURGE_SESSION_HISTORY, false /* ownsWeak */);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
rv = obs->AddObserver(this, PURGE_DOMAIN_DATA, false /* ownsWeak */);
|
||||
|
@ -872,6 +870,7 @@ class ServiceWorkerRegisterJob final : public ServiceWorkerJob,
|
|||
nsRefPtr<ServiceWorkerUpdateFinishCallback> mCallback;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsRefPtr<ServiceWorkerInfo> mUpdateAndInstallInfo;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
|
||||
~ServiceWorkerRegisterJob()
|
||||
{ }
|
||||
|
@ -892,15 +891,19 @@ public:
|
|||
const nsCString& aScope,
|
||||
const nsCString& aScriptSpec,
|
||||
ServiceWorkerUpdateFinishCallback* aCallback,
|
||||
nsIPrincipal* aPrincipal)
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsILoadGroup* aLoadGroup)
|
||||
: ServiceWorkerJob(aQueue)
|
||||
, mScope(aScope)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
, mCallback(aCallback)
|
||||
, mPrincipal(aPrincipal)
|
||||
, mLoadGroup(aLoadGroup)
|
||||
, mJobType(REGISTER_JOB)
|
||||
, mCanceled(false)
|
||||
{ }
|
||||
{
|
||||
MOZ_ASSERT(mLoadGroup);
|
||||
}
|
||||
|
||||
// [[Update]]
|
||||
ServiceWorkerRegisterJob(ServiceWorkerJobQueue* aQueue,
|
||||
|
@ -1230,7 +1233,7 @@ private:
|
|||
nsresult rv =
|
||||
serviceWorkerScriptCache::Compare(mRegistration->mPrincipal, cacheName,
|
||||
NS_ConvertUTF8toUTF16(mRegistration->mScriptSpec),
|
||||
this);
|
||||
this, mLoadGroup);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return Fail(rv);
|
||||
}
|
||||
|
@ -1534,8 +1537,20 @@ ServiceWorkerManager::Register(nsIDOMWindow* aWindow,
|
|||
nsRefPtr<ServiceWorkerResolveWindowPromiseOnUpdateCallback> cb =
|
||||
new ServiceWorkerResolveWindowPromiseOnUpdateCallback(window, promise);
|
||||
|
||||
nsCOMPtr<nsILoadGroup> docLoadGroup = doc->GetDocumentLoadGroup();
|
||||
nsRefPtr<WorkerLoadInfo::InterfaceRequestor> ir =
|
||||
new WorkerLoadInfo::InterfaceRequestor(documentPrincipal, docLoadGroup);
|
||||
ir->MaybeAddTabChild(docLoadGroup);
|
||||
|
||||
// Create a load group that is separate from, yet related to, the document's load group.
|
||||
// This allows checks for interfaces like nsILoadContext to yield the values used by the
|
||||
// the document, yet will not cancel the update job if the document's load group is cancelled.
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
|
||||
rv = loadGroup->SetNotificationCallbacks(ir);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
nsRefPtr<ServiceWorkerRegisterJob> job =
|
||||
new ServiceWorkerRegisterJob(queue, cleanedScope, spec, cb, documentPrincipal);
|
||||
new ServiceWorkerRegisterJob(queue, cleanedScope, spec, cb, documentPrincipal, loadGroup);
|
||||
queue->Append(job);
|
||||
|
||||
AssertIsOnMainThread();
|
||||
|
@ -1553,9 +1568,11 @@ ServiceWorkerManager::AppendPendingOperation(ServiceWorkerJobQueue* aQueue,
|
|||
MOZ_ASSERT(aQueue);
|
||||
MOZ_ASSERT(aJob);
|
||||
|
||||
PendingOperation* opt = mPendingOperations.AppendElement();
|
||||
opt->mQueue = aQueue;
|
||||
opt->mJob = aJob;
|
||||
if (!mShuttingDown) {
|
||||
PendingOperation* opt = mPendingOperations.AppendElement();
|
||||
opt->mQueue = aQueue;
|
||||
opt->mJob = aJob;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1564,8 +1581,10 @@ ServiceWorkerManager::AppendPendingOperation(nsIRunnable* aRunnable)
|
|||
MOZ_ASSERT(!mActor);
|
||||
MOZ_ASSERT(aRunnable);
|
||||
|
||||
PendingOperation* opt = mPendingOperations.AppendElement();
|
||||
opt->mRunnable = aRunnable;
|
||||
if (!mShuttingDown) {
|
||||
PendingOperation* opt = mPendingOperations.AppendElement();
|
||||
opt->mRunnable = aRunnable;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2383,8 +2402,10 @@ private:
|
|||
|
||||
nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
|
||||
MOZ_ASSERT(swm->mActor);
|
||||
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope));
|
||||
// Could it be that we are shutting down.
|
||||
if (swm->mActor) {
|
||||
swm->mActor->SendUnregister(principalInfo, NS_ConvertUTF8toUTF16(mScope));
|
||||
}
|
||||
|
||||
nsAutoCString scopeKey;
|
||||
nsresult rv = swm->PrincipalToScopeKey(mPrincipal, scopeKey);
|
||||
|
@ -2735,10 +2756,15 @@ ServiceWorkerManager::StoreRegistration(
|
|||
nsIPrincipal* aPrincipal,
|
||||
ServiceWorkerRegistrationInfo* aRegistration)
|
||||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
MOZ_ASSERT(aRegistration);
|
||||
|
||||
if (mShuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
ServiceWorkerRegistrationData data;
|
||||
nsresult rv = PopulateRegistrationData(aPrincipal, aRegistration, data);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -4064,6 +4090,10 @@ ServiceWorkerManager::RemoveRegistrationInternal(ServiceWorkerRegistrationInfo*
|
|||
MOZ_ASSERT(aRegistration);
|
||||
MOZ_ASSERT(!aRegistration->IsControllingDocuments());
|
||||
|
||||
if (mShuttingDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
// All callers should be either from a job in which case the actor is
|
||||
// available, or from MaybeStopControlling(), in which case, this will only be
|
||||
// called if a valid registration is found. If a valid registration exists,
|
||||
|
@ -4497,21 +4527,22 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
|
|||
const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
|
||||
if (strcmp(aTopic, PURGE_SESSION_HISTORY) == 0) {
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
RemoveAll();
|
||||
PropagateRemoveAll();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (strcmp(aTopic, PURGE_DOMAIN_DATA) == 0) {
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
nsAutoString domain(aData);
|
||||
RemoveAndPropagate(NS_ConvertUTF16toUTF8(domain));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (strcmp(aTopic, WEBAPPS_CLEAR_DATA) == 0) {
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
|
||||
do_QueryInterface(aSubject);
|
||||
if (NS_WARN_IF(!params)) {
|
||||
|
@ -4541,18 +4572,35 @@ ServiceWorkerManager::Observe(nsISupports* aSubject,
|
|||
}
|
||||
|
||||
RemoveAllRegistrations(principal);
|
||||
} else if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
mShuttingDown = true;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
obs->RemoveObserver(this, PURGE_SESSION_HISTORY);
|
||||
obs->RemoveObserver(this, PURGE_DOMAIN_DATA);
|
||||
obs->RemoveObserver(this, WEBAPPS_CLEAR_DATA);
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
obs->RemoveObserver(this, PURGE_SESSION_HISTORY);
|
||||
obs->RemoveObserver(this, PURGE_DOMAIN_DATA);
|
||||
obs->RemoveObserver(this, WEBAPPS_CLEAR_DATA);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MOZ_CRASH("Received message we aren't supposed to be registered for!");
|
||||
|
||||
if (mActor) {
|
||||
mActor->ManagerShuttingDown();
|
||||
|
||||
nsRefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
|
||||
nsresult rv = NS_DispatchToMainThread(runnable);
|
||||
unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
mActor = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_CRASH("Received message we aren't supposed to be registered for!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -552,6 +552,8 @@ private:
|
|||
|
||||
struct PendingOperation;
|
||||
nsTArray<PendingOperation> mPendingOperations;
|
||||
|
||||
bool mShuttingDown;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
}
|
||||
|
||||
nsresult
|
||||
Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL)
|
||||
Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL, nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
AssertIsOnMainThread();
|
||||
|
@ -91,7 +91,8 @@ public:
|
|||
rv = NS_NewChannel(getter_AddRefs(mChannel),
|
||||
uri, aPrincipal,
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
nsIContentPolicy::TYPE_SCRIPT); // FIXME(nsm): TYPE_SERVICEWORKER
|
||||
nsIContentPolicy::TYPE_SCRIPT, // FIXME(nsm): TYPE_SERVICEWORKER
|
||||
aLoadGroup);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -280,7 +281,7 @@ public:
|
|||
|
||||
nsresult
|
||||
Initialize(nsIPrincipal* aPrincipal, const nsAString& aURL,
|
||||
const nsAString& aCacheName)
|
||||
const nsAString& aCacheName, nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
@ -297,7 +298,7 @@ public:
|
|||
}
|
||||
|
||||
mCN = new CompareNetwork(this);
|
||||
nsresult rv = mCN->Initialize(aPrincipal, aURL);
|
||||
nsresult rv = mCN->Initialize(aPrincipal, aURL, aLoadGroup);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -936,7 +937,8 @@ GenerateCacheName(nsAString& aName)
|
|||
|
||||
nsresult
|
||||
Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName,
|
||||
const nsAString& aURL, CompareCallback* aCallback)
|
||||
const nsAString& aURL, CompareCallback* aCallback,
|
||||
nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
@ -945,7 +947,7 @@ Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName,
|
|||
|
||||
nsRefPtr<CompareManager> cm = new CompareManager(aCallback);
|
||||
|
||||
nsresult rv = cm->Initialize(aPrincipal, aURL, aCacheName);
|
||||
nsresult rv = cm->Initialize(aPrincipal, aURL, aCacheName, aLoadGroup);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
nsresult
|
||||
Compare(nsIPrincipal* aPrincipal, const nsAString& aCacheName,
|
||||
const nsAString& aURL, CompareCallback* aCallback);
|
||||
const nsAString& aURL, CompareCallback* aCallback, nsILoadGroup* aLoadGroup);
|
||||
|
||||
} // serviceWorkerScriptCache namespace
|
||||
|
||||
|
|
|
@ -5962,11 +5962,13 @@ WorkerPrivate::AddFeature(JSContext* aCx, WorkerFeature* aFeature)
|
|||
}
|
||||
|
||||
MOZ_ASSERT(!mFeatures.Contains(aFeature), "Already know about this one!");
|
||||
mFeatures.AppendElement(aFeature);
|
||||
|
||||
return mFeatures.Length() == 1 ?
|
||||
ModifyBusyCountFromWorker(aCx, true) :
|
||||
true;
|
||||
if (mFeatures.IsEmpty() && !ModifyBusyCountFromWorker(aCx, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mFeatures.AppendElement(aFeature);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -70,4 +70,6 @@ LOCAL_INCLUDES += [
|
|||
'/layout/xul',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
|
@ -59,6 +59,8 @@
|
|||
#include "nsIBidiKeyboard.h" // for nsIBidiKeyboard
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
|
||||
class nsPresContext;
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -985,6 +987,14 @@ nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
|
|||
return true;
|
||||
}
|
||||
|
||||
// If the source node is a remote browser, treat this as coming from a
|
||||
// different document and allow the drop.
|
||||
nsCOMPtr<nsIContent> sourceContent = do_QueryInterface(sourceNode);
|
||||
TabParent* tp = TabParent::GetFrom(sourceContent);
|
||||
if (tp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<Selection> selection = mEditor->GetSelection();
|
||||
if (!selection) {
|
||||
return false;
|
||||
|
|
Двоичные данные
embedding/tests/winEmbed/SMALL.ICO
Двоичные данные
embedding/tests/winEmbed/SMALL.ICO
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 318 B |
|
@ -1,591 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: Mozilla-sample-code 1.0
|
||||
*
|
||||
* Copyright (c) 2002 Netscape Communications Corporation and
|
||||
* other contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this Mozilla sample software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Local includes
|
||||
#include "resource.h"
|
||||
#include "winEmbed.h"
|
||||
#include "WebBrowserChrome.h"
|
||||
|
||||
// OS headers
|
||||
#include <stdio.h>
|
||||
|
||||
// Frozen APIs
|
||||
|
||||
#include "nsStringAPI.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsCWebBrowser.h"
|
||||
|
||||
// Glue APIs (not frozen, but safe to use because they are statically linked)
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
// NON-FROZEN APIS!
|
||||
#include "nsIWebNavigation.h"
|
||||
|
||||
WebBrowserChrome::WebBrowserChrome()
|
||||
{
|
||||
mNativeWindow = nullptr;
|
||||
mSizeSet = false;
|
||||
}
|
||||
|
||||
WebBrowserChrome::~WebBrowserChrome()
|
||||
{
|
||||
WebBrowserChromeUI::Destroyed(this);
|
||||
}
|
||||
|
||||
nsresult WebBrowserChrome::CreateBrowser(int32_t aX, int32_t aY,
|
||||
int32_t aCX, int32_t aCY,
|
||||
nsIWebBrowser **aBrowser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aBrowser);
|
||||
*aBrowser = nullptr;
|
||||
|
||||
mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
|
||||
|
||||
if (!mWebBrowser)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
(void)mWebBrowser->SetContainerWindow(static_cast<nsIWebBrowserChrome*>(this));
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> browserBaseWindow = do_QueryInterface(mWebBrowser);
|
||||
|
||||
mNativeWindow = WebBrowserChromeUI::CreateNativeWindow(static_cast<nsIWebBrowserChrome*>(this));
|
||||
|
||||
if (!mNativeWindow)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
browserBaseWindow->InitWindow( mNativeWindow,
|
||||
nullptr,
|
||||
aX, aY, aCX, aCY);
|
||||
browserBaseWindow->Create();
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> listener(static_cast<nsIWebProgressListener*>(this));
|
||||
nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener));
|
||||
(void)mWebBrowser->AddWebBrowserListener(thisListener,
|
||||
NS_GET_IID(nsIWebProgressListener));
|
||||
|
||||
// The window has been created. Now register for history notifications
|
||||
mWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsISHistoryListener));
|
||||
|
||||
if (mWebBrowser)
|
||||
{
|
||||
*aBrowser = mWebBrowser;
|
||||
NS_ADDREF(*aBrowser);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsISupports
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ADDREF(WebBrowserChrome)
|
||||
NS_IMPL_RELEASE(WebBrowserChrome)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(WebBrowserChrome)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) // optional
|
||||
NS_INTERFACE_MAP_ENTRY(nsISHistoryListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIContextMenuListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITooltipListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIInterfaceRequestor
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::GetInterface(const nsIID &aIID, void** aInstancePtr)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtr);
|
||||
|
||||
*aInstancePtr = 0;
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMWindow)))
|
||||
{
|
||||
if (mWebBrowser)
|
||||
{
|
||||
return mWebBrowser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr);
|
||||
}
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIWebBrowserChrome
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::SetStatus(uint32_t aType, const char16_t* aStatus)
|
||||
{
|
||||
WebBrowserChromeUI::UpdateStatusBarText(this, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::GetWebBrowser(nsIWebBrowser** aWebBrowser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWebBrowser);
|
||||
*aWebBrowser = mWebBrowser;
|
||||
NS_IF_ADDREF(*aWebBrowser);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::SetWebBrowser(nsIWebBrowser* aWebBrowser)
|
||||
{
|
||||
mWebBrowser = aWebBrowser;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::GetChromeFlags(uint32_t* aChromeMask)
|
||||
{
|
||||
*aChromeMask = mChromeFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::SetChromeFlags(uint32_t aChromeMask)
|
||||
{
|
||||
mChromeFlags = aChromeMask;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::DestroyBrowserWindow(void)
|
||||
{
|
||||
WebBrowserChromeUI::Destroy(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// IN: The desired browser client area dimensions.
|
||||
NS_IMETHODIMP WebBrowserChrome::SizeBrowserTo(int32_t aWidth, int32_t aHeight)
|
||||
{
|
||||
/* This isn't exactly correct: we're setting the whole window to
|
||||
the size requested for the browser. At time of writing, though,
|
||||
it's fine and useful for winEmbed's purposes. */
|
||||
WebBrowserChromeUI::SizeTo(this, aWidth, aHeight);
|
||||
mSizeSet = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::ShowAsModal(void)
|
||||
{
|
||||
if (mDependentParent)
|
||||
AppCallbacks::EnableChromeWindow(mDependentParent, false);
|
||||
|
||||
mContinueModalLoop = true;
|
||||
AppCallbacks::RunEventLoop(mContinueModalLoop);
|
||||
|
||||
if (mDependentParent)
|
||||
AppCallbacks::EnableChromeWindow(mDependentParent, true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::IsWindowModal(bool *_retval)
|
||||
{
|
||||
*_retval = false;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::ExitModalEventLoop(nsresult aStatus)
|
||||
{
|
||||
mContinueModalLoop = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIWebBrowserChromeFocus
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::FocusNextElement()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::FocusPrevElement()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIWebProgressListener
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::OnProgressChange(nsIWebProgress *progress, nsIRequest *request,
|
||||
int32_t curSelfProgress, int32_t maxSelfProgress,
|
||||
int32_t curTotalProgress, int32_t maxTotalProgress)
|
||||
{
|
||||
WebBrowserChromeUI::UpdateProgress(this, curTotalProgress, maxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::OnStateChange(nsIWebProgress *progress, nsIRequest *request,
|
||||
uint32_t progressStateFlags, nsresult status)
|
||||
{
|
||||
if ((progressStateFlags & STATE_START) && (progressStateFlags & STATE_IS_DOCUMENT))
|
||||
{
|
||||
WebBrowserChromeUI::UpdateBusyState(this, true);
|
||||
}
|
||||
|
||||
if ((progressStateFlags & STATE_STOP) && (progressStateFlags & STATE_IS_DOCUMENT))
|
||||
{
|
||||
WebBrowserChromeUI::UpdateBusyState(this, false);
|
||||
WebBrowserChromeUI::UpdateProgress(this, 0, 100);
|
||||
WebBrowserChromeUI::UpdateStatusBarText(this, nullptr);
|
||||
ContentFinishedLoading();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsIURI *location,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
bool isSubFrameLoad = false; // Is this a subframe load
|
||||
if (aWebProgress) {
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
nsCOMPtr<nsIDOMWindow> topDomWindow;
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
|
||||
if (domWindow) { // Get root domWindow
|
||||
domWindow->GetTop(getter_AddRefs(topDomWindow));
|
||||
}
|
||||
if (domWindow != topDomWindow)
|
||||
isSubFrameLoad = true;
|
||||
}
|
||||
if (!isSubFrameLoad)
|
||||
WebBrowserChromeUI::UpdateCurrentURI(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnStatusChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const char16_t* aMessage)
|
||||
{
|
||||
WebBrowserChromeUI::UpdateStatusBarText(this, aMessage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnSecurityChange(nsIWebProgress *aWebProgress,
|
||||
nsIRequest *aRequest,
|
||||
uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsISHistoryListener
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryNewEntry(nsIURI * aNewURI)
|
||||
{
|
||||
return SendHistoryStatusMessage(aNewURI, "add");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryGoBack(nsIURI * aBackURI, bool * aContinue)
|
||||
{
|
||||
// For now, let the operation continue
|
||||
*aContinue = true;
|
||||
return SendHistoryStatusMessage(aBackURI, "back");
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryGoForward(nsIURI * aForwardURI, bool * aContinue)
|
||||
{
|
||||
// For now, let the operation continue
|
||||
*aContinue = true;
|
||||
return SendHistoryStatusMessage(aForwardURI, "forward");
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryGotoIndex(int32_t aIndex, nsIURI * aGotoURI, bool * aContinue)
|
||||
{
|
||||
// For now, let the operation continue
|
||||
*aContinue = true;
|
||||
return SendHistoryStatusMessage(aGotoURI, "goto", aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryReload(nsIURI * aURI, uint32_t aReloadFlags, bool * aContinue)
|
||||
{
|
||||
// For now, let the operation continue
|
||||
*aContinue = true;
|
||||
return SendHistoryStatusMessage(aURI, "reload", 0 /* no info to pass here */, aReloadFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryPurge(int32_t aNumEntries, bool *aContinue)
|
||||
{
|
||||
// For now let the operation continue
|
||||
*aContinue = false;
|
||||
return SendHistoryStatusMessage(nullptr, "purge", aNumEntries);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserChrome::OnHistoryReplaceEntry(int32_t aIndex)
|
||||
{
|
||||
return SendHistoryStatusMessage(nullptr, "replace", aIndex);
|
||||
}
|
||||
|
||||
static void
|
||||
AppendIntToCString(int32_t info1, nsCString& aResult)
|
||||
{
|
||||
char intstr[10];
|
||||
_snprintf(intstr, sizeof(intstr) - 1, "%i", info1);
|
||||
intstr[sizeof(intstr) - 1] = '\0';
|
||||
aResult.Append(intstr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebBrowserChrome::SendHistoryStatusMessage(nsIURI * aURI, char * operation, int32_t info1, uint32_t aReloadFlags)
|
||||
{
|
||||
nsCString uriSpec;
|
||||
if (aURI)
|
||||
{
|
||||
aURI->GetSpec(uriSpec);
|
||||
}
|
||||
|
||||
nsCString status;
|
||||
|
||||
if(!(strcmp(operation, "back")))
|
||||
{
|
||||
status.AssignLiteral("Going back to url: ");
|
||||
status.Append(uriSpec);
|
||||
}
|
||||
else if (!(strcmp(operation, "forward")))
|
||||
{
|
||||
// Going forward. XXX Get string from a resource file
|
||||
status.AssignLiteral("Going forward to url: ");
|
||||
status.Append(uriSpec);
|
||||
}
|
||||
else if (!(strcmp(operation, "reload")))
|
||||
{
|
||||
// Reloading. XXX Get string from a resource file
|
||||
if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY &&
|
||||
aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE)
|
||||
{
|
||||
status.AssignLiteral("Reloading url, (bypassing proxy and cache): ");
|
||||
}
|
||||
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY)
|
||||
{
|
||||
status.AssignLiteral("Reloading url, (bypassing proxy): ");
|
||||
}
|
||||
else if (aReloadFlags & nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE)
|
||||
{
|
||||
status.AssignLiteral("Reloading url, (bypassing cache): ");
|
||||
}
|
||||
else
|
||||
{
|
||||
status.AssignLiteral("Reloading url, (normal): ");
|
||||
}
|
||||
status.Append(uriSpec);
|
||||
}
|
||||
else if (!(strcmp(operation, "add")))
|
||||
{
|
||||
status.Assign(uriSpec);
|
||||
status.AppendLiteral(" added to session History");
|
||||
}
|
||||
else if (!(strcmp(operation, "goto")))
|
||||
{
|
||||
status.AssignLiteral("Going to HistoryIndex: ");
|
||||
|
||||
AppendIntToCString(info1, status);
|
||||
|
||||
status.AppendLiteral(" Url: ");
|
||||
status.Append(uriSpec);
|
||||
}
|
||||
else if (!(strcmp(operation, "purge")))
|
||||
{
|
||||
AppendIntToCString(info1, status);
|
||||
status.AppendLiteral(" purged from Session History");
|
||||
}
|
||||
else if (!(strcmp(operation, "replace")))
|
||||
{
|
||||
status.AssignLiteral("Replacing HistoryIndex: ");
|
||||
AppendIntToCString(info1, status);
|
||||
}
|
||||
|
||||
nsString wstatus;
|
||||
NS_CStringToUTF16(status, NS_CSTRING_ENCODING_UTF8, wstatus);
|
||||
WebBrowserChromeUI::UpdateStatusBarText(this, wstatus.get());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void WebBrowserChrome::ContentFinishedLoading()
|
||||
{
|
||||
// if it was a chrome window and no one has already specified a size,
|
||||
// size to content
|
||||
if (mWebBrowser && !mSizeSet &&
|
||||
(mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
|
||||
nsCOMPtr<nsIDOMWindow> contentWin;
|
||||
mWebBrowser->GetContentDOMWindow(getter_AddRefs(contentWin));
|
||||
if (contentWin)
|
||||
contentWin->SizeToContent();
|
||||
WebBrowserChromeUI::ShowWindow(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIEmbeddingSiteWindow
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::SetDimensions(uint32_t aFlags, int32_t x, int32_t y, int32_t cx, int32_t cy)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::GetDimensions(uint32_t aFlags, int32_t *x, int32_t *y, int32_t *cx, int32_t *cy)
|
||||
{
|
||||
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
}
|
||||
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER ||
|
||||
aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)
|
||||
{
|
||||
*cx = 0;
|
||||
*cy = 0;
|
||||
}
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void setFocus (); */
|
||||
NS_IMETHODIMP WebBrowserChrome::SetFocus()
|
||||
{
|
||||
WebBrowserChromeUI::SetFocus(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void blur (); */
|
||||
NS_IMETHODIMP WebBrowserChrome::Blur()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute wstring title; */
|
||||
NS_IMETHODIMP WebBrowserChrome::GetTitle(char16_t * *aTitle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aTitle);
|
||||
|
||||
*aTitle = nullptr;
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHODIMP WebBrowserChrome::SetTitle(const char16_t * aTitle)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* attribute boolean visibility; */
|
||||
NS_IMETHODIMP WebBrowserChrome::GetVisibility(bool * aVisibility)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aVisibility);
|
||||
*aVisibility = true;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP WebBrowserChrome::SetVisibility(bool aVisibility)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute nativeSiteWindow siteWindow */
|
||||
NS_IMETHODIMP WebBrowserChrome::GetSiteWindow(void * *aSiteWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSiteWindow);
|
||||
|
||||
*aSiteWindow = mNativeWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIObserver
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP WebBrowserChrome::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (strcmp(aTopic, "profile-change-teardown") == 0)
|
||||
{
|
||||
// A profile change means death for this window
|
||||
WebBrowserChromeUI::Destroy(this);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsIContextMenuListener
|
||||
//*****************************************************************************
|
||||
|
||||
/* void OnShowContextMenu (in unsigned long aContextFlags, in nsIDOMEvent aEvent, in nsIDOMNode aNode); */
|
||||
NS_IMETHODIMP WebBrowserChrome::OnShowContextMenu(uint32_t aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode)
|
||||
{
|
||||
WebBrowserChromeUI::ShowContextMenu(this, aContextFlags, aEvent, aNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// WebBrowserChrome::nsITooltipListener
|
||||
//*****************************************************************************
|
||||
|
||||
/* void OnShowTooltip (in long aXCoords, in long aYCoords, in wstring aTipText); */
|
||||
NS_IMETHODIMP WebBrowserChrome::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText)
|
||||
{
|
||||
WebBrowserChromeUI::ShowTooltip(this, aXCoords, aYCoords, aTipText);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void OnHideTooltip (); */
|
||||
NS_IMETHODIMP WebBrowserChrome::OnHideTooltip()
|
||||
{
|
||||
WebBrowserChromeUI::HideTooltip(this);
|
||||
return NS_OK;
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: Mozilla-sample-code 1.0
|
||||
*
|
||||
* Copyright (c) 2002 Netscape Communications Corporation and
|
||||
* other contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this Mozilla sample software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __WebBrowserChrome__
|
||||
#define __WebBrowserChrome__
|
||||
|
||||
// OS headers
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// FROZEN APIs
|
||||
|
||||
#include "nsStringAPI.h"
|
||||
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIWebBrowserChromeFocus.h"
|
||||
|
||||
#include "nsIContextMenuListener.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsISHistoryListener.h"
|
||||
#include "nsITooltipListener.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWebBrowser.h"
|
||||
|
||||
// GLUE APIs (not frozen, but safe because we're statically linking them)
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class WebBrowserChromeUI
|
||||
{
|
||||
public:
|
||||
static HWND CreateNativeWindow(nsIWebBrowserChrome* chrome);
|
||||
static void Destroy(nsIWebBrowserChrome* chrome);
|
||||
static void Destroyed(nsIWebBrowserChrome* chrome);
|
||||
static void SetFocus(nsIWebBrowserChrome *chrome);
|
||||
static void UpdateStatusBarText(nsIWebBrowserChrome *aChrome, const char16_t* aStatusText);
|
||||
static void UpdateCurrentURI(nsIWebBrowserChrome *aChrome);
|
||||
static void UpdateBusyState(nsIWebBrowserChrome *aChrome, bool aBusy);
|
||||
static void UpdateProgress(nsIWebBrowserChrome *aChrome, int32_t aCurrent, int32_t aMax);
|
||||
static void GetResourceStringById(int32_t aID, char ** aReturn);
|
||||
static void ShowContextMenu(nsIWebBrowserChrome *aChrome, uint32_t aContextFlags, nsIDOMEvent *aEvent, nsIDOMNode *aNode);
|
||||
static void ShowTooltip(nsIWebBrowserChrome *aChrome, int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText);
|
||||
static void HideTooltip(nsIWebBrowserChrome *aChrome);
|
||||
static void ShowWindow(nsIWebBrowserChrome *aChrome, bool aShow);
|
||||
static void SizeTo(nsIWebBrowserChrome *aChrome, int32_t aWidth, int32_t aHeight);
|
||||
};
|
||||
|
||||
class WebBrowserChrome : public nsIWebBrowserChrome,
|
||||
public nsIWebBrowserChromeFocus,
|
||||
public nsIWebProgressListener,
|
||||
public nsIEmbeddingSiteWindow,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsISHistoryListener,
|
||||
public nsIObserver,
|
||||
public nsIContextMenuListener,
|
||||
public nsITooltipListener,
|
||||
public nsSupportsWeakReference
|
||||
|
||||
{
|
||||
public:
|
||||
WebBrowserChrome();
|
||||
virtual ~WebBrowserChrome();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBBROWSERCHROME
|
||||
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIEMBEDDINGSITEWINDOW
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSISHISTORYLISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSICONTEXTMENULISTENER
|
||||
NS_DECL_NSITOOLTIPLISTENER
|
||||
|
||||
nsresult CreateBrowser(int32_t aX, int32_t aY, int32_t aCX, int32_t aCY,
|
||||
nsIWebBrowser **aBrowser);
|
||||
|
||||
void SetParent(nsIWebBrowserChrome *aParent)
|
||||
{ mDependentParent = aParent; }
|
||||
|
||||
protected:
|
||||
nsresult SendHistoryStatusMessage(nsIURI * aURI, char * operation, int32_t info1=0, uint32_t info2=0);
|
||||
|
||||
void ContentFinishedLoading();
|
||||
|
||||
HWND mNativeWindow;
|
||||
uint32_t mChromeFlags;
|
||||
bool mContinueModalLoop;
|
||||
bool mSizeSet;
|
||||
|
||||
nsCOMPtr<nsIWebBrowser> mWebBrowser;
|
||||
nsCOMPtr<nsIWebBrowserChrome> mDependentParent; // opener (for dependent windows only)
|
||||
};
|
||||
|
||||
#endif /* __WebBrowserChrome__ */
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: Mozilla-sample-code 1.0
|
||||
*
|
||||
* Copyright (c) 2002 Netscape Communications Corporation and
|
||||
* other contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this Mozilla sample software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "WindowCreator.h"
|
||||
#include "winEmbed.h"
|
||||
|
||||
WindowCreator::WindowCreator()
|
||||
{
|
||||
}
|
||||
|
||||
WindowCreator::~WindowCreator()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(WindowCreator, nsIWindowCreator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowCreator::CreateChromeWindow(nsIWebBrowserChrome *parent,
|
||||
uint32_t chromeFlags,
|
||||
nsIWebBrowserChrome **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
AppCallbacks::CreateBrowserWindow(int32_t(chromeFlags), parent, _retval);
|
||||
return *_retval ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: Mozilla-sample-code 1.0
|
||||
*
|
||||
* Copyright (c) 2002 Netscape Communications Corporation and
|
||||
* other contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this Mozilla sample software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __WindowCreator_h_
|
||||
#define __WindowCreator_h_
|
||||
|
||||
#include "nsIWindowCreator.h"
|
||||
|
||||
class WindowCreator :
|
||||
public nsIWindowCreator
|
||||
{
|
||||
public:
|
||||
WindowCreator();
|
||||
virtual ~WindowCreator();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWINDOWCREATOR
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
GeckoProgram('winEmbed')
|
||||
|
||||
SOURCES += [
|
||||
'WebBrowserChrome.cpp',
|
||||
'WindowCreator.cpp',
|
||||
'winEmbed.cpp',
|
||||
]
|
||||
|
||||
XPI_NAME = 'winembed'
|
||||
|
||||
RESFILE = 'winEmbed.res'
|
||||
|
||||
if CONFIG['GNU_CC']:
|
||||
# Get rid of console window
|
||||
LDFLAGS += ['-mwindows']
|
||||
else:
|
||||
# Control the default heap size.
|
||||
# This is the heap returned by GetProcessHeap().
|
||||
# As we use the CRT heap, the default size is too large and wastes VM.
|
||||
#
|
||||
# The default heap size is 1MB on Win32.
|
||||
# The heap will grow if need be.
|
||||
#
|
||||
# Set it to 256k. See bug 127069.
|
||||
LDFLAGS += ['/HEAP:0x40000']
|
||||
|
||||
DISABLE_STL_WRAPPING = True
|
||||
|
||||
USE_LIBS += [
|
||||
'profdirserviceprovidersa_s',
|
||||
]
|
||||
|
||||
OS_LIBS += [
|
||||
'ole32',
|
||||
'comdlg32',
|
||||
'shell32',
|
||||
'version',
|
||||
]
|
|
@ -1,69 +0,0 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by winEmbed.rc
|
||||
//
|
||||
#define IDC_MYICON 2
|
||||
#define IDD_WINEMBED_DIALOG 102
|
||||
#define IDD_ABOUTBOX 103
|
||||
#define IDS_APP_TITLE 103
|
||||
#define IDM_ABOUT 104
|
||||
#define MOZ_OpenURI 104
|
||||
#define MOZ_GetURI 104
|
||||
#define IDM_EXIT 105
|
||||
#define IDS_HELLO 106
|
||||
#define IDI_WINEMBED 107
|
||||
#define IDS_ABOUT 107
|
||||
#define IDI_SMALL 108
|
||||
#define IDS_ABOUT_TITLE 108
|
||||
#define IDC_WINEMBED 109
|
||||
#define IDS_HIST_BACK 109
|
||||
#define IDS_HIST_FORWARD 110
|
||||
#define IDS_HIST_RELOAD_NORMAL 111
|
||||
#define IDS_HIST_RELOAD_BYPASSPROXY 112
|
||||
#define IDS_HIST_RELOAD_BYPASSCACHE 113
|
||||
#define IDS_HIST_ADDURL 114
|
||||
#define IDS_HIST_RELOAD_BYPASSPROXYANDCACHE 115
|
||||
#define IDS_HIST_PURGE 116
|
||||
#define IDS_HIST_GOTO 117
|
||||
#define IDS_HIST_URL 118
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDD_BROWSER 130
|
||||
#define IDD_BROWSER_NC 131
|
||||
#define IDD_CHOOSEPROFILE 132
|
||||
#define MOZ_EDIT_URI 1001
|
||||
#define IDC_GO 1003
|
||||
#define IDC_BROWSER 1004
|
||||
#define IDC_ADDRESS 1005
|
||||
#define IDC_STOP 1006
|
||||
#define IDC_STATUS 1007
|
||||
#define IDC_BACK 1008
|
||||
#define IDC_FORWARD 1009
|
||||
#define IDC_PROGRESS 1010
|
||||
#define IDC_RELOAD 1011
|
||||
#define IDC_PROFILELIST 1011
|
||||
#define MOZ_Open 32771
|
||||
#define MOZ_NewBrowser 32773
|
||||
#define MOZ_NewEditor 32774
|
||||
#define MOZ_Cut 32776
|
||||
#define MOZ_Copy 32777
|
||||
#define MOZ_Paste 32778
|
||||
#define MOZ_Delete 32779
|
||||
#define MOZ_SelectAll 32780
|
||||
#define MOZ_SelectNone 32781
|
||||
#define MOZ_GoBack 32782
|
||||
#define MOZ_GoForward 32783
|
||||
#define MOZ_About 32784
|
||||
#define ID_DEBUG_THISSPACEFORRENT 32786
|
||||
#define MOZ_SwitchProfile 32787
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 133
|
||||
#define _APS_NEXT_COMMAND_VALUE 32788
|
||||
#define _APS_NEXT_CONTROL_VALUE 1012
|
||||
#define _APS_NEXT_SYMED_VALUE 110
|
||||
#endif
|
||||
#endif
|
Двоичные данные
embedding/tests/winEmbed/winEmbed.ICO
Двоичные данные
embedding/tests/winEmbed/winEmbed.ICO
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 1.1 KiB |
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,43 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: Mozilla-sample-code 1.0
|
||||
*
|
||||
* Copyright (c) 2002 Netscape Communications Corporation and
|
||||
* other contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this Mozilla sample software and associated documentation files
|
||||
* (the "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIWebBrowserChrome;
|
||||
|
||||
namespace AppCallbacks {
|
||||
nsresult CreateBrowserWindow(uint32_t aChromeFlags,
|
||||
nsIWebBrowserChrome *aParent,
|
||||
nsIWebBrowserChrome **aNewWindow);
|
||||
|
||||
void EnableChromeWindow(nsIWebBrowserChrome *aWindow, bool aEnabled);
|
||||
|
||||
uint32_t RunEventLoop(bool &aRunCondition);
|
||||
}
|
|
@ -1,265 +0,0 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_WINEMBED ICON "winEmbed.ICO"
|
||||
IDI_SMALL ICON "SMALL.ICO"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDC_WINEMBED MENU
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "New Browser...", MOZ_NewBrowser
|
||||
MENUITEM "E&xit", IDM_EXIT
|
||||
END
|
||||
POPUP "&Edit"
|
||||
BEGIN
|
||||
MENUITEM "Cu&t", MOZ_Cut
|
||||
MENUITEM "&Copy", MOZ_Copy
|
||||
MENUITEM "&Paste", MOZ_Paste
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Select All", MOZ_SelectAll
|
||||
MENUITEM "Select None", MOZ_SelectNone
|
||||
END
|
||||
POPUP "&Go"
|
||||
BEGIN
|
||||
MENUITEM "&Back", MOZ_GoBack
|
||||
MENUITEM "&Forward", MOZ_GoForward
|
||||
END
|
||||
POPUP "&Debug"
|
||||
BEGIN
|
||||
MENUITEM "&This space for rent", ID_DEBUG_THISSPACEFORRENT
|
||||
, GRAYED
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About winEmbed...", MOZ_About
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""resource.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_APP_TITLE "winEmbed"
|
||||
IDS_HELLO "Embedding Mozilla is so much fun!!"
|
||||
IDS_ABOUT "winEmbed - Gecko embedding sample"
|
||||
IDS_ABOUT_TITLE "About winEmbed"
|
||||
IDS_HIST_BACK "Going Back to: "
|
||||
IDS_HIST_FORWARD "Going Forward to: "
|
||||
IDS_HIST_RELOAD_NORMAL "Reloading url, (normal) :"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_HIST_RELOAD_BYPASSPROXY "Reloading url, (bypassing Proxy) :"
|
||||
IDS_HIST_RELOAD_BYPASSCACHE "Reloading url, (bypassing cache) :"
|
||||
IDS_HIST_ADDURL " added to Session History"
|
||||
IDS_HIST_RELOAD_BYPASSPROXYANDCACHE
|
||||
"Reloading url, (bypassing Proxy and cache) :"
|
||||
IDS_HIST_PURGE "purged from session history"
|
||||
IDS_HIST_GOTO "Going to history index : "
|
||||
IDS_HIST_URL " URL : "
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.K.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_BROWSER DIALOG 0, 0, 400, 217
|
||||
STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
|
||||
WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
CAPTION "winEmbed sample - UNSUPPORTED"
|
||||
MENU IDC_WINEMBED
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
PUSHBUTTON "Back",IDC_BACK,1,1,21,13
|
||||
PUSHBUTTON "Forward",IDC_FORWARD,23,1,30,13
|
||||
PUSHBUTTON "Reload",IDC_RELOAD,57,1,28,13
|
||||
PUSHBUTTON "Stop",IDC_STOP,86,1,25,13
|
||||
LTEXT "Address:",IDC_STATIC,115,3,28,8
|
||||
COMBOBOX IDC_ADDRESS,145,1,193,52,CBS_DROPDOWN | CBS_AUTOHSCROLL |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
DEFPUSHBUTTON "Go",IDC_GO,340,1,25,13
|
||||
CONTROL "Embedded Browser",IDC_BROWSER,"WINEMBED",WS_TABSTOP,0,
|
||||
16,400,192
|
||||
CONTROL "Status",IDC_STATUS,"Static",SS_LEFTNOWORDWRAP |
|
||||
SS_SUNKEN | WS_GROUP,0,208,316,9
|
||||
CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,
|
||||
316,208,84,9
|
||||
END
|
||||
|
||||
IDD_BROWSER_NC DIALOG 0, 0, 400, 217
|
||||
STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
|
||||
WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
|
||||
CAPTION "winEmbed chromeless sample"
|
||||
MENU IDC_WINEMBED
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Embedded Browser",IDC_BROWSER,"WINEMBED",WS_TABSTOP,0,0,
|
||||
400,217
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_BROWSER, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 292
|
||||
BOTTOMMARGIN, 216
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.K.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (Ireland) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENI)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_EIRE
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_CHOOSEPROFILE DIALOG 0, 0, 186, 154
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION |
|
||||
WS_SYSMENU
|
||||
CAPTION "Choose Profile"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Available Profiles:",IDC_STATIC,7,7,56,8
|
||||
LISTBOX IDC_PROFILELIST,7,18,117,129,LBS_NOINTEGRALHEIGHT |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
DEFPUSHBUTTON "Select",IDOK,129,18,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,36,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_CHOOSEPROFILE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 147
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (Ireland) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
# Microsoft Developer Studio Project File - Name="winembed" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) External Target" 0x0106
|
||||
|
||||
CFG=winembed - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "winembed.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "winembed.mak" CFG="winembed - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "winembed - Win32 Release" (based on "Win32 (x86) External Target")
|
||||
!MESSAGE "winembed - Win32 Debug" (based on "Win32 (x86) External Target")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
|
||||
!IF "$(CFG)" == "winembed - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Cmd_Line "NMAKE /f winembed.mak"
|
||||
# PROP BASE Rebuild_Opt "/a"
|
||||
# PROP BASE Target_File "winembed.exe"
|
||||
# PROP BASE Bsc_Name "winembed.bsc"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Cmd_Line "nmake /f makefile.win"
|
||||
# PROP Rebuild_Opt "/a"
|
||||
# PROP Target_File "win32_o.obj\winembed.exe"
|
||||
# PROP Bsc_Name ""
|
||||
# PROP Target_Dir ""
|
||||
|
||||
!ELSEIF "$(CFG)" == "winembed - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Cmd_Line "NMAKE /f winembed.mak"
|
||||
# PROP BASE Rebuild_Opt "/a"
|
||||
# PROP BASE Target_File "winembed.exe"
|
||||
# PROP BASE Bsc_Name "winembed.bsc"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Cmd_Line "nmake /f makefile.win"
|
||||
# PROP Rebuild_Opt "/a"
|
||||
# PROP Target_File "win32_d.obj\winembed.exe"
|
||||
# PROP Bsc_Name ""
|
||||
# PROP Target_Dir ""
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "winembed - Win32 Release"
|
||||
# Name "winembed - Win32 Debug"
|
||||
|
||||
!IF "$(CFG)" == "winembed - Win32 Release"
|
||||
|
||||
!ELSEIF "$(CFG)" == "winembed - Win32 Debug"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\WebBrowserChrome.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\WindowCreator.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winEmbed.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\WebBrowserChrome.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\WindowCreator.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winEmbed.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SMALL.ICO
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winEmbed.ICO
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winEmbed.rc
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -1639,10 +1639,14 @@ nsEventStatus AsyncPanZoomController::OnPanBegin(const PanGestureInput& aEvent)
|
|||
}
|
||||
|
||||
float dx = aEvent.mPanDisplacement.x, dy = aEvent.mPanDisplacement.y;
|
||||
double angle = atan2(dy, dx); // range [-pi, pi]
|
||||
angle = fabs(angle); // range [0, pi]
|
||||
|
||||
HandlePanning(angle);
|
||||
if (dx || dy) {
|
||||
double angle = atan2(dy, dx); // range [-pi, pi]
|
||||
angle = fabs(angle); // range [0, pi]
|
||||
HandlePanning(angle);
|
||||
} else {
|
||||
SetState(PANNING);
|
||||
}
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
|
|
@ -605,12 +605,14 @@ static struct lutmABType *read_tag_lutmABType(struct mem_source *src, struct tag
|
|||
memset(lut, 0, sizeof(struct lutmABType));
|
||||
lut->clut_table = &lut->clut_table_data[0];
|
||||
|
||||
for (i = 0; i < num_in_channels; i++) {
|
||||
lut->num_grid_points[i] = read_u8(src, clut_offset + i);
|
||||
if (lut->num_grid_points[i] == 0) {
|
||||
invalid_source(src, "bad grid_points");
|
||||
if (clut_offset) {
|
||||
for (i = 0; i < num_in_channels; i++) {
|
||||
lut->num_grid_points[i] = read_u8(src, clut_offset + i);
|
||||
if (lut->num_grid_points[i] == 0) {
|
||||
invalid_source(src, "bad grid_points");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse the processing of transformation elements for mBA type.
|
||||
lut->reversed = (type == LUT_MBA_TYPE);
|
||||
|
|
|
@ -149,43 +149,6 @@ public:
|
|||
int32_t* aDestLength);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsTableDecoderSupport [declaration]
|
||||
|
||||
/**
|
||||
* Support class for a single-table-driven Unicode decoder.
|
||||
*
|
||||
* @created 15/Mar/1999
|
||||
* @author Catalin Rotaru [CATA]
|
||||
*/
|
||||
class nsTableDecoderSupport : public nsBufferDecoderSupport
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
nsTableDecoderSupport(uScanClassID aScanClass, uShiftInTable * aShiftInTable,
|
||||
uMappingTable * aMappingTable, uint32_t aMaxLengthFactor);
|
||||
|
||||
/**
|
||||
* Class destructor.
|
||||
*/
|
||||
virtual ~nsTableDecoderSupport();
|
||||
|
||||
protected:
|
||||
|
||||
uScanClassID mScanClass;
|
||||
uShiftInTable * mShiftInTable;
|
||||
uMappingTable * mMappingTable;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Subclassing of nsBufferDecoderSupport class [declaration]
|
||||
|
||||
NS_IMETHOD ConvertNoBuff(const char * aSrc, int32_t * aSrcLength,
|
||||
char16_t * aDest, int32_t * aDestLength);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsMultiTableDecoderSupport [declaration]
|
||||
|
||||
|
|
|
@ -12,55 +12,21 @@
|
|||
|
||||
#include "nsGBKToUnicode.h"
|
||||
#include "gbku.h"
|
||||
|
||||
//------------------------------------------------------------
|
||||
// nsGB18030Unique2BytesToUnicode
|
||||
//------------------------------------------------------------
|
||||
class nsGB18030Unique2BytesToUnicode : public nsTableDecoderSupport
|
||||
{
|
||||
public:
|
||||
nsGB18030Unique2BytesToUnicode();
|
||||
virtual ~nsGB18030Unique2BytesToUnicode()
|
||||
{ }
|
||||
protected:
|
||||
};
|
||||
#include "nsUnicodeDecodeHelper.h"
|
||||
|
||||
static const uint16_t g_utGB18030Unique2Bytes[] = {
|
||||
#include "gb18030uniq2b.ut"
|
||||
};
|
||||
nsGB18030Unique2BytesToUnicode::nsGB18030Unique2BytesToUnicode()
|
||||
: nsTableDecoderSupport(u2BytesCharset, nullptr,
|
||||
(uMappingTable*) &g_utGB18030Unique2Bytes, 1)
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// nsGB18030Unique4BytesToUnicode
|
||||
//------------------------------------------------------------
|
||||
class nsGB18030Unique4BytesToUnicode : public nsTableDecoderSupport
|
||||
{
|
||||
public:
|
||||
nsGB18030Unique4BytesToUnicode();
|
||||
virtual ~nsGB18030Unique4BytesToUnicode()
|
||||
{ }
|
||||
protected:
|
||||
};
|
||||
|
||||
static const uint16_t g_utGB18030Unique4Bytes[] = {
|
||||
#include "gb180304bytes.ut"
|
||||
};
|
||||
nsGB18030Unique4BytesToUnicode::nsGB18030Unique4BytesToUnicode()
|
||||
: nsTableDecoderSupport(u4BytesGB18030Charset, nullptr,
|
||||
(uMappingTable*) &g_utGB18030Unique4Bytes, 1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsGBKToUnicode [implementation]
|
||||
// Class nsGB18030ToUnicode [implementation]
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Subclassing of nsTablesDecoderSupport class [implementation]
|
||||
// Subclassing of nsBufferDecoderSupport class [implementation]
|
||||
|
||||
#define LEGAL_GBK_MULTIBYTE_FIRST_BYTE(c) \
|
||||
(UINT8_IN_RANGE(0x81, (c), 0xFE))
|
||||
|
@ -207,14 +173,6 @@ NS_IMETHODIMP nsGB18030ToUnicode::ConvertNoBuff(const char* aSrc,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void nsGB18030ToUnicode::CreateExtensionDecoder()
|
||||
{
|
||||
mExtensionDecoder = new nsGB18030Unique2BytesToUnicode();
|
||||
}
|
||||
void nsGB18030ToUnicode::Create4BytesDecoder()
|
||||
{
|
||||
m4BytesDecoder = new nsGB18030Unique4BytesToUnicode();
|
||||
}
|
||||
bool nsGB18030ToUnicode::DecodeToSurrogate(const char* aSrc, char16_t* aOut)
|
||||
{
|
||||
NS_ASSERTION(FIRST_BYTE_IS_SURROGATE(aSrc[0]), "illegal first byte");
|
||||
|
@ -250,43 +208,32 @@ bool nsGB18030ToUnicode::DecodeToSurrogate(const char* aSrc, char16_t* aOut)
|
|||
}
|
||||
bool nsGB18030ToUnicode::TryExtensionDecoder(const char* aSrc, char16_t* aOut)
|
||||
{
|
||||
if(!mExtensionDecoder)
|
||||
CreateExtensionDecoder();
|
||||
NS_ASSERTION(mExtensionDecoder, "cannot creqte 2 bytes unique converter");
|
||||
if(mExtensionDecoder)
|
||||
{
|
||||
nsresult res = mExtensionDecoder->Reset();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "2 bytes unique conversoin reset failed");
|
||||
int32_t len = 2;
|
||||
int32_t dstlen = 1;
|
||||
res = mExtensionDecoder->Convert(aSrc,&len, aOut, &dstlen);
|
||||
NS_ASSERTION(NS_FAILED(res) || ((len==2) && (dstlen == 1)),
|
||||
"some strange conversion result");
|
||||
// if we failed, we then just use the 0xfffd
|
||||
// therefore, we ignore the res here.
|
||||
if(NS_SUCCEEDED(res))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
int32_t len = 2;
|
||||
int32_t dstlen = 1;
|
||||
nsresult res =
|
||||
nsUnicodeDecodeHelper::ConvertByTable(aSrc, &len, aOut, &dstlen,
|
||||
u2BytesCharset, nullptr,
|
||||
(uMappingTable*) &g_utGB18030Unique2Bytes,
|
||||
false);
|
||||
NS_ASSERTION(NS_FAILED(res) || ((len==2) && (dstlen == 1)),
|
||||
"some strange conversion result");
|
||||
// if we failed, we then just use the 0xfffd
|
||||
// therefore, we ignore the res here.
|
||||
return NS_SUCCEEDED(res);
|
||||
}
|
||||
|
||||
bool nsGB18030ToUnicode::Try4BytesDecoder(const char* aSrc, char16_t* aOut)
|
||||
{
|
||||
if(!m4BytesDecoder)
|
||||
Create4BytesDecoder();
|
||||
if(m4BytesDecoder)
|
||||
{
|
||||
nsresult res = m4BytesDecoder->Reset();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "4 bytes unique conversoin reset failed");
|
||||
int32_t len = 4;
|
||||
int32_t dstlen = 1;
|
||||
res = m4BytesDecoder->Convert(aSrc,&len, aOut, &dstlen);
|
||||
NS_ASSERTION(NS_FAILED(res) || ((len==4) && (dstlen == 1)),
|
||||
"some strange conversion result");
|
||||
// if we failed, we then just use the 0xfffd
|
||||
// therefore, we ignore the res here.
|
||||
if(NS_SUCCEEDED(res))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
int32_t len = 4;
|
||||
int32_t dstlen = 1;
|
||||
nsresult res =
|
||||
nsUnicodeDecodeHelper::ConvertByTable(aSrc, &len, aOut, &dstlen,
|
||||
u4BytesGB18030Charset, nullptr,
|
||||
(uMappingTable*) &g_utGB18030Unique4Bytes,
|
||||
false);
|
||||
NS_ASSERTION(NS_FAILED(res) || ((len==4) && (dstlen == 1)),
|
||||
"some strange conversion result");
|
||||
// if we failed, we then just use the 0xfffd
|
||||
// therefore, we ignore the res here.
|
||||
return NS_SUCCEEDED(res);
|
||||
}
|
||||
|
|
|
@ -29,23 +29,17 @@ public:
|
|||
*/
|
||||
nsGB18030ToUnicode() : nsBufferDecoderSupport(1)
|
||||
{
|
||||
mExtensionDecoder = nullptr;
|
||||
m4BytesDecoder = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Subclassing of nsDecoderSupport class [declaration]
|
||||
// Subclassing of nsBufferDecoderSupport class [declaration]
|
||||
NS_IMETHOD ConvertNoBuff(const char* aSrc, int32_t * aSrcLength, char16_t *aDest, int32_t * aDestLength);
|
||||
|
||||
protected:
|
||||
nsGBKConvUtil mUtil;
|
||||
nsCOMPtr<nsIUnicodeDecoder> mExtensionDecoder;
|
||||
nsCOMPtr<nsIUnicodeDecoder> m4BytesDecoder;
|
||||
|
||||
void CreateExtensionDecoder();
|
||||
void Create4BytesDecoder();
|
||||
bool TryExtensionDecoder(const char* aSrc, char16_t* aDest);
|
||||
bool Try4BytesDecoder(const char* aSrc, char16_t* aDest);
|
||||
bool DecodeToSurrogate(const char* aSrc, char16_t* aDest);
|
||||
|
|
|
@ -198,39 +198,6 @@ NS_IMETHODIMP nsBufferDecoderSupport::GetMaxLength(const char* aSrc,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsTableDecoderSupport [implementation]
|
||||
|
||||
nsTableDecoderSupport::nsTableDecoderSupport(uScanClassID aScanClass,
|
||||
uShiftInTable* aShiftInTable,
|
||||
uMappingTable* aMappingTable,
|
||||
uint32_t aMaxLengthFactor)
|
||||
: nsBufferDecoderSupport(aMaxLengthFactor)
|
||||
{
|
||||
mScanClass = aScanClass;
|
||||
mShiftInTable = aShiftInTable;
|
||||
mMappingTable = aMappingTable;
|
||||
}
|
||||
|
||||
nsTableDecoderSupport::~nsTableDecoderSupport()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Subclassing of nsBufferDecoderSupport class [implementation]
|
||||
|
||||
NS_IMETHODIMP nsTableDecoderSupport::ConvertNoBuff(const char* aSrc,
|
||||
int32_t* aSrcLength,
|
||||
char16_t* aDest,
|
||||
int32_t* aDestLength)
|
||||
{
|
||||
return nsUnicodeDecodeHelper::ConvertByTable(aSrc, aSrcLength,
|
||||
aDest, aDestLength,
|
||||
mScanClass,
|
||||
mShiftInTable, mMappingTable,
|
||||
mErrBehavior == kOnError_Signal);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Class nsMultiTableDecoderSupport [implementation]
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// |jit-test| baseline-eager; error: TypeError
|
||||
try {
|
||||
__defineGetter__("x", Iterator)()
|
||||
} catch (e) {}
|
||||
f = function() {
|
||||
return (function() {
|
||||
this.x
|
||||
})
|
||||
}()
|
||||
try {
|
||||
f()
|
||||
} catch (e) {}
|
||||
f()
|
|
@ -7666,14 +7666,13 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
|
||||
Label failure;
|
||||
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
AllocatableGeneralRegisterSet regs(availableGeneralRegs(1));
|
||||
Register objReg = InvalidReg;
|
||||
|
||||
MOZ_ASSERT(!(inputDefinitelyObject_ && outerClass_));
|
||||
if (inputDefinitelyObject_) {
|
||||
objReg = R0.scratchReg();
|
||||
} else {
|
||||
regs.take(R0);
|
||||
// Guard input is an object and unbox.
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
objReg = masm.extractObject(R0, ExtractTemp0);
|
||||
|
@ -7683,12 +7682,11 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
masm.branchTestObjClass(Assembler::NotEqual, objReg, tmp, outerClass_, &failure);
|
||||
masm.loadPtr(Address(objReg, ProxyDataOffset + offsetof(ProxyDataLayout, values)), tmp);
|
||||
masm.loadValue(Address(tmp, offsetof(ProxyValueArray, privateSlot)), val);
|
||||
objReg = masm.extractObject(val, ExtractTemp0);
|
||||
masm.movePtr(masm.extractObject(val, ExtractTemp0), objReg);
|
||||
regs.add(val);
|
||||
regs.add(tmp);
|
||||
}
|
||||
}
|
||||
regs.takeUnchecked(objReg);
|
||||
|
||||
Register scratch = regs.takeAnyExcluding(ICTailCallReg);
|
||||
|
||||
|
@ -7704,6 +7702,13 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
regs.add(holderReg);
|
||||
}
|
||||
|
||||
// Box and push obj onto baseline frame stack for decompiler
|
||||
if (inputDefinitelyObject_)
|
||||
masm.tagValue(JSVAL_TYPE_OBJECT, objReg, R0);
|
||||
EmitStowICValues(masm, 1);
|
||||
if (inputDefinitelyObject_)
|
||||
objReg = masm.extractObject(R0, ExtractTemp0);
|
||||
|
||||
// Push a stub frame so that we can perform a non-tail call.
|
||||
enterStubFrame(masm, scratch);
|
||||
|
||||
|
@ -7715,15 +7720,14 @@ ICGetProp_CallNative::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
masm.push(objReg);
|
||||
masm.push(callee);
|
||||
|
||||
if (!inputDefinitelyObject_)
|
||||
regs.add(R0);
|
||||
else
|
||||
regs.add(objReg);
|
||||
regs.add(R0);
|
||||
|
||||
if (!callVM(DoCallNativeGetterInfo, masm))
|
||||
return false;
|
||||
leaveStubFrame(masm);
|
||||
|
||||
EmitUnstowICValues(masm, 1, /* discard = */true);
|
||||
|
||||
// Enter type monitor IC to type-check result.
|
||||
EmitEnterTypeMonitorIC(masm);
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ enum JitSpewChannel {
|
|||
};
|
||||
|
||||
class MIRGenerator;
|
||||
class TempAllocator;
|
||||
|
||||
// The JitSpewer is only available on debug builds.
|
||||
// None of the global functions have effect on non-debug builds.
|
||||
|
|
|
@ -46,6 +46,7 @@ class LTableSwitchV : public LInstruction
|
|||
class LGuardShape : public LInstruction {};
|
||||
class LGuardObjectGroup : public LInstruction {};
|
||||
class LMulI : public LInstruction {};
|
||||
class LRandom : public LInstructionHelper<1, 0, 5> {};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
|
|
@ -85,7 +85,7 @@ class LIRGeneratorNone : public LIRGeneratorShared
|
|||
void visitSimdValueX4(MSimdValueX4* lir) { MOZ_CRASH(); }
|
||||
void visitSubstr(MSubstr*) { MOZ_CRASH(); }
|
||||
void visitSimdBinaryArith(js::jit::MSimdBinaryArith*) { MOZ_CRASH(); }
|
||||
|
||||
void visitRandom(MRandom* ) { MOZ_CRASH(); }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -143,6 +143,11 @@ class Operand
|
|||
{
|
||||
public:
|
||||
Operand (const Address&) { MOZ_CRASH();}
|
||||
Operand (const Register) { MOZ_CRASH();}
|
||||
Operand (const FloatRegister) { MOZ_CRASH();}
|
||||
Operand (Register, Imm32 ) { MOZ_CRASH(); }
|
||||
Operand (Register, int32_t ) { MOZ_CRASH(); }
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче