mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge branch 'mozilla-central'
This commit is contained in:
commit
fb4fc2cfb1
@ -64,7 +64,6 @@ browser/base/content/test/**
|
||||
browser/base/content/newtab/**
|
||||
browser/components/downloads/**
|
||||
browser/components/feeds/**
|
||||
browser/components/pocket/**
|
||||
browser/components/preferences/**
|
||||
browser/components/privatebrowsing/**
|
||||
browser/components/sessionstore/**
|
||||
@ -105,7 +104,6 @@ devtools/client/scratchpad/**
|
||||
devtools/client/shadereditor/**
|
||||
devtools/client/shared/**
|
||||
devtools/client/sourceeditor/**
|
||||
devtools/client/storage/**
|
||||
devtools/client/tilt/**
|
||||
devtools/client/webaudioeditor/**
|
||||
devtools/client/webconsole/**
|
||||
@ -182,7 +180,6 @@ toolkit/modules/tests/xpcshell/test_task.js
|
||||
|
||||
# Not yet updated
|
||||
toolkit/components/osfile/**
|
||||
toolkit/components/passwordmgr/**
|
||||
|
||||
# Uses preprocessing
|
||||
toolkit/content/widgets/videocontrols.xml
|
||||
|
@ -21,18 +21,38 @@ using namespace mozilla::a11y;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TreeWalker::
|
||||
TreeWalker(Accessible* aContext, nsIContent* aContent, uint32_t aFlags) :
|
||||
mDoc(aContext->Document()), mContext(aContext), mAnchorNode(aContent),
|
||||
mFlags(aFlags)
|
||||
TreeWalker(Accessible* aContext) :
|
||||
mDoc(aContext->Document()), mContext(aContext), mAnchorNode(nullptr),
|
||||
mARIAOwnsIdx(0),
|
||||
mChildFilter(nsIContent::eSkipPlaceholderContent), mFlags(0)
|
||||
{
|
||||
NS_ASSERTION(aContent, "No node for the accessible tree walker!");
|
||||
|
||||
mChildFilter = mContext->NoXBLKids() ?
|
||||
mChildFilter |= mContext->NoXBLKids() ?
|
||||
nsIContent::eAllButXBL : nsIContent::eAllChildren;
|
||||
mChildFilter |= nsIContent::eSkipPlaceholderContent;
|
||||
|
||||
if (aContent)
|
||||
PushState(aContent);
|
||||
mAnchorNode = mContext->IsDoc() ?
|
||||
mDoc->DocumentNode()->GetRootElement() : mContext->GetContent();
|
||||
|
||||
if (mAnchorNode) {
|
||||
PushState(mAnchorNode);
|
||||
}
|
||||
|
||||
MOZ_COUNT_CTOR(TreeWalker);
|
||||
}
|
||||
|
||||
TreeWalker::
|
||||
TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags) :
|
||||
mDoc(aContext->Document()), mContext(aContext), mAnchorNode(aAnchorNode),
|
||||
mARIAOwnsIdx(0),
|
||||
mChildFilter(nsIContent::eSkipPlaceholderContent), mFlags(aFlags)
|
||||
{
|
||||
MOZ_ASSERT(aAnchorNode, "No anchor node for the accessible tree walker");
|
||||
MOZ_ASSERT(mDoc->GetAccessibleOrContainer(aAnchorNode) == mContext,
|
||||
"Unexpected anchor node was given");
|
||||
|
||||
mChildFilter |= mContext->NoXBLKids() ?
|
||||
nsIContent::eAllButXBL : nsIContent::eAllChildren;
|
||||
|
||||
PushState(aAnchorNode);
|
||||
|
||||
MOZ_COUNT_CTOR(TreeWalker);
|
||||
}
|
||||
@ -48,29 +68,44 @@ TreeWalker::~TreeWalker()
|
||||
Accessible*
|
||||
TreeWalker::Next()
|
||||
{
|
||||
if (mStateStack.IsEmpty())
|
||||
return nullptr;
|
||||
if (mStateStack.IsEmpty()) {
|
||||
return mDoc->ARIAOwnedAt(mContext, mARIAOwnsIdx++);
|
||||
}
|
||||
|
||||
ChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
|
||||
dom::AllChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
|
||||
while (top) {
|
||||
Accessible* child = nullptr;
|
||||
bool skipSubtree = false;
|
||||
while (nsIContent* childNode = Next(top, &child, &skipSubtree)) {
|
||||
if (child)
|
||||
while (nsIContent* childNode = top->GetNextChild()) {
|
||||
bool skipSubtree = false;
|
||||
Accessible* child = nullptr;
|
||||
if (mFlags & eWalkCache) {
|
||||
child = mDoc->GetAccessible(childNode);
|
||||
}
|
||||
else if (mContext->IsAcceptableChild(childNode)) {
|
||||
child = GetAccService()->
|
||||
GetOrCreateAccessible(childNode, mContext, &skipSubtree);
|
||||
}
|
||||
|
||||
// Ignore the accessible and its subtree if it was repositioned by means
|
||||
// of aria-owns.
|
||||
if (child) {
|
||||
if (child->IsRelocated()) {
|
||||
continue;
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
// Walk down into subtree to find accessibles.
|
||||
if (!skipSubtree && childNode->IsElement())
|
||||
if (!skipSubtree && childNode->IsElement()) {
|
||||
top = PushState(childNode);
|
||||
}
|
||||
}
|
||||
|
||||
top = PopState();
|
||||
}
|
||||
|
||||
// If we traversed the whole subtree of the anchor node. Move to next node
|
||||
// relative anchor node within the context subtree if possible.
|
||||
if (mFlags != eWalkContextTree)
|
||||
return nullptr;
|
||||
return Next();
|
||||
|
||||
nsINode* contextNode = mContext->GetNode();
|
||||
while (mAnchorNode != contextNode) {
|
||||
@ -80,7 +115,7 @@ TreeWalker::Next()
|
||||
|
||||
nsIContent* parent = parentNode->AsElement();
|
||||
top = PushState(parent);
|
||||
if (top->mDOMIter.Seek(mAnchorNode)) {
|
||||
if (top->Seek(mAnchorNode)) {
|
||||
mAnchorNode = parent;
|
||||
return Next();
|
||||
}
|
||||
@ -92,55 +127,10 @@ TreeWalker::Next()
|
||||
mAnchorNode = parent;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return Next();
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
TreeWalker::Next(ChildrenIterator* aIter, Accessible** aAccesible,
|
||||
bool* aSkipSubtree)
|
||||
{
|
||||
nsIContent* childEl = aIter->mDOMIter.GetNextChild();
|
||||
if (!aAccesible)
|
||||
return childEl;
|
||||
|
||||
*aAccesible = nullptr;
|
||||
*aSkipSubtree = false;
|
||||
|
||||
if (childEl) {
|
||||
Accessible* accessible = nullptr;
|
||||
if (mFlags & eWalkCache) {
|
||||
accessible = mDoc->GetAccessible(childEl);
|
||||
}
|
||||
else if (mContext->IsAcceptableChild(childEl)) {
|
||||
accessible = GetAccService()->
|
||||
GetOrCreateAccessible(childEl, mContext, aSkipSubtree);
|
||||
}
|
||||
|
||||
// Ignore the accessible and its subtree if it was repositioned by means of
|
||||
// aria-owns.
|
||||
if (accessible) {
|
||||
if (accessible->IsRelocated()) {
|
||||
*aSkipSubtree = true;
|
||||
} else {
|
||||
*aAccesible = accessible;
|
||||
}
|
||||
}
|
||||
return childEl;
|
||||
}
|
||||
|
||||
// At last iterate over ARIA owned children.
|
||||
Accessible* parent = mDoc->GetAccessible(aIter->mDOMIter.Parent());
|
||||
if (parent) {
|
||||
Accessible* child = mDoc->ARIAOwnedAt(parent, aIter->mARIAOwnsIdx++);
|
||||
if (child) {
|
||||
*aAccesible = child;
|
||||
return child->GetContent();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TreeWalker::ChildrenIterator*
|
||||
dom::AllChildrenIterator*
|
||||
TreeWalker::PopState()
|
||||
{
|
||||
size_t length = mStateStack.Length();
|
||||
|
@ -33,14 +33,20 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Used to navigate and create if needed the accessible children.
|
||||
*/
|
||||
explicit TreeWalker(Accessible* aContext);
|
||||
|
||||
/**
|
||||
* Used to navigate the accessible children relative to the anchor.
|
||||
*
|
||||
* @param aContext [in] container accessible for the given node, used to
|
||||
* define accessible context
|
||||
* @param aNode [in] the node the search will be prepared relative to
|
||||
* @param aAnchorNode [in] the node the search will be prepared relative to
|
||||
* @param aFlags [in] flags (see enum above)
|
||||
*/
|
||||
TreeWalker(Accessible* aContext, nsIContent* aNode, uint32_t aFlags = 0);
|
||||
TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags = 0);
|
||||
|
||||
~TreeWalker();
|
||||
|
||||
/**
|
||||
@ -57,37 +63,30 @@ private:
|
||||
TreeWalker(const TreeWalker&);
|
||||
TreeWalker& operator =(const TreeWalker&);
|
||||
|
||||
struct ChildrenIterator {
|
||||
ChildrenIterator(nsIContent* aNode, uint32_t aFilter) :
|
||||
mDOMIter(aNode, aFilter), mARIAOwnsIdx(0) { }
|
||||
|
||||
dom::AllChildrenIterator mDOMIter;
|
||||
uint32_t mARIAOwnsIdx;
|
||||
};
|
||||
|
||||
nsIContent* Next(ChildrenIterator* aIter, Accessible** aAccessible = nullptr,
|
||||
bool* aSkipSubtree = nullptr);
|
||||
|
||||
/**
|
||||
* Create new state for the given node and push it on top of stack.
|
||||
*
|
||||
* @note State stack is used to navigate up/down the DOM subtree during
|
||||
* accessible children search.
|
||||
*/
|
||||
ChildrenIterator* PushState(nsIContent* aContent)
|
||||
dom::AllChildrenIterator* PushState(nsIContent* aContent)
|
||||
{
|
||||
return mStateStack.AppendElement(ChildrenIterator(aContent, mChildFilter));
|
||||
return mStateStack.AppendElement(
|
||||
dom::AllChildrenIterator(aContent, mChildFilter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop state from stack.
|
||||
*/
|
||||
ChildrenIterator* PopState();
|
||||
dom::AllChildrenIterator* PopState();
|
||||
|
||||
DocAccessible* mDoc;
|
||||
Accessible* mContext;
|
||||
nsIContent* mAnchorNode;
|
||||
AutoTArray<ChildrenIterator, 20> mStateStack;
|
||||
|
||||
AutoTArray<dom::AllChildrenIterator, 20> mStateStack;
|
||||
uint32_t mARIAOwnsIdx;
|
||||
|
||||
int32_t mChildFilter;
|
||||
uint32_t mFlags;
|
||||
};
|
||||
|
@ -2541,10 +2541,9 @@ Accessible::LastRelease()
|
||||
void
|
||||
Accessible::CacheChildren()
|
||||
{
|
||||
DocAccessible* doc = Document();
|
||||
NS_ENSURE_TRUE_VOID(doc);
|
||||
NS_ENSURE_TRUE_VOID(Document());
|
||||
|
||||
TreeWalker walker(this, mContent);
|
||||
TreeWalker walker(this);
|
||||
|
||||
Accessible* child = nullptr;
|
||||
while ((child = walker.Next()) && AppendChild(child));
|
||||
|
@ -1248,6 +1248,12 @@ DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const
|
||||
if (!(currNode = parent)) break;
|
||||
}
|
||||
|
||||
// HTML comboboxes have no-content list accessible as an intermediate
|
||||
// containing all options.
|
||||
if (accessible && accessible->IsHTMLCombobox()) {
|
||||
return accessible->FirstChild();
|
||||
}
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
@ -1418,25 +1424,6 @@ if (!aNode->IsContent() || !aNode->AsContent()->IsHTMLElement(nsGkAtoms::area))
|
||||
return GetAccessible(aNode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible protected
|
||||
|
||||
void
|
||||
DocAccessible::CacheChildren()
|
||||
{
|
||||
// Search for accessible children starting from the document element since
|
||||
// some web pages tend to insert elements under it rather than document body.
|
||||
dom::Element* rootElm = mDocumentNode->GetRootElement();
|
||||
if (!rootElm)
|
||||
return;
|
||||
|
||||
TreeWalker walker(this, rootElm);
|
||||
Accessible* child = nullptr;
|
||||
while ((child = walker.Next())) {
|
||||
AppendChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected members
|
||||
|
||||
@ -1725,11 +1712,6 @@ DocAccessible::ProcessContentInserted(Accessible* aContainer,
|
||||
// there is no HTML body element.
|
||||
}
|
||||
|
||||
// HTML comboboxes have no-content list accessible as an intermidiate
|
||||
// containing all options.
|
||||
if (container->IsHTMLCombobox())
|
||||
container = container->FirstChild();
|
||||
|
||||
// We have a DOM/layout change under the container accessible, and its tree
|
||||
// might need an update. Since DOM/layout change of the element may affect
|
||||
// on the accessibleness of adjacent elements (for example, insertion of
|
||||
|
@ -359,9 +359,6 @@ protected:
|
||||
|
||||
void LastRelease();
|
||||
|
||||
// Accessible
|
||||
virtual void CacheChildren() override;
|
||||
|
||||
// DocAccessible
|
||||
virtual nsresult AddEventListeners();
|
||||
virtual nsresult RemoveEventListeners();
|
||||
|
@ -114,35 +114,12 @@ HTMLSelectListAccessible::SetCurrentItem(Accessible* aItem)
|
||||
true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLSelectListAccessible: Accessible protected
|
||||
|
||||
void
|
||||
HTMLSelectListAccessible::CacheChildren()
|
||||
bool
|
||||
HTMLSelectListAccessible::IsAcceptableChild(nsIContent* aEl) const
|
||||
{
|
||||
// Cache accessibles for <optgroup> and <option> DOM decendents as children,
|
||||
// as well as the accessibles for them. Avoid whitespace text nodes. We want
|
||||
// to count all the <optgroup>s and <option>s as children because we want
|
||||
// a flat tree under the Select List.
|
||||
for (nsIContent* childContent = mContent->GetFirstChild(); childContent;
|
||||
childContent = childContent->GetNextSibling()) {
|
||||
if (!childContent->IsHTMLElement()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (childContent->IsAnyOfHTMLElements(nsGkAtoms::option,
|
||||
nsGkAtoms::optgroup)) {
|
||||
|
||||
// Get an accessible for option or optgroup and cache it.
|
||||
RefPtr<Accessible> accessible =
|
||||
GetAccService()->GetOrCreateAccessible(childContent, this);
|
||||
if (accessible)
|
||||
AppendChild(accessible);
|
||||
}
|
||||
}
|
||||
return aEl->IsAnyOfHTMLElements(nsGkAtoms::option, nsGkAtoms::optgroup);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLSelectOptionAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -51,10 +51,7 @@ public:
|
||||
virtual Accessible* CurrentItem() override;
|
||||
virtual void SetCurrentItem(Accessible* aItem) override;
|
||||
|
||||
protected:
|
||||
|
||||
// Accessible
|
||||
virtual void CacheChildren() override;
|
||||
virtual bool IsAcceptableChild(nsIContent* aEl) const override;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -251,11 +251,13 @@ enum CheckboxValue {
|
||||
{
|
||||
mozAccessible* nativeAcc = nil;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
Accessible* accTab = accWrap->GetSelectedItem(0);
|
||||
accTab->GetNativeInterface((void**)&nativeAcc);
|
||||
if (Accessible* accTab = accWrap->GetSelectedItem(0)) {
|
||||
accTab->GetNativeInterface((void**)&nativeAcc);
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
ProxyAccessible* proxyTab = proxy->GetSelectedItem(0);
|
||||
nativeAcc = GetNativeFromProxy(proxyTab);
|
||||
if (ProxyAccessible* proxyTab = proxy->GetSelectedItem(0)) {
|
||||
nativeAcc = GetNativeFromProxy(proxyTab);
|
||||
}
|
||||
}
|
||||
|
||||
return nativeAcc;
|
||||
|
@ -102,7 +102,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// gA11yEventDumpToConsole = true;
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
|
@ -42,5 +42,4 @@ skip-if = true
|
||||
[tab-close-on-startup.xpi]
|
||||
[toolkit-require-reload.xpi]
|
||||
[translators.xpi]
|
||||
[unpacked.xpi]
|
||||
[unsafe-content-script.xpi]
|
||||
|
@ -17,7 +17,9 @@ exports.main = function main(options, callbacks) {
|
||||
assert.ok('loadReason' in options, 'loadReason is in options provided by main');
|
||||
assert.equal(typeof callbacks.print, 'function', 'callbacks.print is a function');
|
||||
assert.equal(typeof callbacks.quit, 'function', 'callbacks.quit is a function');
|
||||
assert.equal(options.loadReason, 'install', 'options.loadReason is install');
|
||||
|
||||
// Re-enable when bug 1251664 is fixed
|
||||
//assert.equal(options.loadReason, 'install', 'options.loadReason is install');
|
||||
}
|
||||
|
||||
require('sdk/test/runner').runTestsFromModule({exports: tests});
|
||||
|
@ -1,18 +0,0 @@
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
const { packed } = require("sdk/self");
|
||||
const url = require("sdk/url");
|
||||
|
||||
exports["test self.packed"] = function (assert) {
|
||||
assert.ok(!packed, "require('sdk/self').packed is correct");
|
||||
}
|
||||
|
||||
exports["test url.toFilename"] = function (assert) {
|
||||
assert.ok(/.*main\.js$/.test(url.toFilename(module.uri)),
|
||||
"url.toFilename() on resource: URIs should work");
|
||||
}
|
||||
|
||||
require("sdk/test/runner").runTestsFromModule(module);
|
@ -1,6 +0,0 @@
|
||||
{
|
||||
"id": "test-url@jetpack",
|
||||
"unpack": true,
|
||||
"main": "./main.js",
|
||||
"version": "0.0.1"
|
||||
}
|
@ -31,7 +31,7 @@ externalProtocolChkMsg=Remember my choice for all links of this type.
|
||||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
|
||||
phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
|
||||
deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
|
||||
forbiddenBlocked=The site at %S has been blocked by your browser configuration.
|
||||
cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
|
||||
corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
|
||||
|
@ -1201,10 +1201,6 @@ pref("security.sandbox.content.level", 2);
|
||||
pref("security.sandbox.content.level", 0);
|
||||
#endif
|
||||
|
||||
// ID (a UUID when set by gecko) that is used as a per profile suffix to a low
|
||||
// integrity temp directory.
|
||||
pref("security.sandbox.content.tempDirSuffix", "");
|
||||
|
||||
#if defined(MOZ_STACKWALKING)
|
||||
// This controls the depth of stack trace that is logged when Windows sandbox
|
||||
// logging is turned on. This is only currently available for the content
|
||||
@ -1227,6 +1223,15 @@ pref("security.sandbox.windows.log.stackTraceDepth", 0);
|
||||
pref("security.sandbox.content.level", 1);
|
||||
#endif
|
||||
|
||||
#if defined(XP_MACOSX) || defined(XP_WIN)
|
||||
#if defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
|
||||
// ID (a UUID when set by gecko) that is used to form the name of a
|
||||
// sandbox-writable temporary directory to be used by content processes
|
||||
// when a temporary writable file is required in a level 1 sandbox.
|
||||
pref("security.sandbox.content.tempDirSuffix", "");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This pref governs whether we attempt to work around problems caused by
|
||||
// plugins using OS calls to manipulate the cursor while running out-of-
|
||||
// process. These workarounds all involve intercepting (hooking) certain
|
||||
|
@ -414,9 +414,6 @@
|
||||
<h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
|
||||
<h1 id="et_nssFailure2">&nssFailure2.title;</h1>
|
||||
<h1 id="et_nssBadCert">&nssBadCert.title;</h1>
|
||||
<h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
|
||||
<h1 id="et_unwantedBlocked">&unwantedBlocked.title;</h1>
|
||||
<h1 id="et_forbiddenBlocked">&forbiddenBlocked.title;</h1>
|
||||
<h1 id="et_cspBlocked">&cspBlocked.title;</h1>
|
||||
<h1 id="et_remoteXUL">&remoteXUL.title;</h1>
|
||||
<h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
|
||||
@ -444,9 +441,6 @@
|
||||
<div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
|
||||
<div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
|
||||
<div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
|
||||
<div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
|
||||
<div id="ed_unwantedBlocked">&unwantedBlocked.longDesc;</div>
|
||||
<div id="ed_forbiddenBlocked">&forbiddenBlocked.longDesc;</div>
|
||||
<div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
|
||||
<div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
|
||||
<div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
|
||||
|
@ -88,7 +88,7 @@
|
||||
case "malwareBlocked" :
|
||||
error = "malware";
|
||||
break;
|
||||
case "phishingBlocked" :
|
||||
case "deceptiveBlocked" :
|
||||
error = "phishing";
|
||||
break;
|
||||
case "unwantedBlocked" :
|
||||
@ -200,7 +200,7 @@
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 id="errorTitleText_phishing">&safeb.blocked.phishingPage.title;</h1>
|
||||
<h1 id="errorTitleText_phishing">&safeb.blocked.phishingPage.title2;</h1>
|
||||
<h1 id="errorTitleText_malware">&safeb.blocked.malwarePage.title;</h1>
|
||||
<h1 id="errorTitleText_unwanted">&safeb.blocked.unwantedPage.title;</h1>
|
||||
<h1 id="errorTitleText_forbidden">&safeb.blocked.forbiddenPage.title2;</h1>
|
||||
@ -210,7 +210,7 @@
|
||||
|
||||
<!-- Short Description -->
|
||||
<div id="errorShortDesc">
|
||||
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc;</p>
|
||||
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc2;</p>
|
||||
<p id="errorShortDescText_malware">&safeb.blocked.malwarePage.shortDesc;</p>
|
||||
<p id="errorShortDescText_unwanted">&safeb.blocked.unwantedPage.shortDesc;</p>
|
||||
<p id="errorShortDescText_forbidden">&safeb.blocked.forbiddenPage.shortDesc2;</p>
|
||||
@ -218,7 +218,7 @@
|
||||
|
||||
<!-- Long Description -->
|
||||
<div id="errorLongDesc">
|
||||
<p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc;</p>
|
||||
<p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc2;</p>
|
||||
<p id="errorLongDescText_malware">&safeb.blocked.malwarePage.longDesc;</p>
|
||||
<p id="errorLongDescText_unwanted">&safeb.blocked.unwantedPage.longDesc;</p>
|
||||
</div>
|
||||
|
@ -4,15 +4,9 @@
|
||||
|
||||
<menu id="charsetMenu"
|
||||
label="&charsetMenu2.label;"
|
||||
#ifndef OMIT_ACCESSKEYS
|
||||
accesskey="&charsetMenu2.accesskey;"
|
||||
#endif
|
||||
oncommand="BrowserSetForcedCharacterSet(event.target.getAttribute('charset'));"
|
||||
#ifdef OMIT_ACCESSKEYS
|
||||
onpopupshowing="CharsetMenu.build(event.target, false);"
|
||||
#else
|
||||
onpopupshowing="CharsetMenu.build(event.target);"
|
||||
#endif
|
||||
onpopupshown="UpdateCurrentCharset(this);">
|
||||
<menupopup>
|
||||
</menupopup>
|
||||
|
@ -15,7 +15,7 @@ var gSafeBrowsing = {
|
||||
// will point to the internal error page we loaded instead.
|
||||
var docURI = gBrowser.selectedBrowser.documentURI;
|
||||
var isPhishingPage =
|
||||
docURI && docURI.spec.startsWith("about:blocked?e=phishingBlocked");
|
||||
docURI && docURI.spec.startsWith("about:blocked?e=deceptiveBlocked");
|
||||
|
||||
// Show/hide the appropriate menu item.
|
||||
document.getElementById("menu_HelpPopup_reportPhishingtoolmenu")
|
||||
|
@ -160,7 +160,7 @@ XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
|
||||
XPCOMUtils.defineLazyGetter(this, "DeveloperToolbar", function() {
|
||||
let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let { DeveloperToolbar } = require("devtools/client/shared/developer-toolbar");
|
||||
return new DeveloperToolbar(window, document.getElementById("developer-toolbar"));
|
||||
return new DeveloperToolbar(window);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() {
|
||||
@ -2915,10 +2915,10 @@ var BrowserOnClick = {
|
||||
}
|
||||
};
|
||||
} else if (reason === 'phishing') {
|
||||
title = gNavigatorBundle.getString("safebrowsing.reportedWebForgery");
|
||||
title = gNavigatorBundle.getString("safebrowsing.deceptiveSite");
|
||||
buttons[1] = {
|
||||
label: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.label"),
|
||||
accessKey: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.accessKey"),
|
||||
label: gNavigatorBundle.getString("safebrowsing.notADeceptiveSiteButton.label"),
|
||||
accessKey: gNavigatorBundle.getString("safebrowsing.notADeceptiveSiteButton.accessKey"),
|
||||
callback: function() {
|
||||
openUILinkIn(gSafeBrowsing.getReportURL('PhishMistake'), 'tab');
|
||||
}
|
||||
@ -5492,9 +5492,9 @@ function BrowserCharsetReload()
|
||||
}
|
||||
|
||||
function UpdateCurrentCharset(target) {
|
||||
let selectedCharset = CharsetMenu.foldCharset(gBrowser.selectedBrowser.characterSet);
|
||||
for (let menuItem of target.getElementsByTagName("menuitem")) {
|
||||
let isSelected = menuItem.getAttribute("charset") ===
|
||||
CharsetMenu.foldCharset(gBrowser.selectedBrowser.characterSet);
|
||||
let isSelected = menuItem.getAttribute("charset") === selectedCharset;
|
||||
menuItem.setAttribute("checked", isSelected);
|
||||
}
|
||||
}
|
||||
|
@ -1109,29 +1109,6 @@
|
||||
|
||||
<vbox id="browser-bottombox" layer="true">
|
||||
<notificationbox id="global-notificationbox" notificationside="bottom"/>
|
||||
<toolbar id="developer-toolbar"
|
||||
hidden="true">
|
||||
#ifdef XP_MACOSX
|
||||
<toolbarbutton id="developer-toolbar-closebutton"
|
||||
class="devtools-closebutton"
|
||||
oncommand="DeveloperToolbar.hide();"
|
||||
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
|
||||
#endif
|
||||
<stack class="gclitoolbar-stack-node" flex="1">
|
||||
<textbox class="gclitoolbar-input-node" rows="1"/>
|
||||
<hbox class="gclitoolbar-complete-node"/>
|
||||
</stack>
|
||||
<toolbarbutton id="developer-toolbar-toolbox-button"
|
||||
class="developer-toolbar-button"
|
||||
observes="devtoolsMenuBroadcaster_DevToolbox"
|
||||
tooltiptext="&devToolbarToolsButton.tooltip;"/>
|
||||
#ifndef XP_MACOSX
|
||||
<toolbarbutton id="developer-toolbar-closebutton"
|
||||
class="devtools-closebutton"
|
||||
oncommand="DeveloperToolbar.hide();"
|
||||
tooltiptext="&devToolbarCloseButton.tooltiptext;"/>
|
||||
#endif
|
||||
</toolbar>
|
||||
</vbox>
|
||||
|
||||
<svg:svg height="0">
|
||||
|
@ -18,15 +18,15 @@
|
||||
</broadcasterset>
|
||||
<menupopup id="menu_HelpPopup">
|
||||
<menuitem id="menu_HelpPopup_reportPhishingtoolmenu"
|
||||
label="&reportPhishSiteMenu.title2;"
|
||||
accesskey="&reportPhishSiteMenu.accesskey;"
|
||||
label="&reportDeceptiveSiteMenu.title;"
|
||||
accesskey="&reportDeceptiveSiteMenu.accesskey;"
|
||||
insertbefore="aboutSeparator"
|
||||
observes="reportPhishingBroadcaster"
|
||||
oncommand="openUILink(gSafeBrowsing.getReportURL('Phish'), event);"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu"
|
||||
label="&safeb.palm.notforgery.label2;"
|
||||
accesskey="&reportPhishSiteMenu.accesskey;"
|
||||
label="&safeb.palm.notdeceptive.label;"
|
||||
accesskey="&reportDeceptiveSiteMenu.accesskey;"
|
||||
insertbefore="aboutSeparator"
|
||||
observes="reportPhishingErrorBroadcaster"
|
||||
oncommand="openUILinkIn(gSafeBrowsing.getReportURL('PhishMistake'), 'tab');"
|
||||
|
@ -288,9 +288,8 @@ Sanitizer.prototype = {
|
||||
}),
|
||||
|
||||
promiseClearPluginCookies: Task.async(function* (range) {
|
||||
const phInterface = Ci.nsIPluginHost;
|
||||
const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
|
||||
const FLAG_CLEAR_ALL = Ci.nsIPluginHost.FLAG_CLEAR_ALL;
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
|
||||
// Determine age range in seconds. (-1 means clear all.) We don't know
|
||||
// that range[1] is actually now, so we compute age range based
|
||||
@ -299,6 +298,13 @@ Sanitizer.prototype = {
|
||||
if (!range || age >= 0) {
|
||||
let tags = ph.getPluginTags();
|
||||
for (let tag of tags) {
|
||||
let refObj = {};
|
||||
let probe = "";
|
||||
if (/\bFlash\b/.test(tag.name)) {
|
||||
probe = tag.loaded ? "FX_SANITIZE_LOADED_FLASH"
|
||||
: "FX_SANITIZE_UNLOADED_FLASH";
|
||||
TelemetryStopwatch.start(probe, refObj);
|
||||
}
|
||||
try {
|
||||
let rv = yield new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, age, resolve)
|
||||
@ -309,8 +315,14 @@ Sanitizer.prototype = {
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, -1, resolve)
|
||||
);
|
||||
}
|
||||
if (probe) {
|
||||
TelemetryStopwatch.finish(probe, refObj);
|
||||
}
|
||||
} catch (ex) {
|
||||
// Ignore errors from plug-ins
|
||||
if (probe) {
|
||||
TelemetryStopwatch.cancel(probe, refObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,28 @@
|
||||
"use strict";
|
||||
|
||||
const {PlacesTestUtils} =
|
||||
Cu.import("resource://testing-common/PlacesTestUtils.jsm", {});
|
||||
|
||||
let tab;
|
||||
let notificationURL = "http://example.org/browser/browser/base/content/test/alerts/file_dom_notifications.html";
|
||||
let oldShowFavicons;
|
||||
|
||||
add_task(function* test_notificationClose() {
|
||||
let pm = Services.perms;
|
||||
pm.add(makeURI(notificationURL), "desktop-notification", pm.ALLOW_ACTION);
|
||||
let notificationURI = makeURI(notificationURL);
|
||||
pm.add(notificationURI, "desktop-notification", pm.ALLOW_ACTION);
|
||||
|
||||
oldShowFavicons = Services.prefs.getBoolPref("alerts.showFavicons");
|
||||
Services.prefs.setBoolPref("alerts.showFavicons", true);
|
||||
|
||||
yield PlacesTestUtils.addVisits(notificationURI);
|
||||
let faviconURI = yield new Promise(resolve => {
|
||||
let faviconURI = makeURI("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4//8/AAX+Av7czFnnAAAAAElFTkSuQmCC");
|
||||
PlacesUtils.favicons.setAndFetchFaviconForPage(notificationURI, faviconURI,
|
||||
true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
|
||||
(faviconURI, iconSize, iconData, mimeType) => resolve(faviconURI),
|
||||
Services.scriptSecurityManager.getSystemPrincipal());
|
||||
});
|
||||
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
@ -26,6 +43,8 @@ add_task(function* test_notificationClose() {
|
||||
is(alertTitleLabel.value, "Test title", "Title text of notification should be present");
|
||||
let alertTextLabel = alertWindow.document.getElementById("alertTextLabel");
|
||||
is(alertTextLabel.textContent, "Test body 2", "Body text of notification should be present");
|
||||
let alertIcon = alertWindow.document.getElementById("alertIcon");
|
||||
is(alertIcon.src, faviconURI.spec, "Icon of notification should be present");
|
||||
|
||||
let alertCloseButton = alertWindow.document.querySelector(".alertCloseButton");
|
||||
is(alertCloseButton.localName, "toolbarbutton", "close button found");
|
||||
@ -47,4 +66,7 @@ add_task(function* test_notificationClose() {
|
||||
|
||||
add_task(function* cleanup() {
|
||||
Services.perms.remove(makeURI(notificationURL), "desktop-notification");
|
||||
if (typeof oldShowFavicons == "boolean") {
|
||||
Services.prefs.setBoolPref("alerts.showFavicons", oldShowFavicons);
|
||||
}
|
||||
});
|
||||
|
@ -142,7 +142,6 @@ skip-if = e10s # Bug 1093153 - no about:home support yet
|
||||
[browser_alltabslistener.js]
|
||||
[browser_audioTabIcon.js]
|
||||
[browser_autocomplete_a11y_label.js]
|
||||
skip-if = e10s # Bug 1101993 - times out for unknown reasons when run in the dir (works on its own)
|
||||
[browser_autocomplete_cursor.js]
|
||||
[browser_autocomplete_edit_completed.js]
|
||||
[browser_autocomplete_enter_race.js]
|
||||
@ -367,7 +366,7 @@ skip-if = buildapp == 'mulet'
|
||||
[browser_popup_blocker.js]
|
||||
skip-if = (os == 'linux') || (e10s && debug) # Frequent bug 1081925 and bug 1125520 failures
|
||||
[browser_printpreview.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 1101973 - breaks the next test in e10s, and may be responsible for later timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_private_browsing_window.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_private_no_prompt.js]
|
||||
@ -393,11 +392,11 @@ skip-if = buildapp == 'mulet'
|
||||
[browser_sanitizeDialog.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_save_link-perwindowpb.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_save_private_link_perwindowpb.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # e10s: Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_save_link_when_window_navigates.js]
|
||||
skip-if = buildapp == 'mulet' || e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_save_video.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_save_video_frame.js]
|
||||
|
@ -51,6 +51,7 @@ function* test_bookmarks_popup({isNewBookmark, popupShowFn, popupEditFn,
|
||||
|
||||
if (!shouldAutoClose) {
|
||||
yield new Promise(resolve => setTimeout(resolve, 400));
|
||||
is(bookmarkPanel.state, "open", "Panel should still be 'open' for non-autoclose");
|
||||
}
|
||||
|
||||
let hiddenPromise = promisePopupHidden(bookmarkPanel);
|
||||
@ -144,7 +145,8 @@ add_task(function* panel_shown_for_new_bookmarks_mouseover_mouseout() {
|
||||
|
||||
yield new Promise(resolve => setTimeout(resolve, 400));
|
||||
is(bookmarkPanel.state, "open", "Panel should still be open on mouseover");
|
||||
|
||||
},
|
||||
*popupHideFn() {
|
||||
let mouseOutPromise = new Promise(resolve => {
|
||||
bookmarkPanel.addEventListener("mouseout", function onmouseout() {
|
||||
bookmarkPanel.removeEventListener("mouseout", onmouseout);
|
||||
@ -158,7 +160,7 @@ add_task(function* panel_shown_for_new_bookmarks_mouseover_mouseout() {
|
||||
yield mouseOutPromise;
|
||||
info("Got mouseout event, should autoclose now");
|
||||
},
|
||||
shouldAutoClose: true,
|
||||
shouldAutoClose: false,
|
||||
isBookmarkRemoved: false,
|
||||
});
|
||||
});
|
||||
@ -208,7 +210,7 @@ add_task(function* panel_shown_for_new_bookmark_keypress_no_autoclose() {
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* contextmenu_new_bookmark_click_no_autoclose() {
|
||||
add_task(function* contextmenu_new_bookmark_keypress_no_autoclose() {
|
||||
yield test_bookmarks_popup({
|
||||
isNewBookmark: true,
|
||||
*popupShowFn(browser) {
|
||||
@ -227,7 +229,7 @@ add_task(function* contextmenu_new_bookmark_click_no_autoclose() {
|
||||
yield awaitPopupHidden;
|
||||
},
|
||||
popupEditFn() {
|
||||
bookmarkPanelTitle.click();
|
||||
EventUtils.sendChar("VK_TAB", window);
|
||||
},
|
||||
shouldAutoClose: false,
|
||||
popupHideFn() {
|
||||
|
@ -1,14 +1,23 @@
|
||||
let ourTab;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
ok(!gInPrintPreviewMode,
|
||||
"Should NOT be in print preview mode at starting this tests");
|
||||
// Skip access key test on platforms which don't support access key.
|
||||
if (!/Win|Linux/.test(navigator.platform)) {
|
||||
openPrintPreview(testClosePrintPreviewWithEscKey);
|
||||
} else {
|
||||
openPrintPreview(testClosePrintPreviewWithAccessKey);
|
||||
}
|
||||
BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home", true).then(function(tab) {
|
||||
ourTab = tab;
|
||||
ok(!gInPrintPreviewMode,
|
||||
"Should NOT be in print preview mode at starting this tests");
|
||||
// Skip access key test on platforms which don't support access key.
|
||||
if (!/Win|Linux/.test(navigator.platform)) {
|
||||
openPrintPreview(testClosePrintPreviewWithEscKey);
|
||||
} else {
|
||||
openPrintPreview(testClosePrintPreviewWithAccessKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function tidyUp() {
|
||||
BrowserTestUtils.removeTab(ourTab).then(finish);
|
||||
}
|
||||
|
||||
function testClosePrintPreviewWithAccessKey() {
|
||||
@ -34,7 +43,7 @@ function testClosePrintPreviewWithClosingWindowShortcutKey() {
|
||||
checkPrintPreviewClosed(function (aSucceeded) {
|
||||
ok(aSucceeded,
|
||||
"print preview mode should be finished by closing window shortcut key");
|
||||
finish();
|
||||
tidyUp();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ function triggerSave(aWindow, aCallback) {
|
||||
{ type: "contextmenu", button: 2 },
|
||||
testBrowser.contentWindow);
|
||||
info("right clicked!");
|
||||
}, testBrowser.contentWindow);
|
||||
}, testBrowser);
|
||||
}, false);
|
||||
|
||||
function contextMenuOpened(event) {
|
||||
|
@ -106,7 +106,7 @@ function test() {
|
||||
EventUtils.synthesizeMouseAtCenter(img,
|
||||
{ type: "contextmenu", button: 2 },
|
||||
aWindow.gBrowser.contentWindow);
|
||||
}, aWindow.gBrowser.selectedBrowser.contentWindow);
|
||||
}, aWindow.gBrowser.selectedBrowser);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,6 @@ skip-if = os == "linux" # Intermittent failures
|
||||
[browser_962884_opt_in_disable_hyphens.js]
|
||||
[browser_963639_customizing_attribute_non_customizable_toolbar.js]
|
||||
[browser_967000_button_charEncoding.js]
|
||||
skip-if = e10s # Bug 1088710
|
||||
[browser_967000_button_feeds.js]
|
||||
[browser_967000_button_sync.js]
|
||||
[browser_968447_bookmarks_toolbar_items_in_panel.js]
|
||||
@ -127,7 +126,6 @@ skip-if = os == "linux"
|
||||
[browser_987185_syncButton.js]
|
||||
[browser_987492_window_api.js]
|
||||
[browser_987640_charEncoding.js]
|
||||
skip-if = e10s # Bug 1088710
|
||||
[browser_988072_sidebar_events.js]
|
||||
[browser_989338_saved_placements_not_resaved.js]
|
||||
[browser_989751_subviewbutton_class.js]
|
||||
|
@ -6,9 +6,6 @@
|
||||
|
||||
const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test_967000_charEncoding_page.html";
|
||||
|
||||
var newTab;
|
||||
var initialLocation = gBrowser.currentURI.spec;
|
||||
|
||||
add_task(function*() {
|
||||
info("Check Character Encoding button functionality");
|
||||
|
||||
@ -28,14 +25,15 @@ add_task(function*() {
|
||||
PanelUI.hide();
|
||||
yield panelHidePromise;
|
||||
|
||||
newTab = gBrowser.selectedTab;
|
||||
yield promiseTabLoadEvent(newTab, TEST_PAGE)
|
||||
let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE, true, true);
|
||||
|
||||
yield PanelUI.show();
|
||||
ok(!charEncodingButton.hasAttribute("disabled"), "The Character encoding button gets enabled");
|
||||
charEncodingButton.click();
|
||||
|
||||
let characterEncodingView = document.getElementById("PanelUI-characterEncodingView");
|
||||
let subviewShownPromise = subviewShown(characterEncodingView);
|
||||
charEncodingButton.click();
|
||||
yield subviewShownPromise;
|
||||
|
||||
ok(characterEncodingView.hasAttribute("current"), "The Character encoding panel is displayed");
|
||||
|
||||
let pinnedEncodings = document.getElementById("PanelUI-characterEncodingView-pinned");
|
||||
@ -53,14 +51,12 @@ add_task(function*() {
|
||||
panelHidePromise = promisePanelHidden(window);
|
||||
PanelUI.hide();
|
||||
yield panelHidePromise;
|
||||
|
||||
yield BrowserTestUtils.removeTab(newTab);
|
||||
});
|
||||
|
||||
add_task(function* asyncCleanup() {
|
||||
// reset the panel to the default state
|
||||
yield resetCustomization();
|
||||
ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
|
||||
|
||||
// restore the initial location
|
||||
gBrowser.addTab(initialLocation);
|
||||
gBrowser.removeTab(newTab);
|
||||
});
|
||||
|
@ -5,7 +5,6 @@
|
||||
"use strict";
|
||||
|
||||
const TEST_PAGE = "http://mochi.test:8888/browser/browser/components/customizableui/test/support/test_967000_charEncoding_page.html";
|
||||
var newTab = null;
|
||||
|
||||
add_task(function*() {
|
||||
info("Check Character Encoding panel functionality");
|
||||
@ -14,14 +13,15 @@ add_task(function*() {
|
||||
CustomizableUI.addWidgetToArea("characterencoding-button",
|
||||
CustomizableUI.AREA_PANEL);
|
||||
|
||||
newTab = gBrowser.addTab(TEST_PAGE);
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, TEST_PAGE);
|
||||
let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE, true, true);
|
||||
|
||||
yield PanelUI.show();
|
||||
let charEncodingButton = document.getElementById("characterencoding-button");
|
||||
charEncodingButton.click();
|
||||
|
||||
let characterEncodingView = document.getElementById("PanelUI-characterEncodingView");
|
||||
let subviewShownPromise = subviewShown(characterEncodingView);
|
||||
charEncodingButton.click();
|
||||
yield subviewShownPromise;
|
||||
|
||||
let checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
|
||||
let initialEncoding = checkedButtons[0];
|
||||
is(initialEncoding.getAttribute("label"), "Unicode", "The unicode encoding is initially selected");
|
||||
@ -50,13 +50,11 @@ add_task(function*() {
|
||||
charEncodingButton.click();
|
||||
checkedButtons = characterEncodingView.querySelectorAll("toolbarbutton[checked='true']");
|
||||
is(checkedButtons[0].getAttribute("label"), "Unicode", "The encoding was reset to Unicode");
|
||||
yield BrowserTestUtils.removeTab(newTab);
|
||||
});
|
||||
|
||||
add_task(function* asyncCleanup() {
|
||||
// reset the panel to the default state
|
||||
yield resetCustomization();
|
||||
ok(CustomizableUI.inDefaultState, "The UI is in default state again.");
|
||||
|
||||
// remove the added tab
|
||||
gBrowser.removeTab(newTab);
|
||||
});
|
||||
|
@ -377,34 +377,50 @@ DistributionCustomizer.prototype = {
|
||||
let localizedStr = Cc["@mozilla.org/pref-localizedstring;1"].
|
||||
createInstance(Ci.nsIPrefLocalizedString);
|
||||
|
||||
if (sections["LocalizablePreferences"]) {
|
||||
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences"))) {
|
||||
var usedLocalizablePreferences = [];
|
||||
|
||||
if (sections["LocalizablePreferences-" + this._locale]) {
|
||||
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
|
||||
try {
|
||||
let value = eval(this._ini.getString("LocalizablePreferences", key));
|
||||
value = value.replace(/%LOCALE%/g, this._locale);
|
||||
value = value.replace(/%LANGUAGE%/g, this._language);
|
||||
localizedStr.data = "data:text/plain," + key + "=" + value;
|
||||
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
|
||||
let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
|
||||
if (value !== undefined) {
|
||||
localizedStr.data = "data:text/plain," + key + "=" + value;
|
||||
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
|
||||
}
|
||||
usedLocalizablePreferences.push(key);
|
||||
} catch (e) { /* ignore bad prefs and move on */ }
|
||||
}
|
||||
}
|
||||
|
||||
if (sections["LocalizablePreferences-" + this._language]) {
|
||||
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._language))) {
|
||||
if (usedLocalizablePreferences.indexOf(key) > -1) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
let value = eval(this._ini.getString("LocalizablePreferences-" + this._language, key));
|
||||
localizedStr.data = "data:text/plain," + key + "=" + value;
|
||||
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
|
||||
if (value !== undefined) {
|
||||
localizedStr.data = "data:text/plain," + key + "=" + value;
|
||||
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
|
||||
}
|
||||
usedLocalizablePreferences.push(key);
|
||||
} catch (e) { /* ignore bad prefs and move on */ }
|
||||
}
|
||||
}
|
||||
|
||||
if (sections["LocalizablePreferences-" + this._locale]) {
|
||||
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
|
||||
if (sections["LocalizablePreferences"]) {
|
||||
for (let key of enumerate(this._ini.getKeys("LocalizablePreferences"))) {
|
||||
if (usedLocalizablePreferences.indexOf(key) > -1) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
|
||||
localizedStr.data = "data:text/plain," + key + "=" + value;
|
||||
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
|
||||
let value = eval(this._ini.getString("LocalizablePreferences", key));
|
||||
if (value !== undefined) {
|
||||
value = value.replace(/%LOCALE%/g, this._locale);
|
||||
value = value.replace(/%LANGUAGE%/g, this._language);
|
||||
localizedStr.data = "data:text/plain," + key + "=" + value;
|
||||
defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
|
||||
}
|
||||
} catch (e) { /* ignore bad prefs and move on */ }
|
||||
}
|
||||
}
|
||||
|
@ -397,16 +397,20 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
}).api(),
|
||||
|
||||
create: function(createProperties) {
|
||||
return new Promise(resolve => {
|
||||
return new Promise((resolve, reject) => {
|
||||
function createInWindow(window) {
|
||||
let url;
|
||||
|
||||
if (createProperties.url !== null) {
|
||||
url = context.uri.resolve(createProperties.url);
|
||||
} else {
|
||||
url = window.BROWSER_NEW_TAB_URL;
|
||||
|
||||
if (!context.checkLoadURL(url, {dontReportErrors: true})) {
|
||||
reject({message: `URL not allowed: ${url}`});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let tab = window.gBrowser.addTab(url);
|
||||
let tab = window.gBrowser.addTab(url || window.BROWSER_NEW_TAB_URL);
|
||||
|
||||
let active = true;
|
||||
if (createProperties.active !== null) {
|
||||
@ -460,10 +464,23 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
|
||||
update: function(tabId, updateProperties) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let tabbrowser = tab.ownerDocument.defaultView.gBrowser;
|
||||
if (updateProperties.url !== null) {
|
||||
tab.linkedBrowser.loadURI(updateProperties.url);
|
||||
|
||||
if (!tab) {
|
||||
return Promise.reject({message: `No tab found with tabId: ${tabId}`});
|
||||
}
|
||||
|
||||
let tabbrowser = tab.ownerDocument.defaultView.gBrowser;
|
||||
|
||||
if (updateProperties.url !== null) {
|
||||
let url = context.uri.resolve(updateProperties.url);
|
||||
|
||||
if (!context.checkLoadURL(url, {dontReportErrors: true})) {
|
||||
return Promise.reject({message: `URL not allowed: ${url}`});
|
||||
}
|
||||
|
||||
tab.linkedBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
if (updateProperties.active !== null) {
|
||||
if (updateProperties.active) {
|
||||
tabbrowser.selectedTab = tab;
|
||||
@ -626,7 +643,7 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
message, recipient);
|
||||
},
|
||||
|
||||
_execute: function(tabId, details, kind) {
|
||||
_execute: function(tabId, details, kind, method) {
|
||||
let tab = tabId !== null ? TabManager.getTab(tabId) : TabManager.activeTab;
|
||||
let mm = tab.linkedBrowser.messageManager;
|
||||
|
||||
@ -635,6 +652,15 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
css: [],
|
||||
};
|
||||
|
||||
// We require a `code` or a `file` property, but we can't accept both.
|
||||
if ((details.code === null) == (details.file === null)) {
|
||||
return Promise.reject({message: `${method} requires either a 'code' or a 'file' property, but not both`});
|
||||
}
|
||||
|
||||
if (details.frameId !== null && details.allFrames) {
|
||||
return Promise.reject({message: `'frameId' and 'allFrames' are mutually exclusive`});
|
||||
}
|
||||
|
||||
let recipient = {
|
||||
innerWindowID: tab.linkedBrowser.innerWindowID,
|
||||
};
|
||||
@ -660,22 +686,27 @@ extensions.registerSchemaAPI("tabs", null, (extension, context) => {
|
||||
if (details.allFrames) {
|
||||
options.all_frames = details.allFrames;
|
||||
}
|
||||
if (details.frameId !== null) {
|
||||
options.frame_id = details.frameId;
|
||||
}
|
||||
if (details.matchAboutBlank) {
|
||||
options.match_about_blank = details.matchAboutBlank;
|
||||
}
|
||||
if (details.runAt !== null) {
|
||||
options.run_at = details.runAt;
|
||||
} else {
|
||||
options.run_at = "document_idle";
|
||||
}
|
||||
|
||||
return context.sendMessage(mm, "Extension:Execute", {options}, recipient);
|
||||
},
|
||||
|
||||
executeScript: function(tabId, details) {
|
||||
return self.tabs._execute(tabId, details, "js");
|
||||
return self.tabs._execute(tabId, details, "js", "executeScript");
|
||||
},
|
||||
|
||||
insertCSS: function(tabId, details) {
|
||||
return self.tabs._execute(tabId, details, "css");
|
||||
return self.tabs._execute(tabId, details, "css", "insertCSS");
|
||||
},
|
||||
|
||||
connect: function(tabId, connectInfo) {
|
||||
|
@ -7,6 +7,8 @@ support-files =
|
||||
context_tabs_onUpdated_iframe.html
|
||||
file_popup_api_injection_a.html
|
||||
file_popup_api_injection_b.html
|
||||
file_iframe_document.html
|
||||
file_iframe_document.sjs
|
||||
|
||||
[browser_ext_simple.js]
|
||||
[browser_ext_commands.js]
|
||||
@ -29,12 +31,15 @@ support-files =
|
||||
[browser_ext_tabs_executeScript.js]
|
||||
[browser_ext_tabs_executeScript_good.js]
|
||||
[browser_ext_tabs_executeScript_bad.js]
|
||||
[browser_ext_tabs_executeScript_runAt.js]
|
||||
[browser_ext_tabs_insertCSS.js]
|
||||
[browser_ext_tabs_query.js]
|
||||
[browser_ext_tabs_getCurrent.js]
|
||||
[browser_ext_tabs_create.js]
|
||||
[browser_ext_tabs_create_invalid_url.js]
|
||||
[browser_ext_tabs_duplicate.js]
|
||||
[browser_ext_tabs_update.js]
|
||||
[browser_ext_tabs_update_url.js]
|
||||
[browser_ext_tabs_onUpdated.js]
|
||||
[browser_ext_tabs_sendMessage.js]
|
||||
[browser_ext_tabs_move.js]
|
||||
@ -43,4 +48,4 @@ support-files =
|
||||
[browser_ext_windows_update.js]
|
||||
[browser_ext_contentscript_connect.js]
|
||||
[browser_ext_tab_runtimeConnect.js]
|
||||
[browser_ext_webNavigation_getFrames.js]
|
||||
[browser_ext_webNavigation_getFrames.js]
|
||||
|
@ -0,0 +1,66 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
function* testTabsCreateInvalidURL(tabsCreateURL) {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"],
|
||||
},
|
||||
|
||||
background: function() {
|
||||
browser.test.sendMessage("ready");
|
||||
browser.test.onMessage.addListener((msg, tabsCreateURL) => {
|
||||
browser.tabs.create({url: tabsCreateURL}, (tab) => {
|
||||
browser.test.assertEq(undefined, tab, "on error tab should be undefined");
|
||||
browser.test.assertTrue(/URL not allowed/.test(browser.runtime.lastError.message),
|
||||
"runtime.lastError should report the expected error message");
|
||||
|
||||
// Remove the opened tab is any.
|
||||
if (tab) {
|
||||
browser.tabs.remove(tab.id);
|
||||
}
|
||||
browser.test.sendMessage("done");
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
yield extension.awaitMessage("ready");
|
||||
|
||||
info(`test tab.create on invalid URL "${tabsCreateURL}"`);
|
||||
|
||||
extension.sendMessage("start", tabsCreateURL);
|
||||
yield extension.awaitMessage("done");
|
||||
|
||||
yield extension.unload();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
info("Start testing tabs.create on invalid URLs");
|
||||
|
||||
let dataURLPage = `data:text/html,
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1>data url page</h1>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
let testCases = [
|
||||
{tabsCreateURL: "about:addons"},
|
||||
{tabsCreateURL: "javascript:console.log('tabs.update execute javascript')"},
|
||||
{tabsCreateURL: dataURLPage},
|
||||
];
|
||||
|
||||
for (let {tabsCreateURL} of testCases) {
|
||||
yield* testTabsCreateInvalidURL(tabsCreateURL);
|
||||
}
|
||||
|
||||
info("done");
|
||||
});
|
@ -8,33 +8,134 @@ add_task(function* testExecuteScript() {
|
||||
let messageManagersSize = MessageChannel.messageManagers.size;
|
||||
let responseManagersSize = MessageChannel.responseManagers.size;
|
||||
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/", true);
|
||||
const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
|
||||
const URL = BASE + "file_iframe_document.html";
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, URL, true);
|
||||
|
||||
function background() {
|
||||
browser.tabs.executeScript({
|
||||
file: "script.js",
|
||||
code: "42",
|
||||
}, result => {
|
||||
browser.test.assertEq(42, result, "Expected callback result");
|
||||
browser.test.sendMessage("got result", result);
|
||||
});
|
||||
browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
|
||||
return browser.webNavigation.getAllFrames({tabId: tabs[0].id});
|
||||
}).then(frames => {
|
||||
browser.test.log(`FRAMES: ${frames[1].frameId} ${JSON.stringify(frames)}\n`);
|
||||
return Promise.all([
|
||||
browser.tabs.executeScript({
|
||||
code: "42",
|
||||
}).then(result => {
|
||||
browser.test.assertEq(42, result, "Expected callback result");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
file: "script2.js",
|
||||
}, result => {
|
||||
browser.test.assertEq(27, result, "Expected callback result");
|
||||
browser.test.sendMessage("got callback", result);
|
||||
});
|
||||
browser.tabs.executeScript({
|
||||
file: "script.js",
|
||||
code: "42",
|
||||
}).then(result => {
|
||||
browser.test.fail("Expected not to be able to execute a script with both file and code");
|
||||
}, error => {
|
||||
browser.test.assertTrue(/a 'code' or a 'file' property, but not both/.test(error.message),
|
||||
"Got expected error");
|
||||
}),
|
||||
|
||||
browser.runtime.onMessage.addListener(message => {
|
||||
browser.test.assertEq("script ran", message, "Expected runtime message");
|
||||
browser.test.sendMessage("got message", message);
|
||||
browser.tabs.executeScript({
|
||||
file: "script.js",
|
||||
}).then(result => {
|
||||
browser.test.assertEq(undefined, result, "Expected callback result");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
file: "script2.js",
|
||||
}).then(result => {
|
||||
browser.test.assertEq(27, result, "Expected callback result");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "location.href;",
|
||||
allFrames: true,
|
||||
}).then(result => {
|
||||
browser.test.assertTrue(Array.isArray(result), "Result is an array");
|
||||
|
||||
browser.test.assertEq(2, result.length, "Result has correct length");
|
||||
|
||||
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
|
||||
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "location.href;",
|
||||
runAt: "document_end",
|
||||
}).then(result => {
|
||||
browser.test.assertTrue(typeof(result) == "string", "Result is a string");
|
||||
|
||||
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result), "Result is correct");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "window",
|
||||
}).then(result => {
|
||||
browser.test.fail("Expected error when returning non-structured-clonable object");
|
||||
}, error => {
|
||||
browser.test.assertEq("Script returned non-structured-clonable data",
|
||||
error.message, "Got expected error");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "Promise.resolve(window)",
|
||||
}).then(result => {
|
||||
browser.test.fail("Expected error when returning non-structured-clonable object");
|
||||
}, error => {
|
||||
browser.test.assertEq("Script returned non-structured-clonable data",
|
||||
error.message, "Got expected error");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "Promise.resolve(42)",
|
||||
}).then(result => {
|
||||
browser.test.assertEq(42, result, "Got expected promise resolution value as result");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "location.href;",
|
||||
runAt: "document_end",
|
||||
allFrames: true,
|
||||
}).then(result => {
|
||||
browser.test.assertTrue(Array.isArray(result), "Result is an array");
|
||||
|
||||
browser.test.assertEq(2, result.length, "Result has correct length");
|
||||
|
||||
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result[0]), "First result is correct");
|
||||
browser.test.assertEq("http://mochi.test:8888/", result[1], "Second result is correct");
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "location.href;",
|
||||
frameId: frames[0].frameId,
|
||||
}).then(result => {
|
||||
browser.test.assertTrue(/\/file_iframe_document\.html$/.test(result), `Result for frameId[0] is correct: ${result}`);
|
||||
}),
|
||||
|
||||
browser.tabs.executeScript({
|
||||
code: "location.href;",
|
||||
frameId: frames[1].frameId,
|
||||
}).then(result => {
|
||||
browser.test.assertEq("http://mochi.test:8888/", result, "Result for frameId[1] is correct");
|
||||
}),
|
||||
|
||||
new Promise(resolve => {
|
||||
browser.runtime.onMessage.addListener(message => {
|
||||
browser.test.assertEq("script ran", message, "Expected runtime message");
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
]);
|
||||
}).then(() => {
|
||||
browser.test.notifyPass("executeScript");
|
||||
}).catch(e => {
|
||||
browser.test.fail(`Error: ${e} :: ${e.stack}`);
|
||||
browser.test.notifyFail("executeScript");
|
||||
});
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["http://mochi.test/"],
|
||||
"permissions": ["http://mochi.test/", "webNavigation"],
|
||||
},
|
||||
|
||||
background,
|
||||
@ -50,9 +151,7 @@ add_task(function* testExecuteScript() {
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
yield extension.awaitMessage("got result");
|
||||
yield extension.awaitMessage("got callback");
|
||||
yield extension.awaitMessage("got message");
|
||||
yield extension.awaitFinish("executeScript");
|
||||
|
||||
yield extension.unload();
|
||||
|
||||
|
@ -0,0 +1,110 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* These tests ensure that the runAt argument to tabs.executeScript delays
|
||||
* script execution until the document has reached the correct state.
|
||||
*
|
||||
* Since tests of this nature are especially race-prone, it relies on a
|
||||
* server-JS script to delay the completion of our test page's load cycle long
|
||||
* enough for us to attempt to load our scripts in the earlies phase we support.
|
||||
*
|
||||
* And since we can't actually rely on that timing, it retries any attempts that
|
||||
* fail to load as early as expected, but don't load at any illegal time.
|
||||
*/
|
||||
|
||||
add_task(function* testExecuteScript() {
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank", true);
|
||||
|
||||
function background() {
|
||||
let tab;
|
||||
|
||||
const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
|
||||
const URL = BASE + "file_iframe_document.sjs";
|
||||
|
||||
const MAX_TRIES = 10;
|
||||
let tries = 0;
|
||||
|
||||
function again() {
|
||||
if (tries++ == MAX_TRIES) {
|
||||
return Promise.reject(new Error("Max tries exceeded"));
|
||||
}
|
||||
|
||||
let loadingPromise = new Promise(resolve => {
|
||||
browser.tabs.onUpdated.addListener(function listener(tabId, changed, tab_) {
|
||||
if (tabId == tab.id && changed.status == "loading" && tab_.url == URL) {
|
||||
browser.tabs.onUpdated.removeListener(listener);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Test allFrames and frameId.
|
||||
|
||||
return browser.tabs.update({url: URL}).then(() => {
|
||||
return loadingPromise;
|
||||
}).then(() => {
|
||||
return Promise.all([
|
||||
// Send the executeScript requests in the reverse order that we expect
|
||||
// them to execute in, to avoid them passing only because of timing
|
||||
// races.
|
||||
browser.tabs.executeScript({
|
||||
code: "document.readyState",
|
||||
runAt: "document_idle",
|
||||
}),
|
||||
browser.tabs.executeScript({
|
||||
code: "document.readyState",
|
||||
runAt: "document_end",
|
||||
}),
|
||||
browser.tabs.executeScript({
|
||||
code: "document.readyState",
|
||||
runAt: "document_start",
|
||||
}),
|
||||
].reverse());
|
||||
}).then(states => {
|
||||
browser.test.log(`Got states: ${states}`);
|
||||
|
||||
// Make sure that none of our scripts executed earlier than expected,
|
||||
// regardless of retries.
|
||||
browser.test.assertTrue(states[1] == "interactive" || states[1] == "complete",
|
||||
`document_end state is valid: ${states[1]}`);
|
||||
browser.test.assertTrue(states[2] == "complete",
|
||||
`document_idle state is valid: ${states[2]}`);
|
||||
|
||||
// If we have the earliest valid states for each script, we're done.
|
||||
// Otherwise, try again.
|
||||
if (states[0] != "loading" || states[1] != "interactive" || states[2] != "complete") {
|
||||
return again();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
|
||||
tab = tabs[0];
|
||||
|
||||
return again();
|
||||
}).then(() => {
|
||||
browser.test.notifyPass("executeScript-runAt");
|
||||
}).catch(e => {
|
||||
browser.test.fail(`Error: ${e} :: ${e.stack}`);
|
||||
browser.test.notifyFail("executeScript-runAt");
|
||||
});
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["http://mochi.test/", "tabs"],
|
||||
},
|
||||
|
||||
background,
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
yield extension.awaitFinish("executeScript-runAt");
|
||||
|
||||
yield extension.unload();
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
});
|
@ -13,39 +13,20 @@ add_task(function* testExecuteScript() {
|
||||
function background() {
|
||||
let promises = [
|
||||
{
|
||||
background: "rgb(0, 0, 0)",
|
||||
foreground: "rgb(255, 192, 203)",
|
||||
promise: resolve => {
|
||||
browser.tabs.insertCSS({
|
||||
file: "file1.css",
|
||||
code: "* { background: black }",
|
||||
}, result => {
|
||||
browser.test.assertEq(undefined, result, "Expected callback result");
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
background: "rgb(0, 0, 0)",
|
||||
background: "transparent",
|
||||
foreground: "rgb(0, 113, 4)",
|
||||
promise: resolve => {
|
||||
browser.tabs.insertCSS({
|
||||
promise: () => {
|
||||
return browser.tabs.insertCSS({
|
||||
file: "file2.css",
|
||||
}, result => {
|
||||
browser.test.assertEq(undefined, result, "Expected callback result");
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
background: "rgb(42, 42, 42)",
|
||||
foreground: "rgb(0, 113, 4)",
|
||||
promise: resolve => {
|
||||
browser.tabs.insertCSS({
|
||||
promise: () => {
|
||||
return browser.tabs.insertCSS({
|
||||
code: "* { background: rgb(42, 42, 42) }",
|
||||
}, result => {
|
||||
browser.test.assertEq(undefined, result, "Expected callback result");
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
},
|
||||
@ -58,23 +39,29 @@ add_task(function* testExecuteScript() {
|
||||
|
||||
function next() {
|
||||
if (!promises.length) {
|
||||
browser.test.notifyPass("insertCSS");
|
||||
return;
|
||||
}
|
||||
|
||||
let {promise, background, foreground} = promises.shift();
|
||||
new Promise(promise).then(() => {
|
||||
browser.tabs.executeScript({
|
||||
return promise().then(result => {
|
||||
browser.test.assertEq(undefined, result, "Expected callback result");
|
||||
|
||||
return browser.tabs.executeScript({
|
||||
code: `(${checkCSS})()`,
|
||||
}, result => {
|
||||
browser.test.assertEq(background, result[0], "Expected background color");
|
||||
browser.test.assertEq(foreground, result[1], "Expected foreground color");
|
||||
next();
|
||||
});
|
||||
}).then(result => {
|
||||
browser.test.assertEq(background, result[0], "Expected background color");
|
||||
browser.test.assertEq(foreground, result[1], "Expected foreground color");
|
||||
return next();
|
||||
});
|
||||
}
|
||||
|
||||
next();
|
||||
next().then(() => {
|
||||
browser.test.notifyPass("insertCSS");
|
||||
}).catch(e => {
|
||||
browser.test.fail(`Error: ${e} :: ${e.stack}`);
|
||||
browser.test.notifyFailure("insertCSS");
|
||||
});
|
||||
}
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
@ -85,7 +72,6 @@ add_task(function* testExecuteScript() {
|
||||
background,
|
||||
|
||||
files: {
|
||||
"file1.css": "* { color: pink }",
|
||||
"file2.css": "* { color: rgb(0, 113, 4) }",
|
||||
},
|
||||
});
|
||||
|
@ -159,7 +159,7 @@ add_task(function* test_url() {
|
||||
browser.test.assertEq(tabId, tab.id, "Check tab id");
|
||||
browser.test.log("onUpdate: " + JSON.stringify(changeInfo));
|
||||
if ("url" in changeInfo) {
|
||||
browser.test.assertEq("about:preferences", changeInfo.url,
|
||||
browser.test.assertEq("about:blank", changeInfo.url,
|
||||
"Check changeInfo.url");
|
||||
browser.tabs.onUpdated.removeListener(onUpdated);
|
||||
// Remove created tab.
|
||||
@ -168,7 +168,7 @@ add_task(function* test_url() {
|
||||
return;
|
||||
}
|
||||
});
|
||||
browser.tabs.update(tab.id, {url: "about:preferences"});
|
||||
browser.tabs.update(tab.id, {url: "about:blank"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,120 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
function* testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected) {
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"],
|
||||
},
|
||||
|
||||
files: {
|
||||
"tab.html": `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1>tab page</h1>
|
||||
</body>
|
||||
</html>
|
||||
`.trim(),
|
||||
},
|
||||
background: function() {
|
||||
browser.test.sendMessage("ready", browser.runtime.getURL("tab.html"));
|
||||
|
||||
browser.test.onMessage.addListener((msg, tabsUpdateURL, isErrorExpected) => {
|
||||
let onTabsUpdated = (tab) => {
|
||||
if (isErrorExpected) {
|
||||
browser.test.fail(`tabs.update with URL ${tabsUpdateURL} should be rejected`);
|
||||
} else {
|
||||
browser.test.assertTrue(tab, "on success the tab should be defined");
|
||||
}
|
||||
};
|
||||
|
||||
let onTabsUpdateError = (error) => {
|
||||
if (!isErrorExpected) {
|
||||
browser.test.fails(`tabs.update with URL ${tabsUpdateURL} should not be rejected`);
|
||||
} else {
|
||||
browser.test.assertTrue(/^URL not allowed/.test(error.message),
|
||||
"tabs.update should be rejected with the expected error message");
|
||||
}
|
||||
};
|
||||
|
||||
let onTabsUpdateDone = () => browser.test.sendMessage("done");
|
||||
|
||||
browser.tabs.query({lastFocusedWindow: true}, (tabs) => {
|
||||
browser.tabs.update(tabs[1].id, {url: tabsUpdateURL})
|
||||
.then(onTabsUpdated, onTabsUpdateError)
|
||||
.then(onTabsUpdateDone);
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
yield extension.startup();
|
||||
|
||||
let mozExtTabURL = yield extension.awaitMessage("ready");
|
||||
|
||||
if (tabsUpdateURL == "self") {
|
||||
tabsUpdateURL = mozExtTabURL;
|
||||
}
|
||||
|
||||
info(`tab.update URL "${tabsUpdateURL}" on tab with URL "${existentTabURL}"`);
|
||||
|
||||
let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, existentTabURL);
|
||||
|
||||
extension.sendMessage("start", tabsUpdateURL, isErrorExpected);
|
||||
yield extension.awaitMessage("done");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab1);
|
||||
yield extension.unload();
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
info("Start testing tabs.update on javascript URLs");
|
||||
|
||||
let dataURLPage = `data:text/html,
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1>data url page</h1>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
let checkList = [
|
||||
{
|
||||
tabsUpdateURL: "http://example.net",
|
||||
isErrorExpected: false,
|
||||
},
|
||||
{
|
||||
tabsUpdateURL: "self",
|
||||
isErrorExpected: false,
|
||||
},
|
||||
{
|
||||
tabsUpdateURL: "about:addons",
|
||||
isErrorExpected: true,
|
||||
},
|
||||
{
|
||||
tabsUpdateURL: "javascript:console.log('tabs.update execute javascript')",
|
||||
isErrorExpected: true,
|
||||
},
|
||||
{
|
||||
tabsUpdateURL: dataURLPage,
|
||||
isErrorExpected: true,
|
||||
},
|
||||
];
|
||||
|
||||
let testCases = checkList
|
||||
.map((check) => Object.assign({}, check, {existentTabURL: "about:blank"}));
|
||||
|
||||
for (let {existentTabURL, tabsUpdateURL, isErrorExpected} of testCases) {
|
||||
yield* testTabsUpdateURL(existentTabURL, tabsUpdateURL, isErrorExpected);
|
||||
}
|
||||
|
||||
info("done");
|
||||
});
|
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="/"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,40 @@
|
||||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80 ft=javascript: */
|
||||
"use strict";
|
||||
|
||||
// This script slows the load of an HTML document so that we can reliably test
|
||||
// all phases of the load cycle supported by the extension API.
|
||||
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
const DELAY = 1 * 1000; // Delay one second before completing the request.
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
let nsTimer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
|
||||
|
||||
let timer;
|
||||
|
||||
function handleRequest(request, response) {
|
||||
response.processAsync();
|
||||
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
`);
|
||||
|
||||
// Note: We need to store a reference to the timer to prevent it from being
|
||||
// canceled when it's GCed.
|
||||
timer = new nsTimer(() => {
|
||||
response.write(`
|
||||
<iframe src="/"></iframe>
|
||||
</body>
|
||||
</html>`);
|
||||
response.finish();
|
||||
}, DELAY, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
@ -972,7 +972,7 @@ PlacesController.prototype = {
|
||||
PlacesUtils.bhistory.removePages(URIslice, URIslice.length);
|
||||
Services.tm.mainThread.dispatch(() => gen.next(),
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
yield unefined;
|
||||
yield undefined;
|
||||
}
|
||||
}
|
||||
let gen = pagesChunkGenerator(URIs);
|
||||
|
@ -177,14 +177,28 @@ var SessionFileInternal = {
|
||||
},
|
||||
}),
|
||||
|
||||
// `true` once `write` has succeeded at last once.
|
||||
// Used for error-reporting.
|
||||
_hasWriteEverSucceeded: false,
|
||||
// Number of attempted calls to `write`.
|
||||
// Note that we may have _attempts > _successes + _failures,
|
||||
// if attempts never complete.
|
||||
// Used for error reporting.
|
||||
_attempts: 0,
|
||||
|
||||
// Number of successful calls to `write`.
|
||||
// Used for error reporting.
|
||||
_successes: 0,
|
||||
|
||||
// Number of failed calls to `write`.
|
||||
// Used for error reporting.
|
||||
_failures: 0,
|
||||
|
||||
// Resolved once initialization is complete.
|
||||
// The promise never rejects.
|
||||
_deferredInitialized: PromiseUtils.defer(),
|
||||
|
||||
// `true` once we have started initialization, i.e. once something
|
||||
// has been scheduled that will eventually resolve `_deferredInitialized`.
|
||||
_initializationStarted: false,
|
||||
|
||||
// The ID of the latest version of Gecko for which we have an upgrade backup
|
||||
// or |undefined| if no upgrade backup was ever written.
|
||||
get latestUpgradeBackupID() {
|
||||
@ -195,7 +209,10 @@ var SessionFileInternal = {
|
||||
}
|
||||
},
|
||||
|
||||
// Find the correct session file, read it and setup the worker.
|
||||
read: Task.async(function* () {
|
||||
this._initializationStarted = true;
|
||||
|
||||
let result;
|
||||
let noFilesFound = true;
|
||||
// Attempt to load by order of priority from the various backups
|
||||
@ -205,6 +222,7 @@ var SessionFileInternal = {
|
||||
try {
|
||||
let path = this.Paths[key];
|
||||
let startMs = Date.now();
|
||||
|
||||
let source = yield OS.File.read(path, { encoding: "utf-8" });
|
||||
let parsed = JSON.parse(source);
|
||||
|
||||
@ -259,19 +277,39 @@ var SessionFileInternal = {
|
||||
|
||||
result.noFilesFound = noFilesFound;
|
||||
|
||||
// Initialize the worker to let it handle backups and also
|
||||
// Initialize the worker (in the background) to let it handle backups and also
|
||||
// as a workaround for bug 964531.
|
||||
let initialized = SessionWorker.post("init", [result.origin, this.Paths, {
|
||||
let promiseInitialized = SessionWorker.post("init", [result.origin, this.Paths, {
|
||||
maxUpgradeBackups: Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3),
|
||||
maxSerializeBack: Preferences.get(PREF_MAX_SERIALIZE_BACK, 10),
|
||||
maxSerializeForward: Preferences.get(PREF_MAX_SERIALIZE_FWD, -1)
|
||||
}]);
|
||||
|
||||
initialized.catch(Promise.reject).then(() => this._deferredInitialized.resolve());
|
||||
promiseInitialized.catch(err => {
|
||||
// Ensure that we report errors but that they do not stop us.
|
||||
Promise.reject(err);
|
||||
}).then(() => this._deferredInitialized.resolve());
|
||||
|
||||
return result;
|
||||
}),
|
||||
|
||||
// Post a message to the worker, making sure that it has been initialized
|
||||
// first.
|
||||
_postToWorker: Task.async(function*(...args) {
|
||||
if (!this._initializationStarted) {
|
||||
// Initializing the worker is somewhat complex, as proper handling of
|
||||
// backups requires us to first read and check the session. Consequently,
|
||||
// the only way to initialize the worker is to first call `this.read()`.
|
||||
|
||||
// The call to `this.read()` causes background initialization of the worker.
|
||||
// Initialization will be complete once `this._deferredInitialized.promise`
|
||||
// resolves.
|
||||
this.read();
|
||||
}
|
||||
yield this._deferredInitialized.promise;
|
||||
return SessionWorker.post(...args)
|
||||
}),
|
||||
|
||||
write: function (aData) {
|
||||
if (RunState.isClosed) {
|
||||
return Promise.reject(new Error("SessionFile is closed"));
|
||||
@ -288,14 +326,15 @@ var SessionFileInternal = {
|
||||
let performShutdownCleanup = isFinalWrite &&
|
||||
!sessionStartup.isAutomaticRestoreEnabled();
|
||||
|
||||
this._attempts++;
|
||||
let options = {isFinalWrite, performShutdownCleanup};
|
||||
let promise = this._deferredInitialized.promise.then(() => SessionWorker.post("write", [aData, options]));
|
||||
let promise = this._postToWorker("write", [aData, options]);
|
||||
|
||||
// Wait until the write is done.
|
||||
promise = promise.then(msg => {
|
||||
// Record how long the write took.
|
||||
this._recordTelemetry(msg.telemetry);
|
||||
this._hasWriteEverSucceeded = true;
|
||||
this._successes++;
|
||||
if (msg.result.upgradeBackup) {
|
||||
// We have just completed a backup-on-upgrade, store the information
|
||||
// in preferences.
|
||||
@ -305,6 +344,7 @@ var SessionFileInternal = {
|
||||
}, err => {
|
||||
// Catch and report any errors.
|
||||
console.error("Could not write session state file ", err, err.stack);
|
||||
this._failures++;
|
||||
// By not doing anything special here we ensure that |promise| cannot
|
||||
// be rejected anymore. The shutdown/cleanup code at the end of the
|
||||
// function will thus always be executed.
|
||||
@ -318,7 +358,9 @@ var SessionFileInternal = {
|
||||
{
|
||||
fetchState: () => ({
|
||||
options,
|
||||
hasEverSucceeded: this._hasWriteEverSucceeded
|
||||
attempts: this._attempts,
|
||||
successes: this._successes,
|
||||
failures: this._failures,
|
||||
})
|
||||
});
|
||||
|
||||
@ -336,7 +378,7 @@ var SessionFileInternal = {
|
||||
},
|
||||
|
||||
wipe: function () {
|
||||
return this._deferredInitialized.promise.then(() => SessionWorker.post("wipe"));
|
||||
return this._postToWorker("wipe");
|
||||
},
|
||||
|
||||
_recordTelemetry: function(telemetry) {
|
||||
|
@ -151,8 +151,10 @@ var SessionStorageInternal = {
|
||||
try {
|
||||
let storageManager = aDocShell.QueryInterface(Ci.nsIDOMStorageManager);
|
||||
storage = storageManager.getStorage(window, aPrincipal);
|
||||
storage.length; // XXX: Bug 1232955 - storage.length can throw, catch that failure
|
||||
} catch (e) {
|
||||
// sessionStorage might throw if it's turned off, see bug 458954
|
||||
storage = null;
|
||||
}
|
||||
|
||||
if (storage && storage.length) {
|
||||
|
@ -52,6 +52,7 @@ support-files =
|
||||
restore_redirect_http.html^headers^
|
||||
restore_redirect_js.html
|
||||
restore_redirect_target.html
|
||||
browser_1234021_page.html
|
||||
|
||||
#NB: the following are disabled
|
||||
# browser_464620_a.html
|
||||
@ -220,3 +221,4 @@ run-if = e10s
|
||||
[browser_async_window_flushing.js]
|
||||
[browser_forget_async_closings.js]
|
||||
[browser_sessionStoreContainer.js]
|
||||
[browser_1234021.js]
|
||||
|
18
browser/components/sessionstore/test/browser_1234021.js
Normal file
18
browser/components/sessionstore/test/browser_1234021.js
Normal file
@ -0,0 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
const PREF = 'network.cookie.cookieBehavior';
|
||||
const PAGE_URL = 'http://mochi.test:8888/browser/' +
|
||||
'browser/components/sessionstore/test/browser_1234021_page.html';
|
||||
const BEHAVIOR_REJECT = 2;
|
||||
|
||||
add_task(function* test() {
|
||||
yield pushPrefs([PREF, BEHAVIOR_REJECT]);
|
||||
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser: gBrowser,
|
||||
url: PAGE_URL
|
||||
}, function* handler(aBrowser) {
|
||||
yield TabStateFlusher.flush(aBrowser);
|
||||
ok(true, "Flush didn't time out");
|
||||
});
|
||||
});
|
@ -0,0 +1,6 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<script>
|
||||
sessionStorage
|
||||
</script>
|
||||
</html>
|
@ -15,18 +15,21 @@ distribution.test.bool.false=false
|
||||
|
||||
[LocalizablePreferences]
|
||||
distribution.test.locale="%LOCALE%"
|
||||
distribution.test.reset="Set"
|
||||
distribution.test.locale.set="First Set"
|
||||
distribution.test.language.set="First Set"
|
||||
distribution.test.language.reset="Preference Set"
|
||||
distribution.test.locale.reset="Preference Set"
|
||||
distribution.test.locale.set="Preference Set"
|
||||
distribution.test.language.set="Preference Set"
|
||||
|
||||
[LocalizablePreferences-en]
|
||||
distribution.test.language.en="en"
|
||||
distribution.test.language.set="Second Set"
|
||||
distribution.test.language.reset=
|
||||
distribution.test.language.set="Language Set"
|
||||
distribution.test.locale.set="Language Set"
|
||||
|
||||
[LocalizablePreferences-en-US]
|
||||
distribution.test.locale.en-US="en-US"
|
||||
distribution.test.reset=
|
||||
distribution.test.locale.set="Second Set"
|
||||
distribution.test.locale.reset=
|
||||
distribution.test.locale.set="Locale Set"
|
||||
|
||||
[LocalizablePreferences-de]
|
||||
distribution.test.locale.de="de"
|
||||
|
@ -71,11 +71,14 @@ add_task(function* () {
|
||||
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.en", Ci.nsIPrefLocalizedString).data, "en");
|
||||
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.en-US", Ci.nsIPrefLocalizedString).data, "en-US");
|
||||
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.locale.de", Ci.nsIPrefLocalizedString));
|
||||
// This value was never set because of the empty language specific pref
|
||||
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.language.reset", Ci.nsIPrefLocalizedString));
|
||||
// This value was never set because of the empty locale specific pref
|
||||
// This testcase currently fails - the value is set to "undefined" - it should not be set at all (throw)
|
||||
// Assert.throws(() => Services.prefs.getComplexValue("distribution.test.reset", Ci.nsIPrefLocalizedString));
|
||||
// This value was overriden by a locale specific setting
|
||||
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Second Set");
|
||||
// This value was overriden by a language specific setting
|
||||
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Second Set");
|
||||
Assert.throws(() => Services.prefs.getComplexValue("distribution.test.locale.reset", Ci.nsIPrefLocalizedString));
|
||||
// This value was overridden by a locale specific setting
|
||||
Assert.equal(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Locale Set");
|
||||
// This value was overridden by a language specific setting
|
||||
Assert.equal(Services.prefs.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Language Set");
|
||||
// Language should not override locale
|
||||
Assert.notEqual(Services.prefs.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Language Set");
|
||||
});
|
||||
|
@ -1,3 +1,3 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 1.4.83
|
||||
Current extension version is: 1.4.95
|
||||
|
@ -288,7 +288,7 @@ ChromeActions.prototype = {
|
||||
try {
|
||||
// contentDisposition/contentDispositionFilename is readonly before FF18
|
||||
channel.contentDisposition = Ci.nsIChannel.DISPOSITION_ATTACHMENT;
|
||||
if (self.contentDispositionFilename) {
|
||||
if (self.contentDispositionFilename && !data.isAttachment) {
|
||||
channel.contentDispositionFilename = self.contentDispositionFilename;
|
||||
} else {
|
||||
channel.contentDispositionFilename = filename;
|
||||
|
@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdf = {}));
|
||||
// Use strict in our context only - users might not want it
|
||||
'use strict';
|
||||
|
||||
var pdfjsVersion = '1.4.83';
|
||||
var pdfjsBuild = '0629fd0';
|
||||
var pdfjsVersion = '1.4.95';
|
||||
var pdfjsBuild = '2b813c0';
|
||||
|
||||
var pdfjsFilePath =
|
||||
typeof document !== 'undefined' && document.currentScript ?
|
||||
@ -407,6 +407,17 @@ var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
|
||||
font: 'font'
|
||||
};
|
||||
|
||||
// Gets the file name from a given URL.
|
||||
function getFilenameFromUrl(url) {
|
||||
var anchor = url.indexOf('#');
|
||||
var query = url.indexOf('?');
|
||||
var end = Math.min(
|
||||
anchor > 0 ? anchor : url.length,
|
||||
query > 0 ? query : url.length);
|
||||
return url.substring(url.lastIndexOf('/', end) + 1, end);
|
||||
}
|
||||
PDFJS.getFilenameFromUrl = getFilenameFromUrl;
|
||||
|
||||
// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
|
||||
// absolute URL, it will be returned as is.
|
||||
function combineUrl(baseUrl, url) {
|
||||
@ -1537,6 +1548,7 @@ exports.combineUrl = combineUrl;
|
||||
exports.createPromiseCapability = createPromiseCapability;
|
||||
exports.deprecated = deprecated;
|
||||
exports.error = error;
|
||||
exports.getFilenameFromUrl = getFilenameFromUrl;
|
||||
exports.getLookupTableFactory = getLookupTableFactory;
|
||||
exports.info = info;
|
||||
exports.isArray = isArray;
|
||||
@ -1577,6 +1589,7 @@ var AnnotationBorderStyleType = sharedUtil.AnnotationBorderStyleType;
|
||||
var AnnotationType = sharedUtil.AnnotationType;
|
||||
var Util = sharedUtil.Util;
|
||||
var addLinkAttributes = sharedUtil.addLinkAttributes;
|
||||
var getFilenameFromUrl = sharedUtil.getFilenameFromUrl;
|
||||
var warn = sharedUtil.warn;
|
||||
var CustomStyle = displayDOMUtils.CustomStyle;
|
||||
|
||||
@ -1587,6 +1600,7 @@ var CustomStyle = displayDOMUtils.CustomStyle;
|
||||
* @property {PDFPage} page
|
||||
* @property {PageViewport} viewport
|
||||
* @property {IPDFLinkService} linkService
|
||||
* @property {DownloadManager} downloadManager
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -1628,6 +1642,9 @@ AnnotationElementFactory.prototype =
|
||||
case AnnotationType.STRIKEOUT:
|
||||
return new StrikeOutAnnotationElement(parameters);
|
||||
|
||||
case AnnotationType.FILEATTACHMENT:
|
||||
return new FileAttachmentAnnotationElement(parameters);
|
||||
|
||||
default:
|
||||
return new AnnotationElement(parameters);
|
||||
}
|
||||
@ -1646,6 +1663,7 @@ var AnnotationElement = (function AnnotationElementClosure() {
|
||||
this.page = parameters.page;
|
||||
this.viewport = parameters.viewport;
|
||||
this.linkService = parameters.linkService;
|
||||
this.downloadManager = parameters.downloadManager;
|
||||
|
||||
if (isRenderable) {
|
||||
this.container = this._createContainer();
|
||||
@ -1744,6 +1762,43 @@ var AnnotationElement = (function AnnotationElementClosure() {
|
||||
return container;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a popup for the annotation's HTML element. This is used for
|
||||
* annotations that do not have a Popup entry in the dictionary, but
|
||||
* are of a type that works with popups (such as Highlight annotations).
|
||||
*
|
||||
* @private
|
||||
* @param {HTMLSectionElement} container
|
||||
* @param {HTMLDivElement|HTMLImageElement|null} trigger
|
||||
* @param {Object} data
|
||||
* @memberof AnnotationElement
|
||||
*/
|
||||
_createPopup:
|
||||
function AnnotationElement_createPopup(container, trigger, data) {
|
||||
// If no trigger element is specified, create it.
|
||||
if (!trigger) {
|
||||
trigger = document.createElement('div');
|
||||
trigger.style.height = container.style.height;
|
||||
trigger.style.width = container.style.width;
|
||||
container.appendChild(trigger);
|
||||
}
|
||||
|
||||
var popupElement = new PopupElement({
|
||||
container: container,
|
||||
trigger: trigger,
|
||||
color: data.color,
|
||||
title: data.title,
|
||||
contents: data.contents,
|
||||
hideWrapper: true
|
||||
});
|
||||
var popup = popupElement.render();
|
||||
|
||||
// Position the popup next to the annotation's container.
|
||||
popup.style.left = container.style.width;
|
||||
|
||||
container.appendChild(popup);
|
||||
},
|
||||
|
||||
/**
|
||||
* Render the annotation's HTML element in the empty container.
|
||||
*
|
||||
@ -1872,20 +1927,7 @@ var TextAnnotationElement = (function TextAnnotationElementClosure() {
|
||||
image.dataset.l10nArgs = JSON.stringify({type: this.data.name});
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
var popupElement = new PopupElement({
|
||||
container: this.container,
|
||||
trigger: image,
|
||||
color: this.data.color,
|
||||
title: this.data.title,
|
||||
contents: this.data.contents,
|
||||
hideWrapper: true
|
||||
});
|
||||
var popup = popupElement.render();
|
||||
|
||||
// Position the popup next to the Text annotation's container.
|
||||
popup.style.left = image.style.width;
|
||||
|
||||
this.container.appendChild(popup);
|
||||
this._createPopup(this.container, image, this.data);
|
||||
}
|
||||
|
||||
this.container.appendChild(image);
|
||||
@ -2162,7 +2204,9 @@ var PopupElement = (function PopupElementClosure() {
|
||||
var HighlightAnnotationElement = (
|
||||
function HighlightAnnotationElementClosure() {
|
||||
function HighlightAnnotationElement(parameters) {
|
||||
AnnotationElement.call(this, parameters, true);
|
||||
var isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
AnnotationElement.call(this, parameters, isRenderable);
|
||||
}
|
||||
|
||||
Util.inherit(HighlightAnnotationElement, AnnotationElement, {
|
||||
@ -2175,6 +2219,11 @@ var HighlightAnnotationElement = (
|
||||
*/
|
||||
render: function HighlightAnnotationElement_render() {
|
||||
this.container.className = 'highlightAnnotation';
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
}
|
||||
|
||||
return this.container;
|
||||
}
|
||||
});
|
||||
@ -2189,7 +2238,9 @@ var HighlightAnnotationElement = (
|
||||
var UnderlineAnnotationElement = (
|
||||
function UnderlineAnnotationElementClosure() {
|
||||
function UnderlineAnnotationElement(parameters) {
|
||||
AnnotationElement.call(this, parameters, true);
|
||||
var isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
AnnotationElement.call(this, parameters, isRenderable);
|
||||
}
|
||||
|
||||
Util.inherit(UnderlineAnnotationElement, AnnotationElement, {
|
||||
@ -2202,6 +2253,11 @@ var UnderlineAnnotationElement = (
|
||||
*/
|
||||
render: function UnderlineAnnotationElement_render() {
|
||||
this.container.className = 'underlineAnnotation';
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
}
|
||||
|
||||
return this.container;
|
||||
}
|
||||
});
|
||||
@ -2215,7 +2271,9 @@ var UnderlineAnnotationElement = (
|
||||
*/
|
||||
var SquigglyAnnotationElement = (function SquigglyAnnotationElementClosure() {
|
||||
function SquigglyAnnotationElement(parameters) {
|
||||
AnnotationElement.call(this, parameters, true);
|
||||
var isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
AnnotationElement.call(this, parameters, isRenderable);
|
||||
}
|
||||
|
||||
Util.inherit(SquigglyAnnotationElement, AnnotationElement, {
|
||||
@ -2228,6 +2286,11 @@ var SquigglyAnnotationElement = (function SquigglyAnnotationElementClosure() {
|
||||
*/
|
||||
render: function SquigglyAnnotationElement_render() {
|
||||
this.container.className = 'squigglyAnnotation';
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
}
|
||||
|
||||
return this.container;
|
||||
}
|
||||
});
|
||||
@ -2242,7 +2305,9 @@ var SquigglyAnnotationElement = (function SquigglyAnnotationElementClosure() {
|
||||
var StrikeOutAnnotationElement = (
|
||||
function StrikeOutAnnotationElementClosure() {
|
||||
function StrikeOutAnnotationElement(parameters) {
|
||||
AnnotationElement.call(this, parameters, true);
|
||||
var isRenderable = !!(parameters.data.hasPopup ||
|
||||
parameters.data.title || parameters.data.contents);
|
||||
AnnotationElement.call(this, parameters, isRenderable);
|
||||
}
|
||||
|
||||
Util.inherit(StrikeOutAnnotationElement, AnnotationElement, {
|
||||
@ -2255,6 +2320,11 @@ var StrikeOutAnnotationElement = (
|
||||
*/
|
||||
render: function StrikeOutAnnotationElement_render() {
|
||||
this.container.className = 'strikeoutAnnotation';
|
||||
|
||||
if (!this.data.hasPopup) {
|
||||
this._createPopup(this.container, null, this.data);
|
||||
}
|
||||
|
||||
return this.container;
|
||||
}
|
||||
});
|
||||
@ -2262,6 +2332,62 @@ var StrikeOutAnnotationElement = (
|
||||
return StrikeOutAnnotationElement;
|
||||
})();
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @alias FileAttachmentAnnotationElement
|
||||
*/
|
||||
var FileAttachmentAnnotationElement = (
|
||||
function FileAttachmentAnnotationElementClosure() {
|
||||
function FileAttachmentAnnotationElement(parameters) {
|
||||
AnnotationElement.call(this, parameters, true);
|
||||
|
||||
this.filename = getFilenameFromUrl(parameters.data.file.filename);
|
||||
this.content = parameters.data.file.content;
|
||||
}
|
||||
|
||||
Util.inherit(FileAttachmentAnnotationElement, AnnotationElement, {
|
||||
/**
|
||||
* Render the file attachment annotation's HTML element in the empty
|
||||
* container.
|
||||
*
|
||||
* @public
|
||||
* @memberof FileAttachmentAnnotationElement
|
||||
* @returns {HTMLSectionElement}
|
||||
*/
|
||||
render: function FileAttachmentAnnotationElement_render() {
|
||||
this.container.className = 'fileAttachmentAnnotation';
|
||||
|
||||
var trigger = document.createElement('div');
|
||||
trigger.style.height = this.container.style.height;
|
||||
trigger.style.width = this.container.style.width;
|
||||
trigger.addEventListener('dblclick', this._download.bind(this));
|
||||
|
||||
if (!this.data.hasPopup && (this.data.title || this.data.contents)) {
|
||||
this._createPopup(this.container, trigger, this.data);
|
||||
}
|
||||
|
||||
this.container.appendChild(trigger);
|
||||
return this.container;
|
||||
},
|
||||
|
||||
/**
|
||||
* Download the file attachment associated with this annotation.
|
||||
*
|
||||
* @private
|
||||
* @memberof FileAttachmentAnnotationElement
|
||||
*/
|
||||
_download: function FileAttachmentAnnotationElement_download() {
|
||||
if (!this.downloadManager) {
|
||||
warn('Download cannot be started due to unavailable download manager');
|
||||
return;
|
||||
}
|
||||
this.downloadManager.downloadData(this.content, this.filename, '');
|
||||
}
|
||||
});
|
||||
|
||||
return FileAttachmentAnnotationElement;
|
||||
})();
|
||||
|
||||
/**
|
||||
* @typedef {Object} AnnotationLayerParameters
|
||||
* @property {PageViewport} viewport
|
||||
@ -2298,7 +2424,8 @@ var AnnotationLayer = (function AnnotationLayerClosure() {
|
||||
layer: parameters.div,
|
||||
page: parameters.page,
|
||||
viewport: parameters.viewport,
|
||||
linkService: parameters.linkService
|
||||
linkService: parameters.linkService,
|
||||
downloadManager: parameters.downloadManager
|
||||
};
|
||||
var element = annotationElementFactory.create(properties);
|
||||
if (element.isRenderable) {
|
||||
|
@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdfWorker = {}));
|
||||
// Use strict in our context only - users might not want it
|
||||
'use strict';
|
||||
|
||||
var pdfjsVersion = '1.4.83';
|
||||
var pdfjsBuild = '0629fd0';
|
||||
var pdfjsVersion = '1.4.95';
|
||||
var pdfjsBuild = '2b813c0';
|
||||
|
||||
var pdfjsFilePath =
|
||||
typeof document !== 'undefined' && document.currentScript ?
|
||||
@ -2366,6 +2366,17 @@ var UNSUPPORTED_FEATURES = PDFJS.UNSUPPORTED_FEATURES = {
|
||||
font: 'font'
|
||||
};
|
||||
|
||||
// Gets the file name from a given URL.
|
||||
function getFilenameFromUrl(url) {
|
||||
var anchor = url.indexOf('#');
|
||||
var query = url.indexOf('?');
|
||||
var end = Math.min(
|
||||
anchor > 0 ? anchor : url.length,
|
||||
query > 0 ? query : url.length);
|
||||
return url.substring(url.lastIndexOf('/', end) + 1, end);
|
||||
}
|
||||
PDFJS.getFilenameFromUrl = getFilenameFromUrl;
|
||||
|
||||
// Combines two URLs. The baseUrl shall be absolute URL. If the url is an
|
||||
// absolute URL, it will be returned as is.
|
||||
function combineUrl(baseUrl, url) {
|
||||
@ -3496,6 +3507,7 @@ exports.combineUrl = combineUrl;
|
||||
exports.createPromiseCapability = createPromiseCapability;
|
||||
exports.deprecated = deprecated;
|
||||
exports.error = error;
|
||||
exports.getFilenameFromUrl = getFilenameFromUrl;
|
||||
exports.getLookupTableFactory = getLookupTableFactory;
|
||||
exports.info = info;
|
||||
exports.isArray = isArray;
|
||||
@ -34982,6 +34994,7 @@ var ObjectLoader = (function() {
|
||||
exports.Catalog = Catalog;
|
||||
exports.ObjectLoader = ObjectLoader;
|
||||
exports.XRef = XRef;
|
||||
exports.FileSpec = FileSpec;
|
||||
}));
|
||||
|
||||
|
||||
@ -38792,6 +38805,7 @@ var isName = corePrimitives.isName;
|
||||
var Stream = coreStream.Stream;
|
||||
var ColorSpace = coreColorSpace.ColorSpace;
|
||||
var ObjectLoader = coreObj.ObjectLoader;
|
||||
var FileSpec = coreObj.FileSpec;
|
||||
var OperatorList = coreEvaluator.OperatorList;
|
||||
|
||||
/**
|
||||
@ -38817,6 +38831,7 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
|
||||
|
||||
// Return the right annotation object based on the subtype and field type.
|
||||
var parameters = {
|
||||
xref: xref,
|
||||
dict: dict,
|
||||
ref: ref
|
||||
};
|
||||
@ -38850,6 +38865,9 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ {
|
||||
case 'StrikeOut':
|
||||
return new StrikeOutAnnotation(parameters);
|
||||
|
||||
case 'FileAttachment':
|
||||
return new FileAttachmentAnnotation(parameters);
|
||||
|
||||
default:
|
||||
warn('Unimplemented annotation type "' + subtype + '", ' +
|
||||
'falling back to base annotation');
|
||||
@ -39083,6 +39101,24 @@ var Annotation = (function AnnotationClosure() {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare the annotation for working with a popup in the display layer.
|
||||
*
|
||||
* @private
|
||||
* @memberof Annotation
|
||||
* @param {Dict} dict - The annotation's data dictionary
|
||||
*/
|
||||
_preparePopup: function Annotation_preparePopup(dict) {
|
||||
if (!dict.has('C')) {
|
||||
// Fall back to the default background color.
|
||||
this.data.color = null;
|
||||
}
|
||||
|
||||
this.data.hasPopup = dict.has('Popup');
|
||||
this.data.title = stringToPDFString(dict.get('T') || '');
|
||||
this.data.contents = stringToPDFString(dict.get('Contents') || '');
|
||||
},
|
||||
|
||||
loadResources: function Annotation_loadResources(keys) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
this.appearance.dict.getAsync('Resources').then(function (resources) {
|
||||
@ -39400,27 +39436,15 @@ var TextAnnotation = (function TextAnnotationClosure() {
|
||||
|
||||
this.data.annotationType = AnnotationType.TEXT;
|
||||
|
||||
var dict = parameters.dict;
|
||||
if (this.data.hasAppearance) {
|
||||
this.data.name = 'NoIcon';
|
||||
} else {
|
||||
this.data.rect[1] = this.data.rect[3] - DEFAULT_ICON_SIZE;
|
||||
this.data.rect[2] = this.data.rect[0] + DEFAULT_ICON_SIZE;
|
||||
this.data.name = dict.has('Name') ? dict.get('Name').name : 'Note';
|
||||
}
|
||||
|
||||
if (!dict.has('C')) {
|
||||
// Fall back to the default background color.
|
||||
this.data.color = null;
|
||||
}
|
||||
|
||||
this.data.hasPopup = dict.has('Popup');
|
||||
if (!this.data.hasPopup) {
|
||||
// There is no associated Popup annotation, so the Text annotation
|
||||
// must create its own popup.
|
||||
this.data.title = stringToPDFString(dict.get('T') || '');
|
||||
this.data.contents = stringToPDFString(dict.get('Contents') || '');
|
||||
this.data.name = parameters.dict.has('Name') ?
|
||||
parameters.dict.get('Name').name : 'Note';
|
||||
}
|
||||
this._preparePopup(parameters.dict);
|
||||
}
|
||||
|
||||
Util.inherit(TextAnnotation, Annotation, {});
|
||||
@ -39539,6 +39563,7 @@ var HighlightAnnotation = (function HighlightAnnotationClosure() {
|
||||
Annotation.call(this, parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.HIGHLIGHT;
|
||||
this._preparePopup(parameters.dict);
|
||||
|
||||
// PDF viewers completely ignore any border styles.
|
||||
this.data.borderStyle.setWidth(0);
|
||||
@ -39554,6 +39579,7 @@ var UnderlineAnnotation = (function UnderlineAnnotationClosure() {
|
||||
Annotation.call(this, parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.UNDERLINE;
|
||||
this._preparePopup(parameters.dict);
|
||||
|
||||
// PDF viewers completely ignore any border styles.
|
||||
this.data.borderStyle.setWidth(0);
|
||||
@ -39569,6 +39595,7 @@ var SquigglyAnnotation = (function SquigglyAnnotationClosure() {
|
||||
Annotation.call(this, parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.SQUIGGLY;
|
||||
this._preparePopup(parameters.dict);
|
||||
|
||||
// PDF viewers completely ignore any border styles.
|
||||
this.data.borderStyle.setWidth(0);
|
||||
@ -39584,6 +39611,7 @@ var StrikeOutAnnotation = (function StrikeOutAnnotationClosure() {
|
||||
Annotation.call(this, parameters);
|
||||
|
||||
this.data.annotationType = AnnotationType.STRIKEOUT;
|
||||
this._preparePopup(parameters.dict);
|
||||
|
||||
// PDF viewers completely ignore any border styles.
|
||||
this.data.borderStyle.setWidth(0);
|
||||
@ -39594,6 +39622,22 @@ var StrikeOutAnnotation = (function StrikeOutAnnotationClosure() {
|
||||
return StrikeOutAnnotation;
|
||||
})();
|
||||
|
||||
var FileAttachmentAnnotation = (function FileAttachmentAnnotationClosure() {
|
||||
function FileAttachmentAnnotation(parameters) {
|
||||
Annotation.call(this, parameters);
|
||||
|
||||
var file = new FileSpec(parameters.dict.get('FS'), parameters.xref);
|
||||
|
||||
this.data.annotationType = AnnotationType.FILEATTACHMENT;
|
||||
this.data.file = file.serializable;
|
||||
this._preparePopup(parameters.dict);
|
||||
}
|
||||
|
||||
Util.inherit(FileAttachmentAnnotation, Annotation, {});
|
||||
|
||||
return FileAttachmentAnnotation;
|
||||
})();
|
||||
|
||||
exports.Annotation = Annotation;
|
||||
exports.AnnotationBorderStyle = AnnotationBorderStyle;
|
||||
exports.AnnotationFactory = AnnotationFactory;
|
||||
|
@ -132,7 +132,8 @@
|
||||
.annotationLayer .highlightAnnotation,
|
||||
.annotationLayer .underlineAnnotation,
|
||||
.annotationLayer .squigglyAnnotation,
|
||||
.annotationLayer .strikeoutAnnotation {
|
||||
.annotationLayer .strikeoutAnnotation,
|
||||
.annotationLayer .fileAttachmentAnnotation {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -12,15 +12,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/* globals PDFJS, PDFBug, FirefoxCom, Stats, ProgressBar,
|
||||
DownloadManager, getFileName, getPDFFileNameFromURL,
|
||||
PDFHistory, Preferences, SidebarView, ViewHistory, Stats,
|
||||
PDFThumbnailViewer, URL, noContextMenuHandler, SecondaryToolbar,
|
||||
PasswordPrompt, PDFPresentationMode, PDFDocumentProperties, HandTool,
|
||||
Promise, PDFLinkService, PDFOutlineView, PDFAttachmentView,
|
||||
OverlayManager, PDFFindController, PDFFindBar, PDFViewer,
|
||||
PDFRenderingQueue, PresentationModeState, parseQueryString,
|
||||
RenderingStates, UNKNOWN_SCALE, DEFAULT_SCALE_VALUE,
|
||||
/* globals PDFJS, PDFBug, FirefoxCom, Stats, ProgressBar, DownloadManager,
|
||||
getPDFFileNameFromURL, PDFHistory, Preferences, SidebarView,
|
||||
ViewHistory, Stats, PDFThumbnailViewer, URL, noContextMenuHandler,
|
||||
SecondaryToolbar, PasswordPrompt, PDFPresentationMode,
|
||||
PDFDocumentProperties, HandTool, Promise, PDFLinkService,
|
||||
PDFOutlineView, PDFAttachmentView, OverlayManager,
|
||||
PDFFindController, PDFFindBar, PDFViewer, PDFRenderingQueue,
|
||||
PresentationModeState, parseQueryString, RenderingStates,
|
||||
UNKNOWN_SCALE, DEFAULT_SCALE_VALUE,
|
||||
IGNORE_CURRENT_POSITION_ON_ZOOM: true */
|
||||
|
||||
'use strict';
|
||||
@ -52,15 +52,6 @@ var MAX_AUTO_SCALE = 1.25;
|
||||
var SCROLLBAR_PADDING = 40;
|
||||
var VERTICAL_PADDING = 5;
|
||||
|
||||
function getFileName(url) {
|
||||
var anchor = url.indexOf('#');
|
||||
var query = url.indexOf('?');
|
||||
var end = Math.min(
|
||||
anchor > 0 ? anchor : url.length,
|
||||
query > 0 ? query : url.length);
|
||||
return url.substring(url.lastIndexOf('/', end) + 1, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns scale factor for the canvas. It makes sense for the HiDPI displays.
|
||||
* @return {Object} The object with horizontal (sx) and vertical (sy)
|
||||
@ -4299,6 +4290,7 @@ DefaultTextLayerFactory.prototype = {
|
||||
* @property {HTMLDivElement} pageDiv
|
||||
* @property {PDFPage} pdfPage
|
||||
* @property {IPDFLinkService} linkService
|
||||
* @property {DownloadManager} downloadManager
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -4313,6 +4305,7 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
|
||||
this.pageDiv = options.pageDiv;
|
||||
this.pdfPage = options.pdfPage;
|
||||
this.linkService = options.linkService;
|
||||
this.downloadManager = options.downloadManager;
|
||||
|
||||
this.div = null;
|
||||
}
|
||||
@ -4337,7 +4330,8 @@ var AnnotationLayerBuilder = (function AnnotationLayerBuilderClosure() {
|
||||
div: self.div,
|
||||
annotations: annotations,
|
||||
page: self.pdfPage,
|
||||
linkService: self.linkService
|
||||
linkService: self.linkService,
|
||||
downloadManager: self.downloadManager
|
||||
};
|
||||
|
||||
if (self.div) {
|
||||
@ -4401,6 +4395,8 @@ DefaultAnnotationLayerFactory.prototype = {
|
||||
* @property {HTMLDivElement} container - The container for the viewer element.
|
||||
* @property {HTMLDivElement} viewer - (optional) The viewer element.
|
||||
* @property {IPDFLinkService} linkService - The navigation/linking service.
|
||||
* @property {DownloadManager} downloadManager - (optional) The download
|
||||
* manager component.
|
||||
* @property {PDFRenderingQueue} renderingQueue - (optional) The rendering
|
||||
* queue object.
|
||||
* @property {boolean} removePageBorders - (optional) Removes the border shadow
|
||||
@ -4453,6 +4449,7 @@ var PDFViewer = (function pdfViewer() {
|
||||
this.container = options.container;
|
||||
this.viewer = options.viewer || options.container.firstElementChild;
|
||||
this.linkService = options.linkService || new SimpleLinkService();
|
||||
this.downloadManager = options.downloadManager || null;
|
||||
this.removePageBorders = options.removePageBorders || false;
|
||||
|
||||
this.defaultRenderingQueue = !options.renderingQueue;
|
||||
@ -5118,7 +5115,8 @@ var PDFViewer = (function pdfViewer() {
|
||||
return new AnnotationLayerBuilder({
|
||||
pageDiv: pageDiv,
|
||||
pdfPage: pdfPage,
|
||||
linkService: this.linkService
|
||||
linkService: this.linkService,
|
||||
downloadManager: this.downloadManager
|
||||
});
|
||||
},
|
||||
|
||||
@ -5242,7 +5240,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
|
||||
this.linkService = linkService;
|
||||
this.renderingQueue = renderingQueue;
|
||||
|
||||
this.hasImage = false;
|
||||
this.resume = null;
|
||||
this.renderingState = RenderingStates.INITIAL;
|
||||
|
||||
@ -5298,7 +5295,6 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
|
||||
if (this.renderTask) {
|
||||
this.renderTask.cancel();
|
||||
}
|
||||
this.hasImage = false;
|
||||
this.resume = null;
|
||||
this.renderingState = RenderingStates.INITIAL;
|
||||
|
||||
@ -5401,11 +5397,9 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
|
||||
draw: function PDFThumbnailView_draw() {
|
||||
if (this.renderingState !== RenderingStates.INITIAL) {
|
||||
console.error('Must be in new state before drawing');
|
||||
}
|
||||
if (this.hasImage) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
this.hasImage = true;
|
||||
|
||||
this.renderingState = RenderingStates.RUNNING;
|
||||
|
||||
var resolveRenderPromise, rejectRenderPromise;
|
||||
@ -5426,6 +5420,7 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
|
||||
rejectRenderPromise(error);
|
||||
return;
|
||||
}
|
||||
|
||||
self.renderingState = RenderingStates.FINISHED;
|
||||
self._convertCanvasToImage();
|
||||
|
||||
@ -5469,14 +5464,17 @@ var PDFThumbnailView = (function PDFThumbnailViewClosure() {
|
||||
},
|
||||
|
||||
setImage: function PDFThumbnailView_setImage(pageView) {
|
||||
if (this.renderingState !== RenderingStates.INITIAL) {
|
||||
return;
|
||||
}
|
||||
var img = pageView.canvas;
|
||||
if (this.hasImage || !img) {
|
||||
if (!img) {
|
||||
return;
|
||||
}
|
||||
if (!this.pdfPage) {
|
||||
this.setPdfPage(pageView.pdfPage);
|
||||
}
|
||||
this.hasImage = true;
|
||||
|
||||
this.renderingState = RenderingStates.FINISHED;
|
||||
|
||||
var ctx = this._getPageDrawContext(true);
|
||||
@ -5927,7 +5925,7 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() {
|
||||
|
||||
for (var i = 0; i < attachmentsCount; i++) {
|
||||
var item = attachments[names[i]];
|
||||
var filename = getFileName(item.filename);
|
||||
var filename = PDFJS.getFilenameFromUrl(item.filename);
|
||||
var div = document.createElement('div');
|
||||
div.className = 'attachmentsItem';
|
||||
var button = document.createElement('button');
|
||||
@ -5993,7 +5991,8 @@ var PDFViewerApplication = {
|
||||
container: container,
|
||||
viewer: viewer,
|
||||
renderingQueue: pdfRenderingQueue,
|
||||
linkService: pdfLinkService
|
||||
linkService: pdfLinkService,
|
||||
downloadManager: new DownloadManager()
|
||||
});
|
||||
pdfRenderingQueue.setViewer(this.pdfViewer);
|
||||
pdfLinkService.setViewer(this.pdfViewer);
|
||||
@ -6334,7 +6333,7 @@ var PDFViewerApplication = {
|
||||
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
|
||||
this.url = url;
|
||||
try {
|
||||
this.setTitle(decodeURIComponent(getFileName(url)) || url);
|
||||
this.setTitle(decodeURIComponent(PDFJS.getFilenameFromUrl(url)) || url);
|
||||
} catch (e) {
|
||||
// decodeURIComponent may throw URIError,
|
||||
// fall back to using the unprocessed url in that case
|
||||
|
@ -1,7 +1,7 @@
|
||||
@import url("chrome://pocket-shared/skin/pocket.css");
|
||||
|
||||
#nav-bar #pocket-button > .toolbarbutton-icon {
|
||||
padding: 2px 6px;
|
||||
padding: calc(var(--toolbarbutton-vertical-inner-padding)) 6px;
|
||||
}
|
||||
|
||||
:-moz-any(#TabsToolbar, .widget-overflow-list) #pocket-button > .toolbarbutton-icon {
|
||||
|
@ -403,9 +403,9 @@ pointerLock.autoLock.title3=This site will hide the pointer.
|
||||
# it's okay for them to have the same access key
|
||||
safebrowsing.getMeOutOfHereButton.label=Get me out of here!
|
||||
safebrowsing.getMeOutOfHereButton.accessKey=G
|
||||
safebrowsing.reportedWebForgery=Reported Web Forgery!
|
||||
safebrowsing.notAForgeryButton.label=This isn't a web forgery…
|
||||
safebrowsing.notAForgeryButton.accessKey=F
|
||||
safebrowsing.deceptiveSite=Deceptive Site!
|
||||
safebrowsing.notADeceptiveSiteButton.label=This isn't a deceptive site…
|
||||
safebrowsing.notADeceptiveSiteButton.accessKey=D
|
||||
safebrowsing.reportedAttackSite=Reported Attack Site!
|
||||
safebrowsing.notAnAttackButton.label=This isn't an attack site…
|
||||
safebrowsing.notAnAttackButton.accessKey=A
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
<!ENTITY safeb.palm.accept.label "Get me out of here!">
|
||||
<!ENTITY safeb.palm.decline.label "Ignore this warning">
|
||||
<!ENTITY safeb.palm.notforgery.label2 "This isn't a web forgery…">
|
||||
<!-- Localization note (safeb.palm.notdeceptive.label) - Label of the Help menu item. -->
|
||||
<!ENTITY safeb.palm.notdeceptive.label "This isn't a deceptive site…">
|
||||
<!ENTITY safeb.palm.reportPage.label "Why was this page blocked?">
|
||||
<!ENTITY safeb.palm.whyForbidden.label "Why was this page blocked?">
|
||||
|
||||
@ -18,10 +19,10 @@
|
||||
<!ENTITY safeb.blocked.unwantedPage.shortDesc "This web page at <span id='unwanted_sitename'/> has been reported to contain unwanted software and has been blocked based on your security preferences.">
|
||||
<!ENTITY safeb.blocked.unwantedPage.longDesc "<p>Unwanted software pages try to install software that can be deceptive and affect your system in unexpected ways.</p>">
|
||||
|
||||
<!ENTITY safeb.blocked.phishingPage.title "Reported Web Forgery!">
|
||||
<!-- Localization note (safeb.blocked.phishingPage.shortDesc) - Please don't translate the contents of the <span id="phishing_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
|
||||
<!ENTITY safeb.blocked.phishingPage.shortDesc "This web page at <span id='phishing_sitename'/> has been reported as a web forgery and has been blocked based on your security preferences.">
|
||||
<!ENTITY safeb.blocked.phishingPage.longDesc "<p>Web forgeries are designed to trick you into revealing personal or financial information by imitating sources you may trust.</p><p>Entering any information on this web page may result in identity theft or other fraud.</p>">
|
||||
<!ENTITY safeb.blocked.phishingPage.title2 "Deceptive Site!">
|
||||
<!-- Localization note (safeb.blocked.phishingPage.shortDesc2) - Please don't translate the contents of the <span id="phishing_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
|
||||
<!ENTITY safeb.blocked.phishingPage.shortDesc2 "This web page at <span id='phishing_sitename'/> has been reported as a deceptive site and has been blocked based on your security preferences.">
|
||||
<!ENTITY safeb.blocked.phishingPage.longDesc2 "<p>Deceptive sites are designed to trick you into doing something dangerous, like installing software, or revealing your personal information, like passwords, phone numbers or credit cards.</p><p>Entering any information on this web page may result in identity theft or other fraud.</p>">
|
||||
|
||||
<!ENTITY safeb.blocked.forbiddenPage.title2 "Blocked Site">
|
||||
<!-- Localization note (safeb.blocked.forbiddenPage.shortDesc2) - Please don't translate the contents of the <span id="forbidden_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
|
||||
|
@ -2,5 +2,5 @@
|
||||
- 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/. -->
|
||||
|
||||
<!ENTITY reportPhishSiteMenu.title2 "Report Web Forgery…">
|
||||
<!ENTITY reportPhishSiteMenu.accesskey "F">
|
||||
<!ENTITY reportDeceptiveSiteMenu.title "Report deceptive site…">
|
||||
<!ENTITY reportDeceptiveSiteMenu.accesskey "D">
|
||||
|
@ -31,7 +31,7 @@ externalProtocolChkMsg=Remember my choice for all links of this type.
|
||||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
unwantedBlocked=The site at %S has been reported as serving unwanted software and has been blocked based on your security preferences.
|
||||
phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
|
||||
deceptiveBlocked=This web page at %S has been reported as a deceptive site and has been blocked based on your security preferences.
|
||||
forbiddenBlocked=The site at %S has been blocked by your browser configuration.
|
||||
cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
|
||||
corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
|
||||
|
@ -160,27 +160,6 @@ be temporary, and you can try again later.</li>
|
||||
</ul>
|
||||
">
|
||||
|
||||
<!ENTITY malwareBlocked.title "Suspected Attack Site!">
|
||||
<!ENTITY malwareBlocked.longDesc "
|
||||
<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>
|
||||
<p>Website owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p>
|
||||
">
|
||||
|
||||
<!ENTITY unwantedBlocked.title "Suspected Unwanted Software Site!">
|
||||
<!ENTITY unwantedBlocked.longDesc "
|
||||
<p>Unwanted software pages try to install software that can be deceptive and affect your system in unexpected ways.</p>
|
||||
">
|
||||
|
||||
<!ENTITY phishingBlocked.title "Suspected Web Forgery!">
|
||||
<!ENTITY phishingBlocked.longDesc "
|
||||
<p>Entering any personal information on this page may result in identity theft or other fraud.</p>
|
||||
<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
|
||||
">
|
||||
|
||||
<!ENTITY forbiddenBlocked.title "Forbidden Site">
|
||||
<!ENTITY forbiddenBlocked.longDesc "<p>&brandShortName; prevented this page from loading because it is configured to block it.</p>
|
||||
">
|
||||
|
||||
<!ENTITY cspBlocked.title "Blocked by Content Security Policy">
|
||||
<!ENTITY cspBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
# 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/.
|
||||
|
||||
TEST_EXTENSIONS_DIR = $(DEPTH)/_tests/testing/mochitest/extensions
|
||||
GENERATED_DIRS = $(TEST_EXTENSIONS_DIR)
|
||||
XPI_PKGNAME = mozscreenshots@mozilla.org
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - $(XPI_NAME)) | (cd $(TEST_EXTENSIONS_DIR) && tar -xf -)
|
@ -9,7 +9,7 @@
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>mozscreenshots@mozilla.org</em:id>
|
||||
#expand <em:version>__MOZILLA_VERSION_U__</em:version>
|
||||
<em:version>0.3.2</em:version>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
<!-- for running custom screenshot binaries -->
|
||||
|
@ -15,3 +15,7 @@ FINAL_TARGET_PP_FILES += [
|
||||
'bootstrap.js',
|
||||
'install.rdf',
|
||||
]
|
||||
|
||||
TEST_HARNESS_FILES.testing.mochitest.extensions += [
|
||||
'mozscreenshots-signed.xpi',
|
||||
]
|
||||
|
Binary file not shown.
@ -9,13 +9,18 @@ MOZ_ARG_ENABLE_BOOL(clang-plugin,
|
||||
ENABLE_CLANG_PLUGIN=1,
|
||||
ENABLE_CLANG_PLUGIN= )
|
||||
if test -n "$ENABLE_CLANG_PLUGIN"; then
|
||||
if test -z "$CLANG_CC"; then
|
||||
if test -z "${CLANG_CC}${CLANG_CL}"; then
|
||||
AC_MSG_ERROR([Can't use clang plugin without clang.])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for llvm-config])
|
||||
if test -z "$LLVMCONFIG"; then
|
||||
LLVMCONFIG=`$CXX -print-prog-name=llvm-config`
|
||||
if test -n "$CLANG_CL"; then
|
||||
CXX_COMPILER="$(dirname "$CXX")/clang"
|
||||
else
|
||||
CXX_COMPILER="${CXX}"
|
||||
fi
|
||||
LLVMCONFIG=`$CXX_COMPILER -print-prog-name=llvm-config`
|
||||
fi
|
||||
|
||||
if test -z "$LLVMCONFIG"; then
|
||||
@ -36,18 +41,57 @@ if test -n "$ENABLE_CLANG_PLUGIN"; then
|
||||
dnl The clang package we use on OSX is old, and its llvm-config doesn't
|
||||
dnl recognize --system-libs, so ask for that separately. llvm-config's
|
||||
dnl failure here is benign, so we can ignore it if it happens.
|
||||
LLVM_LDFLAGS=`$LLVMCONFIG --system-libs | xargs`
|
||||
LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader option | xargs`"
|
||||
dnl Use tr instead of xargs in order to avoid problems with path separators on Windows.
|
||||
LLVM_LDFLAGS=`$LLVMCONFIG --system-libs | tr '\n' ' '`
|
||||
LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader option | tr '\n' ' '`"
|
||||
|
||||
if test "${HOST_OS_ARCH}" = "Darwin"; then
|
||||
CLANG_LDFLAGS="-lclangFrontend -lclangDriver -lclangSerialization"
|
||||
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangParse -lclangSema -lclangAnalysis"
|
||||
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangEdit -lclangAST -lclangLex"
|
||||
CLANG_LDFLAGS="$CLANG_LDFLAGS -lclangBasic -lclangASTMatchers"
|
||||
elif test "${HOST_OS_ARCH}" = "WINNT"; then
|
||||
CLANG_LDFLAGS="clangFrontend.lib clangDriver.lib clangSerialization.lib"
|
||||
CLANG_LDFLAGS="$CLANG_LDFLAGS clangParse.lib clangSema.lib clangAnalysis.lib"
|
||||
CLANG_LDFLAGS="$CLANG_LDFLAGS clangEdit.lib clangAST.lib clangLex.lib"
|
||||
CLANG_LDFLAGS="$CLANG_LDFLAGS clangBasic.lib clangASTMatchers.lib"
|
||||
else
|
||||
CLANG_LDFLAGS="-lclangASTMatchers"
|
||||
fi
|
||||
|
||||
if test -n "$CLANG_CL"; then
|
||||
dnl The llvm-config coming with clang-cl may give us arguments in the
|
||||
dnl /ARG form, which in msys will be interpreted as a path name. So we
|
||||
dnl need to split the args and convert the leading slashes that we find
|
||||
dnl into a dash.
|
||||
LLVM_REPLACE_CXXFLAGS=''
|
||||
for arg in $LLVM_CXXFLAGS; do
|
||||
dnl The following expression replaces a leading slash with a dash.
|
||||
dnl Also replace any backslashes with forward slash.
|
||||
arg=`echo "$arg"|sed -e 's/^\//-/' -e 's/\\\\/\//g'`
|
||||
LLVM_REPLACE_CXXFLAGS="$LLVM_REPLACE_CXXFLAGS $arg"
|
||||
done
|
||||
LLVM_CXXFLAGS="$LLVM_REPLACE_CXXFLAGS"
|
||||
|
||||
LLVM_REPLACE_LDFLAGS=''
|
||||
for arg in $LLVM_LDFLAGS; do
|
||||
dnl The following expression replaces a leading slash with a dash.
|
||||
dnl Also replace any backslashes with forward slash.
|
||||
arg=`echo "$arg"|sed -e 's/^\//-/' -e 's/\\\\/\//g'`
|
||||
LLVM_REPLACE_LDFLAGS="$LLVM_REPLACE_LDFLAGS $arg"
|
||||
done
|
||||
LLVM_LDFLAGS="$LLVM_REPLACE_LDFLAGS"
|
||||
|
||||
CLANG_REPLACE_LDFLAGS=''
|
||||
for arg in $CLANG_LDFLAGS; do
|
||||
dnl The following expression replaces a leading slash with a dash.
|
||||
dnl Also replace any backslashes with forward slash.
|
||||
arg=`echo "$arg"|sed -e 's/^\//-/' -e 's/\\\\/\//g'`
|
||||
CLANG_REPLACE_LDFLAGS="$CLANG_REPLACE_LDFLAGS $arg"
|
||||
done
|
||||
CLANG_LDFLAGS="$CLANG_REPLACE_LDFLAGS"
|
||||
fi
|
||||
|
||||
dnl Check for the new ASTMatcher API names. Since this happened in the
|
||||
dnl middle of the 3.8 cycle, our CLANG_VERSION_FULL is impossible to use
|
||||
dnl correctly, so we have to detect this at configure time.
|
||||
|
@ -9,10 +9,14 @@ include $(topsrcdir)/config/config.mk
|
||||
|
||||
# In the current moz.build world, we need to override essentially every
|
||||
# variable to limit ourselves to what we need to build the clang plugin.
|
||||
ifeq ($(HOST_OS_ARCH),WINNT)
|
||||
OS_CXXFLAGS := $(LLVM_CXXFLAGS) -GR- -EHsc
|
||||
else
|
||||
OS_CXXFLAGS := $(LLVM_CXXFLAGS) -fno-rtti -fno-exceptions
|
||||
DSO_LDOPTS := -shared
|
||||
endif
|
||||
OS_COMPILE_CXXFLAGS :=
|
||||
OS_LDFLAGS := $(LLVM_LDFLAGS) $(CLANG_LDFLAGS)
|
||||
DSO_LDOPTS := -shared
|
||||
|
||||
ifeq ($(HOST_OS_ARCH)_$(OS_ARCH),Linux_Darwin)
|
||||
# Use the host compiler instead of the target compiler.
|
||||
|
@ -1517,3 +1517,7 @@ public:
|
||||
|
||||
static FrontendPluginRegistry::Add<MozCheckAction> X("moz-check",
|
||||
"check moz action");
|
||||
// Export the registry on Windows.
|
||||
#ifdef LLVM_EXPORT_REGISTRY
|
||||
LLVM_EXPORT_REGISTRY(FrontendPluginRegistry)
|
||||
#endif
|
||||
|
@ -54,16 +54,9 @@ leak:mozilla::plugins::PPluginModuleParent::OnCallReceived
|
||||
leak:sec_asn1e_allocate_item
|
||||
leak:PORT_Strdup_Util
|
||||
|
||||
# Bug 1021302 - Leak of fds allocated in nsSocketTransport::BuildSocket(). m1, m5, dt, oth
|
||||
leak:nsSocketTransport::BuildSocket
|
||||
leak:nsServerSocket::OnSocketReady
|
||||
|
||||
# Bug 1021350 - Small leak under event_base_once. m1, m4, bc3
|
||||
leak:event_base_once
|
||||
|
||||
# Bug 1021854 - nsFileStreamBase::DoOpen() leaking fds. bc1, oth
|
||||
leak:nsLocalFile::OpenNSPRFileDesc
|
||||
|
||||
# Bug 1022010 - Small leak under _render_glyph_outline. bc1
|
||||
leak:_render_glyph_outline
|
||||
|
||||
@ -74,7 +67,7 @@ leak:SECITEM_AllocItem_Util
|
||||
leak:GlobalPrinters::InitializeGlobalPrinters
|
||||
leak:nsPSPrinterList::GetPrinterList
|
||||
|
||||
# Bug 1028456 - More leaks with _PR_Getfd, in nsLocalFile::CopyToNative and do_create. bc1, bc3
|
||||
# Bug 1028456 - Various NSPR fd-related leaks. m1-m5, bc1,bc2,bc5,bc7,dt4,dt5.
|
||||
leak:_PR_Getfd
|
||||
|
||||
# Bug 1028483 - The XML parser sometimes leaks an object. bc3
|
||||
|
@ -495,6 +495,8 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
if (const char *file = scriptFilename.get()) {
|
||||
CopyUTF8toUTF16(nsDependentCString(file), fileName);
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!JS_IsExceptionPending(cx));
|
||||
}
|
||||
csp->LogViolationDetails(nsIContentSecurityPolicy::VIOLATION_TYPE_EVAL,
|
||||
fileName,
|
||||
|
@ -6,7 +6,7 @@
|
||||
# script. Additional scripts may be added by specific subdirectories.
|
||||
|
||||
ifdef ENABLE_CLANG_PLUGIN
|
||||
CLANG_PLUGIN := $(DEPTH)/build/clang-plugin/$(DLL_PREFIX)clang-plugin$(DLL_SUFFIX)
|
||||
CLANG_PLUGIN := $(topobjdir)/build/clang-plugin/$(DLL_PREFIX)clang-plugin$(DLL_SUFFIX)
|
||||
OS_CXXFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
|
||||
OS_CFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
|
||||
endif
|
||||
|
@ -1,4 +1,7 @@
|
||||
{
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"globals": {
|
||||
"Cc": true,
|
||||
"Ci": true,
|
||||
@ -30,6 +33,23 @@
|
||||
"mozilla/reject-importGlobalProperties": 1,
|
||||
"mozilla/var-only-at-top-level": 1,
|
||||
|
||||
// Rules from the React plugin
|
||||
"react/display-name": 1,
|
||||
"react/no-danger": 1,
|
||||
"react/no-did-mount-set-state": 1,
|
||||
"react/no-did-update-set-state": 1,
|
||||
"react/no-direct-mutation-state": 1,
|
||||
"react/no-unknown-property": 1,
|
||||
"react/prefer-es6-class": 1,
|
||||
"react/prop-types": 1,
|
||||
"react/sort-comp": [1, {
|
||||
order: [
|
||||
"propTypes",
|
||||
"everything-else",
|
||||
"render"
|
||||
]
|
||||
}],
|
||||
|
||||
// Disallow using variables outside the blocks they are defined (especially
|
||||
// since only let and const are used, see "no-var").
|
||||
"block-scoped-var": 2,
|
||||
|
@ -8,26 +8,33 @@
|
||||
|
||||
const Services = require("Services");
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { TabMenu } = require("./tab-menu");
|
||||
const { createFactory, createClass, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
loader.lazyRequireGetter(this, "AddonsTab", "./components/addons-tab", true);
|
||||
loader.lazyRequireGetter(this, "WorkersTab", "./components/workers-tab", true);
|
||||
const TabMenu = createFactory(require("./tab-menu"));
|
||||
loader.lazyGetter(this, "AddonsTab",
|
||||
() => createFactory(require("./addons-tab")));
|
||||
loader.lazyGetter(this, "WorkersTab",
|
||||
() => createFactory(require("./workers-tab")));
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
||||
const tabs = [
|
||||
{ id: "addons", name: Strings.GetStringFromName("addons"),
|
||||
icon: "chrome://devtools/skin/images/debugging-addons.svg",
|
||||
component: AddonsTab },
|
||||
{ id: "workers", name: Strings.GetStringFromName("workers"),
|
||||
icon: "chrome://devtools/skin/images/debugging-workers.svg",
|
||||
component: WorkersTab },
|
||||
];
|
||||
const tabs = [{
|
||||
id: "addons",
|
||||
name: Strings.GetStringFromName("addons"),
|
||||
icon: "chrome://devtools/skin/images/debugging-addons.svg",
|
||||
component: AddonsTab
|
||||
}, {
|
||||
id: "workers",
|
||||
name: Strings.GetStringFromName("workers"),
|
||||
icon: "chrome://devtools/skin/images/debugging-workers.svg",
|
||||
component: WorkersTab
|
||||
}];
|
||||
|
||||
const defaultTabId = "addons";
|
||||
|
||||
exports.AboutDebuggingApp = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "AboutDebuggingApp",
|
||||
|
||||
getInitialState() {
|
||||
@ -55,12 +62,11 @@ exports.AboutDebuggingApp = React.createClass({
|
||||
|
||||
let selectedTab = tabs.find(t => t.id == selectedTabId);
|
||||
|
||||
return React.createElement(
|
||||
"div", { className: "app"},
|
||||
React.createElement(TabMenu, { tabs, selectedTabId, selectTab }),
|
||||
React.createElement("div", { className: "main-content" },
|
||||
React.createElement(selectedTab.component, { client }))
|
||||
);
|
||||
return dom.div({ className: "app" },
|
||||
TabMenu({ tabs, selectedTabId, selectTab }),
|
||||
dom.div({ className: "main-content" },
|
||||
selectedTab.component({ client }))
|
||||
);
|
||||
},
|
||||
|
||||
onHashChange() {
|
||||
|
@ -12,7 +12,7 @@ loader.lazyImporter(this, "AddonManager",
|
||||
const { Cc, Ci } = require("chrome");
|
||||
const Services = require("Services");
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { createClass, DOM: dom } = require("devtools/client/shared/vendor/react");
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
@ -20,32 +20,31 @@ const Strings = Services.strings.createBundle(
|
||||
const MORE_INFO_URL = "https://developer.mozilla.org/docs/Tools" +
|
||||
"/about:debugging#Enabling_add-on_debugging";
|
||||
|
||||
exports.AddonsControls = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "AddonsControls",
|
||||
|
||||
render() {
|
||||
let { debugDisabled } = this.props;
|
||||
|
||||
return React.createElement(
|
||||
"div", { className: "addons-controls" }, React.createElement(
|
||||
"div", { className: "addons-options" },
|
||||
React.createElement("input", {
|
||||
return dom.div({ className: "addons-controls" },
|
||||
dom.div({ className: "addons-options" },
|
||||
dom.input({
|
||||
id: "enable-addon-debugging",
|
||||
type: "checkbox",
|
||||
checked: !debugDisabled,
|
||||
onChange: this.onEnableAddonDebuggingChange,
|
||||
}),
|
||||
React.createElement("label", {
|
||||
dom.label({
|
||||
className: "addons-debugging-label",
|
||||
htmlFor: "enable-addon-debugging",
|
||||
title: Strings.GetStringFromName("addonDebugging.tooltip")
|
||||
}, Strings.GetStringFromName("addonDebugging.label")),
|
||||
"(",
|
||||
React.createElement("a", { href: MORE_INFO_URL, target: "_blank" },
|
||||
dom.a({ href: MORE_INFO_URL, target: "_blank" },
|
||||
Strings.GetStringFromName("addonDebugging.moreInfo")),
|
||||
")"
|
||||
),
|
||||
React.createElement("button", {
|
||||
dom.button({
|
||||
id: "load-addon-from-file",
|
||||
onClick: this.loadAddonFromFile,
|
||||
}, Strings.GetStringFromName("loadTemporaryAddon"))
|
||||
|
@ -2,17 +2,16 @@
|
||||
* 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/. */
|
||||
|
||||
/* global React */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
|
||||
const Services = require("Services");
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { AddonsControls } = require("./addons-controls");
|
||||
const { TabHeader } = require("./tab-header");
|
||||
const { TargetList } = require("./target-list");
|
||||
const { createFactory, createClass, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const AddonsControls = createFactory(require("./addons-controls"));
|
||||
const TabHeader = createFactory(require("./tab-header"));
|
||||
const TargetList = createFactory(require("./target-list"));
|
||||
|
||||
const ExtensionIcon = "chrome://mozapps/skin/extensions/extensionGeneric.svg";
|
||||
const Strings = Services.strings.createBundle(
|
||||
@ -21,7 +20,7 @@ const Strings = Services.strings.createBundle(
|
||||
const CHROME_ENABLED_PREF = "devtools.chrome.enabled";
|
||||
const REMOTE_ENABLED_PREF = "devtools.debugger.remote-enabled";
|
||||
|
||||
exports.AddonsTab = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "AddonsTab",
|
||||
|
||||
getInitialState() {
|
||||
@ -56,19 +55,17 @@ exports.AddonsTab = React.createClass({
|
||||
let { debugDisabled, extensions: targets } = this.state;
|
||||
let name = Strings.GetStringFromName("extensions");
|
||||
|
||||
return React.createElement(
|
||||
"div", { id: "tab-addons", className: "tab", role: "tabpanel",
|
||||
"aria-labelledby": "tab-addons-header-name" },
|
||||
React.createElement(TabHeader, {
|
||||
id: "tab-addons-header-name",
|
||||
name: Strings.GetStringFromName("addons")}),
|
||||
React.createElement(AddonsControls, { debugDisabled }),
|
||||
React.createElement(
|
||||
"div", { id: "addons" },
|
||||
React.createElement(TargetList,
|
||||
{ name, targets, client, debugDisabled })
|
||||
)
|
||||
);
|
||||
return dom.div({
|
||||
id: "tab-addons",
|
||||
className: "tab",
|
||||
role: "tabpanel",
|
||||
"aria-labelledby": "tab-addons-header-name" },
|
||||
TabHeader({
|
||||
id: "tab-addons-header-name",
|
||||
name: Strings.GetStringFromName("addons") }),
|
||||
AddonsControls({ debugDisabled }),
|
||||
dom.div({ id: "addons" },
|
||||
TargetList({ name, targets, client, debugDisabled })));
|
||||
},
|
||||
|
||||
updateDebugStatus() {
|
||||
|
@ -4,16 +4,16 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { createClass, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
exports.TabHeader = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "TabHeader",
|
||||
|
||||
render() {
|
||||
let { name, id } = this.props;
|
||||
|
||||
return React.createElement(
|
||||
"div", { className: "header" }, React.createElement(
|
||||
"h1", { id, className: "header-name" }, name));
|
||||
return dom.div({ className: "header" },
|
||||
dom.h1({ id, className: "header-name" }, name));
|
||||
},
|
||||
});
|
||||
|
@ -4,9 +4,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { createClass, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
exports.TabMenuEntry = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "TabMenuEntry",
|
||||
|
||||
render() {
|
||||
@ -15,13 +16,13 @@ exports.TabMenuEntry = React.createClass({
|
||||
// Here .category, .category-icon, .category-name classnames are used to
|
||||
// apply common styles defined.
|
||||
let className = "category" + (selected ? " selected" : "");
|
||||
return React.createElement(
|
||||
"div", { className, onClick: this.onClick,
|
||||
"aria-selected": selected, role: "tab" },
|
||||
React.createElement("img", { className: "category-icon", src: icon,
|
||||
role: "presentation" }),
|
||||
React.createElement("div", { className: "category-name" }, name)
|
||||
);
|
||||
return dom.div({
|
||||
"aria-selected": selected,
|
||||
className,
|
||||
onClick: this.onClick,
|
||||
role: "tab" },
|
||||
dom.img({ className: "category-icon", src: icon, role: "presentation" }),
|
||||
dom.div({ className: "category-name" }, name));
|
||||
},
|
||||
|
||||
onClick() {
|
||||
|
@ -2,25 +2,23 @@
|
||||
* 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/. */
|
||||
|
||||
/* global React */
|
||||
|
||||
"use strict";
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { TabMenuEntry } = require("./tab-menu-entry");
|
||||
const { createClass, createFactory, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const TabMenuEntry = createFactory(require("./tab-menu-entry"));
|
||||
|
||||
exports.TabMenu = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "TabMenu",
|
||||
|
||||
render() {
|
||||
let { tabs, selectedTabId, selectTab } = this.props;
|
||||
let tabLinks = tabs.map(({ id, name, icon }) => {
|
||||
let selected = id == selectedTabId;
|
||||
return React.createElement(TabMenuEntry,
|
||||
{ tabId: id, name, icon, selected, selectTab });
|
||||
return TabMenuEntry({ tabId: id, name, icon, selected, selectTab });
|
||||
});
|
||||
|
||||
// "categories" id used for styling purposes
|
||||
return React.createElement("div", { id: "categories" }, tabLinks);
|
||||
return dom.div({ id: "categories" }, tabLinks);
|
||||
},
|
||||
});
|
||||
|
@ -2,14 +2,13 @@
|
||||
* 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/. */
|
||||
|
||||
/* global React */
|
||||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { Target } = require("./target");
|
||||
const { createClass, createFactory, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const Target = createFactory(require("./target"));
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
@ -18,19 +17,21 @@ const LocaleCompare = (a, b) => {
|
||||
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
||||
};
|
||||
|
||||
exports.TargetList = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "TargetList",
|
||||
|
||||
render() {
|
||||
let { client, debugDisabled } = this.props;
|
||||
let targets = this.props.targets.sort(LocaleCompare).map(target => {
|
||||
return React.createElement(Target, { client, target, debugDisabled });
|
||||
return Target({ client, target, debugDisabled });
|
||||
});
|
||||
|
||||
return (
|
||||
React.createElement("div", { id: this.props.id, className: "targets" },
|
||||
React.createElement("h4", null, this.props.name),
|
||||
targets.length > 0 ? targets :
|
||||
React.createElement("p", null, Strings.GetStringFromName("nothing"))
|
||||
dom.div({ id: this.props.id, className: "targets" },
|
||||
dom.h4(null, this.props.name),
|
||||
targets.length > 0 ?
|
||||
targets :
|
||||
dom.p(null, Strings.GetStringFromName("nothing"))
|
||||
)
|
||||
);
|
||||
},
|
||||
|
@ -17,28 +17,29 @@ loader.lazyImporter(this, "BrowserToolboxProcess",
|
||||
"resource://devtools/client/framework/ToolboxProcess.jsm");
|
||||
|
||||
const Services = require("Services");
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { createClass, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
|
||||
exports.Target = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "Target",
|
||||
|
||||
render() {
|
||||
let { target, debugDisabled } = this.props;
|
||||
let isServiceWorker = (target.type === "serviceworker");
|
||||
let isRunning = (!isServiceWorker || target.workerActor);
|
||||
return React.createElement("div", { className: "target" },
|
||||
React.createElement("img", {
|
||||
return dom.div({ className: "target" },
|
||||
dom.img({
|
||||
className: "target-icon",
|
||||
role: "presentation",
|
||||
src: target.icon }),
|
||||
React.createElement("div", { className: "target-details" },
|
||||
React.createElement("div", { className: "target-name" }, target.name)
|
||||
dom.div({ className: "target-details" },
|
||||
dom.div({ className: "target-name" }, target.name)
|
||||
),
|
||||
(isRunning ?
|
||||
React.createElement("button", {
|
||||
dom.button({
|
||||
className: "debug-button",
|
||||
onClick: this.debug,
|
||||
disabled: debugDisabled,
|
||||
|
@ -8,15 +8,16 @@ const { Ci } = require("chrome");
|
||||
const { Task } = require("resource://gre/modules/Task.jsm");
|
||||
const Services = require("Services");
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { TargetList } = require("./target-list");
|
||||
const { TabHeader } = require("./tab-header");
|
||||
const { createClass, createFactory, DOM: dom } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const TabHeader = createFactory(require("./tab-header"));
|
||||
const TargetList = createFactory(require("./target-list"));
|
||||
|
||||
const Strings = Services.strings.createBundle(
|
||||
"chrome://devtools/locale/aboutdebugging.properties");
|
||||
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
|
||||
|
||||
exports.WorkersTab = React.createClass({
|
||||
module.exports = createClass({
|
||||
displayName: "WorkersTab",
|
||||
|
||||
getInitialState() {
|
||||
@ -48,27 +49,30 @@ exports.WorkersTab = React.createClass({
|
||||
let { client } = this.props;
|
||||
let { workers } = this.state;
|
||||
|
||||
return React.createElement(
|
||||
"div", { id: "tab-workers", className: "tab", role: "tabpanel",
|
||||
"aria-labelledby": "tab-workers-header-name" },
|
||||
React.createElement(TabHeader, {
|
||||
id: "tab-workers-header-name",
|
||||
name: Strings.GetStringFromName("workers")}),
|
||||
React.createElement(
|
||||
"div", { id: "workers", className: "inverted-icons" },
|
||||
React.createElement(TargetList, {
|
||||
id: "service-workers",
|
||||
name: Strings.GetStringFromName("serviceWorkers"),
|
||||
targets: workers.service, client }),
|
||||
React.createElement(TargetList, {
|
||||
id: "shared-workers",
|
||||
name: Strings.GetStringFromName("sharedWorkers"),
|
||||
targets: workers.shared, client }),
|
||||
React.createElement(TargetList, {
|
||||
id: "other-workers",
|
||||
name: Strings.GetStringFromName("otherWorkers"),
|
||||
targets: workers.other, client }))
|
||||
);
|
||||
return dom.div({
|
||||
id: "tab-workers",
|
||||
className: "tab",
|
||||
role: "tabpanel",
|
||||
"aria-labelledby": "tab-workers-header-name" },
|
||||
TabHeader({
|
||||
id: "tab-workers-header-name",
|
||||
name: Strings.GetStringFromName("workers") }),
|
||||
dom.div({ id: "workers", className: "inverted-icons" },
|
||||
TargetList({
|
||||
id: "service-workers",
|
||||
name: Strings.GetStringFromName("serviceWorkers"),
|
||||
targets: workers.service,
|
||||
client }),
|
||||
TargetList({
|
||||
id: "shared-workers",
|
||||
name: Strings.GetStringFromName("sharedWorkers"),
|
||||
targets: workers.shared,
|
||||
client }),
|
||||
TargetList({
|
||||
id: "other-workers",
|
||||
name: Strings.GetStringFromName("otherWorkers"),
|
||||
targets: workers.other,
|
||||
client })));
|
||||
},
|
||||
|
||||
update() {
|
||||
|
@ -3,7 +3,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* eslint-env browser */
|
||||
/* global DebuggerClient, DebuggerServer */
|
||||
|
||||
"use strict";
|
||||
|
||||
@ -22,8 +21,11 @@ const { BrowserLoader } = Components.utils.import(
|
||||
const { require } =
|
||||
BrowserLoader("resource://devtools/client/aboutdebugging/", window);
|
||||
|
||||
const React = require("devtools/client/shared/vendor/react");
|
||||
const { AboutDebuggingApp } = require("./components/aboutdebugging");
|
||||
const {
|
||||
createFactory,
|
||||
render,
|
||||
unmountComponentAtNode } = require("devtools/client/shared/vendor/react");
|
||||
const AboutDebuggingApp = createFactory(require("./components/aboutdebugging"));
|
||||
|
||||
var AboutDebugging = {
|
||||
init() {
|
||||
@ -38,13 +40,13 @@ var AboutDebugging = {
|
||||
let client = this.client;
|
||||
let telemetry = new Telemetry();
|
||||
|
||||
let app = React.createElement(AboutDebuggingApp, { client, telemetry });
|
||||
React.render(app, document.querySelector("#body"));
|
||||
render(AboutDebuggingApp({ client, telemetry }),
|
||||
document.querySelector("#body"));
|
||||
});
|
||||
},
|
||||
|
||||
destroy() {
|
||||
React.unmountComponentAtNode(document.querySelector("#body"));
|
||||
unmountComponentAtNode(document.querySelector("#body"));
|
||||
|
||||
this.client.close();
|
||||
this.client = null;
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://devtools/client/shared/widgets/SideMenuWidget.jsm");
|
||||
Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm");
|
||||
@ -13,6 +12,7 @@ Cu.import("resource://gre/modules/Console.jsm");
|
||||
|
||||
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const promise = require("promise");
|
||||
const Services = require("Services");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const { CallWatcherFront } = require("devtools/server/actors/call-watcher");
|
||||
const { CanvasFront } = require("devtools/server/actors/canvas");
|
||||
|
@ -4,17 +4,11 @@
|
||||
|
||||
var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
|
||||
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
|
||||
// Disable logging for all the tests. Both the debugger server and frontend will
|
||||
// be affected by this pref.
|
||||
var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
var { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
|
||||
var { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||
var { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
|
||||
var Services = require("Services");
|
||||
var promise = require("promise");
|
||||
var { gDevTools } = require("devtools/client/framework/devtools");
|
||||
var { DebuggerClient } = require("devtools/shared/client/main");
|
||||
@ -43,6 +37,11 @@ const WEBGL_DRAW_ARRAYS = EXAMPLE_URL + "doc_webgl-drawArrays.html";
|
||||
const WEBGL_DRAW_ELEMENTS = EXAMPLE_URL + "doc_webgl-drawElements.html";
|
||||
const RAF_BEGIN_URL = EXAMPLE_URL + "doc_raf-begin.html";
|
||||
|
||||
// Disable logging for all the tests. Both the debugger server and frontend will
|
||||
// be affected by this pref.
|
||||
var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
|
||||
Services.prefs.setBoolPref("devtools.debugger.log", false);
|
||||
|
||||
// All tests are asynchronous.
|
||||
waitForExplicitFinish();
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
// Test various GCLI commands
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,gcli-commands";
|
||||
const HUDService = require("devtools/client/webconsole/hudservice");
|
||||
|
||||
function test() {
|
||||
return Task.spawn(spawnTest).then(finish, helpers.handleError);
|
||||
|
@ -93,7 +93,6 @@ const FRAME_TYPE = {
|
||||
PUBLIC_CLIENT_EVAL: 3
|
||||
};
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://devtools/shared/event-emitter.js");
|
||||
Cu.import("resource://devtools/client/shared/widgets/SimpleListWidget.jsm");
|
||||
@ -137,6 +136,7 @@ var services = {
|
||||
WAIT_UNTIL: waitUntilService.NAME
|
||||
};
|
||||
|
||||
var Services = require("Services");
|
||||
var {TargetFactory} = require("devtools/client/framework/target");
|
||||
var {Toolbox} = require("devtools/client/framework/toolbox");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
|
@ -4,7 +4,7 @@
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="debugger.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/content/debugger/debugger.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://devtools/skin/debugger.css" type="text/css"?>
|
||||
<!DOCTYPE window [
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,8 +5,7 @@
|
||||
"use strict";
|
||||
|
||||
const {Cc, Ci} = require("chrome");
|
||||
|
||||
const { Services } = require("resource://gre/modules/Services.jsm");
|
||||
const Services = require("Services");
|
||||
|
||||
loader.lazyGetter(this, "osString", () => Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS);
|
||||
|
||||
|
@ -7,10 +7,9 @@ const {rgbToHsl} = require("devtools/shared/css-color").colorUtils;
|
||||
const Telemetry = require("devtools/client/shared/telemetry");
|
||||
const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js");
|
||||
const promise = require("promise");
|
||||
const Services = require("Services");
|
||||
const {setTimeout, clearTimeout} = Cu.import("resource://gre/modules/Timer.jsm", {});
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
loader.lazyGetter(this, "clipboardHelper", function() {
|
||||
return Cc["@mozilla.org/widget/clipboardhelper;1"]
|
||||
.getService(Ci.nsIClipboardHelper);
|
||||
|
@ -11,7 +11,6 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
|
||||
const DBG_XUL = "chrome://devtools/content/framework/toolbox-process-window.xul";
|
||||
const CHROME_DEBUGGER_PROFILE_NAME = "chrome_debugger_profile";
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
const { require, DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
|
||||
@ -22,6 +21,7 @@ XPCOMUtils.defineLazyGetter(this, "EventEmitter", function () {
|
||||
return require("devtools/shared/event-emitter");
|
||||
});
|
||||
const promise = require("promise");
|
||||
const Services = require("Services");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["BrowserToolboxProcess"];
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
const Services = Cu.import("resource://gre/modules/Services.jsm", {}).Services;
|
||||
const Services = require("Services");
|
||||
const promise = require("promise");
|
||||
|
||||
function l10n(name) {
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
var Cu = Components.utils;
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var Services = require("Services");
|
||||
var {gDevTools} = require("devtools/client/framework/devtools");
|
||||
var {TargetFactory} = require("devtools/client/framework/target");
|
||||
var {Toolbox} = require("devtools/client/framework/toolbox")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user