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 import os
from StringIO import StringIO from StringIO import StringIO
import shlex import shlex
import sys
old_bytecode = sys.dont_write_bytecode
sys.dont_write_bytecode = True
path = os.path.join(os.path.dirname(__file__), 'mach') 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') path = os.path.join(config.topsrcdir, 'mach')
mach_module = imp.load_module('_mach', open(path), path, ('', 'r', imp.PY_SOURCE)) mach_module = imp.load_module('_mach', open(path), path, ('', 'r', imp.PY_SOURCE))
sys.dont_write_bytecode = old_bytecode
def FlagsForFile(filename): def FlagsForFile(filename):
mach = mach_module.get_mach() mach = mach_module.get_mach()
out = StringIO() out = StringIO()

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

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

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

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

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

@ -39,6 +39,9 @@ InterfacesFor(Accessible* aAcc)
if (aAcc->IsTableCell()) if (aAcc->IsTableCell())
interfaces |= Interfaces::TABLECELL; interfaces |= Interfaces::TABLECELL;
if (aAcc->IsDoc())
interfaces |= Interfaces::DOCUMENT;
return interfaces; return interfaces;
} }
@ -1615,6 +1618,22 @@ DocAccessibleChild::RecvTakeFocus(const uint64_t& aID)
return true; 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 bool
DocAccessibleChild::RecvChildAtPoint(const uint64_t& aID, DocAccessibleChild::RecvChildAtPoint(const uint64_t& aID,
const int32_t& aX, const int32_t& aX,

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

@ -393,6 +393,10 @@ public:
virtual bool RecvTakeFocus(const uint64_t& aID) override; 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, virtual bool RecvChildAtPoint(const uint64_t& aID,
const int32_t& aX, const int32_t& aX,
const int32_t& aY, const int32_t& aY,

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

@ -211,6 +211,8 @@ child:
prio(high) sync Step(uint64_t aID) returns(double aStep); prio(high) sync Step(uint64_t aID) returns(double aStep);
prio(high) sync TakeFocus(uint64_t aID); 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) prio(high) sync ChildAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aWhich)
returns(uint64_t aChild, bool aOk); returns(uint64_t aChild, bool aOk);
prio(high) sync Bounds(uint64_t aID) returns(nsIntRect aRect); prio(high) sync Bounds(uint64_t aID) returns(nsIntRect aRect);

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

@ -903,6 +903,15 @@ ProxyAccessible::TakeFocus()
unused << mDoc->SendTakeFocus(mID); 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*
ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY, ProxyAccessible::ChildAtPoint(int32_t aX, int32_t aY,
Accessible::EWhichChildAtPoint aWhichChild) Accessible::EWhichChildAtPoint aWhichChild)

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

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

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26"> <project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <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="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/> <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/>

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

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <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="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/> <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26"> <project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33"> <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <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="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="9a9797062c6001d6346504161c51187a2968466b"/> <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"> <project name="platform_build" path="build" remote="b2g" revision="2eda36a4795012a5d1275b77ebb20ac377c8cd26">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -17,7 +17,7 @@
</project> </project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <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="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/> <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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

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

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

@ -17,7 +17,7 @@
</project> </project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/> <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="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/> <project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/> <project name="apitrace" path="external/apitrace" remote="apitrace" revision="0627790166dccd8dd370fa7d9f434ed9fc027fb4"/>

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

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33"> <project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </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="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d3868ff4bb3a4b81382795e2784258c210fe6cb8"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/> <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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

@ -3029,6 +3029,21 @@
</certItem> </certItem>
<certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB"> <certItem issuerName="MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB">
<serialNumber>UoRGnb96CUDTxIqVry6LBg==</serialNumber> <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> </certItem>
</certItems> </certItems>

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

@ -1567,6 +1567,21 @@ let BookmarkingUI = {
updatePocketItemVisibility: function BUI_updatePocketItemVisibility(prefix) { updatePocketItemVisibility: function BUI_updatePocketItemVisibility(prefix) {
let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button"); 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 + "pocket").hidden = hidden;
document.getElementById(prefix + "pocketSeparator").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 # 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/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This is a temporary file and not meant for localization; later versions # This is a temporary file, later versions of Firefox will use
# of Firefox include these strings in browser.properties # browser.properties in the usual L10N location.
pocket-button.label = Pocket pocket-button.label = Pocket
pocket-button.tooltiptext = Save to Pocket pocket-button.tooltiptext = Save to Pocket

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

@ -186,6 +186,22 @@ nsContextMenu.prototype = {
CustomizableUI.getPlacementOfWidget("pocket-button") && CustomizableUI.getPlacementOfWidget("pocket-button") &&
(uri.schemeIs("http") || uri.schemeIs("https") || (uri.schemeIs("http") || uri.schemeIs("https") ||
(uri.schemeIs("about") && ReaderMode.getOriginalUrl(uri.spec))); (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()); 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 // Sometimes sessionstore collects data during this test, which causes a sync reflow
// (https://bugzilla.mozilla.org/show_bug.cgi?id=892154 will fix this) // (https://bugzilla.mozilla.org/show_bug.cgi?id=892154 will fix this)
"ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm", "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") { 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*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, 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+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+2, 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, 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, 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*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)"], [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.xul (content/browser.xul)
content/browser/browser-pocket.properties (content/browser-pocket.properties) content/browser/browser-pocket.properties (content/browser-pocket.properties)
content/browser/browser-pocket.dtd (content/browser-pocket.dtd) 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/browser-tabPreviews.xml (content/browser-tabPreviews.xml)
* content/browser/chatWindow.xul (content/chatWindow.xul) * content/browser/chatWindow.xul (content/chatWindow.xul)
content/browser/tab-content.js (content/tab-content.js) 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"; const kBrandBundle = "chrome://branding/locale/brand.properties";
return Services.strings.createBundle(kBrandBundle); 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 kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const kPrefCustomizationDebug = "browser.uiCustomization.debug"; const kPrefCustomizationDebug = "browser.uiCustomization.debug";
@ -1069,10 +1065,11 @@ if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
if (Services.prefs.getBoolPref("browser.pocket.enabled")) { if (Services.prefs.getBoolPref("browser.pocket.enabled")) {
let isEnabledForLocale = true; let isEnabledForLocale = true;
let browserLocale;
if (Services.prefs.getBoolPref("browser.pocket.useLocaleList")) { if (Services.prefs.getBoolPref("browser.pocket.useLocaleList")) {
let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"] let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"]
.getService(Ci.nsIXULChromeRegistry); .getService(Ci.nsIXULChromeRegistry);
let browserLocale = chromeRegistry.getSelectedLocale("browser"); browserLocale = chromeRegistry.getSelectedLocale("browser");
let enabledLocales = []; let enabledLocales = [];
try { try {
enabledLocales = Services.prefs.getCharPref("browser.pocket.enabledLocales").split(' '); enabledLocales = Services.prefs.getCharPref("browser.pocket.enabledLocales").split(' ');
@ -1083,14 +1080,30 @@ if (Services.prefs.getBoolPref("browser.pocket.enabled")) {
} }
if (isEnabledForLocale) { 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 = { let pocketButton = {
id: "pocket-button", id: "pocket-button",
defaultArea: CustomizableUI.AREA_NAVBAR, defaultArea: CustomizableUI.AREA_NAVBAR,
introducedInVersion: "pref", introducedInVersion: "pref",
type: "view", type: "view",
viewId: "PanelUI-pocketView", viewId: "PanelUI-pocketView",
label: PocketBundle.GetStringFromName("pocket-button.label"), label: label,
tooltiptext: PocketBundle.GetStringFromName("pocket-button.tooltiptext"), tooltiptext: tooltiptext,
onViewShowing: Pocket.onPanelViewShowing, onViewShowing: Pocket.onPanelViewShowing,
onViewHiding: Pocket.onPanelViewHiding, 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/saved.css (panels/css/saved.css)
content/browser/pocket/panels/css/signup.css (panels/css/signup.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/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@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/pocketlogo@2x.png (panels/img/pocketlogo@2x.png)
content/browser/pocket/panels/img/pocketlogosolo@1x.png (panels/img/pocketlogosolo@1x.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/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/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/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_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/saved_shell.handlebars (panels/tmpl/saved_shell.handlebars)
content/browser/pocket/panels/tmpl/signup_shell.handlebars (panels/tmpl/signup_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) -- // // -- Initialization (on startup and new windows) -- //
var inited = false; var inited = false;
var currentPanelDidShow, currentPanelDidHide; var _currentPanelDidShow;
var _currentPanelDidHide;
var _isHidden = false; var _isHidden = false;
var _notificationTimeout; var _notificationTimeout;
// 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 prefBranch = Services.prefs.getBranch("browser.pocket.settings.");
var savePanelWidth = 350;
var savePanelHeights = {collapsed: 153, expanded: 272};
/** /**
* Initalizes Pocket UI and panels * Initalizes Pocket UI and panels
*/ */
@ -162,15 +170,15 @@ var pktUI = (function() {
} }
function pocketPanelDidShow(event) { function pocketPanelDidShow(event) {
if (currentPanelDidShow) { if (_currentPanelDidShow) {
currentPanelDidShow(event); _currentPanelDidShow(event);
} }
} }
function pocketPanelDidHide(event) { function pocketPanelDidHide(event) {
if (currentPanelDidHide) { if (_currentPanelDidHide) {
currentPanelDidHide(event); _currentPanelDidHide(event);
} }
// clear the panel // clear the panel
@ -299,7 +307,7 @@ var pktUI = (function() {
startheight = 436; 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() { onShow: function() {
}, },
onHide: panelDidHide, onHide: panelDidHide,
@ -321,15 +329,30 @@ var pktUI = (function() {
var isValidURL = (typeof url !== 'undefined' && (url.startsWith("http") || url.startsWith('https'))); 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() { onShow: function() {
var saveLinkMessageId = 'saveLink';
// Send error message for invalid url // Send error message for invalid url
if (!isValidURL) { if (!isValidURL) {
var error = new Error('Only links can be saved'); // TODO: Pass key for localized error in error object
sendErrorMessage('saveLink', error); var error = {
message: 'Only links can be saved',
localizedKey: "onlylinkssaved"
};
pktUIMessaging.sendErrorMessageToPanel(panelId, saveLinkMessageId, error);
return; 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 // Add url
var options = { var options = {
success: function(data, request) { success: function(data, request) {
@ -338,7 +361,7 @@ var pktUI = (function() {
status: "success", status: "success",
item: item item: item
}; };
sendMessage('saveLink', successResponse); pktUIMessaging.sendMessageToPanel(panelId, saveLinkMessageId, successResponse);
}, },
error: function(error, request) { error: function(error, request) {
// If user is not authorized show singup page // If user is not authorized show singup page
@ -347,8 +370,13 @@ var pktUI = (function() {
return; return;
} }
// 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 // Send error message to panel
sendErrorMessage('saveLink', error); pktUIMessaging.sendErrorMessageToPanel(panelId, saveLinkMessageId, panelError);
} }
} }
@ -361,8 +389,8 @@ var pktUI = (function() {
pktApi.addLink(url, options); pktApi.addLink(url, options);
}, },
onHide: panelDidHide, onHide: panelDidHide,
width: 350, width: savePanelWidth,
height: 267 height: pktApi.isPremiumUser() && isValidURL ? savePanelHeights.expanded : savePanelHeights.collapsed
}); });
} }
@ -370,6 +398,9 @@ var pktUI = (function() {
* Open a generic panel * Open a generic panel
*/ */
function showPanel(url, options) { 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 // 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 // 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 // For some reason setting onpopupshown and onpopuphidden on the panel directly didn't work, so
// do it this hacky way for now // do it this hacky way for now
currentPanelDidShow = options.onShow; _currentPanelDidShow = options.onShow;
currentPanelDidHide = options.onHide; _currentPanelDidHide = options.onHide;
resizePanel({ resizePanel({
width: options.width, width: options.width,
height: options.height height: options.height
}); });
return _panelId;
} }
/** /**
@ -421,168 +454,132 @@ var pktUI = (function() {
function panelDidHide() { 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 * Register all of the messages needed for the panels
*/ */
function registerEventMessages() { 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(); var iframe = getPanelFrame();
// Only register the messages once // Only register the messages once
if (iframe.getAttribute('did_init') == 1) { var didInitAttributeKey = 'did_init';
var didInitMessageListener = iframe.getAttribute(didInitAttributeKey);
if (typeof didInitMessageListener !== "undefined" && didInitMessageListener == 1) {
return; return;
} }
iframe.setAttribute('did_init', 1); iframe.setAttribute(didInitAttributeKey, 1);
// When the panel is displayed it generated an event called // When the panel is displayed it generated an event called
// "show": we will listen for that event and when it happens, // "show": we will listen for that event and when it happens,
// send our own "show" event to the panel's script, so the // send our own "show" event to the panel's script, so the
// script can prepare the panel for display. // 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 // Let panel know that it is ready
sendMessage('show'); pktUIMessaging.sendMessageToPanel(panelId, _showMessageId);
}); });
// Open a new tab with a given url and activate if // Open a new tab with a given url and activate if
addMessageListener("openTabWithUrl", function(payload) { var _openTabWithUrlMessageId = "openTabWithUrl";
pktUIMessaging.addMessageListener(_openTabWithUrlMessageId, function(panelId, data) {
// Check if the tab should become active after opening
var activate = true; var activate = true;
if (typeof payload.activate !== "undefined") { if (typeof data.activate !== "undefined") {
activate = payload.activate; 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 // Close the panel
addMessageListener("close", function(payload) { var _closeMessageId = "close";
pktUIMessaging.addMessageListener(_closeMessageId, function(panelId, data) {
getPanel().hidePopup(); getPanel().hidePopup();
}); });
// Send the current url to the panel // Send the current url to the panel
addMessageListener("getCurrentURL", function(payload) { var _getCurrentURLMessageId = "getCurrentURL";
sendMessage('getCurrentURLResponse', 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. // Callback post initialization to tell background script that panel is "ready" for communication.
addMessageListener("listenerReady", function(payload) { pktUIMessaging.addMessageListener("listenerReady", function(panelId, data) {
}); });
addMessageListener("resizePanel", function(payload) { pktUIMessaging.addMessageListener("collapseSavePanel", function(panelId, data) {
resizePanel(payload); if (!pktApi.isPremiumUser())
resizePanel({width:savePanelWidth, height:savePanelHeights.collapsed});
});
pktUIMessaging.addMessageListener("expandSavePanel", function(panelId, data) {
resizePanel({width:savePanelWidth, height:savePanelHeights.expanded});
}); });
// Ask for recently accessed/used tags for auto complete // 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) { 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 // Ask for suggested tags based on passed url
addMessageListener("getSuggestedTags", function(payload) { var _getSuggestedTagsMessageId = "getSuggestedTags";
var responseMessageId = "getSuggestedTagsResponse"; pktUIMessaging.addMessageListener(_getSuggestedTagsMessageId, function(panelId, data) {
pktApi.getSuggestedTagsForURL(data.url, {
pktApi.getSuggestedTagsForURL(payload.url, {
success: function(data, response) { success: function(data, response) {
var suggestedTags = data.suggested_tags; var suggestedTags = data.suggested_tags;
var successResponse = { var successResponse = {
status: "success", status: "success",
value: { value: {
"suggestedTags" : suggestedTags suggestedTags : suggestedTags
} }
} }
sendMessage(responseMessageId, successResponse); pktUIMessaging.sendResponseMessageToPanel(panelId, _getSuggestedTagsMessageId, successResponse);
}, },
error: function(error, response) { 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 // Pass url and array list of tags, add to existing save item accordingly
addMessageListener("addTags", function(payload) { var _addTagsMessageId = "addTags";
var responseMessageId = "addTagsResponse"; pktUIMessaging.addMessageListener(_addTagsMessageId, function(panelId, data) {
pktApi.addTagsToURL(data.url, data.tags, {
pktApi.addTagsToURL(payload.url, payload.tags, {
success: function(data, response) { success: function(data, response) {
var successResponse = {status: "success"}; var successResponse = {status: "success"};
sendMessage(responseMessageId, successResponse); pktUIMessaging.sendResponseMessageToPanel(panelId, _addTagsMessageId, successResponse);
}, },
error: function(error, response) { 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 // Based on clicking "remove page" CTA, and passed unique item id, remove the item
addMessageListener("deleteItem", function(payload) { var _deleteItemMessageId = "deleteItem";
var responseMessageId = "deleteItemResponse"; pktUIMessaging.addMessageListener(_deleteItemMessageId, function(panelId, data) {
pktApi.deleteItem(data.itemId, {
pktApi.deleteItem(payload.itemId, {
success: function(data, response) { success: function(data, response) {
var successResponse = {status: "success"}; var successResponse = {status: "success"};
sendMessage(responseMessageId, successResponse); pktUIMessaging.sendResponseMessageToPanel(panelId, _deleteItemMessageId, successResponse);
}, },
error: function(error, response) { error: function(error, response) {
sendErrorMessage(responseMessageId, error); pktUIMessaging.sendErrorResponseMessageToPanel(panelId, _deleteItemMessageId, error);
} }
}) })
}); });
@ -748,3 +745,149 @@ var pktUI = (function() {
isHidden 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 { th {
padding: 0; 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 { .pkt_ext_containersaved .pkt_ext_loadingspinner {
position: relative; position: relative;
display: inline-block; display: inline-block;
width: 2.5em;
height: 2.5em; height: 2.5em;
margin: 2em 0 0; left: 50%;
margin: 2em 0 0 -1.25em;
font-size: 10px; font-size: 10px;
text-indent: 999em; text-indent: 999em;
position: absolute;
top: 4em;
overflow: hidden; overflow: hidden;
width: 2.5em;
animation: pkt_ext_spin 0.7s infinite steps(8); animation: pkt_ext_spin 0.7s infinite steps(8);
} }
.pkt_ext_containersaved .pkt_ext_loadingspinner:before, .pkt_ext_containersaved .pkt_ext_loadingspinner:before,
@ -96,7 +99,7 @@
.pkt_ext_containersaved .pkt_ext_initload { .pkt_ext_containersaved .pkt_ext_initload {
left: 0; left: 0;
position: absolute; position: absolute;
top: 1em; top: 0;
width: 100%; width: 100%;
} }
.pkt_ext_containersaved .pkt_ext_detail { .pkt_ext_containersaved .pkt_ext_detail {
@ -106,7 +109,6 @@
z-index: 10; z-index: 10;
} }
.pkt_ext_container_detailactive .pkt_ext_initload { .pkt_ext_container_detailactive .pkt_ext_initload {
transition: opacity 0.2s ease-out;
opacity: 0; opacity: 0;
} }
.pkt_ext_container_detailactive .pkt_ext_initload .pkt_ext_loadingspinner, .pkt_ext_container_detailactive .pkt_ext_initload .pkt_ext_loadingspinner,
@ -116,7 +118,6 @@
.pkt_ext_container_detailactive .pkt_ext_detail { .pkt_ext_container_detailactive .pkt_ext_detail {
max-height: 20em; max-height: 20em;
opacity: 1; opacity: 1;
transition: opacity 0.2s ease-out;
} }
.pkt_ext_container_finalstate .pkt_ext_edit_msg, .pkt_ext_container_finalstate .pkt_ext_edit_msg,
.pkt_ext_container_finalstate .pkt_ext_tag_detail, .pkt_ext_container_finalstate .pkt_ext_tag_detail,
@ -151,30 +152,9 @@
@keyframes fade_in_out { @keyframes fade_in_out {
0% { 0% {
opacity: 1; opacity: 1;
top: 0;
} }
50% { 50% {
opacity: 0; 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% { 100% {
opacity: 1; opacity: 1;
@ -182,18 +162,17 @@
} }
.pkt_ext_container_finalstate h2 { .pkt_ext_container_finalstate h2 {
animation: fade_in_out 0.4s ease-out; animation: fade_in_out 0.4s ease-out;
top: 10px;
} }
.pkt_ext_container_finalerrorstate h2 { .pkt_ext_container_finalerrorstate h2 {
animation: fade_int_outalt 0.4s ease-out; animation: none;
color: #d74345; color: #d74345;
top: 0;
} }
.pkt_ext_containersaved .pkt_ext_errordetail { .pkt_ext_containersaved .pkt_ext_errordetail {
display: none; display: none;
font-size: 12px; font-size: 12px;
font-weight: normal; font-weight: normal;
left: 6.4em; left: 6.4em;
max-width: 21em;
opacity: 0; opacity: 0;
position: absolute; position: absolute;
top: 2.7em; top: 2.7em;
@ -220,20 +199,33 @@
background-size: 44px 40px; 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 { .pkt_ext_containersaved .pkt_ext_topdetail {
float: left; float: left;
} }
.pkt_ext_containersaved .pkt_ext_edit_msg { .pkt_ext_containersaved .pkt_ext_edit_msg {
box-sizing: border-box;
display: none; display: none;
font-size: 0.875em; font-size: 0.75em;
left: auto; left: auto;
padding: 0 1.4em;
position: absolute; position: absolute;
text-align: center; text-align: left;
top: 4.3em; top: 8.7em;
width: 100%; width: 100%;
} }
.pkt_ext_containersaved .pkt_ext_edit_msg_error { .pkt_ext_containersaved .pkt_ext_edit_msg_error {
color: #c10000; color: #d74345;
} }
.pkt_ext_containersaved .pkt_ext_edit_msg_active { .pkt_ext_containersaved .pkt_ext_edit_msg_active {
display: block; display: block;
@ -357,6 +349,9 @@
padding: 0; padding: 0;
display: flex; display: flex;
} }
.pkt_ext_containersaved .pkt_ext_tag_error {
border: none;
}
.pkt_ext_containersaved .pkt_ext_tag_input_wrapper { .pkt_ext_containersaved .pkt_ext_tag_input_wrapper {
box-sizing: border-box; box-sizing: border-box;
flex: 1; flex: 1;
@ -374,6 +369,9 @@
padding-left: 0.5em; padding-left: 0.5em;
padding-right: 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 { .pkt_ext_containersaved .pkt_ext_tag_input_wrapper .token-input-list {
display: block; display: block;
left: 0; left: 0;
@ -418,6 +416,7 @@
} }
.pkt_ext_containersaved .pkt_ext_btn { .pkt_ext_containersaved .pkt_ext_btn {
box-sizing: border-box; box-sizing: border-box;
color: #333;
float: none; float: none;
font-size: 0.875em; font-size: 0.875em;
font-size: 14px; font-size: 14px;
@ -425,13 +424,27 @@
height: 2.2em; height: 2.2em;
min-width: 4em; min-width: 4em;
padding: 0.5em 0; padding: 0.5em 0;
text-decoration: none;
text-transform: none; text-transform: none;
width: auto; width: auto;
} }
.pkt_ext_containersaved .pkt_ext_btn_disabled { .pkt_ext_containersaved .pkt_ext_btn:hover {
background-color: #ededed; 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; 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 { .pkt_ext_containersaved .autocomplete-suggestions {
margin-top: 2.2em; margin-top: 2.2em;
@ -439,19 +452,27 @@
/*=Recent/suggested tags /*=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; border-top: 1px solid #c1c1c1;
bottom: 0;
background: #ebebeb; background: #ebebeb;
clear: both; clear: both;
left: 0;
opacity: 0; opacity: 0;
visibility: hidden;
min-height: 110px; 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; opacity: 1;
transition: opacity 0.2s ease-out, visibility 0.2s ease-out;
visibility: visible; visibility: visible;
} }
.pkt_ext_containersaved .pkt_ext_suggestedtag_detailshown {
padding: 4px 0;
}
.pkt_ext_container_finalstate .pkt_ext_suggestedtag_detail { .pkt_ext_container_finalstate .pkt_ext_suggestedtag_detail {
opacity: 0; opacity: 0;
visibility: hidden; visibility: hidden;
@ -488,6 +509,11 @@
overflow: hidden; overflow: hidden;
padding: 2px 0 0 0; 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_recenttag_detail li,
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail li { .pkt_ext_containersaved .pkt_ext_suggestedtag_detail li {
background: none; background: none;
@ -512,6 +538,9 @@
text-align: left; text-align: left;
top: 2em; top: 2em;
} }
.pkt_ext_containersaved .pkt_ext_suggestedtag_detail .suggestedtag_msg {
margin-right: 1.3em;
}
.pkt_ext_containersaved .token_tag { .pkt_ext_containersaved .token_tag {
border-radius: 4px; border-radius: 4px;
background: #f7f7f7; background: #f7f7f7;
@ -522,7 +551,7 @@
font-weight: normal; font-weight: normal;
letter-spacing: normal; letter-spacing: normal;
margin-right: 0.5em; margin-right: 0.5em;
padding: 0.125em 0.3125em; padding: 0.125em 0.625em;
text-decoration: none; text-decoration: none;
text-transform: none; text-transform: none;
} }
@ -639,7 +668,7 @@
border: 1px solid #c3c3c3; border: 1px solid #c3c3c3;
overflow: hidden; overflow: hidden;
margin: 0; margin: 0;
padding: 0 5px; padding: 0 8px;
background-color: #f7f7f7; background-color: #f7f7f7;
color: #000; color: #000;
font-weight: normal; font-weight: normal;
@ -688,7 +717,7 @@
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;
height: 8px; height: 8px;
margin: 0 2px 0 8px; margin: 0 0 0 8px;
overflow: hidden; overflow: hidden;
width: 8px; width: 8px;
text-indent: -99px; 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", addtags: "Add Tags",
alreadyhaveacct: "Already a Pocket user?", alreadyhaveacct: "Already a Pocket user?",
errorgeneric: "There was an error when trying to save to Pocket.",
learnmore: "Learn More", learnmore: "Learn More",
loginnow: "Log in", 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", onlylinkssaved: "Only links can be saved",
or: "or",
pagenotsaved: "Page Not Saved", pagenotsaved: "Page Not Saved",
pageremoved: "Page Removed", pageremoved: "Page Removed",
pagesaved: "Saved to Pocket", pagesaved: "Saved to Pocket",
@ -14,6 +16,7 @@ Translations.en =
processingtags: "Adding tags...", processingtags: "Adding tags...",
removepage: "Remove Page", removepage: "Remove Page",
save: "Save", save: "Save",
saving: "Saving...",
signupemail: "Sign up with email", signupemail: "Sign up with email",
signuptosave: "Sign up for Pocket. Its free.", signuptosave: "Sign up for Pocket. Its free.",
suggestedtags: "Suggested Tags", suggestedtags: "Suggested Tags",

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

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

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

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

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

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

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

@ -1,5 +1,8 @@
(function() { (function() {
var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {}; 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) { 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; var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
return "<div class=\"pkt_ext_suggestedtag_detail pkt_ext_suggestedtag_detail_loading\">\n <h4>" 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}); },"useData":true});
templates['saved_shell'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { 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; 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))) + 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=\"#\">" + "</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))) + 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))) + 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\">" + "/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))) + 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))) + 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\">" + "\">\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))) + 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}); },"useData":true});
templates['signup_shell'] = template({"1":function(depth0,helpers,partials,data) { templates['signup_shell'] = template({"1":function(depth0,helpers,partials,data) {
var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; 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 class="pkt_ext_loadingspinner"><div></div></div>
</div> </div>
<div class="pkt_ext_detail"> <div class="pkt_ext_detail">
@ -10,11 +14,10 @@
<ul> <ul>
<li><a class="pkt_ext_removeitem" href="#">{{removepage}}</a></li> <li><a class="pkt_ext_removeitem" href="#">{{removepage}}</a></li>
<li class="pkt_ext_actions_separator"></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> </ul>
</nav> </nav>
</div> </div>
<p class="pkt_ext_edit_msg"></p>
<div class="pkt_ext_tag_detail pkt_ext_cf"> <div class="pkt_ext_tag_detail pkt_ext_cf">
<div class="pkt_ext_tag_input_wrapper"> <div class="pkt_ext_tag_input_wrapper">
<div class="pkt_ext_tag_input_blocker"></div> <div class="pkt_ext_tag_input_blocker"></div>
@ -22,4 +25,5 @@
</div> </div>
<a href="#" class="pkt_ext_btn pkt_ext_btn_disabled">{{save}}</a> <a href="#" class="pkt_ext_btn pkt_ext_btn_disabled">{{save}}</a>
</div> </div>
<p class="pkt_ext_edit_msg"></p>
</div> </div>

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

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

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

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

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

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

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

@ -397,7 +397,9 @@ Section "Uninstall"
${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll" ${UnregisterDLL} "$INSTDIR\AccessibleMarshal.dll"
${EndIf} ${EndIf}
${un.RemovePrecompleteEntries} "false" StrCpy $R2 "false"
StrCpy $R3 "false"
${un.RemovePrecompleteEntries} "$R2" "$R3"
${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js" ${If} ${FileExists} "$INSTDIR\defaults\pref\channel-prefs.js"
Delete /REBOOTOK "$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("touch.qunar.com"),
NS_LITERAL_CSTRING("mjs.sinaimg.cn"), // for sina.cn NS_LITERAL_CSTRING("mjs.sinaimg.cn"), // for sina.cn
NS_LITERAL_CSTRING("static.qiyi.com"), // for m.iqiyi.com 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.pc6.com"),
NS_LITERAL_CSTRING("m.haosou.com"), NS_LITERAL_CSTRING("m.haosou.com"),
NS_LITERAL_CSTRING("m.mi.com"), NS_LITERAL_CSTRING("m.mi.com"),

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

@ -244,8 +244,9 @@ CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS))))
CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX))) CMOBJS = $(notdir $(CMSRCS:.m=.$(OBJ_SUFFIX)))
CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX))) CMMOBJS = $(notdir $(CMMSRCS:.mm=.$(OBJ_SUFFIX)))
ASOBJS = $(notdir $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))) ASOBJS = $(notdir $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX)))
RSOBJS = $(addprefix lib,$(notdir $(RSSRCS:.rs=.$(LIB_SUFFIX))))
ifndef OBJS ifndef OBJS
_OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS) _OBJS = $(COBJS) $(SOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS) $(RSOBJS)
OBJS = $(strip $(_OBJS)) OBJS = $(strip $(_OBJS))
endif endif
@ -876,6 +877,11 @@ $(basename $2$(notdir $1)).$(OBJ_SUFFIX): $1 $$(call mkdir_deps,$$(MDDEPDIR))
endef endef
$(foreach f,$(CSRCS) $(SSRCS) $(CPPSRCS) $(CMSRCS) $(CMMSRCS) $(ASFILES),$(eval $(call src_objdep,$(f)))) $(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_))) $(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) $(OBJS) $(HOST_OBJS) $(PROGOBJS) $(HOST_PROGOBJS): $(GLOBAL_DEPS)
@ -924,6 +930,14 @@ $(ASOBJS):
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS) $(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
endif 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): $(SOBJS):
$(REPORT_BUILD) $(REPORT_BUILD)
$(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $< $(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $<

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

@ -429,6 +429,18 @@ MOZ_TOOL_VARIABLES
MOZ_CHECK_COMPILER_WRAPPER 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 ========================================================
dnl Check for MacOS deployment target version dnl Check for MacOS deployment target version
dnl ======================================================== dnl ========================================================

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

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

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

@ -103,10 +103,8 @@ void SetDirectionFromNewTextNode(nsIContent* aTextNode);
* directionality it determined and redetermine their directionality * directionality it determined and redetermine their directionality
* *
* @param aTextNode the text node * @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 * Set the directionality of an element according to the directionality of the

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

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

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

@ -574,10 +574,7 @@ nsObjectLoadingContent::QueueCheckPluginStopEvent()
nsCOMPtr<nsIRunnable> event = new CheckPluginStopEvent(this); nsCOMPtr<nsIRunnable> event = new CheckPluginStopEvent(this);
mPendingCheckPluginStopEvent = event; mPendingCheckPluginStopEvent = event;
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID); NS_DispatchToCurrentThread(event);
if (appShell) {
appShell->RunInStableState(event);
}
} }
// Tedious syntax to create a plugin stream listener with checks and put it in // 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_BEGIN_INHERITED(nsPerformance, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow, mTiming, NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow, mTiming,
mNavigation, mEntries, mNavigation, mUserEntries,
mResourceEntries,
mParentPerformance) mParentPerformance)
tmp->mMozMemory = nullptr; tmp->mMozMemory = nullptr;
mozilla::DropJSObjects(this); 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_BEGIN_INHERITED(nsPerformance, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow, mTiming, NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow, mTiming,
mNavigation, mEntries, mNavigation, mUserEntries,
mResourceEntries,
mParentPerformance) mParentPerformance)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -429,7 +431,7 @@ nsPerformance::nsPerformance(nsPIDOMWindow* aWindow,
mDOMTiming(aDOMTiming), mDOMTiming(aDOMTiming),
mChannel(aChannel), mChannel(aChannel),
mParentPerformance(aParentPerformance), mParentPerformance(aParentPerformance),
mPrimaryBufferSize(kDefaultBufferSize) mResourceTimingBufferSize(kDefaultResourceTimingBufferSize)
{ {
MOZ_ASSERT(aWindow, "Parent window object should be provided"); MOZ_ASSERT(aWindow, "Parent window object should be provided");
} }
@ -513,7 +515,9 @@ nsPerformance::GetEntries(nsTArray<nsRefPtr<PerformanceEntry> >& retval)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
retval = mEntries; retval = mResourceEntries;
retval.AppendElements(mUserEntries);
retval.Sort(PerformanceEntryComparator());
} }
void void
@ -523,10 +527,14 @@ nsPerformance::GetEntriesByType(const nsAString& entryType,
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
retval.Clear(); retval.Clear();
uint32_t count = mEntries.Length(); if (entryType.EqualsLiteral("resource")) {
for (uint32_t i = 0 ; i < count; i++) { retval = mResourceEntries;
if (mEntries[i]->GetEntryType().Equals(entryType)) { } else if (entryType.EqualsLiteral("mark") ||
retval.AppendElement(mEntries[i]); entryType.EqualsLiteral("measure")) {
for (PerformanceEntry* entry : mUserEntries) {
if (entry->GetEntryType().Equals(entryType)) {
retval.AppendElement(entry);
}
} }
} }
} }
@ -539,26 +547,33 @@ nsPerformance::GetEntriesByName(const nsAString& name,
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
retval.Clear(); retval.Clear();
uint32_t count = mEntries.Length(); for (PerformanceEntry* entry : mResourceEntries) {
for (uint32_t i = 0 ; i < count; i++) { if (entry->GetName().Equals(name) &&
if (mEntries[i]->GetName().Equals(name) &&
(!entryType.WasPassed() || (!entryType.WasPassed() ||
mEntries[i]->GetEntryType().Equals(entryType.Value()))) { entry->GetEntryType().Equals(entryType.Value()))) {
retval.AppendElement(mEntries[i]); 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 void
nsPerformance::ClearEntries(const Optional<nsAString>& aEntryName, nsPerformance::ClearUserEntries(const Optional<nsAString>& aEntryName,
const nsAString& aEntryType) const nsAString& aEntryType)
{ {
for (uint32_t i = 0; i < mEntries.Length();) { for (uint32_t i = 0; i < mUserEntries.Length();) {
if ((!aEntryName.WasPassed() || if ((!aEntryName.WasPassed() ||
mEntries[i]->GetName().Equals(aEntryName.Value())) && mUserEntries[i]->GetName().Equals(aEntryName.Value())) &&
(aEntryType.IsEmpty() || (aEntryType.IsEmpty() ||
mEntries[i]->GetEntryType().Equals(aEntryType))) { mUserEntries[i]->GetEntryType().Equals(aEntryType))) {
mEntries.RemoveElementAt(i); mUserEntries.RemoveElementAt(i);
} else { } else {
++i; ++i;
} }
@ -569,15 +584,14 @@ void
nsPerformance::ClearResourceTimings() nsPerformance::ClearResourceTimings()
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
ClearEntries(Optional<nsAString>(), mResourceEntries.Clear();
NS_LITERAL_STRING("resource"));
} }
void void
nsPerformance::SetResourceTimingBufferSize(uint64_t maxSize) nsPerformance::SetResourceTimingBufferSize(uint64_t maxSize)
{ {
MOZ_ASSERT(NS_IsMainThread()); 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 // Don't add the entry if the buffer is full
if (mEntries.Length() >= mPrimaryBufferSize) { if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
return; return;
} }
@ -634,7 +648,7 @@ nsPerformance::AddEntry(nsIHttpChannel* channel,
initiatorType = NS_LITERAL_STRING("other"); initiatorType = NS_LITERAL_STRING("other");
} }
performanceEntry->SetInitiatorType(initiatorType); performanceEntry->SetInitiatorType(initiatorType);
InsertPerformanceEntry(performanceEntry, false); InsertResourceEntry(performanceEntry);
} }
} }
@ -659,16 +673,25 @@ nsPerformance::PerformanceEntryComparator::LessThan(
} }
void void
nsPerformance::InsertPerformanceEntry(PerformanceEntry* aEntry, nsPerformance::InsertResourceEntry(PerformanceEntry* aEntry)
bool aShouldPrint)
{ {
MOZ_ASSERT(aEntry); MOZ_ASSERT(aEntry);
MOZ_ASSERT(mEntries.Length() < mPrimaryBufferSize); MOZ_ASSERT(mResourceEntries.Length() < mResourceTimingBufferSize);
if (mEntries.Length() == mPrimaryBufferSize) { if (mResourceEntries.Length() >= mResourceTimingBufferSize) {
NS_WARNING("Performance Entry buffer size maximum reached!");
return; 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; nsAutoCString uri;
nsresult rv = mWindow->GetDocumentURI()->GetHost(uri); nsresult rv = mWindow->GetDocumentURI()->GetHost(uri);
if(NS_FAILED(rv)) { if(NS_FAILED(rv)) {
@ -683,21 +706,16 @@ nsPerformance::InsertPerformanceEntry(PerformanceEntry* aEntry,
aEntry->Duration(), aEntry->Duration(),
static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC)); static_cast<uint64_t>(PR_Now() / PR_USEC_PER_MSEC));
} }
mEntries.InsertElementSorted(aEntry, mUserEntries.InsertElementSorted(aEntry,
PerformanceEntryComparator()); PerformanceEntryComparator());
if (mEntries.Length() == mPrimaryBufferSize) {
// call onresourcetimingbufferfull
DispatchBufferFullEvent();
}
} }
void void
nsPerformance::Mark(const nsAString& aName, ErrorResult& aRv) nsPerformance::Mark(const nsAString& aName, ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
// Don't add the entry if the buffer is full // Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
if (mEntries.Length() >= mPrimaryBufferSize) { if (mUserEntries.Length() >= mResourceTimingBufferSize) {
NS_WARNING("Performance Entry buffer size maximum reached!");
return; return;
} }
if (IsPerformanceTimingAttribute(aName)) { if (IsPerformanceTimingAttribute(aName)) {
@ -706,14 +724,14 @@ nsPerformance::Mark(const nsAString& aName, ErrorResult& aRv)
} }
nsRefPtr<PerformanceMark> performanceMark = nsRefPtr<PerformanceMark> performanceMark =
new PerformanceMark(this, aName); new PerformanceMark(this, aName);
InsertPerformanceEntry(performanceMark, true); InsertUserEntry(performanceMark);
} }
void void
nsPerformance::ClearMarks(const Optional<nsAString>& aName) nsPerformance::ClearMarks(const Optional<nsAString>& aName)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
ClearEntries(aName, NS_LITERAL_STRING("mark")); ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
} }
DOMHighResTimeStamp DOMHighResTimeStamp
@ -749,9 +767,8 @@ nsPerformance::Measure(const nsAString& aName,
ErrorResult& aRv) ErrorResult& aRv)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
// Don't add the entry if the buffer is full // Don't add the entry if the buffer is full. XXX should be removed by bug 1159003.
if (mEntries.Length() >= mPrimaryBufferSize) { if (mUserEntries.Length() >= mResourceTimingBufferSize) {
NS_WARNING("Performance Entry buffer size maximum reached!");
return; return;
} }
DOMHighResTimeStamp startTime; DOMHighResTimeStamp startTime;
@ -783,14 +800,14 @@ nsPerformance::Measure(const nsAString& aName,
} }
nsRefPtr<PerformanceMeasure> performanceMeasure = nsRefPtr<PerformanceMeasure> performanceMeasure =
new PerformanceMeasure(this, aName, startTime, endTime); new PerformanceMeasure(this, aName, startTime, endTime);
InsertPerformanceEntry(performanceMeasure, true); InsertUserEntry(performanceMeasure);
} }
void void
nsPerformance::ClearMeasures(const Optional<nsAString>& aName) nsPerformance::ClearMeasures(const Optional<nsAString>& aName)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
ClearEntries(aName, NS_LITERAL_STRING("measure")); ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
} }
DOMHighResTimeStamp DOMHighResTimeStamp

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

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

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

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

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

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

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

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

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

@ -13,6 +13,9 @@
Cu.import('resource://gre/modules/Services.jsm'); Cu.import('resource://gre/modules/Services.jsm');
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
"set": [["dom.caches.enabled", true]],
}, function() {
// attach to a different origin's CacheStorage // attach to a different origin's CacheStorage
var url = 'http://example.com/'; var url = 'http://example.com/';
var uri = Services.io.newURI(url, null, null); var uri = Services.io.newURI(url, null, null);
@ -38,6 +41,7 @@
ok(deleted, 'storage should delete cache'); ok(deleted, 'storage should delete cache');
SimpleTest.finish(); SimpleTest.finish();
}); });
});
</script> </script>
</body> </body>
</html> </html>

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

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

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

@ -263,6 +263,10 @@ Request::Constructor(const GlobalObject& aGlobal,
} }
requestHeaders->Clear(); 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->Mode() == RequestMode::No_cors) {
if (!request->HasSimpleMethod()) { if (!request->HasSimpleMethod()) {

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

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

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

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

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

@ -3,5 +3,6 @@
"WeakMap.prototype.delete.length": true, "WeakMap.prototype.delete.length": true,
"WeakMap.prototype.get.length": true, "WeakMap.prototype.get.length": true,
"WeakMap.prototype.has.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 GlobalObjectsComponent.manifest
GlobalObjectsModule.jsm GlobalObjectsModule.jsm
GlobalObjectsSandbox.js GlobalObjectsSandbox.js
metadataRestore_profile.zip
schema18upgrade_profile.zip schema18upgrade_profile.zip
xpcshell-shared.ini xpcshell-shared.ini
@ -29,6 +30,7 @@ skip-if = toolkit == 'android'
# disabled for the moment. # disabled for the moment.
skip-if = true skip-if = true
[test_lowDiskSpace.js] [test_lowDiskSpace.js]
[test_metadataRestore.js]
[test_readwriteflush_disabled.js] [test_readwriteflush_disabled.js]
[test_schema18upgrade.js] [test_schema18upgrade.js]
[test_temporary_storage.js] [test_temporary_storage.js]

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

@ -424,7 +424,7 @@ public:
private: private:
const uint32_t mGeneration; 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; nsRefPtr<nsMemoryReporterManager> mReporterManager;
ContentParent* Owner() ContentParent* Owner()
@ -464,7 +464,7 @@ void
MemoryReportRequestParent::ActorDestroy(ActorDestroyReason aWhy) MemoryReportRequestParent::ActorDestroy(ActorDestroyReason aWhy)
{ {
if (mReporterManager) { if (mReporterManager) {
mReporterManager->EndChildReport(mGeneration, aWhy == Deletion); mReporterManager->EndProcessReport(mGeneration, aWhy == Deletion);
mReporterManager = nullptr; mReporterManager = nullptr;
} }
} }
@ -648,7 +648,6 @@ static const char* sObserverTopics[] = {
"profile-before-change", "profile-before-change",
NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC,
NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC, NS_IPC_IOSERVICE_SET_CONNECTIVITY_TOPIC,
"child-memory-reporter-request",
"memory-pressure", "memory-pressure",
"child-gc-request", "child-gc-request",
"child-cc-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 // remove the global remote preferences observers
Preferences::RemoveObserver(this, ""); Preferences::RemoveObserver(this, "");
@ -2261,15 +2248,6 @@ ContentParent::ContentParent(mozIApplication* aApp,
IToplevelProtocol::SetTransport(mSubprocess->GetChannel()); 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; std::vector<std::string> extraArgs;
if (aIsNuwaProcess) { if (aIsNuwaProcess) {
extraArgs.push_back("-nuwa"); extraArgs.push_back("-nuwa");
@ -2334,13 +2312,6 @@ ContentParent::ContentParent(ContentParent* aTemplate,
aPid, aPid,
*fd); *fd);
// Tell the memory reporter manager that this ContentParent exists.
nsRefPtr<nsMemoryReporterManager> mgr =
nsMemoryReporterManager::GetOrCreate();
if (mgr) {
mgr->IncrementNumChildProcesses();
}
mSubprocess->LaunchAndWaitForProcessHandle(); mSubprocess->LaunchAndWaitForProcessHandle();
// Clone actors routed by aTemplate for this instance. // Clone actors routed by aTemplate for this instance.
@ -3062,46 +3033,6 @@ ContentParent::Observe(nsISupports* aSubject,
nsDependentString(aData))) nsDependentString(aData)))
return NS_ERROR_NOT_AVAILABLE; 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")){ else if (!strcmp(aTopic, "child-gc-request")){
unused << SendGarbageCollect(); unused << SendGarbageCollect();
} }

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

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

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

@ -27,6 +27,9 @@ BaseMediaMgrError::BaseMediaMgrError(const nsAString& aName,
"accessed due to a hardware error (e.g. lock from another process)."); "accessed due to a hardware error (e.g. lock from another process).");
} else if (mName.EqualsLiteral("InternalError")) { } else if (mName.EqualsLiteral("InternalError")) {
mMessage.AssignLiteral("Internal error."); 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', 'TestWebMWriter.cpp',
] ]
if CONFIG['MOZ_RUST']:
SOURCES += ['hello.rs',]
UNIFIED_SOURCES += ['TestRust.cpp',]
TEST_HARNESS_FILES.gtest += [ TEST_HARNESS_FILES.gtest += [
'../test/gizmo-frag.mp4', '../test/gizmo-frag.mp4',
'../test/gizmo.mp4', '../test/gizmo.mp4',

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

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

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

@ -84,28 +84,27 @@ MediaEngineCameraVideoSource::FitnessDistance(ValueType n,
// Binding code doesn't templatize well... // Binding code doesn't templatize well...
template<>
/*static*/ uint32_t /*static*/ uint32_t
MediaEngineCameraVideoSource::FitnessDistance(int32_t n, MediaEngineCameraVideoSource::FitnessDistance(int32_t n,
const OwningLongOrConstrainLongRange& aConstraint) const OwningLongOrConstrainLongRange& aConstraint, bool aAdvanced)
{ {
if (aConstraint.IsLong()) { if (aConstraint.IsLong()) {
ConstrainLongRange range; ConstrainLongRange range;
range.mIdeal.Construct(aConstraint.GetAsLong()); (aAdvanced ? range.mExact : range.mIdeal).Construct(aConstraint.GetAsLong());
return FitnessDistance(n, range); return FitnessDistance(n, range);
} else { } else {
return FitnessDistance(n, aConstraint.GetAsConstrainLongRange()); return FitnessDistance(n, aConstraint.GetAsConstrainLongRange());
} }
} }
template<>
/*static*/ uint32_t /*static*/ uint32_t
MediaEngineCameraVideoSource::FitnessDistance(double n, MediaEngineCameraVideoSource::FitnessDistance(double n,
const OwningDoubleOrConstrainDoubleRange& aConstraint) const OwningDoubleOrConstrainDoubleRange& aConstraint,
bool aAdvanced)
{ {
if (aConstraint.IsDouble()) { if (aConstraint.IsDouble()) {
ConstrainDoubleRange range; ConstrainDoubleRange range;
range.mIdeal.Construct(aConstraint.GetAsDouble()); (aAdvanced ? range.mExact : range.mIdeal).Construct(aConstraint.GetAsDouble());
return FitnessDistance(n, range); return FitnessDistance(n, range);
} else { } else {
return FitnessDistance(n, aConstraint.GetAsConstrainDoubleRange()); return FitnessDistance(n, aConstraint.GetAsConstrainDoubleRange());
@ -114,18 +113,22 @@ MediaEngineCameraVideoSource::FitnessDistance(double n,
/*static*/ uint32_t /*static*/ uint32_t
MediaEngineCameraVideoSource::GetFitnessDistance(const webrtc::CaptureCapability& aCandidate, 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". // Treat width|height|frameRate == 0 on capability as "can do any".
// This allows for orthogonal capabilities that are not in discrete steps. // This allows for orthogonal capabilities that are not in discrete steps.
uint64_t distance = uint64_t distance =
uint64_t(aCandidate.width? FitnessDistance(int32_t(aCandidate.width), 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), uint64_t(aCandidate.height? FitnessDistance(int32_t(aCandidate.height),
aConstraints.mHeight) : 0) + aConstraints.mHeight,
aAdvanced) : 0) +
uint64_t(aCandidate.maxFPS? FitnessDistance(double(aCandidate.maxFPS), 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))); 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 // GetBestFitnessDistance returns the best distance the capture device can offer
// as a whole, given an accumulated number of ConstraintSets. // as a whole, given an accumulated number of ConstraintSets.
// Ideal values are considered in the first ConstraintSet only. // 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. // 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. // 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]; auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap; webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap); GetCapability(candidate.mIndex, cap);
uint32_t distance = GetFitnessDistance(cap, *cs); uint32_t distance = GetFitnessDistance(cap, *cs, !first);
if (distance == UINT32_MAX) { if (distance == UINT32_MAX) {
candidateSet.RemoveElementAt(i); candidateSet.RemoveElementAt(i);
} else { } else {
@ -246,7 +251,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
auto& candidate = candidateSet[i]; auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap; webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap); GetCapability(candidate.mIndex, cap);
candidate.mDistance = GetFitnessDistance(cap, aConstraints); candidate.mDistance = GetFitnessDistance(cap, aConstraints, false);
if (candidate.mDistance == UINT32_MAX) { if (candidate.mDistance == UINT32_MAX) {
candidateSet.RemoveElementAt(i); candidateSet.RemoveElementAt(i);
} else { } else {
@ -263,7 +268,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
auto& candidate = candidateSet[i]; auto& candidate = candidateSet[i];
webrtc::CaptureCapability cap; webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap); GetCapability(candidate.mIndex, cap);
if (GetFitnessDistance(cap, cs) == UINT32_MAX) { if (GetFitnessDistance(cap, cs, true) == UINT32_MAX) {
rejects.AppendElement(candidate); rejects.AppendElement(candidate);
candidateSet.RemoveElementAt(i); candidateSet.RemoveElementAt(i);
} else { } else {
@ -295,7 +300,7 @@ MediaEngineCameraVideoSource::ChooseCapability(
for (auto& candidate : candidateSet) { for (auto& candidate : candidateSet) {
webrtc::CaptureCapability cap; webrtc::CaptureCapability cap;
GetCapability(candidate.mIndex, cap); GetCapability(candidate.mIndex, cap);
candidate.mDistance = GetFitnessDistance(cap, prefs); candidate.mDistance = GetFitnessDistance(cap, prefs, false);
} }
TrimLessFitCandidates(candidateSet); TrimLessFitCandidates(candidateSet);
} }

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

@ -80,8 +80,14 @@ protected:
StreamTime delta); StreamTime delta);
template<class ValueType, class ConstrainRange> template<class ValueType, class ConstrainRange>
static uint32_t FitnessDistance(ValueType n, const ConstrainRange& aRange); 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, 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 TrimLessFitCandidates(CapabilitySet& set);
static void LogConstraints(const dom::MediaTrackConstraintSet& aConstraints, static void LogConstraints(const dom::MediaTrackConstraintSet& aConstraints,
bool aAdvanced); bool aAdvanced);

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

@ -37,13 +37,23 @@ i.addEventListener("load", function loadfunc() {
// Navigate the frame to cause the document with the plugin to go inactive // Navigate the frame to cause the document with the plugin to go inactive
i.removeEventListener("load", loadfunc); i.removeEventListener("load", loadfunc);
i.src = "about:blank"; i.src = "about:blank";
SimpleTest.executeSoon(function() {
// Ensure this event doesn't race with CheckPluginStopEvent const MAX_ATTEMPTS = 5;
SimpleTest.executeSoon(function() { 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"); ok(destroyran, "OnDestroy callback ran and did not crash");
SimpleTest.finish(); SimpleTest.finish();
}); }
}); }
SimpleTest.executeSoon(checkPluginDestroyRan);
}); });
document.body.appendChild(i); document.body.appendChild(i);

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

@ -12,25 +12,33 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
const MAX_ATTEMPTS = 5;
var attempts = 0;
var destroyed = false; var destroyed = false;
function onDestroy() { function onDestroy() {
destroyed = true; destroyed = true;
} }
function checkPluginAlreadyDestroyed() { function checkPluginAlreadyDestroyed() {
// 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."); is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish(); SimpleTest.finish();
} }
}
function startTest() { function startTest() {
var p1 = document.getElementById('plugin1'); var p1 = document.getElementById('plugin1');
var d1 = document.getElementById('div1'); var d1 = document.getElementById('div1');
p1.callOnDestroy(onDestroy); p1.callOnDestroy(onDestroy);
setTimeout(checkPluginAlreadyDestroyed, 0);
d1.removeChild(p1); d1.removeChild(p1);
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
} }
</script> </script>

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

@ -12,15 +12,25 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
const MAX_ATTEMPTS = 5;
var attempts = 0;
var destroyed = false; var destroyed = false;
function onDestroy() { function onDestroy() {
destroyed = true; destroyed = true;
} }
function checkPluginAlreadyDestroyed() { function checkPluginAlreadyDestroyed() {
// 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."); is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish(); SimpleTest.finish();
} }
}
function startTest() { function startTest() {
var p1 = document.getElementById('plugin1'); var p1 = document.getElementById('plugin1');
@ -28,12 +38,12 @@
p1.callOnDestroy(onDestroy); p1.callOnDestroy(onDestroy);
setTimeout(checkPluginAlreadyDestroyed, 0);
// Get two parent check events to run. // Get two parent check events to run.
d1.removeChild(p1); d1.removeChild(p1);
d1.appendChild(p1); d1.appendChild(p1);
d1.removeChild(p1); d1.removeChild(p1);
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
} }
</script> </script>

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

@ -12,15 +12,25 @@
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED);
const MAX_ATTEMPTS = 5;
var attempts = 0;
var destroyed = false; var destroyed = false;
function onDestroy() { function onDestroy() {
destroyed = true; destroyed = true;
} }
function checkPluginAlreadyDestroyed() { function checkPluginAlreadyDestroyed() {
// 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."); is(destroyed, true, "Plugin instance should have been destroyed.");
SimpleTest.finish(); SimpleTest.finish();
} }
}
function startTest() { function startTest() {
var p1 = document.getElementById('plugin1'); var p1 = document.getElementById('plugin1');
@ -28,10 +38,8 @@
var d2 = document.getElementById('div2'); var d2 = document.getElementById('div2');
p1.callOnDestroy(onDestroy); p1.callOnDestroy(onDestroy);
setTimeout(checkPluginAlreadyDestroyed, 0);
d1.removeChild(d2); d1.removeChild(d2);
SimpleTest.executeSoon(checkPluginAlreadyDestroyed);
} }
</script> </script>

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

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

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

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

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

@ -23,7 +23,7 @@ function testDefaultCtor() {
function testClone() { function testClone() {
var orig = new Request("./cloned_request.txt", { var orig = new Request("./cloned_request.txt", {
method: 'POST', method: 'POST',
headers: { "Content-Length": 5 }, headers: { "Sample-Header": "5" },
body: "Sample body", body: "Sample body",
mode: "same-origin", mode: "same-origin",
credentials: "same-origin", credentials: "same-origin",
@ -33,9 +33,9 @@ function testClone() {
ok(clone.method === "POST", "Request method is POST"); ok(clone.method === "POST", "Request method is POST");
ok(clone.headers instanceof Headers, "Request should have non-null Headers object"); 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."); is(clone.headers.get('sample-header'), "5", "Request sample-header should be 5.");
orig.headers.set('content-length', 6); orig.headers.set('sample-header', 6);
is(clone.headers.get('content-length'), "5", "Request content-length should be 5."); 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, ok(clone.url === (new URL("./cloned_request.txt", self.location.href)).href,
"URL should be resolved with entry settings object's API base URL"); "URL should be resolved with entry settings object's API base URL");
@ -124,6 +124,20 @@ function testBug1109574() {
var r3 = new Request(r1); 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() { function testMethod() {
// These get normalized. // These get normalized.
var allowed = ["delete", "get", "head", "options", "post", "put" ]; var allowed = ["delete", "get", "head", "options", "post", "put" ];
@ -434,6 +448,7 @@ function runTest() {
testUrlFragment(); testUrlFragment();
testMethod(); testMethod();
testBug1109574(); testBug1109574();
testHeaderGuard();
testModeCorsPreflightEnumValue(); testModeCorsPreflightEnumValue();
return Promise.resolve() return Promise.resolve()

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

@ -14,6 +14,7 @@ support-files =
image_50.png image_50.png
image_100.png image_100.png
image_200.png image_200.png
performance_timeline_main_test.html
resource_timing_iframe.html resource_timing_iframe.html
resource_timing_main_test.html resource_timing_main_test.html
resource_timing_cross_origin.html resource_timing_cross_origin.html
@ -79,8 +80,10 @@ support-files = test_offsets.js
skip-if = buildapp == 'mulet' skip-if = buildapp == 'mulet'
[test_paste_selection.html] [test_paste_selection.html]
skip-if = buildapp == 'mulet' skip-if = buildapp == 'mulet'
[test_performance_timeline.html]
[test_picture_mutations.html] [test_picture_mutations.html]
[test_picture_pref.html] [test_picture_pref.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_resource_timing.html] [test_resource_timing.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet' skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_resource_timing_cross_origin.html] [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; 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."); is(window.performance.getEntries().length, 5, "Performance.getEntries() returned wrong number of entries.");
checkStringify(window.performance.getEntries()[0]); 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(); SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [ SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true], ["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true] ["dom.serviceWorkers.testing.enabled", true]
]}, runTest); ]}, 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 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-dotafterquote-valid.html spellcheck-dotafterquote-valid-ref.html
== spellcheck-url-valid.html spellcheck-url-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 == 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.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 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>

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