This commit is contained in:
Phil Ringnalda 2015-05-09 14:54:06 -07:00
Родитель 20acfc81a9 0ac407a726
Коммит b382c3535b
240 изменённых файлов: 4215 добавлений и 2125 удалений

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

@ -6,6 +6,10 @@ import imp
import os
from StringIO import StringIO
import shlex
import sys
old_bytecode = sys.dont_write_bytecode
sys.dont_write_bytecode = True
path = os.path.join(os.path.dirname(__file__), 'mach')
@ -15,6 +19,8 @@ if not os.path.exists(path):
path = os.path.join(config.topsrcdir, 'mach')
mach_module = imp.load_module('_mach', open(path), path, ('', 'r', imp.PY_SOURCE))
sys.dont_write_bytecode = old_bytecode
def FlagsForFile(filename):
mach = mach_module.get_mach()
out = StringIO()

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

@ -855,6 +855,13 @@ getIndexInParentCB(AtkObject* aAtkObj)
{
// We don't use Accessible::IndexInParent() because we don't include text
// leaf nodes as children in ATK.
if (ProxyAccessible* proxy = GetProxy(aAtkObj)) {
if (ProxyAccessible* parent = proxy->Parent())
return parent->IndexOfEmbeddedChild(proxy);
return -1;
}
AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
if (!accWrap) {
return -1;
@ -1053,6 +1060,9 @@ GetInterfacesForProxy(ProxyAccessible* aProxy, uint32_t aInterfaces)
if (aInterfaces & Interfaces::IMAGE)
interfaces |= MAI_INTERFACE_IMAGE;
if (aInterfaces & Interfaces::DOCUMENT)
interfaces |= MAI_INTERFACE_DOCUMENT;
return interfaces;
}

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

@ -16,7 +16,7 @@ static AtkHyperlink*
getHyperlinkCB(AtkHyperlinkImpl* aImpl)
{
AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImpl));
if (!accWrap || !GetProxy(ATK_OBJECT(aImpl)))
if (!accWrap && !GetProxy(ATK_OBJECT(aImpl)))
return nullptr;
if (accWrap)

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

@ -39,6 +39,9 @@ InterfacesFor(Accessible* aAcc)
if (aAcc->IsTableCell())
interfaces |= Interfaces::TABLECELL;
if (aAcc->IsDoc())
interfaces |= Interfaces::DOCUMENT;
return interfaces;
}
@ -1615,6 +1618,22 @@ DocAccessibleChild::RecvTakeFocus(const uint64_t& aID)
return true;
}
bool
DocAccessibleChild::RecvIndexOfEmbeddedChild(const uint64_t& aID,
const uint64_t& aChildID,
uint32_t* aChildIdx)
{
*aChildIdx = 0;
Accessible* parent = IdToAccessible(aID);
Accessible* child = IdToAccessible(aChildID);
if (!parent || !child)
return true;
*aChildIdx = parent->GetIndexOfEmbeddedChild(child);
return true;
}
bool
DocAccessibleChild::RecvChildAtPoint(const uint64_t& aID,
const int32_t& aX,

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

@ -393,6 +393,10 @@ public:
virtual bool RecvTakeFocus(const uint64_t& aID) override;
virtual bool RecvIndexOfEmbeddedChild(const uint64_t& aID,
const uint64_t& aChildID,
uint32_t* aChildIdx) override final;
virtual bool RecvChildAtPoint(const uint64_t& aID,
const int32_t& aX,
const int32_t& aY,

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

@ -211,6 +211,8 @@ child:
prio(high) sync Step(uint64_t aID) returns(double aStep);
prio(high) sync TakeFocus(uint64_t aID);
prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
returns(uint32_t childIdx);
prio(high) sync ChildAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aWhich)
returns(uint64_t aChild, bool aOk);
prio(high) sync Bounds(uint64_t aID) returns(nsIntRect aRect);

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

@ -903,6 +903,15 @@ ProxyAccessible::TakeFocus()
unused << mDoc->SendTakeFocus(mID);
}
int32_t
ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
{
uint64_t childID = aChild->mID;
uint32_t childIdx;
unused << mDoc->SendIndexOfEmbeddedChild(mID, childID, &childIdx);
return childIdx;
}
ProxyAccessible*
ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY,
Accessible::EWhichChildAtPoint aWhichChild)

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

@ -47,6 +47,7 @@ public:
// XXX evaluate if this is fast enough.
size_t IndexInParent() const { return mParent->mChildren.IndexOf(this); }
int32_t IndexOfEmbeddedChild(const ProxyAccessible*);
bool MustPruneChildren() const;
void Shutdown();
@ -320,6 +321,7 @@ enum Interfaces
VALUE = 8,
TABLE = 16,
TABLECELL = 32,
DOCUMENT = 64,
};
}

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "3692ad2cf3a047cc66f58f655a56b6ec559ef253",
"git_revision": "5b2a150f6f5d29bddfaac13fcbbf099376f2f275",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "5cf33f632627cefff6e9809144064600fed4c088",
"revision": "75e6c18c2cdd05073434a8d5e749c72a063a0521",
"repo_path": "integration/gaia-central"
}

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

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="3692ad2cf3a047cc66f58f655a56b6ec559ef253"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5b2a150f6f5d29bddfaac13fcbbf099376f2f275"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -3029,6 +3029,21 @@
</certItem>
<certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
<serialNumber>UoRGnb96CUDTxIqVry6LBg==</serialNumber>
</certItem>
<certItem issuerName="MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==">
<serialNumber>ARQ=</serialNumber>
</certItem>
<certItem issuerName="MGcxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpGcmF1bmhvZmVyMSEwHwYDVQQLExhGcmF1bmhvZmVyIENvcnBvcmF0ZSBQS0kxIDAeBgNVBAMTF0ZyYXVuaG9mZXIgUm9vdCBDQSAyMDA3">
<serialNumber>YR3YYQAAAAAABA==</serialNumber>
</certItem>
<certItem issuerName="MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy">
<serialNumber>ATE0vw==</serialNumber>
</certItem>
<certItem issuerName="MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ">
<serialNumber>ATFpsA==</serialNumber>
</certItem>
<certItem issuerName="MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ">
<serialNumber>ATFEdg==</serialNumber>
</certItem>
</certItems>

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

@ -1567,6 +1567,21 @@ let BookmarkingUI = {
updatePocketItemVisibility: function BUI_updatePocketItemVisibility(prefix) {
let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button");
if (!hidden) {
let locale = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIXULChromeRegistry).
getSelectedLocale("browser");
let url = "chrome://browser/content/browser-pocket-" + locale + ".properties";
let bundle = Services.strings.createBundle(url);
let item = document.getElementById(prefix + "pocket");
try {
item.setAttribute("label", bundle.GetStringFromName("pocketMenuitem.label"));
} catch (err) {
// GetStringFromName throws when the bundle doesn't exist. In that
// case, the item will retain the browser-pocket.dtd en-US string that
// it has in the markup.
}
}
document.getElementById(prefix + "pocket").hidden = hidden;
document.getElementById(prefix + "pocketSeparator").hidden = hidden;
},

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

@ -0,0 +1,14 @@
# 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/.
# This is a temporary file, later versions of Firefox will use
# browser.properties in the usual L10N location.
pocket-button.label = Pocket
pocket-button.tooltiptext = Bei Pocket speichern
# From browser-pocket.dtd
saveToPocketCmd.label = Seite bei Pocket speichern
saveToPocketCmd.accesskey = k
pocketMenuitem.label = Pocket-Liste anzeigen

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

@ -0,0 +1,14 @@
# 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/.
# This is a temporary file, later versions of Firefox will use
# browser.properties in the usual L10N location.
pocket-button.label = Pocket
pocket-button.tooltiptext = Guardar en Pocket
# From browser-pocket.dtd
saveToPocketCmd.label = Guardar página en Pocket
saveToPocketCmd.accesskey = k
pocketMenuitem.label = Ver lista de Pocket

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

@ -0,0 +1,14 @@
# 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/.
# This is a temporary file, later versions of Firefox will use
# browser.properties in the usual L10N location.
pocket-button.label = Pocket
pocket-button.tooltiptext = Pocket に保存
# From browser-pocket.dtd
saveToPocketCmd.label = Pocket にページを保存
saveToPocketCmd.accesskey = k
pocketMenuitem.label = Pocket のマイリストを表示

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

@ -0,0 +1,14 @@
# 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/.
# This is a temporary file, later versions of Firefox will use
# browser.properties in the usual L10N location.
pocket-button.label = Pocket
pocket-button.tooltiptext = Сохранить в Pocket
# From browser-pocket.dtd
saveToPocketCmd.label = Сохранить страницу в Pocket
saveToPocketCmd.accesskey = х
pocketMenuitem.label = Показать список Pocket

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

@ -2,8 +2,8 @@
# 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/.
# This is a temporary file and not meant for localization; later versions
# of Firefox include these strings in browser.properties
# This is a temporary file, later versions of Firefox will use
# browser.properties in the usual L10N location.
pocket-button.label = Pocket
pocket-button.tooltiptext = Save to Pocket

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

@ -186,6 +186,22 @@ nsContextMenu.prototype = {
CustomizableUI.getPlacementOfWidget("pocket-button") &&
(uri.schemeIs("http") || uri.schemeIs("https") ||
(uri.schemeIs("about") && ReaderMode.getOriginalUrl(uri.spec)));
if (canPocket) {
let locale = Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIXULChromeRegistry).
getSelectedLocale("browser");
let url = "chrome://browser/content/browser-pocket-" + locale + ".properties";
let bundle = Services.strings.createBundle(url);
let item = document.getElementById("context-pocket");
try {
item.setAttribute("label", bundle.GetStringFromName("saveToPocketCmd.label"));
item.setAttribute("accesskey", bundle.GetStringFromName("saveToPocketCmd.accesskey"));
} catch (err) {
// GetStringFromName throws when the bundle doesn't exist. In that
// case, the item will retain the browser-pocket.dtd en-US string that
// it has in the markup.
}
}
}
this.showItem("context-pocket", canPocket && window.pktApi && window.pktApi.isUserLoggedIn());
},

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

@ -23,9 +23,6 @@ const EXPECTED_REFLOWS = [
// Sometimes sessionstore collects data during this test, which causes a sync reflow
// (https://bugzilla.mozilla.org/show_bug.cgi?id=892154 will fix this)
"ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm",
// We may get a resize event, see bug 1149555.
"PreviewController.prototype.wasResizedSinceLastPreview@resource:///modules/WindowsPreviewPerTab.jsm"
];
if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {

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

@ -72,8 +72,8 @@ var tests = {
[chatWidth*2+popupWidth+2, 2, "big enough to fit 2 - nub remains visible as first is still hidden"],
[chatWidth*3+popupWidth-2, 2, "one smaller than the size necessary to display all three - first still hidden"],
[chatWidth*3+popupWidth+2, 3, "big enough to fit all - all exposed (which removes the nub)"],
[chatWidth*3+4, 3, "now the nub is hidden we can resize back down to chatWidth*3 before overflow."],
[chatWidth*3-4, 2, "4 pixels less and the first is again collapsed (and the nub re-appears)"],
[chatWidth*3+2, 3, "now the nub is hidden we can resize back down to chatWidth*3 before overflow."],
[chatWidth*3-2, 2, "2 pixels less and the first is again collapsed (and the nub re-appears)"],
[chatWidth*2+popupWidth+2, 2, "back down to just big enough to fit 2"],
[chatWidth*2+popupWidth-2, 1, "back down to just not enough to fit 2"],
[chatWidth*3+popupWidth+2, 3, "now a large jump to make all 3 visible (ie, affects 2)"],

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

@ -77,6 +77,10 @@ browser.jar:
* content/browser/browser.xul (content/browser.xul)
content/browser/browser-pocket.properties (content/browser-pocket.properties)
content/browser/browser-pocket.dtd (content/browser-pocket.dtd)
content/browser/browser-pocket-de.properties (content/browser-pocket-de.properties)
content/browser/browser-pocket-es-ES.properties (content/browser-pocket-es-ES.properties)
content/browser/browser-pocket-ja.properties (content/browser-pocket-ja.properties)
content/browser/browser-pocket-ru.properties (content/browser-pocket-ru.properties)
* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml)
* content/browser/chatWindow.xul (content/chatWindow.xul)
content/browser/tab-content.js (content/tab-content.js)

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

@ -39,10 +39,6 @@ XPCOMUtils.defineLazyGetter(this, "BrandBundle", function() {
const kBrandBundle = "chrome://branding/locale/brand.properties";
return Services.strings.createBundle(kBrandBundle);
});
XPCOMUtils.defineLazyGetter(this, "PocketBundle", function() {
const kPocketBundle = "chrome://browser/content/browser-pocket.properties";
return Services.strings.createBundle(kPocketBundle);
});
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
@ -1069,10 +1065,11 @@ if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
if (Services.prefs.getBoolPref("browser.pocket.enabled")) {
let isEnabledForLocale = true;
let browserLocale;
if (Services.prefs.getBoolPref("browser.pocket.useLocaleList")) {
let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
.getService(Ci.nsIXULChromeRegistry);
let browserLocale = chromeRegistry.getSelectedLocale("browser");
browserLocale = chromeRegistry.getSelectedLocale("browser");
let enabledLocales = [];
try {
enabledLocales = Services.prefs.getCharPref("browser.pocket.enabledLocales").split(' ');
@ -1083,14 +1080,30 @@ if (Services.prefs.getBoolPref("browser.pocket.enabled")) {
}
if (isEnabledForLocale) {
let url = "chrome://browser/content/browser-pocket-" + browserLocale + ".properties";
let strings = Services.strings.createBundle(url);
let label;
let tooltiptext;
try {
label = strings.GetStringFromName("pocket-button.label");
tooltiptext = strings.GetStringFromName("pocket-button.tooltiptext");
} catch (err) {
// GetStringFromName throws when the bundle doesn't exist. In that case,
// fall back to the en-US browser-pocket.properties.
url = "chrome://browser/content/browser-pocket.properties";
strings = Services.strings.createBundle(url);
label = strings.GetStringFromName("pocket-button.label");
tooltiptext = strings.GetStringFromName("pocket-button.tooltiptext");
}
let pocketButton = {
id: "pocket-button",
defaultArea: CustomizableUI.AREA_NAVBAR,
introducedInVersion: "pref",
type: "view",
viewId: "PanelUI-pocketView",
label: PocketBundle.GetStringFromName("pocket-button.label"),
tooltiptext: PocketBundle.GetStringFromName("pocket-button.tooltiptext"),
label: label,
tooltiptext: tooltiptext,
onViewShowing: Pocket.onPanelViewShowing,
onViewHiding: Pocket.onPanelViewHiding,

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

@ -12,6 +12,8 @@ browser.jar:
content/browser/pocket/panels/css/saved.css (panels/css/saved.css)
content/browser/pocket/panels/css/signup.css (panels/css/signup.css)
content/browser/pocket/panels/fonts/FiraSans-Regular.woff (panels/fonts/FiraSans-Regular.woff)
content/browser/pocket/panels/img/pocketerror@1x.png (panels/img/pocketerror@1x.png)
content/browser/pocket/panels/img/pocketerror@2x.png (panels/img/pocketerror@2x.png)
content/browser/pocket/panels/img/pocketlogo@1x.png (panels/img/pocketlogo@1x.png)
content/browser/pocket/panels/img/pocketlogo@2x.png (panels/img/pocketlogo@2x.png)
content/browser/pocket/panels/img/pocketlogosolo@1x.png (panels/img/pocketlogosolo@1x.png)
@ -40,6 +42,7 @@ browser.jar:
content/browser/pocket/panels/js/vendor/jquery-2.1.1.min.js (panels/js/vendor/jquery-2.1.1.min.js)
content/browser/pocket/panels/js/vendor/handlebars.runtime.js (panels/js/vendor/handlebars.runtime.js)
content/browser/pocket/panels/js/vendor/jquery.tokeninput.min.js (panels/js/vendor/jquery.tokeninput.min.js)
content/browser/pocket/panels/tmpl/saved_premiumextras.handlebars (panels/tmpl/saved_premiumextras.handlebars)
content/browser/pocket/panels/tmpl/saved_premiumshell.handlebars (panels/tmpl/saved_premiumshell.handlebars)
content/browser/pocket/panels/tmpl/saved_shell.handlebars (panels/tmpl/saved_shell.handlebars)
content/browser/pocket/panels/tmpl/signup_shell.handlebars (panels/tmpl/signup_shell.handlebars)

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

@ -49,13 +49,21 @@ var pktUI = (function() {
// -- Initialization (on startup and new windows) -- //
var inited = false;
var currentPanelDidShow, currentPanelDidHide;
var _currentPanelDidShow;
var _currentPanelDidHide;
var _isHidden = false;
var _notificationTimeout;
var prefBranch = Services.prefs.getBranch("browser.pocket.settings.");
// Init panel id at 0. The first actual panel id will have the number 1 so
// in case at some point any panel has the id 0 we know there is something
// wrong
var _panelId = 0;
var prefBranch = Services.prefs.getBranch("browser.pocket.settings.");
var savePanelWidth = 350;
var savePanelHeights = {collapsed: 153, expanded: 272};
/**
* Initalizes Pocket UI and panels
*/
@ -162,15 +170,15 @@ var pktUI = (function() {
}
function pocketPanelDidShow(event) {
if (currentPanelDidShow) {
currentPanelDidShow(event);
if (_currentPanelDidShow) {
_currentPanelDidShow(event);
}
}
function pocketPanelDidHide(event) {
if (currentPanelDidHide) {
currentPanelDidHide(event);
if (_currentPanelDidHide) {
_currentPanelDidHide(event);
}
// clear the panel
@ -299,7 +307,7 @@ var pktUI = (function() {
startheight = 436;
}
}
showPanel("chrome://browser/content/pocket/panels/signup.html?pockethost=" + Services.prefs.getCharPref("browser.pocket.site") + "&fxasignedin=" + fxasignedin + "&variant=" + pktApi.getSignupAB(), {
var panelId = showPanel("chrome://browser/content/pocket/panels/signup.html?pockethost=" + Services.prefs.getCharPref("browser.pocket.site") + "&fxasignedin=" + fxasignedin + "&variant=" + pktApi.getSignupAB(), {
onShow: function() {
},
onHide: panelDidHide,
@ -321,15 +329,30 @@ var pktUI = (function() {
var isValidURL = (typeof url !== 'undefined' && (url.startsWith("http") || url.startsWith('https')));
showPanel("chrome://browser/content/pocket/panels/saved.html?pockethost=" + Services.prefs.getCharPref("browser.pocket.site") + "&premiumStatus=" + (pktApi.isPremiumUser() ? '1' : '0'), {
var panelId = showPanel("chrome://browser/content/pocket/panels/saved.html?pockethost=" + Services.prefs.getCharPref("browser.pocket.site") + "&premiumStatus=" + (pktApi.isPremiumUser() ? '1' : '0'), {
onShow: function() {
var saveLinkMessageId = 'saveLink';
// Send error message for invalid url
if (!isValidURL) {
var error = new Error('Only links can be saved');
sendErrorMessage('saveLink', error);
// TODO: Pass key for localized error in error object
var error = {
message: 'Only links can be saved',
localizedKey: "onlylinkssaved"
};
pktUIMessaging.sendErrorMessageToPanel(panelId, saveLinkMessageId, error);
return;
}
// Check online state
if (!navigator.onLine) {
// TODO: Pass key for localized error in error object
var error = {
message: 'You must be connected to the Internet in order to save to Pocket. Please connect to the Internet and try again.'
};
pktUIMessaging.sendErrorMessageToPanel(panelId, saveLinkMessageId, error); return;
}
// Add url
var options = {
success: function(data, request) {
@ -338,7 +361,7 @@ var pktUI = (function() {
status: "success",
item: item
};
sendMessage('saveLink', successResponse);
pktUIMessaging.sendMessageToPanel(panelId, saveLinkMessageId, successResponse);
},
error: function(error, request) {
// If user is not authorized show singup page
@ -347,8 +370,13 @@ var pktUI = (function() {
return;
}
// Send error message to panel
sendErrorMessage('saveLink', error);
// If there is no error message in the error use a
// complete catch-all
var errorMessage = error.message || "There was an error when trying to save to Pocket.";
var panelError = { message: errorMessage}
// Send error message to panel
pktUIMessaging.sendErrorMessageToPanel(panelId, saveLinkMessageId, panelError);
}
}
@ -361,8 +389,8 @@ var pktUI = (function() {
pktApi.addLink(url, options);
},
onHide: panelDidHide,
width: 350,
height: 267
width: savePanelWidth,
height: pktApi.isPremiumUser() && isValidURL ? savePanelHeights.expanded : savePanelHeights.collapsed
});
}
@ -370,6 +398,9 @@ var pktUI = (function() {
* Open a generic panel
*/
function showPanel(url, options) {
// Add new panel id
_panelId += 1;
url += ("&panelId=" + _panelId);
// We don't have to hide and show the panel again if it's already shown
// as if the user tries to click again on the toolbar button the overlay
@ -389,13 +420,15 @@ var pktUI = (function() {
// For some reason setting onpopupshown and onpopuphidden on the panel directly didn't work, so
// do it this hacky way for now
currentPanelDidShow = options.onShow;
currentPanelDidHide = options.onHide;
_currentPanelDidShow = options.onShow;
_currentPanelDidHide = options.onHide;
resizePanel({
width: options.width,
height: options.height
});
return _panelId;
}
/**
@ -421,168 +454,132 @@ var pktUI = (function() {
function panelDidHide() {
}
// -- Communication to Panels -- //
// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Interaction_between_privileged_and_non-privileged_pages
/**
* Register a listener and callback for a specific messageId
*/
function addMessageListener(messageId, callback) {
document.addEventListener('PKT_'+messageId, function(e) {
// ignore to ensure we do not pick up other events in the browser
if (e.target.tagName !== 'PKTMESSAGEFROMPANELELEMENT') {
return;
}
// Send payload to callback
callback(JSON.parse(e.target.getAttribute("payload"))[0]);
// Cleanup the element
e.target.parentNode.removeChild(e.target);
}, false, true);
}
/**
* Remove a message listener
*/
function removeMessageListener(messageId, callback) {
document.removeMessageListener('PKT_'+messageId, callback);
}
/**
* Send a message to the panel's iframe
*/
function sendMessage(messageId, payload) {
var doc = getPanelFrame().contentWindow.document;
var AnswerEvt = doc.createElement("PKTMessage");
AnswerEvt.setAttribute("payload", JSON.stringify([payload]));
doc.documentElement.appendChild(AnswerEvt);
var event = doc.createEvent("HTMLEvents");
event.initEvent('PKT_'+messageId, true, false);
AnswerEvt.dispatchEvent(event);
}
/**
* Helper function to package an error object and send it to the panel iframe as a message response
*/
function sendErrorMessage(messageId, error) {
var errorResponse = {status: "error", error: error.message};
sendMessage(messageId, errorResponse);
}
/**
* Register all of the messages needed for the panels
*/
function registerEventMessages() {
// TODO : There are likely some possible race conditions possible here, for example if the user clicks the button quickly multiple times, due to the async property of the messages, a message may be picked up for an older panel. We should consider updating this to include some sort of panelId that changes per open.
var iframe = getPanelFrame();
// Only register the messages once
if (iframe.getAttribute('did_init') == 1) {
return;
var didInitAttributeKey = 'did_init';
var didInitMessageListener = iframe.getAttribute(didInitAttributeKey);
if (typeof didInitMessageListener !== "undefined" && didInitMessageListener == 1) {
return;
}
iframe.setAttribute('did_init', 1);
iframe.setAttribute(didInitAttributeKey, 1);
// When the panel is displayed it generated an event called
// "show": we will listen for that event and when it happens,
// send our own "show" event to the panel's script, so the
// script can prepare the panel for display.
addMessageListener("show", function(payload) {
var _showMessageId = "show";
pktUIMessaging.addMessageListener(_showMessageId, function(panelId, data) {
// Let panel know that it is ready
sendMessage('show');
pktUIMessaging.sendMessageToPanel(panelId, _showMessageId);
});
// Open a new tab with a given url and activate if
addMessageListener("openTabWithUrl", function(payload) {
// Open a new tab with a given url and activate if
var _openTabWithUrlMessageId = "openTabWithUrl";
pktUIMessaging.addMessageListener(_openTabWithUrlMessageId, function(panelId, data) {
// Check if the tab should become active after opening
var activate = true;
if (typeof payload.activate !== "undefined") {
activate = payload.activate;
if (typeof data.activate !== "undefined") {
activate = data.activate;
}
openTabWithUrl(payload.url, activate);
sendMessage("openTabWithUrlResponse", payload.url);
var url = data.url;
openTabWithUrl(url, activate);
pktUIMessaging.sendResponseMessageToPanel(panelId, _openTabWithUrlMessageId, url);
});
// Close the panel
addMessageListener("close", function(payload) {
var _closeMessageId = "close";
pktUIMessaging.addMessageListener(_closeMessageId, function(panelId, data) {
getPanel().hidePopup();
});
// Send the current url to the panel
addMessageListener("getCurrentURL", function(payload) {
sendMessage('getCurrentURLResponse', getCurrentUrl());
var _getCurrentURLMessageId = "getCurrentURL";
pktUIMessaging.addMessageListener(_getCurrentURLMessageId, function(panelId, data) {
pktUIMessaging.sendResponseMessageToPanel(panelId, _getCurrentURLMessageId, getCurrentUrl());
});
var _resizePanelMessageId = "resizePanel";
pktUIMessaging.addMessageListener(_resizePanelMessageId, function(panelId, data) {
resizePanel(data);
});
// Callback post initialization to tell background script that panel is "ready" for communication.
addMessageListener("listenerReady", function(payload) {
pktUIMessaging.addMessageListener("listenerReady", function(panelId, data) {
});
pktUIMessaging.addMessageListener("collapseSavePanel", function(panelId, data) {
if (!pktApi.isPremiumUser())
resizePanel({width:savePanelWidth, height:savePanelHeights.collapsed});
});
addMessageListener("resizePanel", function(payload) {
resizePanel(payload);
pktUIMessaging.addMessageListener("expandSavePanel", function(panelId, data) {
resizePanel({width:savePanelWidth, height:savePanelHeights.expanded});
});
// Ask for recently accessed/used tags for auto complete
addMessageListener("getTags", function(payload) {
var _getTagsMessageId = "getTags";
pktUIMessaging.addMessageListener(_getTagsMessageId, function(panelId, data) {
pktApi.getTags(function(tags, usedTags) {
sendMessage('getTagsResponse', {tags, usedTags});
pktUIMessaging.sendResponseMessageToPanel(panelId, _getTagsMessageId, {
tags: tags,
usedTags: usedTags
});
});
});
// Ask for suggested tags based on passed url
addMessageListener("getSuggestedTags", function(payload) {
var responseMessageId = "getSuggestedTagsResponse";
pktApi.getSuggestedTagsForURL(payload.url, {
var _getSuggestedTagsMessageId = "getSuggestedTags";
pktUIMessaging.addMessageListener(_getSuggestedTagsMessageId, function(panelId, data) {
pktApi.getSuggestedTagsForURL(data.url, {
success: function(data, response) {
var suggestedTags = data.suggested_tags;
var successResponse = {
status: "success",
value: {
"suggestedTags" : suggestedTags
suggestedTags : suggestedTags
}
}
sendMessage(responseMessageId, successResponse);
pktUIMessaging.sendResponseMessageToPanel(panelId, _getSuggestedTagsMessageId, successResponse);
},
error: function(error, response) {
sendErrorMessage(responseMessageId, error);
pktUIMessaging.sendErrorResponseMessageToPanel(panelId, _getSuggestedTagsMessageId, error);
}
})
});
// Pass url and array list of tags, add to existing save item accordingly
addMessageListener("addTags", function(payload) {
var responseMessageId = "addTagsResponse";
pktApi.addTagsToURL(payload.url, payload.tags, {
var _addTagsMessageId = "addTags";
pktUIMessaging.addMessageListener(_addTagsMessageId, function(panelId, data) {
pktApi.addTagsToURL(data.url, data.tags, {
success: function(data, response) {
var successResponse = {status: "success"};
sendMessage(responseMessageId, successResponse);
var successResponse = {status: "success"};
pktUIMessaging.sendResponseMessageToPanel(panelId, _addTagsMessageId, successResponse);
},
error: function(error, response) {
sendErrorMessage(responseMessageId, error);
pktUIMessaging.sendErrorResponseMessageToPanel(panelId, _addTagsMessageId, error);
}
});
});
// Based on clicking "remove page" CTA, and passed unique item id, remove the item
addMessageListener("deleteItem", function(payload) {
var responseMessageId = "deleteItemResponse";
pktApi.deleteItem(payload.itemId, {
var _deleteItemMessageId = "deleteItem";
pktUIMessaging.addMessageListener(_deleteItemMessageId, function(panelId, data) {
pktApi.deleteItem(data.itemId, {
success: function(data, response) {
var successResponse = {status: "success"};
sendMessage(responseMessageId, successResponse);
var successResponse = {status: "success"};
pktUIMessaging.sendResponseMessageToPanel(panelId, _deleteItemMessageId, successResponse);
},
error: function(error, response) {
sendErrorMessage(responseMessageId, error);
pktUIMessaging.sendErrorResponseMessageToPanel(panelId, _deleteItemMessageId, error);
}
})
});
@ -748,3 +745,149 @@ var pktUI = (function() {
isHidden
};
}());
// -- Communication to Background -- //
// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Interaction_between_privileged_and_non-privileged_pages
var pktUIMessaging = (function() {
/**
* Prefix message id for message listening
*/
function prefixedMessageId(messageId) {
return 'PKT_' + messageId;
}
/**
* Register a listener and callback for a specific messageId
*/
function addMessageListener(messageId, callback) {
document.addEventListener(prefixedMessageId(messageId), function(e) {
// ignore to ensure we do not pick up other events in the browser
if (e.target.tagName !== 'PKTMESSAGEFROMPANELELEMENT') {
return;
}
// Pass in information to callback
var payload = JSON.parse(e.target.getAttribute("payload"))[0];
var panelId = payload.panelId;
var data = payload.data;
callback(panelId, data);
// Cleanup the element
e.target.parentNode.removeChild(e.target);
}, false, true);
}
/**
* Remove a message listener
*/
function removeMessageListener(messageId, callback) {
document.removeEventListener(prefixedMessageId(messageId), callback);
}
/**
* Send a message to the panel's iframe
*/
function sendMessageToPanel(panelId, messageId, payload) {
if (!isPanelIdValid(panelId)) { return; };
var panelFrame = document.getElementById('pocket-panel-iframe');
if (!isPocketPanelFrameValid(panelFrame)) { return; }
var doc = panelFrame.contentWindow.document;
var documentElement = doc.documentElement;
// Send message to panel
var panelMessageId = prefixedMessageId(panelId + '_' + messageId);
var AnswerEvt = doc.createElement("PKTMessage");
AnswerEvt.setAttribute("payload", JSON.stringify([payload]));
documentElement.appendChild(AnswerEvt);
var event = doc.createEvent("HTMLEvents");
event.initEvent(panelMessageId, true, false);
AnswerEvt.dispatchEvent(event);
}
function sendResponseMessageToPanel(panelId, messageId, payload) {
var responseMessageId = messageId + "Response";
sendMessageToPanel(panelId, responseMessageId, payload);
}
/**
* Helper function to package an error object and send it to the panel
* iframe as a message response
*/
function sendErrorMessageToPanel(panelId, messageId, error) {
var errorResponse = {status: "error", error: error};
sendMessageToPanel(panelId, messageId, errorResponse);
}
function sendErrorResponseMessageToPanel(panelId, messageId, error) {
var errorResponse = {status: "error", error: error};
sendResponseMessageToPanel(panelId, messageId, errorResponse);
}
/**
* Validation
*/
function isPanelIdValid(panelId) {
// First check if panelId has a valid value > 0. We set the panelId to
// 0 to start. But if for some reason the message is attempted to be
// sent before the panel has a panelId, then it's going to send out
// a message with panelId 0, which is never going to be heard. If this
// happens, it means some race condition occurred where the panel was
// trying to communicate before it should.
if (panelId === 0) {
console.warn("Tried to send message to panel with id 0.")
return false;
}
return true
}
function isPocketPanelFrameValid(panelFrame) {
// Check if panel is available if not throw a warning and bailout.
// We likely try to send to a panel that is not visible anymore
if (typeof panelFrame === "undefined") {
console.warn("Pocket panel frame is undefined");
return false;
}
var contentWindow = panelFrame.contentWindow;
if (typeof contentWindow == "undefined") {
console.warn("Pocket panel frame content window is undefined");
return false;
}
var doc = contentWindow.document;
if (typeof doc === "undefined") {
console.warn("Pocket panel frame content window document is undefined");
return false;
}
var documentElement = doc.documentElement;
if (typeof documentElement === "undefined") {
console.warn("Pocket panel frame content window document document element is undefined");
return false;
}
return true;
}
/**
* Public
*/
return {
addMessageListener: addMessageListener,
removeMessageListener: removeMessageListener,
sendMessageToPanel: sendMessageToPanel,
sendResponseMessageToPanel: sendResponseMessageToPanel,
sendErrorMessageToPanel: sendErrorMessageToPanel,
sendErrorResponseMessageToPanel: sendErrorResponseMessageToPanel
}
}());

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

@ -397,3 +397,28 @@ td,
th {
padding: 0;
}
/* Normalization for FF panel defauts
========================================================================== */
html {
outline: none;
padding: 0;
}
a {
color: #0095dd;
margin: 0;
outline: none;
padding: 0;
text-decoration: none;
}
a:hover,
a:active {
color: #008acb;
text-decoration: underline;
}
a:active {
color: #006b9d;
}

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

@ -52,12 +52,15 @@
.pkt_ext_containersaved .pkt_ext_loadingspinner {
position: relative;
display: inline-block;
width: 2.5em;
height: 2.5em;
margin: 2em 0 0;
left: 50%;
margin: 2em 0 0 -1.25em;
font-size: 10px;
text-indent: 999em;
position: absolute;
top: 4em;
overflow: hidden;
width: 2.5em;
animation: pkt_ext_spin 0.7s infinite steps(8);
}
.pkt_ext_containersaved .pkt_ext_loadingspinner:before,
@ -96,7 +99,7 @@
.pkt_ext_containersaved .pkt_ext_initload {
left: 0;
position: absolute;
top: 1em;
top: 0;
width: 100%;
}
.pkt_ext_containersaved .pkt_ext_detail {
@ -106,7 +109,6 @@
z-index: 10;
}
.pkt_ext_container_detailactive .pkt_ext_initload {
transition: opacity 0.2s ease-out;
opacity: 0;
}
.pkt_ext_container_detailactive .pkt_ext_initload .pkt_ext_loadingspinner,
@ -116,7 +118,6 @@
.pkt_ext_container_detailactive .pkt_ext_detail {
max-height: 20em;
opacity: 1;
transition: opacity 0.2s ease-out;
}
.pkt_ext_container_finalstate .pkt_ext_edit_msg,
.pkt_ext_container_finalstate .pkt_ext_tag_detail,
@ -151,30 +152,9 @@
@keyframes fade_in_out {
0% {
opacity: 1;
top: 0;
}
50% {
opacity: 0;
top: 0;
}
51% {
opacity: 0;
top: 10px;
}
100% {
opacity: 1;
top: 10px;
}
}
@keyframes fade_in_outalt {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
51% {
opacity: 0;
}
100% {
opacity: 1;
@ -182,18 +162,17 @@
}
.pkt_ext_container_finalstate h2 {
animation: fade_in_out 0.4s ease-out;
top: 10px;
}
.pkt_ext_container_finalerrorstate h2 {
animation: fade_int_outalt 0.4s ease-out;
animation: none;
color: #d74345;
top: 0;
}
.pkt_ext_containersaved .pkt_ext_errordetail {
display: none;
font-size: 12px;
font-weight: normal;
left: 6.4em;
max-width: 21em;
opacity: 0;
position: absolute;
top: 2.7em;
@ -220,20 +199,33 @@
background-size: 44px 40px;
}
}
.pkt_ext_container_finalerrorstate .pkt_ext_logo {
background-image: url(../img/pocketerror@1x.png);
height: 44px;
width: 44px;
}
@media (min-resolution: 1.1dppx) {
.pkt_ext_container_finalerrorstate .pkt_ext_logo {
background-image: url(../img/pocketerror@2x.png);
background-size: 44px 44px;
}
}
.pkt_ext_containersaved .pkt_ext_topdetail {
float: left;
}
.pkt_ext_containersaved .pkt_ext_edit_msg {
box-sizing: border-box;
display: none;
font-size: 0.875em;
font-size: 0.75em;
left: auto;
padding: 0 1.4em;
position: absolute;
text-align: center;
top: 4.3em;
text-align: left;
top: 8.7em;
width: 100%;
}
.pkt_ext_containersaved .pkt_ext_edit_msg_error {
color: #c10000;
color: #d74345;
}
.pkt_ext_containersaved .pkt_ext_edit_msg_active {
display: block;
@ -357,6 +349,9 @@
padding: 0;
display: flex;
}
.pkt_ext_containersaved .pkt_ext_tag_error {
border: none;
}
.pkt_ext_containersaved .pkt_ext_tag_input_wrapper {
box-sizing: border-box;
flex: 1;
@ -374,6 +369,9 @@
padding-left: 0.5em;
padding-right: 0.5em;
}
.pkt_ext_containersaved .pkt_ext_tag_error .pkt_ext_tag_input_wrapper {
border: 1px solid #d74345;
}
.pkt_ext_containersaved .pkt_ext_tag_input_wrapper .token-input-list {
display: block;
left: 0;
@ -418,6 +416,7 @@
}
.pkt_ext_containersaved .pkt_ext_btn {
box-sizing: border-box;
color: #333;
float: none;
font-size: 0.875em;
font-size: 14px;
@ -425,13 +424,27 @@
height: 2.2em;
min-width: 4em;
padding: 0.5em 0;
text-decoration: none;
text-transform: none;
width: auto;
}
.pkt_ext_containersaved .pkt_ext_btn_disabled {
background-color: #ededed;
.pkt_ext_containersaved .pkt_ext_btn:hover {
background-color: #ebebeb;
}
.pkt_ext_containersaved .pkt_ext_btn:active {
background-color: #dadada;
}
.pkt_ext_containersaved .pkt_ext_btn_disabled,
.pkt_ext_containersaved .pkt_ext_btn_disabled:hover,
.pkt_ext_containersaved .pkt_ext_btn_disabled:active {
background-color: transparent;
cursor: default;
opacity: 0.5;
opacity: 0.4;
}
.pkt_ext_containersaved .pkt_ext_tag_error .pkt_ext_btn {
border: 1px solid #c3c3c3;
border-width: 1px 1px 1px 0;
height: 2.35em;
}
.pkt_ext_containersaved .autocomplete-suggestions {
margin-top: 2.2em;
@ -439,19 +452,27 @@
/*=Recent/suggested tags
--------------------------------------------------------------------------------------- */
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail {
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail,
.pkt_ext_containersaved .pkt_ext_suggestedtag_detailshown {
border-top: 1px solid #c1c1c1;
bottom: 0;
background: #ebebeb;
clear: both;
left: 0;
opacity: 0;
visibility: hidden;
min-height: 110px;
position: fixed;
visibility: hidden;
width: 100%;
}
.pkt_ext_container_detailactive .pkt_ext_suggestedtag_detail {
.pkt_ext_container_detailactive .pkt_ext_suggestedtag_detail,
.pkt_ext_containersaved .pkt_ext_suggestedtag_detailshown {
opacity: 1;
transition: opacity 0.2s ease-out, visibility 0.2s ease-out;
visibility: visible;
}
.pkt_ext_containersaved .pkt_ext_suggestedtag_detailshown {
padding: 4px 0;
}
.pkt_ext_container_finalstate .pkt_ext_suggestedtag_detail {
opacity: 0;
visibility: hidden;
@ -488,6 +509,11 @@
overflow: hidden;
padding: 2px 0 0 0;
}
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail ul {
height: auto;
margin: 0 2em 0 0;
padding-top: 6px;
}
.pkt_ext_containersaved .pkt_ext_recenttag_detail li,
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail li {
background: none;
@ -512,6 +538,9 @@
text-align: left;
top: 2em;
}
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail .suggestedtag_msg {
margin-right: 1.3em;
}
.pkt_ext_containersaved .token_tag {
border-radius: 4px;
background: #f7f7f7;
@ -522,7 +551,7 @@
font-weight: normal;
letter-spacing: normal;
margin-right: 0.5em;
padding: 0.125em 0.3125em;
padding: 0.125em 0.625em;
text-decoration: none;
text-transform: none;
}
@ -639,7 +668,7 @@
border: 1px solid #c3c3c3;
overflow: hidden;
margin: 0;
padding: 0 5px;
padding: 0 8px;
background-color: #f7f7f7;
color: #000;
font-weight: normal;
@ -688,7 +717,7 @@
cursor: pointer;
display: inline-block;
height: 8px;
margin: 0 2px 0 8px;
margin: 0 0 0 8px;
overflow: hidden;
width: 8px;
text-indent: -99px;

Двоичные данные
browser/components/pocket/panels/img/pocketerror@1x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичные данные
browser/components/pocket/panels/img/pocketerror@2x.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 21 KiB

После

Ширина:  |  Высота:  |  Размер: 22 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 66 KiB

После

Ширина:  |  Высота:  |  Размер: 72 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 40 KiB

После

Ширина:  |  Высота:  |  Размер: 44 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 130 KiB

После

Ширина:  |  Высота:  |  Размер: 145 KiB

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

@ -3,10 +3,12 @@ Translations.en =
{
addtags: "Add Tags",
alreadyhaveacct: "Already a Pocket user?",
errorgeneric: "There was an error when trying to save to Pocket.",
learnmore: "Learn More",
loginnow: "Log in",
maxtaglength: "Tags are limited to 25 characters",
mustbeconnected: "You must be connected to the Internet in order to save to Pocket. Please check your connection and try again.",
onlylinkssaved: "Only links can be saved",
or: "or",
pagenotsaved: "Page Not Saved",
pageremoved: "Page Removed",
pagesaved: "Saved to Pocket",
@ -14,6 +16,7 @@ Translations.en =
processingtags: "Adding tags...",
removepage: "Remove Page",
save: "Save",
saving: "Saving...",
signupemail: "Sign up with email",
signuptosave: "Sign up for Pocket. Its free.",
suggestedtags: "Suggested Tags",

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

@ -1,11 +1,27 @@
// Documentation of methods used here are at:
// https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Interaction_between_privileged_and_non-privileged_pages
var Messaging = (function() {
var pktPanelMessaging = (function() {
function addMessageListener(messageId, callback) {
function panelIdFromURL(url) {
var panelId = url.match(/panelId=([\w|\d|\.]*)&?/);
if (panelId && panelId.length > 1) {
return panelId[1];
}
document.addEventListener('PKT_' + messageId, function(e) {
return 0;
}
function prefixedMessageId(messageId) {
return 'PKT_' + messageId;
}
function panelPrefixedMessageId(panelId, messageId) {
return prefixedMessageId(panelId + '_' + messageId);
}
function addMessageListener(panelId, messageId, callback) {
document.addEventListener(panelPrefixedMessageId(panelId, messageId), function(e) {
callback(JSON.parse(e.target.getAttribute("payload"))[0]);
@ -16,33 +32,36 @@ var Messaging = (function() {
}
function removeMessageListener(messageId, callback) {
document.removeEventListener('PKT_' + messageId, callback);
function removeMessageListener(panelId, messageId, callback) {
document.removeEventListener(panelPrefixedMessageId(panelId, messageId), callback);
}
function sendMessage(messageId, payload, callback) {
function sendMessage(panelId, messageId, payload, callback) {
// Payload needs to be an object in format:
// { panelId: panelId, data: {} }
var messagePayload = {
panelId: panelId,
data: (payload || {})
};
// Create a callback to listen for a response
if (callback) {
// Message response id is messageId + "Response"
var messageResponseId = messageId + "Response";
var responseListener = function(responsePayload) {
callback(responsePayload);
removeMessageListener(messageResponseId, responseListener);
removeMessageListener(panelId, messageResponseId, responseListener);
}
addMessageListener(messageResponseId, responseListener);
addMessageListener(panelId, messageResponseId, responseListener);
}
// Send message
var element = document.createElement("PKTMessageFromPanelElement");
element.setAttribute("payload", JSON.stringify([payload]));
element.setAttribute("payload", JSON.stringify([messagePayload]));
document.documentElement.appendChild(element);
var evt = document.createEvent("Events");
evt.initEvent('PKT_'+messageId, true, false);
evt.initEvent(prefixedMessageId(messageId), true, false);
element.dispatchEvent(evt);
}
@ -51,6 +70,7 @@ var Messaging = (function() {
* Public functions
*/
return {
panelIdFromURL: panelIdFromURL,
addMessageListener : addMessageListener,
removeMessageListener : removeMessageListener,
sendMessage: sendMessage

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

@ -11,6 +11,7 @@ var PKT_SAVED_OVERLAY = function (options)
this.savedItemId = 0;
this.savedUrl = '';
this.premiumStatus = false;
this.panelId = 0;
this.preventCloseTimerCancel = false;
this.closeValid = true;
this.mouseInside = false;
@ -33,14 +34,8 @@ var PKT_SAVED_OVERLAY = function (options)
var newtag = $('<li><a href="#" class="token_tag ' + tagclass + '">' + tags[i] + '</a></li>');
container.append(newtag);
var templeft = newtag.position().left;
if (templeft > newtagleft) {
this.cxt_suggested_available++;
newtagleft = templeft;
}
else {
newtag.remove();
break;
}
this.cxt_suggested_available++;
newtagleft = templeft;
}
};
this.fillUserTags = function() {
@ -190,9 +185,6 @@ var PKT_SAVED_OVERLAY = function (options)
}
}
}
else {
returnlist.push({name:'blah'});
}
if (!$('.token-input-dropdown-tag').data('init')) {
$('.token-input-dropdown-tag').css('width',inputwrapper.outerWidth()).data('init');
inputwrapper.append($('.token-input-dropdown-tag'));
@ -202,7 +194,7 @@ var PKT_SAVED_OVERLAY = function (options)
textToData: function(text) {
if($.trim(text).length > 25 || !$.trim(text).length) {
if (text.length > 25) {
$('.pkt_ext_edit_msg').addClass('pkt_ext_edit_msg_error pkt_ext_edit_msg_active').text(myself.dictJSON.invalidTags);
myself.showTagsError(myself.dictJSON.maxtaglength);
changestamp = Date.now();
setTimeout(function() {
$('.token-input-input-token input').val(text).focus();
@ -211,7 +203,7 @@ var PKT_SAVED_OVERLAY = function (options)
return null;
}
else {
$('.pkt_ext_edit_msg').removeClass('pkt_ext_edit_msg_error pkt_ext_edit_msg_active').text('');
myself.hideTagsError();
return {name:myself.sanitizeText(text.toLowerCase())};
}
},
@ -258,6 +250,12 @@ var PKT_SAVED_OVERLAY = function (options)
changestamp = Date.now();
myself.showActiveTags();
myself.checkPlaceholderStatus();
},
onShowDropdown: function() {
thePKT_SAVED.sendMessage("expandSavePanel");
},
onHideDropdown: function() {
thePKT_SAVED.sendMessage("collapseSavePanel");
}
});
$('body').on('keydown',function(e) {
@ -364,6 +362,14 @@ var PKT_SAVED_OVERLAY = function (options)
myself.closePopup();
});
};
this.showTagsError = function(msg) {
$('.pkt_ext_edit_msg').addClass('pkt_ext_edit_msg_error pkt_ext_edit_msg_active').text(msg);
$('.pkt_ext_tag_detail').addClass('pkt_ext_tag_error');
};
this.hideTagsError = function(msg) {
$('.pkt_ext_edit_msg').removeClass('pkt_ext_edit_msg_error pkt_ext_edit_msg_active').text('');
$('.pkt_ext_tag_detail').removeClass('pkt_ext_tag_error');
};
this.showActiveTags = function() {
if (!$('.pkt_ext_suggestedtag_detail').length) {
return;
@ -567,6 +573,7 @@ PKT_SAVED_OVERLAY.prototype = {
if (this.premiumStatus && !$('.pkt_ext_suggestedtag_detail').length)
{
$('body').append(Handlebars.templates.saved_premiumshell(this.dictJSON));
$('.pkt_ext_initload').append(Handlebars.templates.saved_premiumextras(this.dictJSON));
}
}
};
@ -586,11 +593,11 @@ PKT_SAVED.prototype = {
},
addMessageListener: function(messageId, callback) {
Messaging.addMessageListener(messageId, callback);
pktPanelMessaging.addMessageListener(this.overlay.panelId, messageId, callback);
},
sendMessage: function(messageId, payload, callback) {
Messaging.sendMessage(messageId, payload, callback);
pktPanelMessaging.sendMessage(this.overlay.panelId, messageId, payload, callback);
},
create: function() {
@ -605,6 +612,9 @@ PKT_SAVED.prototype = {
{
myself.overlay.pockethost = host[1];
}
myself.overlay.panelId = pktPanelMessaging.panelIdFromURL(window.location.href);
myself.overlay.create();
// tell back end we're ready
@ -614,7 +624,21 @@ PKT_SAVED.prototype = {
thePKT_SAVED.addMessageListener("saveLink",function(resp)
{
if (resp.status == 'error') {
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,myself.overlay.dictJSON.onlylinkssaved);
if (typeof resp.error == 'object')
{
if (resp.error.localizedKey)
{
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,myself.overlay.dictJSON[resp.error.localizedKey]);
}
else
{
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,resp.error.message);
}
}
else
{
myself.overlay.showStateError(myself.overlay.dictJSON.pagenotsaved,myself.overlay.dictJSON.errorgeneric);
}
return;
}

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

@ -22,6 +22,7 @@ var PKT_SIGNUP_OVERLAY = function (options)
this.variant = "";
this.pockethost = "getpocket.com";
this.fxasignedin = false;
this.panelId = 0;
this.dictJSON = {};
this.initCloseTabEvents = function() {
$('.btn,.pkt_ext_learnmore,.alreadyhave > a').click(function(e)
@ -162,6 +163,8 @@ PKT_SIGNUP_OVERLAY.prototype = {
this.pockethost = host[1];
}
this.panelId = pktPanelMessaging.panelIdFromURL(window.location.href);
if (this.active)
{
return;
@ -207,11 +210,11 @@ PKT_SIGNUP.prototype = {
},
addMessageListener: function(messageId, callback) {
Messaging.addMessageListener(messageId, callback);
pktPanelMessaging.addMessageListener(this.overlay.panelId, messageId, callback);
},
sendMessage: function(messageId, payload, callback) {
Messaging.sendMessage(messageId, payload, callback);
pktPanelMessaging.sendMessage(this.overlay.panelId, messageId, payload, callback);
},
create: function() {

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

@ -1,5 +1,8 @@
(function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
templates['saved_premiumextras'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
return "<div class=\"pkt_ext_suggestedtag_detailshown\">\n</div>";
},"useData":true});
templates['saved_premiumshell'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return "<div class=\"pkt_ext_suggestedtag_detail pkt_ext_suggestedtag_detail_loading\">\n <h4>"
@ -8,19 +11,21 @@ templates['saved_premiumshell'] = template({"compiler":[6,">= 2.0.0-beta.1"],"ma
},"useData":true});
templates['saved_shell'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return "<div class=\"pkt_ext_initload\"> \n <div class=\"pkt_ext_loadingspinner\"><div></div></div>\n</div> \n<div class=\"pkt_ext_detail\"> \n <div class=\"pkt_ext_logo\"></div>\n <div class=\"pkt_ext_topdetail\">\n <h2>"
return "<div class=\"pkt_ext_initload\">\n <div class=\"pkt_ext_logo\"></div> \n <div class=\"pkt_ext_topdetail\">\n <h2>"
+ escapeExpression(((helper = (helper = helpers.saving || (depth0 != null ? depth0.saving : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"saving","hash":{},"data":data}) : helper)))
+ "</h2>\n </div> \n <div class=\"pkt_ext_loadingspinner\"><div></div></div>\n</div> \n<div class=\"pkt_ext_detail\"> \n <div class=\"pkt_ext_logo\"></div>\n <div class=\"pkt_ext_topdetail\">\n <h2>"
+ escapeExpression(((helper = (helper = helpers.pagesaved || (depth0 != null ? depth0.pagesaved : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pagesaved","hash":{},"data":data}) : helper)))
+ "</h2>\n <h3 class=\"pkt_ext_errordetail\"></h3>\n <nav class=\"pkt_ext_item_actions pkt_ext_cf\">\n <ul>\n <li><a class=\"pkt_ext_removeitem\" href=\"#\">"
+ escapeExpression(((helper = (helper = helpers.removepage || (depth0 != null ? depth0.removepage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"removepage","hash":{},"data":data}) : helper)))
+ "</a></li>\n <li class=\"pkt_ext_actions_separator\"></li> \n <li><a class=\"pkt_ext_openpocket\" href=\"http://"
+ "</a></li>\n <li class=\"pkt_ext_actions_separator\"></li> \n <li><a class=\"pkt_ext_openpocket\" href=\"https://"
+ escapeExpression(((helper = (helper = helpers.pockethost || (depth0 != null ? depth0.pockethost : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"pockethost","hash":{},"data":data}) : helper)))
+ "/a?src=ff_ext_saved\" target=\"_blank\">"
+ escapeExpression(((helper = (helper = helpers.viewlist || (depth0 != null ? depth0.viewlist : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"viewlist","hash":{},"data":data}) : helper)))
+ "</a></li>\n </ul>\n </nav> \n </div>\n <p class=\"pkt_ext_edit_msg\"></p> \n <div class=\"pkt_ext_tag_detail pkt_ext_cf\">\n <div class=\"pkt_ext_tag_input_wrapper\">\n <div class=\"pkt_ext_tag_input_blocker\"></div>\n <input class=\"pkt_ext_tag_input\" type=\"text\" placeholder=\""
+ "</a></li>\n </ul>\n </nav> \n </div>\n <div class=\"pkt_ext_tag_detail pkt_ext_cf\">\n <div class=\"pkt_ext_tag_input_wrapper\">\n <div class=\"pkt_ext_tag_input_blocker\"></div>\n <input class=\"pkt_ext_tag_input\" type=\"text\" placeholder=\""
+ escapeExpression(((helper = (helper = helpers.addtags || (depth0 != null ? depth0.addtags : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"addtags","hash":{},"data":data}) : helper)))
+ "\">\n </div>\n <a href=\"#\" class=\"pkt_ext_btn pkt_ext_btn_disabled\">"
+ escapeExpression(((helper = (helper = helpers.save || (depth0 != null ? depth0.save : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"save","hash":{},"data":data}) : helper)))
+ "</a>\n </div>\n</div>";
+ "</a>\n </div>\n <p class=\"pkt_ext_edit_msg\"></p> \n</div>";
},"useData":true});
templates['signup_shell'] = template({"1":function(depth0,helpers,partials,data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -0,0 +1,2 @@
<div class="pkt_ext_suggestedtag_detailshown">
</div>

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

@ -1,4 +1,8 @@
<div class="pkt_ext_initload">
<div class="pkt_ext_initload">
<div class="pkt_ext_logo"></div>
<div class="pkt_ext_topdetail">
<h2>{{saving}}</h2>
</div>
<div class="pkt_ext_loadingspinner"><div></div></div>
</div>
<div class="pkt_ext_detail">
@ -10,11 +14,10 @@
<ul>
<li><a class="pkt_ext_removeitem" href="#">{{removepage}}</a></li>
<li class="pkt_ext_actions_separator"></li>
<li><a class="pkt_ext_openpocket" href="http://{{pockethost}}/a?src=ff_ext_saved" target="_blank">{{viewlist}}</a></li>
<li><a class="pkt_ext_openpocket" href="https://{{pockethost}}/a?src=ff_ext_saved" target="_blank">{{viewlist}}</a></li>
</ul>
</nav>
</div>
<p class="pkt_ext_edit_msg"></p>
<div class="pkt_ext_tag_detail pkt_ext_cf">
<div class="pkt_ext_tag_input_wrapper">
<div class="pkt_ext_tag_input_blocker"></div>
@ -22,4 +25,5 @@
</div>
<a href="#" class="pkt_ext_btn pkt_ext_btn_disabled">{{save}}</a>
</div>
<p class="pkt_ext_edit_msg"></p>
</div>

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

@ -223,8 +223,6 @@ var pktApi = (function() {
}
return;
}
// TODO: Better error handling
if (options.error) {
// In case the user did revoke the access token or it's not
// valid anymore clear the user data
@ -232,15 +230,10 @@ var pktApi = (function() {
clearUserData();
}
// Check to handle Pocket error
var errorMessage = request.getResponseHeader("X-Error");
if (typeof errorMessage !== "undefined") {
options.error(new Error(errorMessage), request);
return;
}
// Handle other error
options.error(new Error(request.statusText), request);
// Handle error message
var errorMessage = request.getResponseHeader("X-Error") || request.statusText;
var error = {message: errorMessage};
options.error(error, request);
}
}
};

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

@ -254,7 +254,10 @@ Section "-InstallStartCleanup"
${CleanUpdateDirectories} "Mozilla\Firefox" "Mozilla\updates"
${RemoveDeprecatedFiles}
${RemovePrecompleteEntries} "false"
StrCpy $R2 "false"
StrCpy $R3 "false"
${RemovePrecompleteEntries} "$R2" "$R3"
${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js"
Delete "$INSTDIR\defaults\pref\channel-prefs.js"

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

@ -71,8 +71,6 @@ Var CanSetAsDefault
Var InstallCounterStep
Var InstallStepSize
Var InstallTotalSteps
Var ProgressCompleted
Var ProgressTotal
Var TmpVal
Var ExitCode
@ -260,7 +258,6 @@ Var ControlRightPX
!insertmacro IsUserAdmin
!insertmacro RemovePrecompleteEntries
!insertmacro SetBrandNameVars
!insertmacro ITBL3Create
!insertmacro UnloadUAC
VIAddVersionKey "FileDescription" "${BrandShortName} Stub Installer"
@ -1296,9 +1293,6 @@ Function createInstall
StrCpy $InstallTotalSteps ${InstallCleanTotalSteps}
${EndIf}
${ITBL3Create}
${ITBL3SetProgressState} "${TBPF_INDETERMINATE}"
${NSD_CreateTimer} StartDownload ${DownloadIntervalMS}
LockWindow off
@ -1321,21 +1315,6 @@ Function StartDownload
${EndIf}
FunctionEnd
Function SetProgressBars
SendMessage $Progressbar ${PBM_SETPOS} $ProgressCompleted 0
${ITBL3SetProgressValue} "$ProgressCompleted" "$ProgressTotal"
FunctionEnd
Function RemoveFileProgressCallback
IntOp $InstallCounterStep $InstallCounterStep + 2
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
FunctionEnd
Function OnDownload
InetBgDL::GetStats
# $0 = HTTP status code, 0=Completed
@ -1354,7 +1333,6 @@ Function OnDownload
${NSD_AddStyle} $Progressbar ${PBS_MARQUEE}
SendMessage $Progressbar ${PBM_SETMARQUEE} 1 \
$ProgressbarMarqueeIntervalMS ; start=1|stop=0 interval(ms)=+N
${ITBL3SetProgressState} "${TBPF_INDETERMINATE}"
${EndIf}
InetBgDL::Get /RESET /END
StrCpy $DownloadSizeBytes ""
@ -1412,9 +1390,8 @@ Function OnDownload
SendMessage $Progressbar ${PBM_SETMARQUEE} 0 0 ; start=1|stop=0 interval(ms)=+N
${RemoveStyle} $Progressbar ${PBS_MARQUEE}
System::Int64Op $HalfOfDownload + $DownloadSizeBytes
Pop $ProgressTotal
StrCpy $ProgressCompleted 0
SendMessage $Progressbar ${PBM_SETRANGE32} $ProgressCompleted $ProgressTotal
Pop $R9
SendMessage $Progressbar ${PBM_SETRANGE32} 0 $R9
${EndIf}
; Don't update the status until after the download starts
@ -1471,13 +1448,12 @@ Function OnDownload
LockWindow on
; Update the progress bars first in the UI change so they take affect
; before other UI changes.
StrCpy $ProgressCompleted "$DownloadSizeBytes"
Call SetProgressBars
SendMessage $Progressbar ${PBM_SETPOS} $DownloadSizeBytes 0
System::Int64Op $InstallStepSize * ${InstallProgressFirstStep}
Pop $R9
System::Int64Op $ProgressCompleted + $R9
Pop $ProgressCompleted
Call SetProgressBars
SendMessage $Progressbar ${PBM_SETSTEP} $R9 0
SendMessage $Progressbar ${PBM_STEPIT} 0 0
SendMessage $Progressbar ${PBM_SETSTEP} $InstallStepSize 0
ShowWindow $LabelDownloading ${SW_HIDE}
ShowWindow $LabelInstalling ${SW_SHOW}
ShowWindow $LabelBlurb2 ${SW_HIDE}
@ -1564,8 +1540,7 @@ Function OnDownload
WriteIniStr "$0" "TASKBAR" "Migrated" "true"
${EndIf}
GetFunctionAddress $0 RemoveFileProgressCallback
${RemovePrecompleteEntries} $0
${RemovePrecompleteEntries} $Progressbar $InstallCounterStep
; Delete the install.log and let the full installer create it. When the
; installer closes it we can detect that it has completed.
@ -1594,8 +1569,7 @@ Function OnDownload
LockWindow off
${EndIf}
StrCpy $DownloadedBytes "$3"
StrCpy $ProgressCompleted "$DownloadedBytes"
Call SetProgressBars
SendMessage $Progressbar ${PBM_SETPOS} $3 0
${EndIf}
${EndIf}
FunctionEnd
@ -1634,9 +1608,7 @@ Function CheckInstall
Return
${EndIf}
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
SendMessage $Progressbar ${PBM_STEPIT} 0 0
${If} ${FileExists} "$INSTDIR\install.log"
Delete "$INSTDIR\install.tmp"
@ -1660,6 +1632,7 @@ Function CheckInstall
Pop $EndInstallPhaseTickCount
System::Int64Op $InstallStepSize * ${InstallProgressFinishStep}
Pop $InstallStepSize
SendMessage $Progressbar ${PBM_SETSTEP} $InstallStepSize 0
${NSD_CreateTimer} FinishInstall ${InstallIntervalMS}
${EndUnless}
${EndIf}
@ -1674,16 +1647,14 @@ Function FinishInstall
${EndIf}
${If} $InstallTotalSteps != $InstallCounterStep
System::Int64Op $ProgressCompleted + $InstallStepSize
Pop $ProgressCompleted
Call SetProgressBars
SendMessage $Progressbar ${PBM_STEPIT} 0 0
Return
${EndIf}
${NSD_KillTimer} FinishInstall
StrCpy $ProgressCompleted "$ProgressTotal"
Call SetProgressBars
SendMessage $Progressbar ${PBM_GETRANGE} 0 0 $R9
SendMessage $Progressbar ${PBM_SETPOS} $R9 0
${If} "$CheckboxSetAsDefault" == "1"
${GetParameters} $0
@ -1964,10 +1935,6 @@ FunctionEnd
Function DisplayDownloadError
${NSD_KillTimer} DisplayDownloadError
; To better display the error state on the taskbar set the progress completed
; value to the total value.
${ITBL3SetProgressValue} "100" "100"
${ITBL3SetProgressState} "${TBPF_ERROR}"
MessageBox MB_OKCANCEL|MB_ICONSTOP "$(ERROR_DOWNLOAD)" IDCANCEL +2 IDOK +1
StrCpy $OpenedDownloadPage "1" ; Already initialized to 0

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

@ -397,7 +397,9 @@ Section "Uninstall"
${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll"
${EndIf}
${un.RemovePrecompleteEntries} "false"
StrCpy $R2 "false"
StrCpy $R3 "false"
${un.RemovePrecompleteEntries} "$R2" "$R3"
${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js"
Delete /REBOOTOK "$INSTDIR\defaults\pref\channel-prefs.js"

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

@ -647,7 +647,7 @@ IsOnFullDomainWhitelist(nsIURI* aURI)
NS_LITERAL_CSTRING("touch.qunar.com"),
NS_LITERAL_CSTRING("mjs.sinaimg.cn"), // for sina.cn
NS_LITERAL_CSTRING("static.qiyi.com"), // for m.iqiyi.com
NS_LITERAL_CSTRING("www.kuaidi100.com"), // for m.kuaidi100.com
NS_LITERAL_CSTRING("cdn.kuaidi100.com"), // for m.kuaidi100.com
NS_LITERAL_CSTRING("m.pc6.com"),
NS_LITERAL_CSTRING("m.haosou.com"),
NS_LITERAL_CSTRING("m.mi.com"),

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

@ -244,8 +244,9 @@ CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS))))
CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX)))
CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
ASOBJS = $(notdir $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
RSOBJS = $(addprefix lib,$(notdir $(RSSRCS:.rs=.$(LIB_SUFFIX))))
ifndef OBJS
_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS) $(RSOBJS)
OBJS = $(strip $(_OBJS))
endif
@ -876,6 +877,11 @@ $(basename $2$(notdir $1)).$(OBJ_SUFFIX): $1 $$(call mkdir_deps,$$(MDDEPDIR))
endef
$(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f))))
$(foreach f,$(HOST_CSRCS) $(HOST_CPPSRCS) $(HOST_CMSRCS) $(HOST_CMMSRCS),$(eval $(call src_objdep,$(f),host_)))
# The rust compiler only outputs library objects, and so we need different
# mangling to generate dependency rules for it.
mk_libname = $(basename lib$(notdir $1)).$(LIB_SUFFIX)
src_libdep = $(call mk_libname,$1): $1 $$(call mkdir_deps,$$(MDDEPDIR))
$(foreach f,$(RSSRCS),$(eval $(call src_libdep,$(f))))
$(OBJS) $(HOST_OBJS) $(PROGOBJS) $(HOST_PROGOBJS): $(GLOBAL_DEPS)
@ -924,6 +930,14 @@ $(ASOBJS):
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
endif
ifdef MOZ_RUST
# Assume any system libraries rustc links against are already
# in the target's LIBS.
$(RSOBJS):
$(REPORT_BUILD)
$(RUSTC) --crate-type staticlib -o $(call mk_libname,$<) $(_VPATH_SRCS)
endif
$(SOBJS):
$(REPORT_BUILD)
$(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $<

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

@ -429,6 +429,18 @@ MOZ_TOOL_VARIABLES
MOZ_CHECK_COMPILER_WRAPPER
MOZ_PATH_PROG(RUSTC, rustc)
MOZ_ARG_ENABLE_BOOL([rust],
[ --enable-rust Include rust language sources],
[MOZ_RUST=1],
[MOZ_RUST= ])
if test -z "$RUSTC" -a -n "$MOZ_RUST"; then
AC_MSG_ERROR([Rust compiler not found.
To compile rust language sources, you must have 'rustc' in your path.
See http://www.rust-lang.org/ for more information.])
fi
AC_SUBST(MOZ_RUST)
dnl ========================================================
dnl Check for MacOS deployment target version
dnl ========================================================

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

@ -506,7 +506,7 @@ private:
nsINode* oldTextNode = static_cast<Element*>(aData);
Element* rootNode = aEntry->GetKey();
nsINode* newTextNode = nullptr;
if (oldTextNode && rootNode->HasDirAuto()) {
if (rootNode->GetParentNode() && rootNode->HasDirAuto()) {
newTextNode = WalkDescendantsSetDirectionFromText(rootNode, true,
oldTextNode);
}
@ -533,11 +533,6 @@ public:
mElements.EnumerateEntries(SetNodeDirection, &aDir);
}
void ClearAutoDirection()
{
mElements.EnumerateEntries(ResetNodeDirection, nullptr);
}
void ResetAutoDirection(nsINode* aTextNode)
{
mElements.EnumerateEntries(ResetNodeDirection, aTextNode);
@ -574,13 +569,6 @@ public:
GetDirectionalityMap(aTextNode)->UpdateAutoDirection(aDir);
}
static void ClearTextNodeDirection(nsINode* aTextNode)
{
MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
"Map missing in ResetTextNodeDirection");
GetDirectionalityMap(aTextNode)->ClearAutoDirection();
}
static void ResetTextNodeDirection(nsINode* aTextNode)
{
MOZ_ASSERT(aTextNode->HasTextNodeDirectionalityMap(),
@ -888,7 +876,7 @@ SetDirectionFromNewTextNode(nsIContent* aTextNode)
}
void
ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent)
ResetDirectionSetByTextNode(nsTextNode* aTextNode)
{
if (!NodeAffectsDirAutoAncestor(aTextNode)) {
nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode);
@ -897,11 +885,7 @@ ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent)
Directionality dir = GetDirectionFromText(aTextNode->GetText());
if (dir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) {
if (aNullParent) {
nsTextNodeDirectionalityMap::ClearTextNodeDirection(aTextNode);
} else {
nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
}
nsTextNodeDirectionalityMap::ResetTextNodeDirection(aTextNode);
}
}

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

@ -103,10 +103,8 @@ void SetDirectionFromNewTextNode(nsIContent* aTextNode);
* directionality it determined and redetermine their directionality
*
* @param aTextNode the text node
* @param aNullParent whether the the parent is also being removed
* (passed from UnbindFromTree)
*/
void ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent);
void ResetDirectionSetByTextNode(nsTextNode* aTextNode);
/**
* Set the directionality of an element according to the directionality of the

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

@ -15,13 +15,13 @@
#include "nsTArray.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FormDataBinding.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class File;
class HTMLFormElement;
class GlobalObject;
} // namespace dom

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

@ -574,10 +574,7 @@ nsObjectLoadingContent::QueueCheckPluginStopEvent()
nsCOMPtr<nsIRunnable> event = new CheckPluginStopEvent(this);
mPendingCheckPluginStopEvent = event;
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
if (appShell) {
appShell->RunInStableState(event);
}
NS_DispatchToCurrentThread(event);
}
// Tedious syntax to create a plugin stream listener with checks and put it in

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

@ -400,7 +400,8 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsPerformance)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsPerformance, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow, mTiming,
mNavigation, mEntries,
mNavigation, mUserEntries,
mResourceEntries,
mParentPerformance)
tmp->mMozMemory = nullptr;
mozilla::DropJSObjects(this);
@ -408,7 +409,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsPerformance, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow, mTiming,
mNavigation, mEntries,
mNavigation, mUserEntries,
mResourceEntries,
mParentPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -429,7 +431,7 @@ nsPerformance::nsPerformance(nsPIDOMWindow* aWindow,
mDOMTiming(aDOMTiming),
mChannel(aChannel),
mParentPerformance(aParentPerformance),
mPrimaryBufferSize(kDefaultBufferSize)
mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
{
MOZ_ASSERT(aWindow, "Parent window object should be provided");
}
@ -509,24 +511,30 @@ nsPerformance::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
}
void
nsPerformance::GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval)
nsPerformance::GetEntries(nsTArray<nsRefPtr<PerformanceEntry>>& retval)
{
MOZ_ASSERT(NS_IsMainThread());
retval = mEntries;
retval = mResourceEntries;
retval.AppendElements(mUserEntries);
retval.Sort(PerformanceEntryComparator());
}
void
nsPerformance::GetEntriesByType(const nsAString& entryType,
nsTArray<nsRefPtr<PerformanceEntry> >& retval)
nsTArray<nsRefPtr<PerformanceEntry>>& retval)
{
MOZ_ASSERT(NS_IsMainThread());
retval.Clear();
uint32_t count = mEntries.Length();
for (uint32_t i = 0 ; i < count; i++) {
if (mEntries[i]->GetEntryType().Equals(entryType)) {
retval.AppendElement(mEntries[i]);
if (entryType.EqualsLiteral("resource")) {
retval = mResourceEntries;
} else if (entryType.EqualsLiteral("mark") ||
entryType.EqualsLiteral("measure")) {
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetEntryType().Equals(entryType)) {
retval.AppendElement(entry);
}
}
}
}
@ -534,31 +542,38 @@ nsPerformance::GetEntriesByType(const nsAString& entryType,
void
nsPerformance::GetEntriesByName(const nsAString& name,
const Optional<nsAString>& entryType,
nsTArray<nsRefPtr<PerformanceEntry> >& retval)
nsTArray<nsRefPtr<PerformanceEntry>>& retval)
{
MOZ_ASSERT(NS_IsMainThread());
retval.Clear();
uint32_t count = mEntries.Length();
for (uint32_t i = 0 ; i < count; i++) {
if (mEntries[i]->GetName().Equals(name) &&
for (PerformanceEntry* entry : mResourceEntries) {
if (entry->GetName().Equals(name) &&
(!entryType.WasPassed() ||
mEntries[i]->GetEntryType().Equals(entryType.Value()))) {
retval.AppendElement(mEntries[i]);
entry->GetEntryType().Equals(entryType.Value()))) {
retval.AppendElement(entry);
}
}
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetName().Equals(name) &&
(!entryType.WasPassed() ||
entry->GetEntryType().Equals(entryType.Value()))) {
retval.AppendElement(entry);
}
}
retval.Sort(PerformanceEntryComparator());
}
void
nsPerformance::ClearEntries(const Optional<nsAString>& aEntryName,
const nsAString& aEntryType)
nsPerformance::ClearUserEntries(const Optional<nsAString>& aEntryName,
const nsAString& aEntryType)
{
for (uint32_t i = 0; i < mEntries.Length();) {
for (uint32_t i = 0; i < mUserEntries.Length();) {
if ((!aEntryName.WasPassed() ||
mEntries[i]->GetName().Equals(aEntryName.Value())) &&
mUserEntries[i]->GetName().Equals(aEntryName.Value())) &&
(aEntryType.IsEmpty() ||
mEntries[i]->GetEntryType().Equals(aEntryType))) {
mEntries.RemoveElementAt(i);
mUserEntries[i]->GetEntryType().Equals(aEntryType))) {
mUserEntries.RemoveElementAt(i);
} else {
++i;
}
@ -569,15 +584,14 @@ void
nsPerformance::ClearResourceTimings()
{
MOZ_ASSERT(NS_IsMainThread());
ClearEntries(Optional<nsAString>(),
NS_LITERAL_STRING("resource"));
mResourceEntries.Clear();
}
void
nsPerformance::SetResourceTimingBufferSize(uint64_t maxSize)
{
MOZ_ASSERT(NS_IsMainThread());
mPrimaryBufferSize = maxSize;
mResourceTimingBufferSize = maxSize;
}
/**
@ -595,7 +609,7 @@ nsPerformance::AddEntry(nsIHttpChannel* channel,
}
// Don't add the entry if the buffer is full
if (mEntries.Length() >= mPrimaryBufferSize) {
if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
return;
}
@ -634,7 +648,7 @@ nsPerformance::AddEntry(nsIHttpChannel* channel,
initiatorType = NS_LITERAL_STRING("other");
}
performanceEntry->SetInitiatorType(initiatorType);
InsertPerformanceEntry(performanceEntry, false);
InsertResourceEntry(performanceEntry);
}
}
@ -659,16 +673,25 @@ nsPerformance::PerformanceEntryComparator::LessThan(
}
void
nsPerformance::InsertPerformanceEntry(PerformanceEntry* aEntry,
bool aShouldPrint)
nsPerformance::InsertResourceEntry(PerformanceEntry* aEntry)
{
MOZ_ASSERT(aEntry);
MOZ_ASSERT(mEntries.Length() < mPrimaryBufferSize);
if (mEntries.Length() == mPrimaryBufferSize) {
NS_WARNING("Performance Entry buffer size maximum reached!");
MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
return;
}
if (aShouldPrint && nsContentUtils::IsUserTimingLoggingEnabled()) {
mResourceEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
if (mResourceEntries.Length() == mResourceTimingBufferSize) {
// call onresourcetimingbufferfull
DispatchBufferFullEvent();
}
}
void
nsPerformance::InsertUserEntry(PerformanceEntry* aEntry)
{
if (nsContentUtils::IsUserTimingLoggingEnabled()) {
nsAutoCString uri;
nsresult rv = mWindow->GetDocumentURI()->GetHost(uri);
if(NS_FAILED(rv)) {
@ -683,21 +706,16 @@ nsPerformance::InsertPerformanceEntry(PerformanceEntry* aEntry,
aEntry->Duration(),
static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC));
}
mEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
if (mEntries.Length() == mPrimaryBufferSize) {
// call onresourcetimingbufferfull
DispatchBufferFullEvent();
}
mUserEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator());
}
void
nsPerformance::Mark(const nsAString& aName, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
// Don't add the entry if the buffer is full
if (mEntries.Length() >= mPrimaryBufferSize) {
NS_WARNING("Performance Entry buffer size maximum reached!");
// Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
if (mUserEntries.Length() >= mResourceTimingBufferSize) {
return;
}
if (IsPerformanceTimingAttribute(aName)) {
@ -706,14 +724,14 @@ nsPerformance::Mark(const nsAString& aName, ErrorResult& aRv)
}
nsRefPtr<PerformanceMark> performanceMark =
new PerformanceMark(this, aName);
InsertPerformanceEntry(performanceMark, true);
InsertUserEntry(performanceMark);
}
void
nsPerformance::ClearMarks(const Optional<nsAString>& aName)
{
MOZ_ASSERT(NS_IsMainThread());
ClearEntries(aName, NS_LITERAL_STRING("mark"));
ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
}
DOMHighResTimeStamp
@ -749,9 +767,8 @@ nsPerformance::Measure(const nsAString& aName,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
// Don't add the entry if the buffer is full
if (mEntries.Length() >= mPrimaryBufferSize) {
NS_WARNING("Performance Entry buffer size maximum reached!");
// Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
if (mUserEntries.Length() >= mResourceTimingBufferSize) {
return;
}
DOMHighResTimeStamp startTime;
@ -783,14 +800,14 @@ nsPerformance::Measure(const nsAString& aName,
}
nsRefPtr<PerformanceMeasure> performanceMeasure =
new PerformanceMeasure(this, aName, startTime, endTime);
InsertPerformanceEntry(performanceMeasure, true);
InsertUserEntry(performanceMeasure);
}
void
nsPerformance::ClearMeasures(const Optional<nsAString>& aName)
{
MOZ_ASSERT(NS_IsMainThread());
ClearEntries(aName, NS_LITERAL_STRING("measure"));
ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
}
DOMHighResTimeStamp

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

@ -328,12 +328,12 @@ public:
nsPerformanceTiming* Timing();
nsPerformanceNavigation* Navigation();
void GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval);
void GetEntries(nsTArray<nsRefPtr<PerformanceEntry>>& retval);
void GetEntriesByType(const nsAString& entryType,
nsTArray<nsRefPtr<PerformanceEntry> >& retval);
nsTArray<nsRefPtr<PerformanceEntry>>& retval);
void GetEntriesByName(const nsAString& name,
const mozilla::dom::Optional< nsAString >& entryType,
nsTArray<nsRefPtr<PerformanceEntry> >& retval);
nsTArray<nsRefPtr<PerformanceEntry>>& retval);
void AddEntry(nsIHttpChannel* channel,
nsITimedChannel* timedChannel);
void ClearResourceTimings();
@ -357,20 +357,22 @@ private:
DOMTimeMilliSec GetPerformanceTimingFromString(const nsAString& aTimingName);
DOMHighResTimeStamp ConvertDOMMilliSecToHighRes(const DOMTimeMilliSec aTime);
void DispatchBufferFullEvent();
void InsertPerformanceEntry(PerformanceEntry* aEntry, bool aShouldPrint);
void ClearEntries(const mozilla::dom::Optional<nsAString>& aEntryName,
const nsAString& aEntryType);
void InsertUserEntry(PerformanceEntry* aEntry);
void ClearUserEntries(const mozilla::dom::Optional<nsAString>& aEntryName,
const nsAString& aEntryType);
void InsertResourceEntry(PerformanceEntry* aEntry);
nsCOMPtr<nsPIDOMWindow> mWindow;
nsRefPtr<nsDOMNavigationTiming> mDOMTiming;
nsCOMPtr<nsITimedChannel> mChannel;
nsRefPtr<nsPerformanceTiming> mTiming;
nsRefPtr<nsPerformanceNavigation> mNavigation;
nsTArray<nsRefPtr<PerformanceEntry> > mEntries;
nsTArray<nsRefPtr<PerformanceEntry>> mResourceEntries;
nsTArray<nsRefPtr<PerformanceEntry>> mUserEntries;
nsRefPtr<nsPerformance> mParentPerformance;
uint64_t mPrimaryBufferSize;
uint64_t mResourceTimingBufferSize;
JS::Heap<JSObject*> mMozMemory;
static const uint64_t kDefaultBufferSize = 150;
static const uint64_t kDefaultResourceTimingBufferSize = 150;
// Helper classes
class PerformanceEntryComparator {

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

@ -150,7 +150,7 @@ nsTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
void nsTextNode::UnbindFromTree(bool aDeep, bool aNullParent)
{
ResetDirectionSetByTextNode(this, aNullParent);
ResetDirectionSetByTextNode(this);
nsGenericDOMDataNode::UnbindFromTree(aDeep, aNullParent);
}

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

@ -48,11 +48,12 @@ addLoadEvent(function() {
// Now flush out layout on the subdocument, to trigger the resize handler
is(bod.getBoundingClientRect().width, 50, "Width of body should still be 50px");
window.requestAnimationFrame(function() {
is(resizeHandlerRan, true, "Resize handler should have run");
win.removeEventListener("resize", handleResize, false);
SimpleTest.finish();
});
is(resizeHandlerRan, true, "Resize handler should have run");
win.removeEventListener("resize", handleResize, false);
SimpleTest.finish();
});
</script>
</pre>

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

@ -35,7 +35,7 @@ function setupTestMultipleEntries(headers) {
return new Promise(function(resolve, reject) {
var response, responseText, cache;
Promise.all(headers.map(function(h) {
return fetch(new Request(requestURL, {headers: h}));
return fetch(requestURL, {headers: h});
})).then(function(r) {
response = r;
return Promise.all(response.map(function(r) {
@ -59,20 +59,20 @@ function setupTestMultipleEntries(headers) {
function testBasics() {
var test;
return setupTest({"WhatToVary": "Cookie"})
return setupTest({"WhatToVary": "Custom"})
.then(function(t) {
test = t;
// Ensure that searching without specifying a Cookie header succeeds.
// Ensure that searching without specifying a Custom header succeeds.
return test.cache.match(requestURL);
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
}).then(function() {
// Ensure that searching with a non-matching value for the Cookie header fails.
return test.cache.match(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}));
// Ensure that searching with a non-matching value for the Custom header fails.
return test.cache.match(new Request(requestURL, {headers: {"Custom": "foo=bar"}}));
}).then(function(r) {
is(typeof r, "undefined", "Searching for a request with an unknown Vary header should not succeed");
// Ensure that searching with a non-matching value for the Cookie header but with ignoreVary set succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}),
// Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom": "foo=bar"}}),
{ignoreVary: true});
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
@ -83,23 +83,23 @@ function testBasicKeys() {
function checkRequest(reqs) {
is(reqs.length, 1, "One request expected");
ok(reqs[0].url.indexOf(requestURL) >= 0, "The correct request expected");
ok(reqs[0].headers.get("WhatToVary"), "Cookie", "The correct request headers expected");
ok(reqs[0].headers.get("WhatToVary"), "Custom", "The correct request headers expected");
}
var test;
return setupTest({"WhatToVary": "Cookie"})
return setupTest({"WhatToVary": "Custom"})
.then(function(t) {
test = t;
// Ensure that searching without specifying a Cookie header succeeds.
// Ensure that searching without specifying a Custom header succeeds.
return test.cache.keys(requestURL);
}).then(function(r) {
return checkRequest(r);
}).then(function() {
// Ensure that searching with a non-matching value for the Cookie header fails.
return test.cache.keys(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}));
// Ensure that searching with a non-matching value for the Custom header fails.
return test.cache.keys(new Request(requestURL, {headers: {"Custom": "foo=bar"}}));
}).then(function(r) {
is(r.length, 0, "Searching for a request with an unknown Vary header should not succeed");
// Ensure that searching with a non-matching value for the Cookie header but with ignoreVary set succeeds.
return test.cache.keys(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}),
// Ensure that searching with a non-matching value for the Custom header but with ignoreVary set succeeds.
return test.cache.keys(new Request(requestURL, {headers: {"Custom": "foo=bar"}}),
{ignoreVary: true});
}).then(function(r) {
return checkRequest(r);
@ -164,15 +164,15 @@ function testStar() {
function testMatch() {
var test;
return setupTest({"WhatToVary": "Cookie", "Cookie": "foo=bar"})
return setupTest({"WhatToVary": "Custom", "Custom": "foo=bar"})
.then(function(t) {
test = t;
// Ensure that searching with a different Cookie header fails.
return test.cache.match(new Request(requestURL, {headers: {"Cookie": "bar=baz"}}));
// Ensure that searching with a different Custom header fails.
return test.cache.match(new Request(requestURL, {headers: {"Custom": "bar=baz"}}));
}).then(function(r) {
is(typeof r, "undefined", "Searching for a request with a non-matching Cookie header should not succeed");
// Ensure that searching with the same Cookie header succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Cookie": "foo=bar"}}));
is(typeof r, "undefined", "Searching for a request with a non-matching Custom header should not succeed");
// Ensure that searching with the same Custom header succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom": "foo=bar"}}));
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
});
@ -180,15 +180,15 @@ function testMatch() {
function testInvalidHeaderName() {
var test;
return setupTest({"WhatToVary": "Foo/Bar, User-Agent"})
return setupTest({"WhatToVary": "Foo/Bar, Custom-User-Agent"})
.then(function(t) {
test = t;
// Ensure that searching with a different User-Agent header fails.
return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}));
return test.cache.match(new Request(requestURL, {headers: {"Custom-User-Agent": "MyUA"}}));
}).then(function(r) {
is(typeof r, "undefined", "Searching for a request with a non-matching User-Agent header should not succeed");
// Ensure that searching with a different User-Agent header but with ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"User-Agent": "MyUA"}}),
is(typeof r, "undefined", "Searching for a request with a non-matching Custom-User-Agent header should not succeed");
// Ensure that searching with a different Custom-User-Agent header but with ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom-User-Agent": "MyUA"}}),
{ignoreVary: true});
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
@ -202,47 +202,47 @@ function testInvalidHeaderName() {
function testMultipleHeaders() {
var test;
return setupTest({"WhatToVary": "Referer,\tAccept-Encoding"})
return setupTest({"WhatToVary": "Custom-Referer,\tCustom-Accept-Encoding"})
.then(function(t) {
test = t;
// Ensure that searching with a different Referer header fails.
return test.cache.match(new Request(requestURL, {headers: {"Referer": "https://somesite.com/"}}));
return test.cache.match(new Request(requestURL, {headers: {"Custom-Referer": "https://somesite.com/"}}));
}).then(function(r) {
is(typeof r, "undefined", "Searching for a request with a non-matching Referer header should not succeed");
// Ensure that searching with a different Referer header but with ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Referer": "https://somesite.com/"}}),
is(typeof r, "undefined", "Searching for a request with a non-matching Custom-Referer header should not succeed");
// Ensure that searching with a different Custom-Referer header but with ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Referer": "https://somesite.com/"}}),
{ignoreVary: true});
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
}).then(function() {
// Ensure that searching with a different Accept-Encoding header fails.
return test.cache.match(new Request(requestURL, {headers: {"Accept-Encoding": "myencoding"}}));
// Ensure that searching with a different Custom-Accept-Encoding header fails.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Accept-Encoding": "myencoding"}}));
}).then(function(r) {
is(typeof r, "undefined", "Searching for a request with a non-matching Accept-Encoding header should not succeed");
// Ensure that searching with a different Accept-Encoding header but with ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Accept-Encoding": "myencoding"}}),
is(typeof r, "undefined", "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed");
// Ensure that searching with a different Custom-Accept-Encoding header but with ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Accept-Encoding": "myencoding"}}),
{ignoreVary: true});
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
}).then(function() {
// Ensure that searching with an empty Referer header succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Referer": ""}}));
// Ensure that searching with an empty Custom-Referer header succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Referer": ""}}));
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
}).then(function() {
// Ensure that searching with an empty Accept-Encoding header succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Accept-Encoding": ""}}));
// Ensure that searching with an empty Custom-Accept-Encoding header succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Accept-Encoding": ""}}));
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);
}).then(function() {
// Ensure that searching with an empty Referer header but with a different Accept-Encoding header fails.
return test.cache.match(new Request(requestURL, {headers: {"Referer": "",
"Accept-Encoding": "myencoding"}}));
// Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header fails.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Referer": "",
"Custom-Accept-Encoding": "myencoding"}}));
}).then(function(r) {
is(typeof r, "undefined", "Searching for a request with a non-matching Accept-Encoding header should not succeed");
// Ensure that searching with an empty Referer header but with a different Accept-Encoding header and ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Referer": "",
"Accept-Encoding": "myencoding"}}),
is(typeof r, "undefined", "Searching for a request with a non-matching Custom-Accept-Encoding header should not succeed");
// Ensure that searching with an empty Custom-Referer header but with a different Custom-Accept-Encoding header and ignoreVary succeeds.
return test.cache.match(new Request(requestURL, {headers: {"Custom-Referer": "",
"Custom-Accept-Encoding": "myencoding"}}),
{ignoreVary: true});
}).then(function(r) {
return checkResponse(r, test.response, test.responseText);

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

@ -13,30 +13,34 @@
Cu.import('resource://gre/modules/Services.jsm');
SimpleTest.waitForExplicitFinish();
// attach to a different origin's CacheStorage
var url = 'http://example.com/';
var uri = Services.io.newURI(url, null, null);
var principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
var storage = new CacheStorage('content', principal);
SpecialPowers.pushPrefEnv({
"set": [["dom.caches.enabled", true]],
}, function() {
// attach to a different origin's CacheStorage
var url = 'http://example.com/';
var uri = Services.io.newURI(url, null, null);
var principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(uri);
var storage = new CacheStorage('content', principal);
// verify we can use the other origin's CacheStorage as normal
var req = new Request('http://example.com/index.html');
var res = new Response('hello world');
var cache;
storage.open('foo').then(function(c) {
cache = c;
ok(cache, 'storage should create cache');
return cache.put(req, res.clone());
}).then(function() {
return cache.match(req);
}).then(function(foundResponse) {
return Promise.all([res.text(), foundResponse.text()]);
}).then(function(results) {
is(results[0], results[1], 'cache should contain response');
return storage.delete('foo');
}).then(function(deleted) {
ok(deleted, 'storage should delete cache');
SimpleTest.finish();
// verify we can use the other origin's CacheStorage as normal
var req = new Request('http://example.com/index.html');
var res = new Response('hello world');
var cache;
storage.open('foo').then(function(c) {
cache = c;
ok(cache, 'storage should create cache');
return cache.put(req, res.clone());
}).then(function() {
return cache.match(req);
}).then(function(foundResponse) {
return Promise.all([res.text(), foundResponse.text()]);
}).then(function(results) {
is(results[0], results[1], 'cache should contain response');
return storage.delete('foo');
}).then(function(deleted) {
ok(deleted, 'storage should delete cache');
SimpleTest.finish();
});
});
</script>
</body>

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

@ -1448,7 +1448,7 @@ nsDOMCameraControl::OnUserError(CameraControlListener::UserContext aContext, nsr
break;
case CameraControlListener::kInSetConfiguration:
if (mSetInitialConfig) {
if (mSetInitialConfig && mCameraControl) {
// If the SetConfiguration() call in the constructor fails, there
// is nothing we can do except release the camera hardware. This
// will trigger a hardware state change, and when the flag that

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

@ -263,6 +263,10 @@ Request::Constructor(const GlobalObject& aGlobal,
}
requestHeaders->Clear();
// From "Let r be a new Request object associated with request and a new
// Headers object whose guard is "request"."
requestHeaders->SetGuard(HeadersGuardEnum::Request, aRv);
MOZ_ASSERT(!aRv.Failed());
if (request->Mode() == RequestMode::No_cors) {
if (!request->HasSimpleMethod()) {

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

@ -878,7 +878,8 @@ void HTMLMediaElement::SelectResource()
mLoadingSrc = uri;
UpdatePreloadAction();
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE) {
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
!IsMediaStreamURI(mLoadingSrc)) {
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad();
@ -1016,7 +1017,8 @@ void HTMLMediaElement::LoadFromSourceChildren()
NS_ASSERTION(mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING,
"Network state should be loading");
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE) {
if (mPreloadAction == HTMLMediaElement::PRELOAD_NONE &&
!IsMediaStreamURI(mLoadingSrc)) {
// preload:none media, suspend the load here before we make any
// network requests.
SuspendLoad();

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

@ -9,11 +9,11 @@
#include "mozilla/Attributes.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIContent.h"
class nsIURI;
class nsIInputStream;
class nsGenericHTMLElement;
class nsIContent;
class nsISaveAsCharset;
class nsIMultiplexInputStream;

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

@ -3,5 +3,6 @@
"WeakMap.prototype.delete.length": true,
"WeakMap.prototype.get.length": true,
"WeakMap.prototype.has.length": true,
"WeakMap.prototype.set.length": true
"WeakMap.prototype.set.length": true,
"WeakMap.prototype.@@toStringTag": true
}

Двоичные данные
dom/indexedDB/test/unit/metadataRestore_profile.zip Normal file

Двоичный файл не отображается.

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

@ -0,0 +1,109 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var testGenerator = testSteps();
function testSteps()
{
const openParams = [
// This one lives in storage/permanent/chrome
{ dbName: "dbA",
dbOptions: { version: 1, storage: "persistent" } },
// This one lives in storage/temporary/http+++localhost
{ url: "http://localhost", dbName: "dbB",
dbOptions: { version: 1, storage: "temporary" } },
// This one lives in storage/default/http+++localhost+81
{ url: "http://localhost:81", dbName: "dbC",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+82
{ url: "http://localhost:82", dbName: "dbD",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+83
{ url: "http://localhost:83", dbName: "dbE",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+84
{ url: "http://localhost:84", dbName: "dbF",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+85
{ url: "http://localhost:85", dbName: "dbG",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+86
{ url: "http://localhost:86", dbName: "dbH",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+87
{ url: "http://localhost:87", dbName: "dbI",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+88
{ url: "http://localhost:88", dbName: "dbJ",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+89
{ url: "http://localhost:89", dbName: "dbK",
dbOptions: { version: 1, storage: "default" } },
// This one lives in storage/default/http+++localhost+90
{ url: "http://localhost:90", dbName: "dbL",
dbOptions: { version: 1, storage: "default" } }
];
let ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
let ssm = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager);
function openDatabase(params) {
let request;
if ("url" in params) {
let uri = ios.newURI(params.url, null, null);
let principal = ssm.getNoAppCodebasePrincipal(uri);
request = indexedDB.openForPrincipal(principal, params.dbName,
params.dbOptions);
} else {
request = indexedDB.open(params.dbName, params.dbOptions);
}
return request;
}
clearAllDatabases(continueToNextStepSync);
yield undefined;
installPackagedProfile("metadataRestore_profile");
for (let params of openParams) {
let request = openDatabase(params);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(event.type, "success", "Correct event type");
}
resetAllDatabases(continueToNextStepSync);
yield undefined;
for (let params of openParams) {
let request = openDatabase(params);
request.onerror = errorHandler;
request.onupgradeneeded = unexpectedSuccessHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield undefined;
is(event.type, "success", "Correct event type");
}
finishTest();
yield undefined;
}

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

@ -15,6 +15,7 @@ support-files =
GlobalObjectsComponent.manifest
GlobalObjectsModule.jsm
GlobalObjectsSandbox.js
metadataRestore_profile.zip
schema18upgrade_profile.zip
xpcshell-shared.ini
@ -29,6 +30,7 @@ skip-if = toolkit == 'android'
# disabled for the moment.
skip-if = true
[test_lowDiskSpace.js]
[test_metadataRestore.js]
[test_readwriteflush_disabled.js]
[test_schema18upgrade.js]
[test_temporary_storage.js]

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

@ -424,7 +424,7 @@ public:
private:
const uint32_t mGeneration;
// Non-null if we haven't yet called EndChildReport() on it.
// Non-null if we haven't yet called EndProcessReport() on it.
nsRefPtr<nsMemoryReporterManager> mReporterManager;
ContentParent* Owner()
@ -464,7 +464,7 @@ void
MemoryReportRequestParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (mReporterManager) {
mReporterManager->EndChildReport(mGeneration, aWhy == Deletion);
mReporterManager->EndProcessReport(mGeneration, aWhy == Deletion);
mReporterManager = nullptr;
}
}
@ -648,7 +648,6 @@ static const char* sObserverTopics[] = {
"profile-before-change",
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
"child-memory-reporter-request",
"memory-pressure",
"child-gc-request",
"child-cc-request",
@ -1976,18 +1975,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
}
}
// Tell the memory reporter manager that this ContentParent is going away.
nsRefPtr<nsMemoryReporterManager> mgr =
nsMemoryReporterManager::GetOrCreate();
#ifdef MOZ_NUWA_PROCESS
bool isMemoryChild = !IsNuwaProcess();
#else
bool isMemoryChild = true;
#endif
if (mgr && isMemoryChild) {
mgr->DecrementNumChildProcesses();
}
// remove the global remote preferences observers
Preferences::RemoveObserver(this, "");
@ -2261,15 +2248,6 @@ ContentParent::ContentParent(mozIApplication* aApp,
IToplevelProtocol::SetTransport(mSubprocess->GetChannel());
if (!aIsNuwaProcess) {
// Tell the memory reporter manager that this ContentParent exists.
nsRefPtr<nsMemoryReporterManager> mgr =
nsMemoryReporterManager::GetOrCreate();
if (mgr) {
mgr->IncrementNumChildProcesses();
}
}
std::vector<std::string> extraArgs;
if (aIsNuwaProcess) {
extraArgs.push_back("-nuwa");
@ -2334,13 +2312,6 @@ ContentParent::ContentParent(ContentParent* aTemplate,
aPid,
*fd);
// Tell the memory reporter manager that this ContentParent exists.
nsRefPtr<nsMemoryReporterManager> mgr =
nsMemoryReporterManager::GetOrCreate();
if (mgr) {
mgr->IncrementNumChildProcesses();
}
mSubprocess->LaunchAndWaitForProcessHandle();
// Clone actors routed by aTemplate for this instance.
@ -3062,46 +3033,6 @@ ContentParent::Observe(nsISupports* aSubject,
nsDependentString(aData)))
return NS_ERROR_NOT_AVAILABLE;
}
else if (!strcmp(aTopic, "child-memory-reporter-request")) {
bool isNuwa = false;
#ifdef MOZ_NUWA_PROCESS
isNuwa = IsNuwaProcess();
#endif
if (!isNuwa) {
unsigned generation;
int anonymize, minimize, identOffset = -1;
nsDependentString msg(aData);
NS_ConvertUTF16toUTF8 cmsg(msg);
if (sscanf(cmsg.get(),
"generation=%x anonymize=%d minimize=%d DMDident=%n",
&generation, &anonymize, &minimize, &identOffset) < 3
|| identOffset < 0) {
return NS_ERROR_INVALID_ARG;
}
// The pre-%n part of the string should be all ASCII, so the byte
// offset in identOffset should be correct as a char offset.
MOZ_ASSERT(cmsg[identOffset - 1] == '=');
MaybeFileDesc dmdFileDesc = void_t();
#ifdef MOZ_DMD
nsAutoString dmdIdent(Substring(msg, identOffset));
if (!dmdIdent.IsEmpty()) {
FILE *dmdFile = nullptr;
nsresult rv = nsMemoryInfoDumper::OpenDMDFile(dmdIdent, Pid(), &dmdFile);
if (NS_WARN_IF(NS_FAILED(rv))) {
// Proceed with the memory report as if DMD were disabled.
dmdFile = nullptr;
}
if (dmdFile) {
dmdFileDesc = FILEToFileDescriptor(dmdFile);
fclose(dmdFile);
}
}
#endif
unused << SendPMemoryReportRequestConstructor(
generation, anonymize, minimize, dmdFileDesc);
}
}
else if (!strcmp(aTopic, "child-gc-request")){
unused << SendGarbageCollect();
}

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

@ -77,6 +77,8 @@
#include "mozilla/WindowsVersion.h"
#endif
#include <map>
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount() and conflicts with MediaStream::GetCurrentTime.
#ifdef GetCurrentTime
@ -530,22 +532,31 @@ uint32_t
VideoDevice::GetBestFitnessDistance(
const nsTArray<const MediaTrackConstraintSet*>& aConstraintSets)
{
// TODO: Minimal kludge to fix plain and ideal facingMode regression, for
// smooth landing and uplift. Proper cleanup is forthcoming (1037389).
uint64_t distance = 0;
// Interrogate device-inherent properties first.
for (size_t i = 0; i < aConstraintSets.Length(); i++) {
auto& c = *aConstraintSets[i];
if (!c.mFacingMode.IsConstrainDOMStringParameters() ||
c.mFacingMode.GetAsConstrainDOMStringParameters().mIdeal.WasPassed() ||
c.mFacingMode.GetAsConstrainDOMStringParameters().mExact.WasPassed()) {
nsString deviceFacingMode;
GetFacingMode(deviceFacingMode);
if (c.mFacingMode.IsString()) {
if (c.mFacingMode.GetAsString() != deviceFacingMode) {
return UINT32_MAX;
if (i == 0) {
distance = 1000;
}
}
} else if (c.mFacingMode.IsStringSequence()) {
if (!c.mFacingMode.GetAsStringSequence().Contains(deviceFacingMode)) {
return UINT32_MAX;
if (i == 0) {
distance = 1000;
}
}
} else {
} else if (c.mFacingMode.GetAsConstrainDOMStringParameters().mExact.WasPassed()) {
auto& exact = c.mFacingMode.GetAsConstrainDOMStringParameters().mExact.Value();
if (exact.IsString()) {
if (exact.GetAsString() != deviceFacingMode) {
@ -554,6 +565,19 @@ VideoDevice::GetBestFitnessDistance(
} else if (!exact.GetAsStringSequence().Contains(deviceFacingMode)) {
return UINT32_MAX;
}
} else if (c.mFacingMode.GetAsConstrainDOMStringParameters().mIdeal.WasPassed()) {
auto& ideal = c.mFacingMode.GetAsConstrainDOMStringParameters().mIdeal.Value();
if (ideal.IsString()) {
if (ideal.GetAsString() != deviceFacingMode) {
if (i == 0) {
distance = 1000;
}
}
} else if (!ideal.GetAsStringSequence().Contains(deviceFacingMode)) {
if (i == 0) {
distance = 1000;
}
}
}
}
nsString s;
@ -563,7 +587,8 @@ VideoDevice::GetBestFitnessDistance(
}
}
// Forward request to underlying object to interrogate per-mode capabilities.
return GetSource()->GetBestFitnessDistance(aConstraintSets);
distance += uint64_t(GetSource()->GetBestFitnessDistance(aConstraintSets));
return uint32_t(std::min(distance, uint64_t(UINT32_MAX)));
}
AudioDevice::AudioDevice(MediaEngineAudioSource* aSource)
@ -1122,13 +1147,23 @@ static void
nsTArray<const MediaTrackConstraintSet*> aggregateConstraints;
aggregateConstraints.AppendElement(&c);
std::multimap<uint32_t, nsRefPtr<DeviceType>> ordered;
for (uint32_t i = 0; i < candidateSet.Length();) {
if (candidateSet[i]->GetBestFitnessDistance(aggregateConstraints) == UINT32_MAX) {
uint32_t distance = candidateSet[i]->GetBestFitnessDistance(aggregateConstraints);
if (distance == UINT32_MAX) {
candidateSet.RemoveElementAt(i);
} else {
ordered.insert(std::pair<uint32_t, nsRefPtr<DeviceType>>(distance,
candidateSet[i]));
++i;
}
}
// Order devices by shortest distance
for (auto& ordinal : ordered) {
candidateSet.RemoveElement(ordinal.second);
candidateSet.AppendElement(ordinal.second);
}
// Then apply advanced constraints.
@ -1318,6 +1353,11 @@ public:
{
MOZ_ASSERT(mOnSuccess);
MOZ_ASSERT(mOnFailure);
if (!IsOn(mConstraints.mVideo) && !IsOn(mConstraints.mAudio)) {
Fail(NS_LITERAL_STRING("NotSupportedError"));
return NS_ERROR_FAILURE;
}
if (IsOn(mConstraints.mVideo)) {
nsTArray<nsRefPtr<VideoDevice>> sources;
GetSources(backend, GetInvariant(mConstraints.mVideo),
@ -1343,6 +1383,11 @@ public:
LOG(("Selected audio device"));
}
if (!mAudioDevice && !mVideoDevice) {
Fail(NS_LITERAL_STRING("NotFoundError"));
return NS_ERROR_FAILURE;
}
return NS_OK;
}

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

@ -27,6 +27,9 @@ BaseMediaMgrError::BaseMediaMgrError(const nsAString& aName,
"accessed due to a hardware error (e.g. lock from another process).");
} else if (mName.EqualsLiteral("InternalError")) {
mMessage.AssignLiteral("Internal error.");
} else if (mName.EqualsLiteral("NotSupportedError")) {
mMessage.AssignLiteral("Constraints with no audio or video in it are not "
"supported");
}
}
}

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

@ -0,0 +1,8 @@
#include <stdint.h>
extern "C" uint8_t* test_rust();
TEST(rust, CallFromCpp) {
auto greeting = test_rust();
EXPECT_STREQ(reinterpret_cast<char*>(greeting), "hello from rust.");
}

6
dom/media/gtest/hello.rs Normal file
Просмотреть файл

@ -0,0 +1,6 @@
#[no_mangle]
pub extern fn test_rust() -> *const u8 {
// NB: rust &str aren't null terminated.
let greeting = "hello from rust.\0";
greeting.as_ptr()
}

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

@ -29,6 +29,11 @@ if CONFIG['MOZ_WEBM_ENCODER']:
'TestWebMWriter.cpp',
]
if CONFIG['MOZ_RUST']:
SOURCES += ['hello.rs',]
UNIFIED_SOURCES += ['TestRust.cpp',]
TEST_HARNESS_FILES.gtest += [
'../test/gizmo-frag.mp4',
'../test/gizmo.mp4',

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

@ -50,6 +50,9 @@ var tests = [
{ message: "unknown mediaSource fails",
constraints: { video: { mediaSource: 'uncle' } },
error: "NotFoundError" },
{ message: "emtpy constraint fails",
constraints: { },
error: "NotSupportedError" },
{ message: "Success-path: optional video facingMode + audio ignoring facingMode",
constraints: { fake: true,
audio: { mediaSource: 'microphone',

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

@ -84,28 +84,27 @@ MediaEngineCameraVideoSource::FitnessDistance(ValueType n,
// Binding code doesn't templatize well...
template<>
/* static */ uint32_t
/*static*/ uint32_t
MediaEngineCameraVideoSource::FitnessDistance(int32_t n,
const OwningLongOrConstrainLongRange& aConstraint)
const OwningLongOrConstrainLongRange& aConstraint, bool aAdvanced)
{
if (aConstraint.IsLong()) {
ConstrainLongRange range;
range.mIdeal.Construct(aConstraint.GetAsLong());
(aAdvanced ? range.mExact : range.mIdeal).Construct(aConstraint.GetAsLong());
return FitnessDistance(n, range);
} else {
return FitnessDistance(n, aConstraint.GetAsConstrainLongRange());
}
}
template<>
/* static */ uint32_t
/*static*/ uint32_t
MediaEngineCameraVideoSource::FitnessDistance(double n,
const OwningDoubleOrConstrainDoubleRange& aConstraint)
const OwningDoubleOrConstrainDoubleRange& aConstraint,
bool aAdvanced)
{
if (aConstraint.IsDouble()) {
ConstrainDoubleRange range;
range.mIdeal.Construct(aConstraint.GetAsDouble());
(aAdvanced ? range.mExact : range.mIdeal).Construct(aConstraint.GetAsDouble());
return FitnessDistance(n, range);
} else {
return FitnessDistance(n, aConstraint.GetAsConstrainDoubleRange());
@ -114,18 +113,22 @@ MediaEngineCameraVideoSource::FitnessDistance(double n,
/*static*/ uint32_t
MediaEngineCameraVideoSource::GetFitnessDistance(const webrtc::CaptureCapability& aCandidate,
const MediaTrackConstraintSet &aConstraints)
const MediaTrackConstraintSet &aConstraints,
bool aAdvanced)
{
// Treat width|height|frameRate == 0 on capability as "can do any".
// This allows for orthogonal capabilities that are not in discrete steps.
uint64_t distance =
uint64_t(aCandidate.width? FitnessDistance(int32_t(aCandidate.width),
aConstraints.mWidth) : 0) +
aConstraints.mWidth,
aAdvanced) : 0) +
uint64_t(aCandidate.height? FitnessDistance(int32_t(aCandidate.height),
aConstraints.mHeight) : 0) +
aConstraints.mHeight,
aAdvanced) : 0) +
uint64_t(aCandidate.maxFPS? FitnessDistance(double(aCandidate.maxFPS),
aConstraints.mFrameRate) : 0);
aConstraints.mFrameRate,
aAdvanced) : 0);
return uint32_t(std::min(distance, uint64_t(UINT32_MAX)));
}
@ -152,6 +155,8 @@ MediaEngineCameraVideoSource::TrimLessFitCandidates(CapabilitySet& set) {
// GetBestFitnessDistance returns the best distance the capture device can offer
// as a whole, given an accumulated number of ConstraintSets.
// Ideal values are considered in the first ConstraintSet only.
// Plain values are treated as Ideal in the first ConstraintSet.
// Plain values are treated as Exact in subsequent ConstraintSets.
// Infinity = UINT32_MAX e.g. device cannot satisfy accumulated ConstraintSets.
// A finite result may be used to calculate this device's ranking as a choice.
@ -172,7 +177,7 @@ MediaEngineCameraVideoSource::GetBestFitnessDistance(
auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
uint32_t distance = GetFitnessDistance(cap, *cs);
uint32_t distance = GetFitnessDistance(cap, *cs, !first);
if (distance == UINT32_MAX) {
candidateSet.RemoveElementAt(i);
} else {
@ -246,7 +251,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
candidate.mDistance = GetFitnessDistance(cap, aConstraints);
candidate.mDistance = GetFitnessDistance(cap, aConstraints, false);
if (candidate.mDistance == UINT32_MAX) {
candidateSet.RemoveElementAt(i);
} else {
@ -263,7 +268,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
if (GetFitnessDistance(cap, cs) == UINT32_MAX) {
if (GetFitnessDistance(cap, cs, true) == UINT32_MAX) {
rejects.AppendElement(candidate);
candidateSet.RemoveElementAt(i);
} else {
@ -295,7 +300,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
for (auto& candidate : candidateSet) {
webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap);
candidate.mDistance = GetFitnessDistance(cap, prefs);
candidate.mDistance = GetFitnessDistance(cap, prefs, false);
}
TrimLessFitCandidates(candidateSet);
}

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

@ -80,8 +80,14 @@ protected:
StreamTime delta);
template<class ValueType, class ConstrainRange>
static uint32_t FitnessDistance(ValueType n, const ConstrainRange& aRange);
static uint32_t FitnessDistance(int32_t n,
const dom::OwningLongOrConstrainLongRange& aConstraint, bool aAdvanced);
static uint32_t FitnessDistance(double n,
const dom::OwningDoubleOrConstrainDoubleRange& aConstraint, bool aAdvanced);
static uint32_t GetFitnessDistance(const webrtc::CaptureCapability& aCandidate,
const dom::MediaTrackConstraintSet &aConstraints);
const dom::MediaTrackConstraintSet &aConstraints,
bool aAdvanced);
static void TrimLessFitCandidates(CapabilitySet& set);
static void LogConstraints(const dom::MediaTrackConstraintSet& aConstraints,
bool aAdvanced);

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

@ -37,13 +37,23 @@ i.addEventListener("load", function loadfunc() {
// Navigate the frame to cause the document with the plugin to go inactive
i.removeEventListener("load", loadfunc);
i.src = "about:blank";
SimpleTest.executeSoon(function() {
// Ensure this event doesn't race with CheckPluginStopEvent
SimpleTest.executeSoon(function() {
const MAX_ATTEMPTS = 5;
var attempts = 0;
function checkPluginDestroyRan() {
// We may need to retry a few times until the plugin stop event makes
// its way through the event queue.
if (attempts < MAX_ATTEMPTS && !destroyran) {
++attempts;
SimpleTest.executeSoon(checkPluginDestroyRan);
} else {
info("Number of retry attempts: " + attempts);
ok(destroyran, "OnDestroy callback ran and did not crash");
SimpleTest.finish();
});
});
}
}
SimpleTest.executeSoon(checkPluginDestroyRan);
});
document.body.appendChild(i);

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

@ -12,14 +12,24 @@
SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
const MAX_ATTEMPTS = 5;
var attempts = 0;
var destroyed = false;
function onDestroy() {
destroyed = true;
}
function checkPluginAlreadyDestroyed() {
is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish();
// We may need to retry a few times until the plugin stop event makes
// its way through the event queue.
if (attempts < MAX_ATTEMPTS && !destroyed) {
++attempts;
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
} else {
info("Number of retry attempts: " + attempts);
is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish();
}
}
function startTest() {
@ -27,10 +37,8 @@
var d1 = document.getElementById('div1');
p1.callOnDestroy(onDestroy);
setTimeout(checkPluginAlreadyDestroyed, 0);
d1.removeChild(p1);
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
}
</script>

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

@ -12,14 +12,24 @@
SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
const MAX_ATTEMPTS = 5;
var attempts = 0;
var destroyed = false;
function onDestroy() {
destroyed = true;
}
function checkPluginAlreadyDestroyed() {
is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish();
// We may need to retry a few times until the plugin stop event makes
// its way through the event queue.
if (attempts < MAX_ATTEMPTS && !destroyed) {
++attempts;
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
} else {
info("Number of retry attempts: " + attempts);
is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish();
}
}
function startTest() {
@ -28,12 +38,12 @@
p1.callOnDestroy(onDestroy);
setTimeout(checkPluginAlreadyDestroyed, 0);
// Get two parent check events to run.
d1.removeChild(p1);
d1.appendChild(p1);
d1.removeChild(p1);
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
}
</script>

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

@ -12,14 +12,24 @@
SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
const MAX_ATTEMPTS = 5;
var attempts = 0;
var destroyed = false;
function onDestroy() {
destroyed = true;
}
function checkPluginAlreadyDestroyed() {
is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish();
// We may need to retry a few times until the plugin stop event makes
// its way through the event queue.
if (attempts < MAX_ATTEMPTS && !destroyed) {
++attempts;
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
} else {
info("Number of retry attempts: " + attempts);
is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish();
}
}
function startTest() {
@ -28,10 +38,8 @@
var d2 = document.getElementById('div2');
p1.callOnDestroy(onDestroy);
setTimeout(checkPluginAlreadyDestroyed, 0);
d1.removeChild(d2);
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
}
</script>

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

@ -573,7 +573,8 @@ class StorageDirectoryHelper final
mozilla::Mutex mMutex;
mozilla::CondVar mCondVar;
nsresult mMainThreadResultCode;
bool mPersistent;
const bool mPersistent;
bool mCreate;
bool mWaiting;
public:
@ -584,18 +585,28 @@ public:
, mCondVar(mMutex, "StorageDirectoryHelper::mCondVar")
, mMainThreadResultCode(NS_OK)
, mPersistent(aPersistent)
, mCreate(true)
, mWaiting(true)
{
AssertIsOnIOThread();
}
nsresult
CreateOrUpgradeMetadataFiles();
CreateOrUpgradeMetadataFiles(bool aCreate);
nsresult
RestoreMetadataFile();
private:
~StorageDirectoryHelper()
{ }
nsresult
AddOriginDirectory(nsIFile* aDirectory);
nsresult
ProcessOriginDirectories(bool aMove);
nsresult
RunOnMainThread();
@ -1050,6 +1061,20 @@ CreateDirectoryMetadata(nsIFile* aDirectory, int64_t aTimestamp,
return NS_OK;
}
nsresult
RestoreDirectoryMetadata(nsIFile* aDirectory, bool aPersistent)
{
nsRefPtr<StorageDirectoryHelper> helper =
new StorageDirectoryHelper(aDirectory, aPersistent);
nsresult rv = helper->RestoreMetadataFile();
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
GetDirectoryMetadataInputStream(nsIFile* aDirectory,
nsIBinaryInputStream** aStream)
@ -1129,6 +1154,83 @@ GetDirectoryMetadata(nsIFile* aDirectory,
return NS_OK;
}
nsresult
GetDirectoryMetadataWithRestore(nsIFile* aDirectory,
bool aPersistent,
int64_t* aTimestamp,
nsACString& aGroup,
nsACString& aOrigin,
bool* aIsApp)
{
nsresult rv = GetDirectoryMetadata(aDirectory,
aTimestamp,
aGroup,
aOrigin,
aIsApp);
if (NS_WARN_IF(NS_FAILED(rv))) {
rv = RestoreDirectoryMetadata(aDirectory, aPersistent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = GetDirectoryMetadata(aDirectory,
aTimestamp,
aGroup,
aOrigin,
aIsApp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
nsresult
GetDirectoryMetadata(nsIFile* aDirectory, int64_t* aTimestamp)
{
AssertIsOnIOThread();
MOZ_ASSERT(aDirectory);
MOZ_ASSERT(aTimestamp);
nsCOMPtr<nsIBinaryInputStream> binaryStream;
nsresult rv =
GetDirectoryMetadataInputStream(aDirectory, getter_AddRefs(binaryStream));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
uint64_t timestamp;
rv = binaryStream->Read64(&timestamp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
*aTimestamp = timestamp;
return NS_OK;
}
nsresult
GetDirectoryMetadataWithRestore(nsIFile* aDirectory,
bool aPersistent,
int64_t* aTimestamp)
{
nsresult rv = GetDirectoryMetadata(aDirectory, aTimestamp);
if (NS_WARN_IF(NS_FAILED(rv))) {
rv = RestoreDirectoryMetadata(aDirectory, aPersistent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = GetDirectoryMetadata(aDirectory, aTimestamp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
return NS_OK;
}
nsresult
MaybeUpgradeOriginDirectory(nsIFile* aDirectory)
{
@ -1822,6 +1924,9 @@ QuotaManager::GetDirectoryForOrigin(PersistenceType aPersistenceType,
nsresult
QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
{
MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_TEMPORARY ||
aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
nsresult rv;
nsCOMPtr<nsIFile> directory =
@ -1885,8 +1990,12 @@ QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
nsCString group;
nsCString origin;
bool isApp;
rv = GetDirectoryMetadata(childDirectory, &timestamp, group, origin,
&isApp);
rv = GetDirectoryMetadataWithRestore(childDirectory,
/* aPersistent */ false,
&timestamp,
group,
origin,
&isApp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2123,7 +2232,7 @@ QuotaManager::MaybeUpgradePersistentStorageDirectory()
nsRefPtr<StorageDirectoryHelper> helper =
new StorageDirectoryHelper(persistentStorageDir, /* aPersistent */ true);
rv = helper->CreateOrUpgradeMetadataFiles();
rv = helper->CreateOrUpgradeMetadataFiles(/* aCreate */ true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2159,7 +2268,7 @@ QuotaManager::MaybeUpgradePersistentStorageDirectory()
helper = new StorageDirectoryHelper(temporaryStorageDir,
/* aPersistent */ false);
rv = helper->CreateOrUpgradeMetadataFiles();
rv = helper->CreateOrUpgradeMetadataFiles(/* aCreate */ false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2278,15 +2387,13 @@ QuotaManager::EnsureOriginIsInitialized(PersistenceType aPersistenceType,
aIsApp);
NS_ENSURE_SUCCESS(rv, rv);
} else {
nsCOMPtr<nsIBinaryInputStream> stream;
rv = GetDirectoryMetadataInputStream(directory, getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
uint64_t ts;
rv = stream->Read64(&ts);
NS_ENSURE_SUCCESS(rv, rv);
timestamp = ts;
bool persistent = aPersistenceType == PERSISTENCE_TYPE_PERSISTENT;
rv = GetDirectoryMetadataWithRestore(directory,
persistent,
&timestamp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
MOZ_ASSERT(timestamp <= PR_Now());
}
@ -3775,11 +3882,18 @@ OriginClearRunnable::DeleteFiles(QuotaManager* aQuotaManager,
continue;
}
bool persistent = aPersistenceType == PERSISTENCE_TYPE_PERSISTENT;
int64_t timestamp;
nsCString group;
nsCString origin;
bool isApp;
rv = GetDirectoryMetadata(file, &timestamp, group, origin, &isApp);
rv = GetDirectoryMetadataWithRestore(file,
persistent,
&timestamp,
group,
origin,
&isApp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
@ -4369,14 +4483,15 @@ SaveOriginAccessTimeRunnable::Run()
}
nsresult
StorageDirectoryHelper::CreateOrUpgradeMetadataFiles()
StorageDirectoryHelper::CreateOrUpgradeMetadataFiles(bool aCreate)
{
AssertIsOnIOThread();
MOZ_ASSERT_IF(mPersistent, aCreate);
nsresult rv;
mCreate = aCreate;
nsCOMPtr<nsISimpleEnumerator> entries;
rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
nsresult rv = mDirectory->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -4392,61 +4507,27 @@ StorageDirectoryHelper::CreateOrUpgradeMetadataFiles()
nsCOMPtr<nsIFile> originDir = do_QueryInterface(entry);
MOZ_ASSERT(originDir);
nsString leafName;
rv = originDir->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
bool isDirectory;
rv = originDir->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!isDirectory) {
nsString leafName;
rv = originDir->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!leafName.EqualsLiteral(DSSTORE_FILE_NAME)) {
NS_WARNING("Something in the storage directory that doesn't belong!");
}
continue;
}
if (mPersistent) {
rv = MaybeUpgradeOriginDirectory(originDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (leafName.EqualsLiteral(kChromeOrigin)) {
OriginProps* originProps = mOriginProps.AppendElement();
originProps->mDirectory = originDir;
originProps->mSpec = kChromeOrigin;
originProps->mType = OriginProps::eChrome;
} else {
nsCString spec;
uint32_t appId;
bool inMozBrowser;
if (NS_WARN_IF(!OriginParser::ParseOrigin(NS_ConvertUTF16toUTF8(leafName),
&appId, &inMozBrowser, spec))) {
return NS_ERROR_FAILURE;
}
OriginProps* originProps = mOriginProps.AppendElement();
originProps->mDirectory = originDir;
originProps->mSpec = spec;
originProps->mAppId = appId;
originProps->mType = OriginProps::eContent;
originProps->mInMozBrowser = inMozBrowser;
if (mPersistent) {
int64_t timestamp = INT64_MIN;
rv = GetLastModifiedTime(originDir, &timestamp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
originProps->mTimestamp = timestamp;
}
rv = AddOriginDirectory(originDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
@ -4454,6 +4535,94 @@ StorageDirectoryHelper::CreateOrUpgradeMetadataFiles()
return NS_OK;
}
rv = ProcessOriginDirectories(/* aMove */ true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
StorageDirectoryHelper::RestoreMetadataFile()
{
AssertIsOnIOThread();
MOZ_ASSERT(mCreate);
nsresult rv = AddOriginDirectory(mDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = ProcessOriginDirectories(/* aMove */ false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
nsresult
StorageDirectoryHelper::AddOriginDirectory(nsIFile* aDirectory)
{
MOZ_ASSERT(aDirectory);
nsresult rv;
if (mPersistent) {
rv = MaybeUpgradeOriginDirectory(aDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
nsString leafName;
rv = aDirectory->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (leafName.EqualsLiteral(kChromeOrigin)) {
OriginProps* originProps = mOriginProps.AppendElement();
originProps->mDirectory = aDirectory;
originProps->mSpec = kChromeOrigin;
originProps->mType = OriginProps::eChrome;
} else {
nsCString spec;
uint32_t appId;
bool inMozBrowser;
if (NS_WARN_IF(!OriginParser::ParseOrigin(NS_ConvertUTF16toUTF8(leafName),
&appId, &inMozBrowser, spec))) {
return NS_ERROR_FAILURE;
}
OriginProps* originProps = mOriginProps.AppendElement();
originProps->mDirectory = aDirectory;
originProps->mSpec = spec;
originProps->mAppId = appId;
originProps->mType = OriginProps::eContent;
originProps->mInMozBrowser = inMozBrowser;
if (mCreate) {
int64_t timestamp = INT64_MIN;
rv = GetLastModifiedTime(aDirectory, &timestamp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
originProps->mTimestamp = timestamp;
}
}
return NS_OK;
}
nsresult
StorageDirectoryHelper::ProcessOriginDirectories(bool aMove)
{
AssertIsOnIOThread();
MOZ_ASSERT(!mOriginProps.IsEmpty());
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(this)));
{
@ -4473,6 +4642,8 @@ StorageDirectoryHelper::CreateOrUpgradeMetadataFiles()
return NS_ERROR_FAILURE;
}
nsresult rv;
nsCOMPtr<nsIFile> permanentStorageDir;
for (uint32_t count = mOriginProps.Length(), index = 0;
@ -4480,7 +4651,7 @@ StorageDirectoryHelper::CreateOrUpgradeMetadataFiles()
index++) {
OriginProps& originProps = mOriginProps[index];
if (mPersistent) {
if (mCreate) {
rv = CreateDirectoryMetadata(originProps.mDirectory,
originProps.mTimestamp,
originProps.mGroup,
@ -4491,7 +4662,9 @@ StorageDirectoryHelper::CreateOrUpgradeMetadataFiles()
}
// Move whitelisted origins to new persistent storage.
if (QuotaManager::IsOriginWhitelistedForPersistentStorage(
if (mPersistent &&
aMove &&
QuotaManager::IsOriginWhitelistedForPersistentStorage(
originProps.mSpec)) {
if (!permanentStorageDir) {
permanentStorageDir =
@ -4586,7 +4759,7 @@ StorageDirectoryHelper::RunOnMainThread()
return rv;
}
if (mPersistent) {
if (mCreate) {
rv = QuotaManager::GetInfoFromPrincipal(principal,
&originProps.mGroup,
&originProps.mOrigin,

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

@ -37,21 +37,23 @@ var innerWidthMax = (isWin8 ? 125 : 100);
function test() {
var w = window.open('data:text/html,null', null, 'width=300,height=300');
var nbResize = 0;
SimpleTest.waitForFocus(function() {
w.onresize = function() {
if (!(w.innerWidth + epsilon >= innerWidthMin &&
w.innerWidth - epsilon <= innerWidthMax)) {
// We need still another resize event.
nbResize++;
if (nbResize == 1) {
return;
}
if (!(w.innerHeight + epsilon >= 100 &&
w.innerHeight - epsilon <= 100)) {
// ditto
return;
}
ok(true, "innerWidth should be between " + innerWidthMin + " and " + innerWidthMax);
ok(true, "innerHeight should be around 100");
ok(w.innerWidth + epsilon >= innerWidthMin && w.innerWidth - epsilon <= innerWidthMax,
"innerWidth should be between " + innerWidthMin + " and " + innerWidthMax);
ok(w.innerHeight + epsilon >= 100 && w.innerHeight - epsilon <= 100,
"innerHeight should be around 100");
// It's not clear why 2 events are coming...
is(nbResize, 2, "We should get 2 events.");
w.close();

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

@ -23,7 +23,7 @@ function testDefaultCtor() {
function testClone() {
var orig = new Request("./cloned_request.txt", {
method: 'POST',
headers: { "Content-Length": 5 },
headers: { "Sample-Header": "5" },
body: "Sample body",
mode: "same-origin",
credentials: "same-origin",
@ -33,9 +33,9 @@ function testClone() {
ok(clone.method === "POST", "Request method is POST");
ok(clone.headers instanceof Headers, "Request should have non-null Headers object");
is(clone.headers.get('content-length'), "5", "Response content-length should be 5.");
orig.headers.set('content-length', 6);
is(clone.headers.get('content-length'), "5", "Request content-length should be 5.");
is(clone.headers.get('sample-header'), "5", "Request sample-header should be 5.");
orig.headers.set('sample-header', 6);
is(clone.headers.get('sample-header'), "5", "Cloned Request sample-header should continue to be 5.");
ok(clone.url === (new URL("./cloned_request.txt", self.location.href)).href,
"URL should be resolved with entry settings object's API base URL");
@ -124,6 +124,20 @@ function testBug1109574() {
var r3 = new Request(r1);
}
function testHeaderGuard() {
var headers = {
"Cookie": "Custom cookie",
"Non-Simple-Header": "value",
};
var r1 = new Request("", { headers: headers });
ok(!r1.headers.has("Cookie"), "Default Request header should have guard request and prevent setting forbidden header.");
ok(r1.headers.has("Non-Simple-Header"), "Default Request header should have guard request and allow setting non-simple header.");
var r2 = new Request("", { mode: "no-cors", headers: headers });
ok(!r2.headers.has("Cookie"), "no-cors Request header should have guard request-no-cors and prevent setting non-simple header.");
ok(!r2.headers.has("Non-Simple-Header"), "no-cors Request header should have guard request-no-cors and prevent setting non-simple header.");
}
function testMethod() {
// These get normalized.
var allowed = ["delete", "get", "head", "options", "post", "put" ];
@ -434,6 +448,7 @@ function runTest() {
testUrlFragment();
testMethod();
testBug1109574();
testHeaderGuard();
testModeCorsPreflightEnumValue();
return Promise.resolve()

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

@ -14,6 +14,7 @@ support-files =
image_50.png
image_100.png
image_200.png
performance_timeline_main_test.html
resource_timing_iframe.html
resource_timing_main_test.html
resource_timing_cross_origin.html
@ -79,8 +80,10 @@ support-files = test_offsets.js
skip-if = buildapp == 'mulet'
[test_paste_selection.html]
skip-if = buildapp == 'mulet'
[test_performance_timeline.html]
[test_picture_mutations.html]
[test_picture_pref.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_resource_timing.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_resource_timing_cross_origin.html]

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

@ -0,0 +1,100 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
function ok(cond, message) {
window.opener.ok(cond, message)
}
function is(received, expected, message) {
window.opener.is(received, expected, message);
}
function isnot(received, notExpected, message) {
window.opener.isnot(received, notExpected, message);
}
var receivedBufferFullEvents = 0;
window.performance.onresourcetimingbufferfull = () => {
receivedBufferFullEvents++;
}
window.onload = () => {
// Here, we should have 4 entries (1 css, 3 png) since the image was loaded.
is(window.performance.getEntries().length, 4, "Performance.getEntries() returned wrong number of entries.");
window.performance.setResourceTimingBufferSize(5);
window.performance.mark("test-start");
window.performance.mark("test-end");
// The URI should be the address of a resource will be loaded later to be used on getEntriesByName.
window.performance.measure("http://mochi.test:8888/tests/dom/tests/mochitest/general/test-data2.json",
"test-start", "test-end");
is(window.performance.getEntries().length, 7, "User Timing APIs should never be affected by setResourceTimingBufferSize.");
is(window.performance.getEntriesByType("resource").length, 4, "The number of PerformanceResourceTiming should be 4.");
is(window.performance.getEntriesByType("mark").length, 2, "The number of PerformanceMark entries should be 2.");
is(window.performance.getEntriesByType("measure").length, 1, "The number of PerformanceMeasure entries should be 1.");
is(receivedBufferFullEvents, 0, "onresourcetimingbufferfull should never be called.");
makeXhr("test-data2.json", firstCheck);
}
function makeXhr(aUrl, aCallback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onload = aCallback;
xmlhttp.open("get", aUrl, true);
xmlhttp.send();
}
function firstCheck() {
is(window.performance.getEntriesByType("resource").length, 5, "The number of PerformanceResourceTiming should be 5.");
is(receivedBufferFullEvents, 1, "onresourcetimingbufferfull should be called once.");
makeXhr("test-data2.json", secondCheck);
}
function secondCheck() {
is(window.performance.getEntriesByType("resource").length, 5, "The number of PerformanceResourceTiming should be 5.");
is(receivedBufferFullEvents, 1, "onresourcetimingbufferfull should never be called since the last call.");
checkOrder(window.performance.getEntries(), "All PerformanceEntry");
checkOrder(window.performance.getEntriesByType("resource"), "PerformanceResourceTiming");
checkOrder(window.performance.getEntriesByType("mark"), "PerformanceMark");
checkOrder(window.performance.getEntriesByType("measure"), "PerformanceMeasure");
is(window.performance.getEntriesByName("http://mochi.test:8888/tests/dom/tests/mochitest/general/test-data2.json").length, 2,
"Both PerformanceMeasure and XMLHttpRequest resource should be included.");
checkOrder(window.performance.getEntriesByName("http://mochi.test:8888/tests/dom/tests/mochitest/general/test-data2.json"),
"Entry with performance.getEntrieByName()");
window.opener.finishTests();
}
function checkOrder(entries, name) {
for (var i = 0; i < entries.length - 1; i++) {
ok(entries[i].startTime <= entries[i + 1].startTime, name + " should be sorted by startTime.");
}
}
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1158731"
title="Buffer for Performance APIs (Resource Timing, User Timing) should be separeted">
Bug #1158731 - Buffer for Performance APIs (Resource Timing, User Timing) should be separeted
</a>
<p id="display"></p>
<div id="content">
<img src="http://mochi.test:8888/tests/image/test/mochitest/over.png">
<object data="http://mochi.test:8888/tests/image/test/mochitest/clear.png" type="image/png"/>
<embed src="http://mochi.test:8888/tests/image/test/mochitest/green.png" type="image/png"/>
</div>
</body>
</html>

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

@ -76,7 +76,7 @@ window.onload = function() {
bufferFullCounter += 1;
}
// Here, we should have 6 entries (1 css, 3 png, 1 html) since the image was loaded.
// Here, we should have 5 entries (1 css, 3 png, 1 html) since the image was loaded.
is(window.performance.getEntries().length, 5, "Performance.getEntries() returned wrong number of entries.");
checkStringify(window.performance.getEntries()[0]);

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

@ -0,0 +1,36 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Resource timing is prefed off by default, so we had to use this workaround
SpecialPowers.pushPrefEnv({"set": [["dom.enable_resource_timing", true],
["dom.enable_user_timing", true]]}, start);
var subwindow = null;
function start() {
subwindow = window.open("performance_timeline_main_test.html");
}
function finishTests() {
subwindow.close();
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

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

@ -62,6 +62,7 @@
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true]
]}, runTest);

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

@ -74,6 +74,12 @@ skip-if(B2G||Mulet) fails-if(Android) needs-focus != spellcheck-hyphen-invalid.h
skip-if(B2G||Mulet) fails-if(Android) needs-focus != spellcheck-hyphen-multiple-invalid.html spellcheck-hyphen-multiple-invalid-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
== spellcheck-dotafterquote-valid.html spellcheck-dotafterquote-valid-ref.html
== spellcheck-url-valid.html spellcheck-url-valid-ref.html
needs-focus == spellcheck-non-latin-arabic.html spellcheck-non-latin-arabic-ref.html
needs-focus == spellcheck-non-latin-chinese-simplified.html spellcheck-non-latin-chinese-simplified-ref.html
needs-focus == spellcheck-non-latin-chinese-traditional.html spellcheck-non-latin-chinese-traditional-ref.html
needs-focus == spellcheck-non-latin-hebrew.html spellcheck-non-latin-hebrew-ref.html
needs-focus == spellcheck-non-latin-japanese.html spellcheck-non-latin-japanese-ref.html
needs-focus == spellcheck-non-latin-korean.html spellcheck-non-latin-korean-ref.html
== unneeded_scroll.html unneeded_scroll-ref.html
skip-if(B2G||Mulet) == caret_on_presshell_reinit.html caret_on_presshell_reinit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
skip-if(B2G||Mulet) == caret_on_presshell_reinit-2.html caret_on_presshell_reinit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<textarea autofocus spellcheck="false">سلام</textarea>
</body>
</html>

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<textarea autofocus>سلام</textarea>
</body>
</html>

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<textarea autofocus spellcheck="false">你好</textarea>
</body>
</html>

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

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<textarea autofocus>你好</textarea>
</body>
</html>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше