Merge from mozilla-central.

This commit is contained in:
Jan de Mooij 2013-02-21 15:56:12 +01:00
commit 000ea99aee
467 changed files with 13904 additions and 7883 deletions

View File

@ -15,4 +15,4 @@
#
# Note: The description below will be part of the error message shown to users.
#
Bug 836654 - IndexedDB test failures without clobber
Bug 829832 - BackgroundFileSaver xpcshell failures without clobber

View File

@ -15,12 +15,12 @@
#include "nsIAccessibleEvent.h"
#include "nsIAccessibleRelation.h"
#include "nsWinUtils.h"
#include "ServiceProvider.h"
#include "Relation.h"
#include "Role.h"
#include "RootAccessible.h"
#include "sdnAccessible.h"
#include "States.h"
#include "uiaRawElmProvider.h"
#ifdef A11Y_LOG
#include "Logging.h"
@ -90,7 +90,7 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
*ppv = static_cast<IEnumVARIANT*>(new ChildrenEnumVariant(this));
} else if (IID_IServiceProvider == iid)
*ppv = static_cast<IServiceProvider*>(this);
*ppv = new ServiceProvider(this);
else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
*ppv = static_cast<IAccessible2*>(this);
else if (IID_ISimpleDOMNode == iid) {
@ -127,32 +127,6 @@ AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
A11Y_TRYBLOCK_END
}
////////////////////////////////////////////////////////////////////////////////
// IServiceProvider
STDMETHODIMP
AccessibleWrap::QueryService(REFGUID aGuidService, REFIID aIID,
void** aInstancePtr)
{
if (!aInstancePtr)
return E_INVALIDARG;
*aInstancePtr = NULL;
// UIA IAccessibleEx
if (aGuidService == IID_IAccessibleEx &&
Preferences::GetBool("accessibility.uia.enable")) {
uiaRawElmProvider* accEx = new uiaRawElmProvider(this);
HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
if (FAILED(hr))
delete accEx;
return hr;
}
return nsAccessNodeWrap::QueryService(aGuidService, aIID, aInstancePtr);
}
//-----------------------------------------------------
// IAccessible methods
//-----------------------------------------------------

View File

@ -138,11 +138,6 @@ public: // construction, destruction
// Return the registered OLE class ID of this object's CfDataObj.
CLSID GetClassID() const;
// IServiceProvider
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
REFIID aIID,
void** aInstancePtr);
public: // COM interface IAccessible
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent);

View File

@ -29,6 +29,7 @@ CPPSRCS = \
Compatibility.cpp \
EnumVariant.cpp \
Platform.cpp \
ServiceProvider.cpp \
RootAccessibleWrap.cpp \
TextLeafAccessibleWrap.cpp \
$(NULL)

View File

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "ServiceProvider.h"
#include "ApplicationAccessibleWrap.h"
#include "Compatibility.h"
#include "DocAccessible.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "uiaRawElmProvider.h"
#include "mozilla/Preferences.h"
#include "nsIDocShell.h"
#include "ISimpleDOMNode_i.c"
namespace mozilla {
namespace a11y {
IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider)
IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider)
return mAccessible->QueryInterface(aIID, aInstancePtr);
A11Y_TRYBLOCK_END
}
////////////////////////////////////////////////////////////////////////////////
// IServiceProvider
STDMETHODIMP
ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID,
void** aInstancePtr)
{
if (!aInstancePtr)
return E_INVALIDARG;
*aInstancePtr = NULL;
// UIA IAccessibleEx
if (aGuidService == IID_IAccessibleEx &&
Preferences::GetBool("accessibility.uia.enable")) {
uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible);
HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
if (FAILED(hr))
delete accEx;
return hr;
}
// Provide a special service ID for getting the accessible for the browser tab
// document that contains this accessible object. If this accessible object
// is not inside a browser tab then the service fails with E_NOINTERFACE.
// A use case for this is for screen readers that need to switch context or
// 'virtual buffer' when focus moves from one browser tab area to another.
static const GUID SID_IAccessibleContentDocument =
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
if (aGuidService == SID_IAccessibleContentDocument) {
if (aIID != IID_IAccessible)
return E_NOINTERFACE;
nsCOMPtr<nsIDocShell> docShell =
nsCoreUtils::GetDocShellFor(mAccessible->GetNode());
if (!docShell)
return E_UNEXPECTED;
// Walk up the parent chain without crossing the boundary at which item
// types change, preventing us from walking up out of tab content.
nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
if (!root)
return E_UNEXPECTED;
// If the item type is typeContent, we assume we are in browser tab content.
// Note this includes content such as about:addons, for consistency.
int32_t itemType;
root->GetItemType(&itemType);
if (itemType != nsIDocShellTreeItem::typeContent)
return E_NOINTERFACE;
// Make sure this is a document.
DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
if (!docAcc)
return E_UNEXPECTED;
*aInstancePtr = static_cast<IAccessible*>(docAcc);
(reinterpret_cast<IUnknown*>(*aInstancePtr))->AddRef();
return S_OK;
}
// Can get to IAccessibleApplication from any node via QS
if (aGuidService == IID_IAccessibleApplication ||
(Compatibility::IsJAWS() && aIID == IID_IAccessibleApplication)) {
ApplicationAccessibleWrap* applicationAcc =
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
if (!applicationAcc)
return E_NOINTERFACE;
return applicationAcc->QueryInterface(aIID, aInstancePtr);
}
static const GUID IID_SimpleDOMDeprecated =
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
if (aGuidService == IID_ISimpleDOMNode ||
aGuidService == IID_SimpleDOMDeprecated ||
aGuidService == IID_IAccessible || aGuidService == IID_IAccessible2)
return mAccessible->QueryInterface(aIID, aInstancePtr);
return E_INVALIDARG;
}
} // namespace a11y
} // namespace mozilla

View File

@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_a11y_ServiceProvider_h_
#define mozilla_a11y_ServiceProvider_h_
#include <servprov.h>
#include "AccessibleWrap.h"
namespace mozilla {
namespace a11y {
class ServiceProvider MOZ_FINAL : public IServiceProvider
{
public:
ServiceProvider(AccessibleWrap* aAcc) : mRefCnt(0), mAccessible(aAcc) {}
~ServiceProvider() {}
DECL_IUNKNOWN
// IServiceProvider
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
REFIID aIID,
void** aInstancePtr);
private:
nsRefPtr<AccessibleWrap> mAccessible;
};
}
}
#endif

View File

@ -5,22 +5,9 @@
#include "nsAccessNodeWrap.h"
#include "AccessibleApplication.h"
#include "ApplicationAccessibleWrap.h"
#include "sdnAccessible.h"
#include "Compatibility.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "DocAccessible.h"
#include "nsWinUtils.h"
#include "RootAccessible.h"
#include "Statistics.h"
#include "nsAttrName.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMHTMLElement.h"
#include "nsINameSpaceManager.h"
#include "nsPIDOMWindow.h"
#include "nsIServiceManager.h"
@ -47,101 +34,6 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
{
*ppv = nullptr;
if (IID_IUnknown == iid) {
*ppv = static_cast<IUnknown*>(this);
} else {
return E_NOINTERFACE; //iid not supported.
}
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
return S_OK;
}
STDMETHODIMP
nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
{
*ppv = nullptr;
// Provide a special service ID for getting the accessible for the browser tab
// document that contains this accessible object. If this accessible object
// is not inside a browser tab then the service fails with E_NOINTERFACE.
// A use case for this is for screen readers that need to switch context or
// 'virtual buffer' when focus moves from one browser tab area to another.
static const GUID SID_IAccessibleContentDocument =
{ 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
if (guidService == SID_IAccessibleContentDocument) {
if (iid != IID_IAccessible)
return E_NOINTERFACE;
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent);
if (!docShell)
return E_UNEXPECTED;
// Walk up the parent chain without crossing the boundary at which item
// types change, preventing us from walking up out of tab content.
nsCOMPtr<nsIDocShellTreeItem> root;
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
if (!root)
return E_UNEXPECTED;
// If the item type is typeContent, we assume we are in browser tab content.
// Note this includes content such as about:addons, for consistency.
int32_t itemType;
root->GetItemType(&itemType);
if (itemType != nsIDocShellTreeItem::typeContent)
return E_NOINTERFACE;
// Make sure this is a document.
DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
if (!docAcc)
return E_UNEXPECTED;
*ppv = static_cast<IAccessible*>(docAcc);
(reinterpret_cast<IUnknown*>(*ppv))->AddRef();
return S_OK;
}
// Can get to IAccessibleApplication from any node via QS
if (guidService == IID_IAccessibleApplication ||
(Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
ApplicationAccessibleWrap* applicationAcc =
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
if (!applicationAcc)
return E_NOINTERFACE;
return applicationAcc->QueryInterface(iid, ppv);
}
/**
* To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
* or any IAccessible2 interface on should use IServiceProvider like this:
* -----------------------------------------------------------------------
* ISimpleDOMDocument *pAccDoc = NULL;
* IServiceProvider *pServProv = NULL;
* pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
* if (pServProv) {
* const GUID unused;
* pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
* pServProv->Release();
* }
*/
static const GUID IID_SimpleDOMDeprecated =
{ 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
if (guidService == IID_ISimpleDOMNode ||
guidService == IID_SimpleDOMDeprecated ||
guidService == IID_IAccessible || guidService == IID_IAccessible2)
return QueryInterface(iid, ppv);
return E_INVALIDARG;
}
int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
{
if (aCode == EXCEPTION_ACCESS_VIOLATION) {

View File

@ -53,8 +53,7 @@ namespace a11y {
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
#endif
class nsAccessNodeWrap : public nsAccessNode,
public IServiceProvider
class nsAccessNodeWrap : public nsAccessNode
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -63,15 +62,6 @@ public: // construction, destruction
nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
virtual ~nsAccessNodeWrap();
// IUnknown
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID,
void** aInstancePtr);
// IServiceProvider
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
REFIID aIID,
void** aInstancePtr);
static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,

View File

@ -1,36 +1,36 @@
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(topsrcdir)/config/config.mk
TEST_DIRS += test
libs::
$(PYTHON) $(srcdir)/copy_source.py $(topsrcdir) $(srcdir)/source/lib $(FINAL_TARGET)/modules/commonjs >copy_source.mk
$(MAKE) -f copy_source.mk libs
include $(topsrcdir)/config/rules.mk
TEST_FILES = \
source/app-extension \
source/bin \
source/data \
source/python-lib \
source/test \
source/package.json \
source/mapping.json \
$(NULL)
# Remove this once the test harness uses the APIs built into Firefox
TEST_FILES += source/lib
PKG_STAGE = $(DIST)/test-package-stage
stage-tests-package:: $(TEST_FILES)
$(INSTALL) $^ $(PKG_STAGE)/jetpack
# 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/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(topsrcdir)/config/config.mk
TEST_DIRS += test
libs::
$(PYTHON) $(srcdir)/copy_source.py $(topsrcdir) $(srcdir)/source/lib $(FINAL_TARGET)/modules/commonjs >copy_source.mk
$(MAKE) -f copy_source.mk libs
include $(topsrcdir)/config/rules.mk
TEST_FILES = \
source/app-extension \
source/bin \
source/data \
source/python-lib \
source/test \
source/package.json \
source/mapping.json \
$(NULL)
# Remove this once the test harness uses the APIs built into Firefox
TEST_FILES += source/lib
PKG_STAGE = $(DIST)/test-package-stage
stage-tests-package:: $(TEST_FILES)
$(INSTALL) $^ $(PKG_STAGE)/jetpack

View File

@ -1,46 +1,46 @@
# 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/.
import os
import sys
if len(sys.argv) != 4:
print >> sys.stderr, "Usage: copy_source.py " \
"<topsrcdir> <source directory> <target directory>"
sys.exit(1)
topsrcdir = sys.argv[1]
source_dir = sys.argv[2]
target_dir = sys.argv[3]
print """
DEPTH = ..
topsrcdir = %(topsrcdir)s
srcdir = %(topsrcdir)s/addon-sdk
VPATH = %(topsrcdir)s/addon-sdk
include $(topsrcdir)/config/config.mk
""" % {'topsrcdir': topsrcdir}
real_source = source_dir.replace('/', os.sep)
if not os.path.exists(real_source):
print >> sys.stderr, "Error: Missing source file %s" % real_source
sys.exit(1)
elif not os.path.isdir(real_source):
print >> sys.stderr, "Error: Source %s is not a directory" % real_source
sys.exit(1)
for dirpath, dirnames, filenames in os.walk(real_source):
if not filenames:
continue
dirpath = dirpath.replace(os.sep, '/')
relative = dirpath[len(source_dir):]
varname = "COMMONJS%s" % relative.replace('/', '_')
print "%s_FILES = \\" % varname
for name in filenames:
print " %s/%s \\" % (dirpath, name)
print " $(NULL)"
print "%s_DEST = %s%s" % (varname, target_dir, relative)
print "INSTALL_TARGETS += %s\n" % varname
print "include $(topsrcdir)/config/rules.mk"
# 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/.
import os
import sys
if len(sys.argv) != 4:
print >> sys.stderr, "Usage: copy_source.py " \
"<topsrcdir> <source directory> <target directory>"
sys.exit(1)
topsrcdir = sys.argv[1]
source_dir = sys.argv[2]
target_dir = sys.argv[3]
print """
DEPTH = ..
topsrcdir = %(topsrcdir)s
srcdir = %(topsrcdir)s/addon-sdk
VPATH = %(topsrcdir)s/addon-sdk
include $(topsrcdir)/config/config.mk
""" % {'topsrcdir': topsrcdir}
real_source = source_dir.replace('/', os.sep)
if not os.path.exists(real_source):
print >> sys.stderr, "Error: Missing source file %s" % real_source
sys.exit(1)
elif not os.path.isdir(real_source):
print >> sys.stderr, "Error: Source %s is not a directory" % real_source
sys.exit(1)
for dirpath, dirnames, filenames in os.walk(real_source):
if not filenames:
continue
dirpath = dirpath.replace(os.sep, '/')
relative = dirpath[len(source_dir):]
varname = "COMMONJS%s" % relative.replace('/', '_')
print "%s_FILES = \\" % varname
for name in filenames:
print " %s/%s \\" % (dirpath, name)
print " $(NULL)"
print "%s_DEST = %s%s" % (varname, target_dir, relative)
print "INSTALL_TARGETS += %s\n" % varname
print "include $(topsrcdir)/config/rules.mk"

View File

@ -1,37 +1,37 @@
# 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/.
# Integrates the xpcshell test runner with mach.
import os
import sys
from mozbuild.base import (
MachCommandBase,
MozbuildObject,
)
from mach.decorators import (
CommandArgument,
CommandProvider,
Command,
)
class JetpackRunner(MozbuildObject):
"""Run jetpack tests."""
def run_tests(self, **kwargs):
self._run_make(target='jetpack-tests')
@CommandProvider
class MachCommands(MachCommandBase):
@Command('jetpack-test', help='Runs the jetpack test suite.')
def run_jetpack_test(self, **params):
# We should probably have a utility function to ensure the tree is
# ready to run tests. Until then, we just create the state dir (in
# case the tree wasn't built with mach).
self._ensure_state_subdir_exists('.')
jetpack = self._spawn(JetpackRunner)
jetpack.run_tests(**params)
# 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/.
# Integrates the xpcshell test runner with mach.
import os
import sys
from mozbuild.base import (
MachCommandBase,
MozbuildObject,
)
from mach.decorators import (
CommandArgument,
CommandProvider,
Command,
)
class JetpackRunner(MozbuildObject):
"""Run jetpack tests."""
def run_tests(self, **kwargs):
self._run_make(target='jetpack-tests')
@CommandProvider
class MachCommands(MachCommandBase):
@Command('jetpack-test', help='Runs the jetpack test suite.')
def run_jetpack_test(self, **params):
# We should probably have a utility function to ensure the tree is
# ready to run tests. Until then, we just create the state dir (in
# case the tree wasn't built with mach).
self._ensure_state_subdir_exists('.')
jetpack = self._spawn(JetpackRunner)
jetpack.run_tests(**params)

View File

@ -54,7 +54,16 @@ DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
let actorPool = new ActorPool(this.conn);
#ifndef MOZ_WIDGET_GONK
let actor = this._tabActors.get(this.browser);
// Get the chrome debugger actor.
let actor = this._chromeDebugger;
if (!actor) {
actor = new ChromeDebuggerActor(this);
actor.parentID = this.actorID;
this._chromeDebugger = actor;
actorPool.addActor(actor);
}
actor = this._tabActors.get(this.browser);
if (!actor) {
actor = new DeviceTabActor(this.conn, this.browser);
// this.actorID is set by ActorPool when an actor is put into one.
@ -78,7 +87,8 @@ DeviceRootActor.prototype.onListTabs = function DRA_onListTabs() {
'from': 'root',
'selected': 0,
#ifndef MOZ_WIDGET_GONK
'tabs': [actor.grip()]
'tabs': [actor.grip()],
"chromeDebugger": this._chromeDebugger.actorID
#else
'tabs': []
#endif

View File

@ -1,6 +1,6 @@
[{
"size": 608318343,
"digest": "9ab6487eccf44b0781cc96c2af9ba497f720a8d289bde40e29417f9db82788d6c8653c7dafa7443069f5898635eef45fa048ee99c03a9d0113c019a2f80f5aa8",
"size": 606070399,
"digest": "3d3899e2537bee5e3f969bb6d0e90fed93345512123e3133b1de793d59a8993d8174d9456cb92d86a880f6813d6049933de924cd522a433ef26c4bfa997777a7",
"algorithm": "sha512",
"filename": "emulator.zip"
}]

View File

@ -312,7 +312,8 @@ static int do_main(int argc, char* argv[], nsIFile *xreDirectory)
}
ptr++;
}
newArgc--;
if (ptr == newArgv[newArgc-1])
newArgc--;
int result = XRE_main(newArgc, newArgv, appData, mainFlags);
XRE_FreeAppData(appData);
return result;

File diff suppressed because one or more lines are too long

View File

@ -243,6 +243,15 @@ let SocialUI = {
[provider.name, brandShortName]);
description.value = message;
let icon = document.getElementById("social-activation-icon");
if (provider.icon64URL || provider.icon32URL) {
icon.setAttribute('src', provider.icon64URL || provider.icon32URL);
icon.hidden = false;
} else {
icon.removeAttribute('src');
icon.hidden = true;
}
let notificationPanel = SocialUI.notificationPanel;
// Set the origin being activated and the previously active one, to allow undo
notificationPanel.setAttribute("origin", provider.origin);

View File

@ -4374,7 +4374,7 @@ var XULBrowserWindow = {
if (e.target.readyState != "interactive" && e.target.readyState != "complete")
return;
e.target.removeEventListener("readystate", onContentRSChange);
e.target.removeEventListener("readystatechange", onContentRSChange);
disableFindCommands(shouldDisableFind(e.target));
}
@ -4763,7 +4763,7 @@ var TabsProgressListener = {
if (aBrowser.contentWindow == aWebProgress.DOMWindow) {
// Filter out any onLocationChanges triggered by anchor navigation
// or history.push/pop/replaceState.
if (aRequest) {
if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT)) {
// Initialize the click-to-play state.
aBrowser._clickToPlayPluginsActivated = new Map();
aBrowser._clickToPlayAllPluginsActivated = false;

View File

@ -184,7 +184,7 @@
align="start"
role="alert">
<hbox flex="1">
<image src="chrome://browser/content/social-icon.png" class="popup-notification-icon"/>
<image id="social-activation-icon" class="popup-notification-icon"/>
<vbox flex="1">
<description id="social-activation-message" class="popup-notification-description"/>
<spacer flex="1"/>
@ -956,7 +956,7 @@
<toolbarpalette id="BrowserToolbarPalette">
# Update primaryToolbarButtons in browser/themes/browserShared.inc when adding
# Update primaryToolbarButtons in browser/themes/shared/browser.inc when adding
# or removing default items with the toolbarbutton-1 class.
<toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -16,7 +16,7 @@ DIRS += \
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \
head.js \
head_plain.js \
test_feed_discovery.html \
feed_discovery.html \
test_bug395533.html \
@ -161,6 +161,7 @@ _BROWSER_FILES = \
browser_bug783614.js \
browser_bug797677.js \
browser_bug816527.js \
browser_bug822367.js \
browser_bug832435.js \
browser_canonizeURL.js \
browser_customize.js \
@ -237,6 +238,15 @@ _BROWSER_FILES = \
disablechrome.html \
discovery.html \
domplate_test.js \
file_bug822367_1.html \
file_bug822367_1.js \
file_bug822367_2.html \
file_bug822367_3.html \
file_bug822367_4.html \
file_bug822367_4.js \
file_bug822367_4B.html \
file_bug822367_5.html \
file_bug822367_6.html \
moz.png \
video.ogg \
test_bug435035.html \

View File

@ -5,7 +5,7 @@
const PREF_DISPLAY = "security.mixed_content.block_display_content";
const PREF_ACTIVE = "security.mixed_content.block_active_content";
const gHttpTestRoot = "https://example.com/tests/content/base/test/";
const gHttpTestRoot = "https://example.com/browser/browser/base/content/test/";
var origBlockDisplay;
var origBlockActive;
var gTestBrowser = null;

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
<div id="testContent">
<p id="p1"></p>
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">
</script>
</body>
</html>

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
<p id="p1"></p>
<img src="http://example.com/tests/image/test/mochitest/blue.png" onload="foo()">
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">
</script>
</body>
</html>

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
<div id="testContent">
<p id="p1"></p>
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_4.js">
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_4.js">
</script>
</body>
</html>

View File

@ -0,0 +1 @@
document.location = "https://example.com/browser/browser/base/content/test/file_bug822367_4B.html";

View File

@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
<div id="testContent">
<p id="p1"></p>
</div>
<script src="http://example.com/tests/content/base/test/file_bug822367_1.js">
<script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">
</script>
</body>
</html>

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
function createDoc()
{
var doc=document.open("text/html","replace");
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/tests/content/base/test/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/browser/browser/base/content/test/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
doc.close();
}
</script>

View File

@ -10,7 +10,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
</head>
<body>
<div id="testContent">
<iframe name="f1" id="f1" src="https://example.com/tests/content/base/test/file_bug822367_5.html"></iframe>
<iframe name="f1" id="f1" src="https://example.com/browser/browser/base/content/test/file_bug822367_5.html"></iframe>
</div>
</body>
</html>

View File

@ -1,4 +1,3 @@
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",

View File

@ -0,0 +1,15 @@
function waitForCondition(condition, nextTest, errorMsg) {
var tries = 0;
var interval = setInterval(function() {
if (tries >= 30) {
ok(false, errorMsg);
moveOn();
}
if (condition()) {
moveOn();
}
tries++;
}, 100);
var moveOn = function() { clearInterval(interval); nextTest(); };
}

View File

@ -4,7 +4,7 @@
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript;version=1.7" src="head.js"></script>
<script type="application/javascript;version=1.7" src="head_plain.js"></script>
<script>
SpecialPowers.setBoolPref('plugins.click_to_play', true);
</script>

View File

@ -122,7 +122,6 @@ browser.jar:
#ifdef XP_WIN
content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
#endif
content/browser/social-icon.png (content/social-icon.png)
content/browser/socialchat.xml (content/socialchat.xml)
# the following files are browser-specific overrides
* content/browser/license.html (/toolkit/content/license.html)

View File

@ -67,7 +67,7 @@
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromListMenuItem"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"
accesskey="&cmd.removeFromHistory.accesskey;"/>
<menuitem command="downloadsCmd_show"

View File

@ -438,7 +438,8 @@ BrowserGlue.prototype = {
},
_trackSlowStartup: function () {
if (Services.prefs.getBoolPref("browser.slowStartup.notificationDisabled"))
if (Services.startup.interrupted ||
Services.prefs.getBoolPref("browser.slowStartup.notificationDisabled"))
return;
let currentTime = Date.now() - Services.startup.getStartupInfo().process;

View File

@ -221,11 +221,11 @@ let SessionFileInternal = {
return TaskUtils.spawn(function task() {
try {
yield OS.File.copy(self.path, self.backupPath);
} catch (ex if self._isNoSuchFile(ex)) {
// Ignore exceptions about non-existent files.
} catch (ex) {
if (!self._isNoSuchFile(ex)) {
Cu.reportError("Could not backup session state file: " + ex);
throw ex;
}
Cu.reportError("Could not backup session state file: " + ex);
throw ex;
}
});
},
@ -235,12 +235,17 @@ let SessionFileInternal = {
return TaskUtils.spawn(function task() {
try {
yield OS.File.remove(self.path);
} catch (ex if self._isNoSuchFile(ex)) {
// Ignore exceptions about non-existent files.
} catch (ex) {
Cu.reportError("Could not remove session state file: " + ex);
throw ex;
}
try {
yield OS.File.remove(self.backupPath);
} catch (ex if self._isNoSuchFile(ex)) {
// Ignore exceptions about non-existent files.
} catch (ex) {
Cu.reportError("Could not remove session state backup file: " + ex);
throw ex;

View File

@ -1,4 +1,5 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<meta charset="utf-8">
<title>Test for bug 248970</title>
<h3>Text Fields</h3>

View File

@ -1,4 +1,5 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<meta charset="utf-8">
<title>Test for bug 339445</title>
storageTestItem = <span id="storageTestItem">FAIL</span>

View File

@ -1,6 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
// generate an enormous random number...
var r = Math.floor(Math.random() * Math.pow(2, 62)).toString();

View File

@ -1,4 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Testcase for bug 447951</title>
<a href="#end">click me</a>

View File

@ -4,7 +4,7 @@
<title>Test for bug 459906</title>
<body>
<iframe src="data:text/html,not_on_localhost"></iframe>
<iframe src="data:text/html;charset=utf-8,not_on_localhost"></iframe>
<iframe></iframe>
<script type="application/javascript">

View File

@ -4,7 +4,7 @@
<title>Test for bug 461743</title>
<body>
<iframe src="data:text/html,empty"></iframe>
<iframe src="data:text/html;charset=utf-8,empty"></iframe>
<iframe></iframe>
<script type="application/javascript">

View File

@ -13,9 +13,9 @@ function test() {
let doneURL = "done";
let mainURL = testURL;
let frame1URL = "data:text/html,<input%20id='original'>";
let frame1URL = "data:text/html;charset=utf-8,<input%20id='original'>";
let frame2URL = rootDir + "browser_463205_helper.html";
let frame3URL = "data:text/html,mark2";
let frame3URL = "data:text/html;charset=utf-8,mark2";
let frameCount = 0;
@ -68,7 +68,7 @@ function test() {
frame1URL = "http://mochi.test:8888/browser/" +
"browser/components/sessionstore/test/browser_463205_helper.html";
frame2URL = rootDir + "browser_463205_helper.html";
frame3URL = "data:text/html,mark2";
frame3URL = "data:text/html;charset=utf-8,mark2";
frameCount = 0;

View File

@ -1,4 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for bug 463205 (cross domain)</title>
<input id="original" value="preserve me">

View File

@ -1,17 +1,18 @@
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for bug 463205</title>
<body onload="onLoad()">
<iframe src="data:text/html,<input%20id='original'>"></iframe>
<iframe src="data:text/html;charset=utf-8,<input%20id='original'>"></iframe>
<iframe src="browser_463205_helper.html"></iframe>
<iframe src="data:text/html,mark1"></iframe>
<iframe src="data:text/html;charset=utf-8,mark1"></iframe>
<script type="application/javascript">
function onLoad() {
if (frames[2].document.location.href == "data:text/html,mark1") {
frames[2].document.location = "data:text/html,mark2";
if (frames[2].document.location.href == "data:text/html;charset-utf-8,mark1") {
frames[2].document.location = "data:text/html;charset=utf-8,mark2";
}
else {
frames[1].document.location.hash = "#original";

View File

@ -1,10 +1,11 @@
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for bug 463206</title>
<iframe src="data:text/html,<iframe></iframe><iframe%20src='data:text/html,<input%2520id=%2522in1%2522>'></iframe>"></iframe>
<iframe src="data:text/html,<input%20id='out1'><input%20id='out2'><iframe%20src='data:text/html,<input%2520id=%2522in1%2522>'>"></iframe>
<iframe src="data:text/html;charset=utf-8,<iframe></iframe><iframe%20src='data:text/html;charset=utf-8,<input%2520id=%2522in1%2522>'></iframe>"></iframe>
<iframe src="data:text/html;charset=utf-8,<input%20id='out1'><input%20id='out2'><iframe%20src='data:text/html;charset=utf-8,<input%2520id=%2522in1%2522>'>"></iframe>
<input id="out1">
<input name="1|#out2">

View File

@ -15,7 +15,7 @@
return;
firstPass = frames[1].location.href == "about:blank";
if (firstPass) {
frames[0].location = 'data:text/html,<body onload="if (parent.firstPass) parent.step();"><input id="x" oninput="parent.xss()">XXX</body>';
frames[0].location = 'data:text/html;charset=utf-8,<body onload="if (parent.firstPass) parent.step();"><input id="x" oninput="parent.xss()">XXX</body>';
}
frames[1].location = targetUrl;
}

View File

@ -16,8 +16,8 @@
return;
firstPass = frames[2].location.href == "about:blank";
if (firstPass) {
frames[0].location = 'data:text/html,<body onload="parent.step()">a</body>';
frames[1].location = 'data:text/html,<body onload="document.designMode=\'on\';">XXX</body>';
frames[0].location = 'data:text/html;charset=utf-8,<body onload="parent.step()">a</body>';
frames[1].location = 'data:text/html;charset=utf-8,<body onload="document.designMode=\'on\';">XXX</body>';
}
frames[2].location = targetUrl;
}

View File

@ -1,6 +1,7 @@
<!-- Testcase originally by <moz_bug_r_a4@yahoo.com> -->
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for bug 466937</title>
<input id="thief" value="/home/user/secret">

View File

@ -33,5 +33,5 @@ function test() {
}, true);
}, true);
browser.loadURI("data:text/html,<body style='width: 100000px; height: 100000px;'><p>top</p></body>");
browser.loadURI("data:text/html;charset=utf-8,<body style='width: 100000px; height: 100000px;'><p>top</p></body>");
}

View File

@ -33,7 +33,7 @@ function test() {
}
// test content URL
const TEST_URL = "data:text/html,"
const TEST_URL = "data:text/html;charset=utf-8,"
+ "<body style='width: 100000px; height: 100000px;'><p>top</p></body>"
// preferences that we use

View File

@ -1,7 +1,7 @@
function test() {
waitForExplicitFinish();
var tab1 = gBrowser.addTab("data:text/plain,foo");
var tab1 = gBrowser.addTab("data:text/plain;charset=utf-8,foo");
gBrowser.pinTab(tab1);
tab1.linkedBrowser.addEventListener("load", function () {

View File

@ -3,6 +3,7 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function boom()
@ -18,7 +19,7 @@ function boom()
</script>
</head>
<body onload="boom();">
<iframe src="data:text/html,1" id="f"></iframe>
<iframe src="data:text/html;charset=utf-8,1" id="f"></iframe>
</body>
</html>

View File

@ -2,7 +2,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
let tabState = {
entries: [{url: "data:text/html,<input%20id='foo'>", formdata: { id: { "foo": "bar" } } }]
entries: [{url: "data:text/html;charset=utf-8,<input%20id='foo'>", formdata: { id: { "foo": "bar" } } }]
};
function test() {

View File

@ -1,4 +1,5 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test for form restore events (originally bug 476161)</title>
<script>

View File

@ -18,7 +18,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "Toolbox",
XPCOMUtils.defineLazyModuleGetter(this, "TargetFactory",
"resource:///modules/devtools/Target.jsm");
const FORBIDDEN_IDS = new Set("toolbox", "");
const FORBIDDEN_IDS = new Set(["toolbox", ""]);
/**
* DevTools is a class that represents a set of developer tools, it holds a
@ -388,7 +388,7 @@ let gDevToolsBrowser = {
doc.getElementById("mainCommandSet").appendChild(elements.cmd);
if (elements.key) {
this.attachKeybindingsToBrowser(doc, elements.keys);
this.attachKeybindingsToBrowser(doc, elements.key);
}
doc.getElementById("mainBroadcasterSet").appendChild(elements.bc);

View File

@ -140,11 +140,13 @@ Highlighter.prototype = {
if (id != "inspector") {
this.chromeWin.clearTimeout(this.pageEventsMuter);
this.detachMouseListeners();
this.disabled = true;
this.hide();
} else {
if (!this.locked) {
this.attachMouseListeners();
}
this.disabled = false;
this.show();
}
}.bind(this);
@ -206,6 +208,9 @@ Highlighter.prototype = {
this.selection.isElementNode();
if (canHighlightNode) {
if (this.selection.reason != "navigateaway") {
this.disabled = false;
}
this.show();
this.updateInfobar();
this.invalidateSize();
@ -214,6 +219,7 @@ Highlighter.prototype = {
LayoutHelpers.scrollIntoViewIfNeeded(this.selection.node);
}
} else {
this.disabled = true;
this.hide();
}
},
@ -246,7 +252,7 @@ Highlighter.prototype = {
* Show the highlighter if it has been hidden.
*/
show: function() {
if (!this.hidden) return;
if (!this.hidden || this.disabled) return;
this.showOutline();
this.showInfobar();
this.computeZoomFactor();

View File

@ -242,8 +242,12 @@ InspectorPanel.prototype = {
function onDOMReady() {
newWindow.removeEventListener("DOMContentLoaded", onDOMReady, true);
if (self._destroyed) {
return;
}
if (!self.selection.node) {
self.selection.setNode(newWindow.document.documentElement);
self.selection.setNode(newWindow.document.documentElement, "navigateaway");
}
self._initMarkup();
}

View File

@ -38,6 +38,8 @@ _BROWSER_FILES = \
browser_inspector_bug_817558_delete_node.js \
browser_inspector_bug_650804_search.js \
browser_inspector_bug_650804_search.html \
browser_inspector_bug_840156_destroy_after_navigation.js \
browser_inspector_bug_835722_infobar_reappears.js \
head.js \
helpers.js \
$(NULL)

View File

@ -0,0 +1,92 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let inspector;
function startLocationTests() {
openInspector(runInspectorTests);
}
function runInspectorTests(aInspector) {
inspector = aInspector;
executeSoon(function() {
inspector.selection.once("new-node", onNewSelection);
info("selecting the DOCTYPE node");
inspector.selection.setNode(content.document.doctype, "test");
});
}
function onNewSelection() {
is(inspector.highlighter.isHidden(), true,
"The infobar should be hidden now on selecting a non element node.");
inspector.sidebar.select("ruleview");
let ruleView = inspector.sidebar.getTab("ruleview");
ruleView.addEventListener("mouseover", function onMouseOver() {
ruleView.removeEventListener("mouseover", onMouseOver, false);
is(inspector.highlighter.isHidden(), true,
"The infobar was hidden so mouseover on the rules view did nothing");
mouseOutAndContinue();
}, false);
EventUtils.synthesizeMouse(ruleView, 10, 50, {type: "mouseover"},
ruleView.ownerDocument.defaultView);
}
function mouseOutAndContinue() {
let ruleView = inspector.sidebar.getTab("ruleview");
ruleView.addEventListener("mouseout", function onMouseOut() {
ruleView.removeEventListener("mouseout", onMouseOut, false);
is(inspector.highlighter.isHidden(), true,
"The infobar should not be visible after we mouseout of rules view");
switchToWebConsole();
}, false);
EventUtils.synthesizeMouse(ruleView, 10, 10, {type: "mousemove"},
ruleView.ownerDocument.defaultView);
EventUtils.synthesizeMouse(ruleView, -10, -10, {type: "mouseout"},
ruleView.ownerDocument.defaultView);
}
function switchToWebConsole() {
inspector.selection.once("new-node", function() {
is(inspector.highlighter.isHidden(), false,
"The infobar should be visible after we select a div.");
gDevTools.showToolbox(inspector.target, "webconsole").then(function() {
is(inspector.highlighter.isHidden(), true,
"The infobar should not be visible after we switched to webconsole");
reloadAndWait();
});
});
inspector.selection.setNode(content.document.querySelector("div"), "test");
}
function reloadAndWait() {
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);
waitForFocus(testAfterReload, content);
}, true);
content.location.reload();
}
function testAfterReload() {
is(inspector.highlighter.isHidden(), true,
"The infobar should not be visible after we reload with webconsole shown");
testEnd();
}
function testEnd() {
gBrowser.removeCurrentTab();
executeSoon(finish);
}
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);
waitForFocus(startLocationTests, content);
}, true);
content.location = "data:text/html,<!DOCTYPE html><div>Infobar should not " +
"reappear</div><p>init</p>";
}

View File

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let temp = {};
Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", temp);
let Promise = temp.Promise;
temp = {};
Cu.import("resource:///modules/devtools/Toolbox.jsm", temp);
let Toolbox = temp.Toolbox;
temp = {};
Cu.import("resource:///modules/devtools/Target.jsm", temp);
let TargetFactory = temp.TargetFactory;
temp = null;
function test() {
waitForExplicitFinish();
const URL_1 = "data:text/plain;charset=UTF-8,abcde";
const URL_2 = "data:text/plain;charset=UTF-8,12345";
let target, toolbox;
// open tab, load URL_1, and wait for load to finish
let tab = gBrowser.selectedTab = gBrowser.addTab();
let target = TargetFactory.forTab(gBrowser.selectedTab);
let deferred = Promise.defer();
let browser = gBrowser.getBrowserForTab(tab);
function onTabLoad() {
browser.removeEventListener("load", onTabLoad, true);
deferred.resolve(null);
}
browser.addEventListener("load", onTabLoad, true);
browser.loadURI(URL_1);
// open devtools panel
deferred.promise
.then(function () gDevTools.showToolbox(target, null, Toolbox.HostType.BOTTOM))
.then(function (aToolbox) { toolbox = aToolbox; })
// select the inspector
.then(function () toolbox.selectTool("inspector"))
// navigate to URL_2
.then(function () {
let deferred = Promise.defer();
target.once("navigate", function () deferred.resolve());
browser.loadURI(URL_2);
return deferred.promise;
})
// destroy the toolbox (and hence the inspector) before the load completes
.then(function () toolbox.destroy())
// this (or any other) exception should not occur:
// [JavaScript Error: "TypeError: self.selection is null" {file: "resource:///modules/devtools/InspectorPanel.jsm" line: 250}]
.then(function cleanUp() {
gBrowser.removeCurrentTab();
finish();
});
}

View File

@ -125,8 +125,6 @@ CssLogic.prototype = {
_matchedRules: null,
_matchedSelectors: null,
domUtils: Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils),
/**
* Reset various properties
*/
@ -470,8 +468,9 @@ CssLogic.prototype = {
rule.selectors.forEach(function (aSelector) {
if (aSelector._matchId !== this._matchId &&
(aSelector.elementStyle ||
this._selectorMatchesElement(aSelector))) {
(aSelector.elementStyle ||
this.selectorMatchesElement(rule._domRule, aSelector.selectorIndex))) {
aSelector._matchId = this._matchId;
this._matchedSelectors.push([ aSelector, status ]);
if (aCallback) {
@ -489,15 +488,19 @@ CssLogic.prototype = {
* parents.
*
* @private
* @param {string} aSelector the selector string you want to check.
* @return {boolean} true if the given selector matches the highlighted
* element or any of its parents, otherwise false is returned.
* @param {DOMRule} domRule
* The DOM Rule containing the selector.
* @param {Number} idx
* The index of the selector within the DOMRule.
* @return {boolean}
* true if the given selector matches the highlighted element or any
* of its parents, otherwise false is returned.
*/
_selectorMatchesElement: function CL__selectorMatchesElement(aSelector)
selectorMatchesElement: function CL_selectorMatchesElement2(domRule, idx)
{
let element = this.viewedElement;
do {
if (element.mozMatchesSelector(aSelector)) {
if (domUtils.selectorMatchesElement(element, domRule, idx)) {
return true;
}
} while ((element = element.parentNode) &&
@ -531,7 +534,7 @@ CssLogic.prototype = {
if (rule.getPropertyValue(aProperty) &&
(status == CssLogic.STATUS.MATCHED ||
(status == CssLogic.STATUS.PARENT_MATCH &&
this.domUtils.isInheritedProperty(aProperty)))) {
domUtils.isInheritedProperty(aProperty)))) {
result[aProperty] = true;
return false;
}
@ -569,7 +572,7 @@ CssLogic.prototype = {
CssLogic.STATUS.MATCHED : CssLogic.STATUS.PARENT_MATCH;
try {
domRules = this.domUtils.getCSSStyleRules(element);
domRules = domUtils.getCSSStyleRules(element);
} catch (ex) {
Services.console.
logStringMessage("CL__buildMatchedRules error: " + ex);
@ -690,65 +693,22 @@ CssLogic.getShortNamePath = function CssLogic_getShortNamePath(aElement)
};
/**
* Get a string list of selectors for a given CSSStyleRule.selectorText
* Get a string list of selectors for a given DOMRule.
*
* @param {string} aSelectorText The CSSStyleRule.selectorText to parse.
* @return {array} An array of string selectors.
* @param {DOMRule} aDOMRule
* The DOMRule to parse.
* @return {Array}
* An array of string selectors.
*/
CssLogic.getSelectors = function CssLogic_getSelectors(aSelectorText)
CssLogic.getSelectors = function CssLogic_getSelectors(aDOMRule)
{
let selectors = [];
let selector = aSelectorText.trim();
if (!selector) {
return selectors;
let len = domUtils.getSelectorCount(aDOMRule);
for (let i = 0; i < len; i++) {
let text = domUtils.getSelectorText(aDOMRule, i);
selectors.push(text);
}
let nesting = 0;
let currentSelector = [];
// Parse a selector group into selectors. Normally we could just .split(',')
// however Gecko allows -moz-any(a, b, c) as a selector so we ignore commas
// inside brackets.
for (let i = 0, selLen = selector.length; i < selLen; i++) {
let c = selector.charAt(i);
switch (c) {
case ",":
if (nesting == 0 && currentSelector.length > 0) {
let selectorStr = currentSelector.join("").trim();
if (selectorStr) {
selectors.push(selectorStr);
}
currentSelector = [];
} else {
currentSelector.push(c);
}
break;
case "(":
nesting++;
currentSelector.push(c);
break;
case ")":
nesting--;
currentSelector.push(c);
break;
default:
currentSelector.push(c);
break;
}
}
// Add the last selector.
if (nesting == 0 && currentSelector.length > 0) {
let selectorStr = currentSelector.join("").trim();
if (selectorStr) {
selectors.push(selectorStr);
}
}
return selectors;
}
@ -1171,7 +1131,7 @@ function CssRule(aCssSheet, aDomRule, aElement)
if (this._cssSheet) {
// parse _domRule.selectorText on call to this.selectors
this._selectors = null;
this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule);
this.line = domUtils.getRuleLine(this._domRule);
this.source = this._cssSheet.shortSource + ":" + this.line;
if (this.mediaText) {
this.source += " @media " + this.mediaText;
@ -1179,7 +1139,7 @@ function CssRule(aCssSheet, aDomRule, aElement)
this.href = this._cssSheet.href;
this.contentRule = this._cssSheet.contentSheet;
} else if (aElement) {
this._selectors = [ new CssSelector(this, "@element.style") ];
this._selectors = [ new CssSelector(this, "@element.style", 0) ];
this.line = -1;
this.source = CssLogic.l10n("rule.sourceElement");
this.href = "#";
@ -1263,8 +1223,12 @@ CssRule.prototype = {
return this._selectors;
}
let selectors = CssLogic.getSelectors(this._domRule.selectorText);
this._selectors = [new CssSelector(this, text) for (text of selectors)];
let selectors = CssLogic.getSelectors(this._domRule);
for (let i = 0, len = selectors.length; i < len; i++) {
this._selectors.push(new CssSelector(this, selectors[i], i));
}
return this._selectors;
},
@ -1281,13 +1245,15 @@ CssRule.prototype = {
* @constructor
* @param {CssRule} aCssRule the CssRule instance from where the selector comes.
* @param {string} aSelector The selector that we wish to investigate.
* @param {Number} aIndex The index of the selector within it's rule.
*/
this.CssSelector = function CssSelector(aCssRule, aSelector)
this.CssSelector = function CssSelector(aCssRule, aSelector, aIndex)
{
this._cssRule = aCssRule;
this.text = aSelector;
this.elementStyle = this.text == "@element.style";
this._specificity = null;
this.selectorIndex = aIndex;
}
CssSelector.prototype = {
@ -1402,8 +1368,7 @@ CssSelector.prototype = {
* @see http://www.w3.org/TR/css3-selectors/#specificity
* @see http://www.w3.org/TR/CSS2/selector.html
*
* @return {object} an object holding specificity information for the current
* selector.
* @return {Number} The selector's specificity.
*/
get specificity()
{
@ -1411,59 +1376,8 @@ CssSelector.prototype = {
return this._specificity;
}
let specificity = {
ids: 0,
classes: 0,
tags: 0
};
let text = this.text;
if (!this.elementStyle) {
// Remove universal selectors as they are not relevant as far as specificity
// is concerned.
text = text.replace(RX_UNIVERSAL_SELECTOR, "");
// not() is ignored but any selectors contained by it are counted. Let's
// remove the not() and keep the contents.
text = text.replace(RX_NOT, " $1");
// Simplify remaining psuedo classes & elements.
text = text.replace(RX_PSEUDO_CLASS_OR_ELT, " $1)");
// Replace connectors with spaces
text = text.replace(RX_CONNECTORS, " ");
text.split(/\s/).forEach(function(aSimple) {
// Count IDs.
aSimple = aSimple.replace(RX_ID, function() {
specificity.ids++;
return "";
});
// Count class names and attribute matchers.
aSimple = aSimple.replace(RX_CLASS_OR_ATTRIBUTE, function() {
specificity.classes++;
return "";
});
aSimple = aSimple.replace(RX_PSEUDO, function(aDummy, aPseudoName) {
if (this.pseudoElements.has(aPseudoName)) {
// Pseudo elements count as tags.
specificity.tags++;
} else {
// Pseudo classes count as classes.
specificity.classes++;
}
return "";
}.bind(this));
if (aSimple) {
specificity.tags++;
}
}, this);
}
this._specificity = specificity;
this._specificity = domUtils.getSpecificity(this._cssRule._domRule,
this.selectorIndex);
return this._specificity;
},
@ -1610,7 +1524,7 @@ CssPropertyInfo.prototype = {
if (value &&
(aStatus == CssLogic.STATUS.MATCHED ||
(aStatus == CssLogic.STATUS.PARENT_MATCH &&
this._cssLogic.domUtils.isInheritedProperty(this.property)))) {
domUtils.isInheritedProperty(this.property)))) {
let selectorInfo = new CssSelectorInfo(aSelector, this.property, value,
aStatus);
this._matchedSelectors.push(selectorInfo);
@ -1677,25 +1591,6 @@ function CssSelectorInfo(aSelector, aProperty, aValue, aStatus)
let priority = this.selector._cssRule.getPropertyPriority(this.property);
this.important = (priority === "important");
/* Score prefix:
0 UA normal property
1 UA important property
2 normal property
3 inline (element.style)
4 important
5 inline important
*/
let scorePrefix = this.contentRule ? 2 : 0;
if (this.elementStyle) {
scorePrefix++;
}
if (this.important) {
scorePrefix += this.contentRule ? 2 : 1;
}
this.specificityScore = "" + scorePrefix + this.specificity.ids +
this.specificity.classes + this.specificity.tags;
}
CssSelectorInfo.prototype = {
@ -1824,14 +1719,8 @@ CssSelectorInfo.prototype = {
if (this.important && !aThat.important) return -1;
if (aThat.important && !this.important) return 1;
if (this.specificity.ids > aThat.specificity.ids) return -1;
if (aThat.specificity.ids > this.specificity.ids) return 1;
if (this.specificity.classes > aThat.specificity.classes) return -1;
if (aThat.specificity.classes > this.specificity.classes) return 1;
if (this.specificity.tags > aThat.specificity.tags) return -1;
if (aThat.specificity.tags > this.specificity.tags) return 1;
if (this.specificity > aThat.specificity) return -1;
if (aThat.specificity > this.specificity) return 1;
if (this.sheetIndex > aThat.sheetIndex) return -1;
if (aThat.sheetIndex > this.sheetIndex) return 1;
@ -1847,3 +1736,7 @@ CssSelectorInfo.prototype = {
return this.selector + " -> " + this.value;
},
};
XPCOMUtils.defineLazyGetter(this, "domUtils", function() {
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
});

View File

@ -108,8 +108,6 @@ ElementStyle.prototype = {
// to figure out how shorthand properties will be parsed.
dummyElement: null,
domUtils: Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils),
/**
* Called by the Rule object when it has been changed through the
* setProperty* methods.
@ -158,7 +156,7 @@ ElementStyle.prototype = {
});
// Get the styles that apply to the element.
var domRules = this.domUtils.getCSSStyleRules(aElement);
var domRules = domUtils.getCSSStyleRules(aElement);
// getCSStyleRules returns ordered from least-specific to
// most-specific.
@ -413,7 +411,7 @@ Rule.prototype = {
// No stylesheet, no ruleLine
return null;
}
return this.elementStyle.domUtils.getRuleLine(this.domRule);
return domUtils.getRuleLine(this.domRule);
},
/**
@ -576,8 +574,7 @@ Rule.prototype = {
continue;
let name = matches[1];
if (this.inherited &&
!this.elementStyle.domUtils.isInheritedProperty(name)) {
if (this.inherited && !domUtils.isInheritedProperty(name)) {
continue;
}
let value = store.userProperties.getProperty(this.style, name, matches[2]);
@ -1448,7 +1445,7 @@ RuleEditor.prototype = {
// actually match. For custom selector text (such as for the 'element'
// style, just show the text directly.
if (this.rule.domRule && this.rule.domRule.selectorText) {
let selectors = CssLogic.getSelectors(this.rule.selectorText);
let selectors = CssLogic.getSelectors(this.rule.domRule);
let element = this.rule.inherited || this.ruleView._viewedElement;
for (let i = 0; i < selectors.length; i++) {
let selector = selectors[i];
@ -1458,8 +1455,12 @@ RuleEditor.prototype = {
textContent: ", "
});
}
let cls = element.mozMatchesSelector(selector) ? "ruleview-selector-matched" :
"ruleview-selector-unmatched";
let cls;
if (domUtils.selectorMatchesElement(element, this.rule.domRule, i)) {
cls = "ruleview-selector-matched";
} else {
cls = "ruleview-selector-unmatched";
}
createChild(this.selectorText, "span", {
class: cls,
textContent: selector
@ -2847,3 +2848,7 @@ XPCOMUtils.defineLazyGetter(this, "_strings", function() {
XPCOMUtils.defineLazyGetter(this, "osString", function() {
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
});
XPCOMUtils.defineLazyGetter(this, "domUtils", function() {
return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
});

View File

@ -6,44 +6,98 @@
let tempScope = {};
Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
let CssLogic = tempScope.CssLogic;
let CssSelector = tempScope.CssSelector;
function test()
function createDocument()
{
let tests = [
{text: "*", expected: "000"},
{text: "LI", expected: "001"},
{text: "UL LI", expected: "002"},
{text: "UL OL+LI", expected: "003"},
{text: "H1 + *[REL=up]", expected: "011"},
{text: "UL OL LI.red", expected: "013"},
{text: "LI.red.level", expected: "021"},
{text: ".red .level", expected: "020"},
{text: "#x34y", expected: "100"},
{text: "#s12:not(FOO)", expected: "101"},
{text: "body#home div#warning p.message", expected: "213"},
{text: "* body#home div#warning p.message", expected: "213"},
{text: "#footer *:not(nav) li", expected: "102"},
{text: "bar:nth-child(1n+0)", expected: "011"},
{text: "li::-moz-list-number", expected: "002"},
{text: "a:hover", expected: "011"},
];
let doc = content.document;
doc.body.innerHTML = getStylesheetText();
doc.title = "Computed view specificity test";
runTests(doc);
}
tests.forEach(function(aTest) {
let selector = new CssSelector(null, aTest.text);
let specificity = selector.specificity;
function runTests(doc) {
let cssLogic = new CssLogic();
cssLogic.highlight(doc.body);
let result = "" + specificity.ids + specificity.classes + specificity.tags;
is(result, aTest.expected, "selector \"" + aTest.text +
"\" produces expected result");
});
let tests = getTests();
let cssSheet = cssLogic.sheets[0];
let cssRule = cssSheet.domSheet.cssRules[0];
let selectors = CssLogic.getSelectors(cssRule);
for (let i = 0; i < selectors.length; i++) {
let selectorText = selectors[i];
let selector = new CssSelector(cssRule, selectorText, i);
let expected = getExpectedSpecificity(selectorText);
let specificity = DOMUtils.getSpecificity(selector._cssRule,
selector.selectorIndex)
is(specificity, expected,
'selector "' + selectorText + '" has a specificity of ' + expected);
}
finishUp();
}
function getExpectedSpecificity(selectorText) {
let tests = getTests();
for (let test of tests) {
if (test.text == selectorText) {
return test.expected;
}
}
}
function getTests() {
return [
{text: "*", expected: 0},
{text: "LI", expected: 1},
{text: "UL LI", expected: 2},
{text: "UL OL + LI", expected: 3},
{text: "H1 + [REL=\"up\"]", expected: 257},
{text: "UL OL LI.red", expected: 259},
{text: "LI.red.level", expected: 513},
{text: ".red .level", expected: 512},
{text: "#x34y", expected: 65536},
{text: "#s12:not(FOO)", expected: 65537},
{text: "body#home div#warning p.message", expected: 131331},
{text: "* body#home div#warning p.message", expected: 131331},
{text: "#footer :not(nav) li", expected: 65538},
{text: "bar:nth-child(n)", expected: 257},
{text: "li::-moz-list-number", expected: 1},
{text: "a:hover", expected: 257},
];
}
function getStylesheetText() {
let tests = getTests();
let text = "";
tests.forEach(function(test) {
if (text.length > 0) {
text += ",";
}
text += test.text;
});
return '<style type="text/css">' + text + " {color:red;}</style>";
}
function finishUp()
{
CssLogic = CssSelector = null;
CssLogic = CssSelector = tempScope = null;
finish();
}
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html,Computed view specificity test";
}

View File

@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html dir="ltr" mozdisallowselectionprint>
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

View File

@ -20,12 +20,11 @@ Function RegisterCEH
!endif
FunctionEnd
; If MOZ_METRO is defined and we're at least win8, then we should re-create
; the start menu shortcut so that the Metro browser is accessible.
; This is also for zip builds who won't have a start menu shortcut yet.
Function CreateStartMenuTile
; If we're in Win8 make sure we have a start menu shortcut and that it has
; the correct AppuserModelID so that the Metro browser has a Metro tile.
Function RegisterStartMenuTile
!ifdef MOZ_METRO
Delete "$SMPROGRAMS\${BrandFullName}.lnk"
${If} ${AtLeastWin8}
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}"
${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
@ -34,10 +33,39 @@ Function CreateStartMenuTile
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true"
${EndIf}
${EndIf}
${EndIf}
!endif
FunctionEnd
!macro PostUpdate
; Determine if we're the protected UserChoice default or not. If so fix the
; start menu tile. In case there are 2 Firefox installations, we only do
; this if the application being updated is the default.
ReadRegStr $0 HKCU "Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" "ProgId"
${If} $0 == "FirefoxURL"
ReadRegStr $0 HKCU "Software\Classes\FirefoxURL\shell\open\command" ""
${GetPathFromString} "$0" $0
${GetParent} "$0" $0
${If} ${FileExists} "$0"
${GetLongPath} "$0" $0
${EndIf}
${If} "$0" == "$INSTDIR"
; PostUpdate is called from both session 0 and from the user session
; for service updates, make sure that we only register with the user session
; Otherwise ApplicationID::Set can fail intermittently with a file in use error.
System::Call "kernel32::GetCurrentProcessId() i.r0"
System::Call "kernel32::ProcessIdToSessionId(i $0, *i ${NSIS_MAX_STRLEN} r9)"
${If} $9 != 0 ; We're not running in session 0
; Win8 specific registration
Call RegisterStartMenuTile
${EndIf}
${EndIf}
${EndIf}
${CreateShortcutsLog}
; Remove registry entries for non-existent apps and for apps that point to our
@ -54,10 +82,6 @@ FunctionEnd
; Win7 taskbar and start menu link maintenance
Call FixShortcutAppModelIDs
; Win8 specific registration
Call RegisterCEH
Call CreateStartMenuTile
ClearErrors
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test"
${If} ${Errors}
@ -176,6 +200,21 @@ FunctionEnd
${EndIf}
!endif
; Register the DEH
!ifdef MOZ_METRO
${If} ${AtLeastWin8}
${AndIf} $9 != 0 ; We're not running in session 0
; If RegisterCEH is called too close to changing the shortcut AppUserModelID
; and if the tile image is not already in cache. Then Windows won't refresh
; the tile image on the start screen. So wait before calling RegisterCEH.
; We only need to do this when the DEH doesn't already exist.
ReadRegStr $0 HKCU "Software\Classes\FirefoxURL\shell\open\command" "DelegateExecute"
${If} $0 != ${DELEGATE_EXECUTE_HANDLER_ID}
Sleep 3000
${EndIf}
Call RegisterCEH
${EndIf}
!endif
!macroend
!define PostUpdate "!insertmacro PostUpdate"
@ -1175,7 +1214,7 @@ Function SetAsDefaultAppUserHKCU
${SetStartMenuInternet} "HKCU"
${FixShellIconHandler} "HKCU"
${FixClassKeys} ; Does not use SHCTX
Call CreateStartMenuTile
Call RegisterStartMenuTile
${EndIf}
${SetHandlers}

View File

@ -23,12 +23,16 @@ var ContextCommands = {
* Context menu handlers
*/
// Text specific
copy: function cc_copy() {
let target = ContextMenuUI.popupState.target;
if (target.localName == "browser") {
// content
if (ContextMenuUI.popupState.string != "undefined") {
this.clipboard.copyString(ContextMenuUI.popupState.string,
this.docRef);
this.showToast(Strings.browser.GetStringFromName("selectionHelper.textCopied"));
} else {
let x = ContextMenuUI.popupState.x;
let y = ContextMenuUI.popupState.y;
@ -36,7 +40,9 @@ var ContextCommands = {
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
}
} else {
// chrome
target.editor.copy();
this.showToast(Strings.browser.GetStringFromName("selectionHelper.textCopied"));
}
if (target)
@ -46,11 +52,13 @@ var ContextCommands = {
paste: function cc_paste() {
let target = ContextMenuUI.popupState.target;
if (target.localName == "browser") {
// content
let x = ContextMenuUI.popupState.x;
let y = ContextMenuUI.popupState.y;
let json = {x: x, y: y, command: "paste" };
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
} else {
// chrome
target.editor.paste(Ci.nsIClipboard.kGlobalClipboard);
target.focus();
}
@ -63,24 +71,157 @@ var ContextCommands = {
BrowserUI.goToURI();
},
select: function cc_select() {
let contextInfo = { name: "",
json: ContextMenuUI.popupState,
target: ContextMenuUI.popupState.target };
SelectionHelperUI.openEditSession(contextInfo);
},
selectAll: function cc_selectAll() {
let target = ContextMenuUI.popupState.target;
if (target.localName == "browser") {
// content
let x = ContextMenuUI.popupState.x;
let y = ContextMenuUI.popupState.y;
let json = {x: x, y: y, command: "select-all" };
target.messageManager.sendAsyncMessage("Browser:ContextCommand", json);
let contextInfo = { name: "",
json: ContextMenuUI.popupState,
target: ContextMenuUI.popupState.target };
SelectionHelperUI.attachEditSession(contextInfo);
} else {
// chrome
target.editor.selectAll();
target.focus();
}
},
openInNewTab: function cc_openInNewTab() {
Browser.addTab(ContextMenuUI.popupState.linkURL, false, Browser.selectedTab);
ContextUI.peekTabs();
// called on display of the search text menu item
searchTextSetup: function cc_searchTextSetup(aRichListItem, aSearchString) {
let defaultURI;
let defaultName;
try {
let defaultPB = Services.prefs.getDefaultBranch(null);
const nsIPLS = Ci.nsIPrefLocalizedString;
defaultName = defaultPB.getComplexValue("browser.search.defaultenginename", nsIPLS).data;
let defaultEngine = Services.search.getEngineByName(defaultName);
defaultURI = defaultEngine.getSubmission(aSearchString).uri.spec;
} catch (ex) {
Cu.reportError(ex);
return false;
}
// label child node
let label = Services.strings
.createBundle("chrome://browser/locale/browser.properties")
.formatStringFromName("browser.search.contextTextSearchLabel",
[defaultName], 1);
aRichListItem.childNodes[0].setAttribute("value", label);
aRichListItem.setAttribute("searchString", defaultURI);
return true;
},
searchText: function cc_searchText(aRichListItem) {
let defaultURI = aRichListItem.getAttribute("searchString");
aRichListItem.childNodes[0].setAttribute("value", "");
aRichListItem.setAttribute("searchString", "");
BrowserUI.newTab(defaultURI, Browser.selectedTab);
},
// Link specific
openLinkInNewTab: function cc_openLinkInNewTab() {
BrowserUI.newTab(ContextMenuUI.popupState.linkURL, Browser.selectedTab);
},
copyLink: function cc_copyLink() {
this.clipboard.copyString(ContextMenuUI.popupState.linkURL,
this.docRef);
this.showToast(Strings.browser.GetStringFromName("selectionHelper.linkCopied"));
},
bookmarkLink: function cc_bookmarkLink() {
let state = ContextMenuUI.popupState;
let uri = Util.makeURI(state.linkURL);
let title = state.linkTitle || state.linkURL;
try {
Bookmarks.addForURI(uri, title);
} catch (e) {
return;
}
this.showToast(Strings.browser.GetStringFromName("alertLinkBookmarked"));
},
// Image specific
saveImageToLib: function cc_saveImageToLib() {
this.saveToWinLibrary("Pict");
},
copyImage: function cc_copyImage() {
// copy to clibboard
this.sendCommand("copy-image-contents");
},
copyImageSrc: function cc_copyImageSrc() {
this.clipboard.copyString(ContextMenuUI.popupState.mediaURL,
this.docRef);
this.showToast(Strings.browser.GetStringFromName("selectionHelper.linkCopied"));
},
openImageInNewTab: function cc_openImageInNewTab() {
BrowserUI.newTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab);
},
// Video specific
saveVideoToLib: function cc_saveVideoToLib() {
this.saveToWinLibrary("Vids");
},
copyVideoSrc: function cc_copyVideoSrc() {
this.clipboard.copyString(ContextMenuUI.popupState.mediaURL,
this.docRef);
this.showToast(Strings.browser.GetStringFromName("selectionHelper.linkCopied"));
},
openVideoInNewTab: function cc_openVideoInNewTab() {
BrowserUI.newTab(ContextMenuUI.popupState.mediaURL, Browser.selectedTab);
},
openVideoInFullscreen: function cc_openVideoInFullscreen() {
// XXX currently isn't working.
this.sendCommand('videotab');
},
// Bookmarks
editBookmark: function cc_editBookmark() {
let target = ContextMenuUI.popupState.target;
target.startEditing();
},
removeBookmark: function cc_removeBookmark() {
let target = ContextMenuUI.popupState.target;
target.remove();
},
// App bar
findInPage: function cc_findInPage() {
FindHelperUI.show();
},
viewOnDesktop: function cc_viewOnDesktop() {
Appbar.onViewOnDesktop();
},
/*
* Utilities
*/
saveToWinLibrary: function cc_saveToWinLibrary(aType) {
let popupState = ContextMenuUI.popupState;
let browser = popupState.target;
@ -116,55 +257,9 @@ var ContextCommands = {
});
},
saveVideo: function cc_saveVideo() {
this.saveToWinLibrary("Vids");
},
saveVideoTo: function cc_saveVideoTo() {
this.saveFileAs(ContextMenuUI.popupState);
},
saveImage: function cc_saveImage() {
this.saveToWinLibrary("Pict");
},
saveImageTo: function cc_saveImageTo() {
this.saveFileAs(ContextMenuUI.popupState);
},
copyLink: function cc_copyLink() {
this.clipboard.copyString(ContextMenuUI.popupState.linkURL,
this.docRef);
},
copyEmail: function cc_copyEmail() {
this.clipboard.copyString(ContextMenuUI.popupState.linkURL.substr(ContextMenuUI.popupState.linkURL.indexOf(':')+1),
this.docRef);
},
copyPhone: function cc_copyPhone() {
this.clipboard.copyString(ContextMenuUI.popupState.linkURL.substr(ContextMenuUI.popupState.linkURL.indexOf(':')+1),
this.docRef);
},
copyImage: function cc_copyImage() {
this.sendCommand("copy-image-contents");
},
bookmarkLink: function cc_bookmarkLink() {
let state = ContextMenuUI.popupState;
let uri = Util.makeURI(state.linkURL);
let title = state.linkTitle || state.linkURL;
try {
Bookmarks.addForURI(uri, title);
} catch (e) {
return;
}
let message = Strings.browser.GetStringFromName("alertLinkBookmarked");
showToast: function showToast(aString) {
let toaster = Cc["@mozilla.org/toaster-alerts-service;1"].getService(Ci.nsIAlertsService);
toaster.showAlertNotification(null, message, "", false, "", null);
toaster.showAlertNotification(null, aString, "", false, "", null);
},
sendCommand: function cc_playVideo(aCommand) {
@ -173,28 +268,6 @@ var ContextCommands = {
browser.messageManager.sendAsyncMessage("Browser:ContextCommand", { command: aCommand });
},
editBookmark: function cc_editBookmark() {
let target = ContextMenuUI.popupState.target;
target.startEditing();
},
removeBookmark: function cc_removeBookmark() {
let target = ContextMenuUI.popupState.target;
target.remove();
},
findInPage: function cc_findInPage() {
FindHelperUI.show();
},
viewOnDesktop: function cc_viewOnDesktop() {
Appbar.onViewOnDesktop();
},
/*
* Utilities
*/
/*
* isAccessibleDirectory
*

View File

@ -57,21 +57,21 @@
<commandset id="mainCommandSet">
<!-- basic navigation -->
<command id="cmd_back" label="&back.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_forward" label="&forward.label;" disabled="true" oncommand="CommandUpdater.doCommand(this.id);" observes="bcast_urlbarState"/>
<command id="cmd_back" disabled="true" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_forward" disabled="true" oncommand="CommandUpdater.doCommand(this.id);" observes="bcast_urlbarState"/>
<command id="cmd_handleBackspace" oncommand="BrowserUI.handleBackspace();" />
<command id="cmd_handleShiftBackspace" oncommand="BrowserUI.handleShiftBackspace();" />
<command id="cmd_reload" label="&reload.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_reload" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_forceReload" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_stop" label="&stop.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_go" label="&go.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_stop" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_go" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_openLocation" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_home" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- tabs -->
<command id="cmd_newTab" label="&newtab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_closeTab" label="&closetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_undoCloseTab" label="&undoclosetab.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_newTab" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_closeTab" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_undoCloseTab" oncommand="CommandUpdater.doCommand(this.id);"/>
#ifdef MOZ_SERVICES_SYNC
<command id="cmd_remoteTabs" oncommand="CommandUpdater.doCommand(this.id);"/>
#endif
@ -101,12 +101,12 @@
<command id="cmd_scrollPageDown" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- editing -->
<command id="cmd_cut" label="&cut.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_copy" label="&copy.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_copylink" label="&copylink.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_paste" label="&paste.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_delete" label="&delete.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_selectAll" label="&selectAll.label;" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_cut" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_copy" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_copylink" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_paste" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_delete" oncommand="CommandUpdater.doCommand(this.id);"/>
<command id="cmd_selectAll" oncommand="CommandUpdater.doCommand(this.id);"/>
<!-- forms navigation -->
<command id="cmd_formPrevious" oncommand="FormHelperUI.goToPrevious();"/>
@ -195,10 +195,10 @@
forwarddisabled="true"
title="Back/Forward">
<toolbarbutton id="back-button" class="toolbarbutton"
label="Back"
label="&back.label;"
command="cmd_back"/>
<toolbarbutton id="forward-button" class="toolbarbutton"
label="Forward"
label="&forward.label;"
command="cmd_forward"/>
<dummyobservertarget hidden="true"
onbroadcast="if (this.getAttribute('disabled') == 'true')
@ -245,7 +245,7 @@
</toolbar>
<box id="toolbar-transition" observes="bcast_windowState" >
<toolbarbutton id="tool-new-tab" command="cmd_newTab"/>
<toolbarbutton id="tool-new-tab" command="cmd_newTab" label="&newtab.label;"/>
</box>
</hbox>
@ -559,78 +559,83 @@
<box id="context-container" class="menu-container" hidden="true">
<vbox id="context-popup" class="menu-popup">
<richlistbox id="context-commands" bindingType="contextmenu" flex="1">
<!-- priority="low" items are hidden by default when a context is being displayed
for two or more media types. (e.g. a linked image) -->
<!-- Note the order of richlistitem here is important as it is reflected in the
menu itself. -->
<!-- ux spec: https://bug782810.bugzilla.mozilla.org/attachment.cgi?id=714804 -->
<!-- Text related -->
<richlistitem id="context-copy" type="copy" onclick="ContextCommands.copy();">
<label value="&copy.label;"/>
</richlistitem>
<richlistitem id="context-copy-all" type="copy-all" onclick="ContextCommands.copy();">
<label value="&copyAll.label;"/>
<!-- for text inputs, this will copy selected text, or if no text is selected, copy all -->
<richlistitem id="context-copy" type="copy,selectable" onclick="ContextCommands.copy();">
<label value="&contextTextCopy.label;"/>
</richlistitem>
<!-- only displayed if there is text on the clipboard -->
<richlistitem id="context-paste" type="paste" onclick="ContextCommands.paste();">
<label value="&paste.label;"/>
<label value="&contextTextPaste.label;"/>
</richlistitem>
<!-- Search Bing for "..." -->
<richlistitem id="context-search" type="copy,selected-text" onclick="ContextCommands.searchText(this);">
<label id="context-search-label" value=""/>
</richlistitem>
<!-- only display if there is text on the clipboard and the target is the urlbar -->
<richlistitem id="context-paste-n-go" type="paste-url" onclick="ContextCommands.pasteAndGo();">
<label value="&pasteAndGo.label;"/>
<label value="&contextTextPasteAndGo.label;"/>
</richlistitem>
<richlistitem id="context-select-all" type="select-all" onclick="ContextCommands.selectAll();">
<label value="&selectAll.label;"/>
<!-- only displayed in inputs with text that do not have selection -->
<richlistitem id="context-select" type="selectable" onclick="ContextCommands.select();">
<label value="&contextTextSelect.label;"/>
</richlistitem>
<!-- only displayed in inputs with text that do not have selection -->
<richlistitem id="context-select-all" type="selectable" onclick="ContextCommands.selectAll();">
<label value="&contextTextSelectAll.label;"/>
</richlistitem>
<!-- Image related -->
<richlistitem id="context-viewinnewtab" type="image" onclick="ContextCommands.openInNewTab();">
<label value="&contextViewInNewTab.label;"/>
<!-- save image to user pictures library -->
<richlistitem id="context-save-image-lib" type="image" onclick="ContextCommands.saveImageToLib();">
<label value="&contextSaveImageLib.label;"/>
</richlistitem>
<richlistitem id="context-copy-image" type="image-loaded" onclick="ContextCommands.copyImage();">
<!-- copy image data to clipboard -->
<richlistitem id="context-copy-image" type="image" onclick="ContextCommands.copyImage();">
<label value="&contextCopyImage.label;"/>
</richlistitem>
<richlistitem id="context-save-image" type="image-loaded" onclick="ContextCommands.saveImage();">
<label value="&contextSaveImage.label;"/>
<!-- copy the uri of the image src -->
<richlistitem id="context-copy-image-loc" type="image" onclick="ContextCommands.copyImageSrc();">
<label value="&contextCopyImageLocation.label;"/>
</richlistitem>
<richlistitem id="context-save-image-to" type="image-loaded" onclick="ContextCommands.saveImageTo();">
<label value="&contextSaveImageTo.label;"/>
</richlistitem>
<!-- Link related -->
<richlistitem id="context-openinnewtab" type="link-openable" onclick="ContextCommands.openInNewTab();">
<label value="&contextOpenInNewTab.label;"/>
</richlistitem>
<richlistitem id="context-bookmark-link" type="link" onclick="ContextCommands.bookmarkLink();">
<label value="&contextBookmarkLink.label;"/>
</richlistitem>
<richlistitem id="context-copy-link" type="link" onclick="ContextCommands.copyLink();">
<label value="&contextCopyLink.label;"/>
</richlistitem>
<richlistitem id="context-copy-email" type="mailto" onclick="ContextCommands.copyEmail();">
<label value="&contextCopyEmail.label;"/>
</richlistitem>
<richlistitem id="context-copy-phone" type="callto" onclick="ContextCommands.copyPhone();">
<label value="&contextCopyPhone.label;"/>
<!-- open the uri of the image src in a new tab -->
<richlistitem id="context-open-image-tab" type="image" priority="low" onclick="ContextCommands.openImageInNewTab();">
<label value="&contextOpenImageTab.label;"/>
</richlistitem>
<!-- Video related -->
<richlistitem id="context-play-media" type="media-paused" onclick="ContextCommands.sendCommand('play');">
<label value="&contextPlayMedia.label;"/>
<!-- save video to user videos library -->
<richlistitem id="context-save-video-lib" type="video" onclick="ContextCommands.saveVideoToLib();">
<label value="&contextSaveVideoLib.label;"/>
</richlistitem>
<richlistitem id="context-pause-video" type="media-playing" onclick="ContextCommands.sendCommand('pause');">
<label value="&contextPauseMedia.label;"/>
<!-- copy the uri of the video src -->
<richlistitem id="context-copy-video-loc" type="video" onclick="ContextCommands.copyVideoSrc();">
<label value="&contextCopyVideoLocation.label;"/>
</richlistitem>
<richlistitem id="context-videotab" type="video" onclick="ContextCommands.sendCommand('videotab');">
<label value="&contextVideoTab.label;"/>
</richlistitem>
<richlistitem id="context-save-video" type="video" onclick="ContextCommands.saveVideo();">
<label value="&contextSaveVideo.label;"/>
</richlistitem>
<richlistitem id="context-save-video-to" type="video" onclick="ContextCommands.saveVideoTo();">
<label value="&contextSaveVideoTo.label;"/>
<!-- open the uri of the video src in a new tab -->
<richlistitem id="context-open-video-tab" type="video" priority="low" onclick="ContextCommands.openVideoInNewTab();">
<label value="&contextOpenVideoTab.label;"/>
</richlistitem>
<!-- Misc. related -->
<richlistitem id="context-editbookmark" type="edit-bookmark" onclick="ContextCommands.editBookmark();">
<label value="&contextEditBookmark.label;"/>
<!-- Link related -->
<!-- all of these apply to underlying link href values -->
<richlistitem id="context-open-in-new-tab" type="link" onclick="ContextCommands.openLinkInNewTab();">
<label value="&contextOpenLinkTab.label;"/>
</richlistitem>
<richlistitem id="context-removebookmark" type="edit-bookmark" onclick="ContextCommands.removeBookmark();">
<label value="&contextRemoveBookmark.label;"/>
<richlistitem id="context-copy-link" type="link" onclick="ContextCommands.copyLink();">
<label value="&contextCopyLinkHref.label;"/>
</richlistitem>
<richlistitem id="context-bookmark-link" type="link" priority="low" onclick="ContextCommands.bookmarkLink();">
<label value="&contextBookmarkLinkHref.label;"/>
</richlistitem>
<!-- App bar: 'more' button context menu -->
<richlistitem id="context-findinpage" type="find-in-page" onclick="ContextCommands.findInPage();">
<label value="&appbarFindInPage.label;"/>
</richlistitem>

View File

@ -175,6 +175,8 @@ var ContextMenuHandler = {
linkUrl = state.linkURL;
state.linkTitle = popupNode.textContent || popupNode.title;
state.linkProtocol = this._getProtocol(this._getURI(state.linkURL));
// mark as text so we can pickup on selection below
isText = true;
break;
} else if (this._isTextInput(elem)) {
let selectionStart = elem.selectionStart;
@ -188,16 +190,13 @@ var ContextMenuHandler = {
if (selectionStart != selectionEnd) {
state.types.push("copy");
state.string = elem.value.slice(selectionStart, selectionEnd);
} else if (elem.value) {
state.types.push("copy-all");
}
if (elem.value && (selectionStart > 0 || selectionEnd < elem.textLength)) {
state.types.push("selectable");
state.string = elem.value;
}
}
if (selectionStart > 0 || selectionEnd < elem.textLength) {
state.types.push("select-all");
}
if (!elem.textLength) {
state.types.push("input-empty");
}
@ -227,6 +226,7 @@ var ContextMenuHandler = {
elem = elem.parentNode;
}
// Over arching text tests
if (isText) {
// If this is text and has a selection, we want to bring
// up the copy option on the context menu.
@ -334,36 +334,3 @@ var ContextMenuHandler = {
};
ContextMenuHandler.init();
ContextMenuHandler.registerType("mailto", function(aState, aElement) {
return aState.linkProtocol == "mailto";
});
ContextMenuHandler.registerType("callto", function(aState, aElement) {
let protocol = aState.linkProtocol;
return protocol == "tel" || protocol == "callto" || protocol == "sip" || protocol == "voipto";
});
ContextMenuHandler.registerType("link-openable", function(aState, aElement) {
return Util.isOpenableScheme(aState.linkProtocol);
});
["image", "video"].forEach(function(aType) {
ContextMenuHandler.registerType(aType+"-shareable", function(aState, aElement) {
if (aState.types.indexOf(aType) == -1)
return false;
let protocol = ContextMenuHandler._getProtocol(ContextMenuHandler._getURI(aState.mediaURL));
return Util.isShareableScheme(protocol);
});
});
ContextMenuHandler.registerType("image-loaded", function(aState, aElement) {
if (aState.types.indexOf("image") != -1) {
let request = aElement.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
return true;
}
return false;
});

View File

@ -55,6 +55,7 @@ var SelectionHandler = {
init: function init() {
addMessageListener("Browser:SelectionStart", this);
addMessageListener("Browser:SelectionAttach", this);
addMessageListener("Browser:SelectionEnd", this);
addMessageListener("Browser:SelectionMoveStart", this);
addMessageListener("Browser:SelectionMove", this);
@ -68,6 +69,7 @@ var SelectionHandler = {
shutdown: function shutdown() {
removeMessageListener("Browser:SelectionStart", this);
removeMessageListener("Browser:SelectionAttach", this);
removeMessageListener("Browser:SelectionEnd", this);
removeMessageListener("Browser:SelectionMoveStart", this);
removeMessageListener("Browser:SelectionMove", this);
@ -114,6 +116,17 @@ var SelectionHandler = {
this._updateSelectionUI(true, true);
},
_onSelectionAttach: function _onSelectionAttach(aX, aY) {
// Init content window information
if (!this._initTargetInfo(aX, aY)) {
this._onFail("failed to get frame offset");
return;
}
// Update the position of our selection monocles
this._updateSelectionUI(true, true);
},
/*
* Selection monocle start move event handler
*/
@ -894,6 +907,10 @@ var SelectionHandler = {
this._onSelectionStart(json.xPos, json.yPos);
break;
case "Browser:SelectionAttach":
this._onSelectionAttach(json.xPos, json.yPos);
break;
case "Browser:SelectionClose":
this._onSelectionClose();
break;

View File

@ -118,14 +118,54 @@ var ContextMenuUI = {
this._popupState.target = aMessage.target;
let contentTypes = this._popupState.types;
let optionsAvailable = false;
for (let i = 0; i < this._commands.childElementCount; i++) {
let command = this._commands.childNodes[i];
command.hidden = true;
/*
* Types in ContextMenuHandler:
* image
* link
* input-text - generic form input control
* copy - form input that has some selected text
* selectable - form input with text that can be selected
* input-empty - form input (empty)
* paste - form input and there's text on the clipboard
* selected-text - generic content text that is selected
* content-text - generic content text
* video
* media-paused, media-playing
* paste-url - url bar w/text on the clipboard
*/
Util.dumpLn("contentTypes:", contentTypes);
// Defines whether or not low priority items in images, text, and
// links are displayed.
let multipleMediaTypes = false;
if (contentTypes.indexOf("link") != -1 &&
(contentTypes.indexOf("image") != -1 ||
contentTypes.indexOf("video") != -1 ||
contentTypes.indexOf("selected-text") != -1))
multipleMediaTypes = true;
for (let command of Array.slice(this._commands.childNodes)) {
command.hidden = true;
}
let optionsAvailable = false;
for (let command of Array.slice(this._commands.childNodes)) {
let types = command.getAttribute("type").split(",");
let lowPriority = (command.hasAttribute("priority") &&
command.getAttribute("priority") == "low");
let searchTextItem = (command.id == "context-search");
// filter low priority items if we have more than one media type.
if (multipleMediaTypes && lowPriority)
continue;
let types = command.getAttribute("type").split(/\s+/);
for (let i = 0; i < types.length; i++) {
if (contentTypes.indexOf(types[i]) != -1) {
// If this is the special search text item, we need to set its label dynamically.
if (searchTextItem && !ContextCommands.searchTextSetup(command, this._popupState.string)) {
break;
}
optionsAvailable = true;
command.hidden = false;
break;
@ -138,14 +178,7 @@ var ContextMenuUI = {
return false;
}
this._menuPopup.show(this._popupState);
let event = document.createEvent("Events");
event.initEvent("CancelTouchSequence", true, false);
if (this._popupState.target) {
this._popupState.target.dispatchEvent(event);
}
return true;
},
@ -303,6 +336,10 @@ MenuPopup.prototype = {
this._panel.addEventListener("transitionend", function () {
self._panel.removeEventListener("transitionend", arguments.callee);
self._panel.removeAttribute("showingfrom");
let event = document.createEvent("Events");
event.initEvent("popupshown", true, false);
document.dispatchEvent(event);
});
let popupFrom = (aPositionOptions.forcePosition && !aPositionOptions.bottomAligned) ? "above" : "below";
@ -326,6 +363,9 @@ MenuPopup.prototype = {
self._panel.removeEventListener("transitionend", arguments.callee);
self._panel.hidden = true;
self._popupState = null;
let event = document.createEvent("Events");
event.initEvent("popuphidden", true, false);
document.dispatchEvent(event);
});
this._panel.removeAttribute("showing");

View File

@ -226,9 +226,6 @@ var SelectionHelperUI = {
* the section.
*/
openEditSession: function openEditSession(aMessage) {
if (!this.canHandle(aMessage))
return;
/*
* aMessage - from _onContentContextMenu in ContextMenuHandler
* name: aMessage.name,
@ -265,22 +262,42 @@ var SelectionHelperUI = {
this._setupDebugOptions();
},
/*
* attachEditSession
*
* Attaches to existing selection and begins editing.
*/
attachEditSession: function attachEditSession(aMessage) {
this._popupState = aMessage.json;
this._popupState._target = aMessage.target;
this._init();
Util.dumpLn("enableSelection target:", this._popupState._target);
// Set the track bounds for each marker NIY
this.startMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
this.endMark.setTrackBounds(this._popupState.xPos, this._popupState.yPos);
// Send this over to SelectionHandler in content, they'll message us
// back with information on the current selection.
this._popupState._target.messageManager.sendAsyncMessage(
"Browser:SelectionAttach",
{ xPos: this._popupState.xPos,
yPos: this._popupState.yPos });
this._setupDebugOptions();
},
/*
* canHandle
*
* Determines if we can handle a ContextMenuHandler message.
*/
canHandle: function canHandle(aMessage) {
// Reject empty text inputs, nothing to do here
if (aMessage.json.types.indexOf("input-empty") != -1) {
return false;
}
// Input with text or general text in a page
if (aMessage.json.types.indexOf("content-text") == -1 &&
aMessage.json.types.indexOf("input-text") == -1) {
return false;
}
return true;
if (aMessage.json.types.indexOf("content-text") != -1)
return true;
return false;
},
/*

View File

@ -165,8 +165,6 @@ var TouchModule = {
this._targetScrollbox = null;
this._targetScrollInterface = null;
this._cleanClickBuffer();
},
_onContextMenu: function _onContextMenu(aEvent) {

View File

@ -11,7 +11,7 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_FILES = \
BROWSER_TESTS = \
head.js \
browser_test.js \
browser_canonizeURL.js \
@ -23,7 +23,17 @@ _BROWSER_FILES = \
browser_plugin_input.html \
browser_plugin_input_mouse.js \
browser_plugin_input_keyboard.js \
browser_context_menu_tests.js \
browser_context_menu_tests_01.html \
browser_context_menu_tests_02.html \
$(NULL)
libs:: $(_BROWSER_FILES)
BROWSER_TEST_RESOURCES = \
res\image01.png \
$(NULL)
libs:: $(BROWSER_TESTS)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/
libs:: $(BROWSER_TEST_RESOURCES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/metro/res

View File

@ -0,0 +1,402 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function debugClipFlavors(aClip)
{
let xfer = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
xfer.init(null);
aClip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard);
let array = xfer.flavorsTransferableCanExport();
let count = array.Count();
info("flavors:" + count);
for (let idx = 0; idx < count; idx++) {
let string = array.GetElementAt(idx).QueryInterface(Ci.nsISupportsString);
info("[" + idx + "] " + string);
}
}
// XXX won't work with out of process content
function emptyClipboard() {
Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard)
.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard);
}
// Image context menu tests
gTests.push({
desc: "text context menu",
run: function test() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
info(chromeRoot + "browser_context_menu_tests_02.html");
yield addTab(chromeRoot + "browser_context_menu_tests_02.html");
purgeEventQueue();
let win = Browser.selectedTab.browser.contentWindow;
yield hideContextUI();
////////////////////////////////////////////////////////////
// Context menu in content on selected text
// select some text
let span = win.document.getElementById("text1");
win.getSelection().selectAllChildren(span);
// invoke selection context menu
let promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, span, 85, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
// selected text context:
checkContextUIMenuItemVisibility(["context-copy",
"context-search"]);
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
win.getSelection().removeAllRanges();
////////////////////////////////////////////////////////////
// Context menu in content on selected text that includes a link
// invoke selection with link context menu
let link = win.document.getElementById("text2-link");
win.getSelection().selectAllChildren(link);
promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, link, 40, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
// selected text context:
checkContextUIMenuItemVisibility(["context-copy",
"context-search",
"context-open-in-new-tab",
"context-copy-link"]);
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
win.getSelection().removeAllRanges();
////////////////////////////////////////////////////////////
// Context menu in content on a link
link = win.document.getElementById("text2-link");
promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, link, 40, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
// selected text context:
checkContextUIMenuItemVisibility(["context-open-in-new-tab",
"context-copy-link",
"context-bookmark-link"]);
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
////////////////////////////////////////////////////////////
// context in input with no selection, no data on clipboard
emptyClipboard();
let input = win.document.getElementById("text3-input");
promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, input, 20, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
checkContextUIMenuItemVisibility(["context-copy",
"context-select",
"context-select-all"]);
// copy menu item should copy all text
let menuItem = document.getElementById("context-copy");
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
let string = SpecialPowers.getClipboardData("text/unicode");
ok(string, "hello, I'm sorry but I must be going.", "copy all");
emptyClipboard();
////////////////////////////////////////////////////////////
// context in input with text selection, no data on clipboard
input = win.document.getElementById("text3-input");
input.select();
promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, input, 20, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
// selected text context:
checkContextUIMenuItemVisibility(["context-copy",
"context-search"]);
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
////////////////////////////////////////////////////////////
// context in input with no selection, data on clipboard
SpecialPowers.clipboardCopyString("foo");
input = win.document.getElementById("text3-input");
input.select();
promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, input, 20, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
// selected text context:
checkContextUIMenuItemVisibility(["context-copy",
"context-search",
"context-paste"]);
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
////////////////////////////////////////////////////////////
// context in empty input, data on clipboard (paste operation)
SpecialPowers.clipboardCopyString("foo");
input = win.document.getElementById("text3-input");
input.value = "";
promise = waitForEvent(document, "popupshown");
sendContextMenuClickToElement(win, input, 20, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should be visible
ok(ContextMenuUI._menuPopup._visible, "is visible");
// selected text context:
checkContextUIMenuItemVisibility(["context-paste"]);
promise = waitForEvent(document, "popuphidden");
ContextMenuUI.hide();
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
////////////////////////////////////////////////////////////
// context in empty input, no data on clipboard (??)
emptyClipboard();
input = win.document.getElementById("text3-input");
input.value = "";
promise = waitForEvent(Elements.tray, "transitionend");
sendContextMenuClickToElement(win, input, 20, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
// should *not* be visible
ok(!ContextMenuUI._menuPopup._visible, "is visible");
// the test above will invoke the app bar
yield hideContextUI();
Browser.closeTab(Browser.selectedTab);
purgeEventQueue();
}
});
// Image context menu tests
gTests.push({
desc: "image context menu",
run: function test() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
info(chromeRoot + "browser_context_menu_tests_01.html");
yield addTab(chromeRoot + "browser_context_menu_tests_01.html");
let win = Browser.selectedTab.browser.contentWindow;
purgeEventQueue();
yield hideContextUI();
// If we don't do this, sometimes the first sendContextMenuClick
// will trigger the app bar.
yield waitForImageLoad(win, "image01");
////////////////////////////////////////////////////////////
// Context menu options
// image01 - 1x1x100x100
let promise = waitForEvent(document, "popupshown");
sendContextMenuClick(win, 10, 10);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
purgeEventQueue();
ok(ContextMenuUI._menuPopup._visible, "is visible");
checkContextUIMenuItemVisibility(["context-save-image-lib",
"context-copy-image",
"context-copy-image-loc",
"context-open-image-tab"]);
////////////////////////////////////////////////////////////
// Save to image library
let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
let saveLocationPath = dirSvc.get("Pict", Components.interfaces.nsIFile);
saveLocationPath.append("image01.png");
registerCleanupFunction(function () {
saveLocationPath.remove(false);
});
if (saveLocationPath.exists()) {
info("had to remove old image!");
saveLocationPath.remove(false);
}
let menuItem = document.getElementById("context-save-image-lib");
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let downloadPromise = waitForObserver("dl-done");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
yield downloadPromise;
ok(downloadPromise && !(downloadPromise instanceof Error), "promise error");
purgeEventQueue();
ok(saveLocationPath.exists(), "image saved");
////////////////////////////////////////////////////////////
// Copy image
let promise = waitForEvent(document, "popupshown");
sendContextMenuClick(win, 20, 20);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
ok(ContextMenuUI._menuPopup._visible, "is visible");
menuItem = document.getElementById("context-copy-image");
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
purgeEventQueue();
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
let flavors = ["image/png"];
ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my png flavor");
////////////////////////////////////////////////////////////
// Copy image location
promise = waitForEvent(document, "popupshown");
sendContextMenuClick(win, 30, 30);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
ok(ContextMenuUI._menuPopup._visible, "is visible");
menuItem = document.getElementById("context-copy-image-loc");
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
purgeEventQueue();
let clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
let flavors = ["text/unicode"];
ok(clip.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard), "clip has my text flavor");
let xfer = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
xfer.init(null);
xfer.addDataFlavor("text/unicode");
clip.getData(xfer, Ci.nsIClipboard.kGlobalClipboard);
let str = new Object();
let strLength = new Object();
xfer.getTransferData("text/unicode", str, strLength);
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
ok(str == "chrome://mochitests/content/metro/res/image01.png", "url copied");
////////////////////////////////////////////////////////////
// Open image in new tab
promise = waitForEvent(document, "popupshown");
sendContextMenuClick(win, 40, 40);
yield promise;
ok(promise && !(promise instanceof Error), "promise error");
ok(ContextMenuUI._menuPopup._visible, "is visible");
menuItem = document.getElementById("context-open-image-tab");
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let tabPromise = waitForEvent(document, "TabOpen");
popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise;
let event = yield tabPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
ok(tabPromise && !(tabPromise instanceof Error), "promise error");
purgeEventQueue();
let imagetab = Browser.getTabFromChrome(event.originalTarget);
ok(imagetab != null, "tab created");
ok(imagetab.browser.currentURI.spec == "chrome://mochitests/content/metro/res/image01.png", "tab location");
Browser.closeTab(imagetab);
}
});
function test() {
runTests();
}

View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body style="padding: 1px; margin: 1px;">
<div style="margin: 0; padding: 0;">
<span>
<img id="image01" width="100" height="100" src="./res/image01.png" />
</span>
</div>
</body>
</html>

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body style="padding: 10px; margin: 10px;">
<div style="margin: 0; padding: 5px;">
<span id="text1">hello, I'm sorry but I must be going.</span>
</div>
<div style="margin: 0; padding: 5px;">
<span id="text2"><a id="text2-link" href="#test">hello, I'm sorry but</a> I must be going.</span>
</div>
<div style="margin: 0; padding: 5px;">
<span id="text3"><input id="text3-input" value="hello, I'm sorry but I must be going." style="width:200px;"/></span>
</div>
</body>
</html>

View File

@ -18,6 +18,53 @@ const chromeRoot = getRootDirectory(gTestPath);
const kDefaultWait = 10000;
const kDefaultInterval = 50;
/*=============================================================================
Metro ui helpers
=============================================================================*/
function checkContextUIMenuItemCount(aCount)
{
let visibleCount = 0;
for (let idx = 0; idx < ContextMenuUI._commands.childNodes.length; idx++) {
if (!ContextMenuUI._commands.childNodes[idx].hidden)
visibleCount++;
}
is(visibleCount, aCount, "command list count");
}
function checkContextUIMenuItemVisibility(aVisibleList)
{
let errors = 0;
for (let idx = 0; idx < ContextMenuUI._commands.childNodes.length; idx++) {
let item = ContextMenuUI._commands.childNodes[idx];
if (aVisibleList.indexOf(item.id) != -1 && item.hidden) {
// item should be visible
errors++;
info("should be visible:" + item.id);
} else if (aVisibleList.indexOf(item.id) == -1 && !item.hidden) {
// item should be hidden
errors++;
info("should be hidden:" + item.id);
}
}
is(errors, 0, "context menu item list visibility");
}
/*=============================================================================
Asynchronous Metro ui helpers
=============================================================================*/
function hideContextUI()
{
purgeEventQueue();
if (ContextUI.isVisible) {
info("is visible, waiting...");
let promise = waitForEvent(Elements.tray, "transitionend");
ContextUI.dismiss();
return promise;
}
}
/*=============================================================================
Asynchronous test helpers
=============================================================================*/
@ -66,6 +113,7 @@ function addTab(aUrl) {
* @returns a Promise that resolves to the received event, or to an Error
*/
function waitForEvent(aSubject, aEventName, aTimeoutMs) {
info("waitForEvent: on " + aSubject + " event: " + aEventName);
let eventDeferred = Promise.defer();
let timeoutMs = aTimeoutMs || kDefaultWait;
let timerID = setTimeout(function wfe_canceller() {
@ -162,6 +210,78 @@ function waitForCondition(aCondition, aTimeoutMs, aIntervalMs) {
return deferred.promise;
}
/*
* Waits for an image in a page to load. Wrapper around waitForCondition.
*
* @param aWindow the tab or window that contains the image.
* @param aImageId the id of the image in the page.
* @returns a Promise that resolves to true, or to an Error
*/
function waitForImageLoad(aWindow, aImageId) {
let elem = aWindow.document.getElementById(aImageId);
return waitForCondition(function () {
let request = elem.getRequest(Ci.nsIImageLoadingContent.CURRENT_REQUEST);
if (request && (request.imageStatus & request.STATUS_SIZE_AVAILABLE))
return true;
return false;
}, 5000, 100);
}
/**
* Waits a specified number of miliseconds for an observer event.
*
* @param aObsEvent the observer event to wait for
* @param aTimeoutMs the number of miliseconds to wait before giving up
* @returns a Promise that resolves to true, or to an Error
*/
function waitForObserver(aObsEvent, aTimeoutMs) {
try {
let deferred = Promise.defer();
let timeoutMs = aTimeoutMs || kDefaultWait;
let timerID = 0;
var observeWatcher = {
onEvent: function () {
clearTimeout(timerID);
Services.obs.removeObserver(this, aObsEvent);
deferred.resolve();
},
onError: function () {
clearTimeout(timerID);
Services.obs.removeObserver(this, aObsEvent);
deferred.reject(new Error(aObsEvent + " event timeout"));
},
observe: function (aSubject, aTopic, aData) {
if (aTopic == aObsEvent) {
this.onEvent();
}
},
QueryInterface: function (aIID) {
if (!aIID.equals(Ci.nsIObserver) &&
!aIID.equals(Ci.nsISupportsWeakReference) &&
!aIID.equals(Ci.nsISupports)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
}
timerID = setTimeout(function wfo_canceller() {
observeWatcher.onError();
}, timeoutMs);
Services.obs.addObserver(observeWatcher, aObsEvent, true);
return deferred.promise;
} catch (ex) {
info(ex.message);
}
}
/*=============================================================================
Native input synthesis helpers
=============================================================================*/
@ -246,6 +366,41 @@ function synthesizeNativeMouseMUp(aElement, aOffsetX, aOffsetY) {
0x0040); // MOUSEEVENTF_MIDDLEUP
}
/*
* sendContextMenuClick - simulates a press-hold touch input event.
*/
function sendContextMenuClick(aWindow, aX, aY) {
let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.sendMouseEventToWindow("contextmenu", aX, aY, 2, 1, 0, true,
1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
}
function sendContextMenuClickToElement(aWindow, aElement, aX, aY) {
let utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
let rect = aElement.getBoundingClientRect();
utils.sendMouseEventToWindow("contextmenu", rect.left + aX, rect.top + aY, 2, 1, 0, true,
1, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH);
}
/*=============================================================================
System utilities
=============================================================================*/
/*
* purgeEventQueue - purges the event queue on the calling thread.
* Pumps latent in-process message manager events awaiting delivery.
*/
function purgeEventQueue() {
let thread = Services.tm.currentThread;
while (thread.hasPendingEvents()) {
if (!thread.processNextEvent(true))
break;
}
}
/*=============================================================================
Test-running helpers
=============================================================================*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -7,26 +7,12 @@
<!ENTITY back.label "Back">
<!ENTITY forward.label "Forward">
<!ENTITY reload.label "Reload">
<!ENTITY stop.label "Stop">
<!ENTITY go.label "Go">
<!ENTITY star.label "Star">
<!ENTITY toggleTabsOnly.label "Always show tabs">
<!ENTITY showTabs.label "Show Tabs">
<!ENTITY newtab.label "New Tab">
<!ENTITY closetab.label "Close Tab">
<!ENTITY undoclosetab.label "Undo Close Tab">
<!ENTITY cut.label "Cut">
<!ENTITY copy.label "Copy">
<!ENTITY copyAll.label "Copy All">
<!ENTITY copylink.label "Copy Link Location">
<!ENTITY paste.label "Paste">
<!ENTITY pasteAndGo.label "Paste &amp; Go">
<!ENTITY delete.label "Delete">
<!ENTITY selectAll.label "Select All">
<!ENTITY appbarFindInPage.label "Find in Page">
<!ENTITY appbarViewOnDesktop.label "View on Desktop">
@ -38,8 +24,6 @@
<!ENTITY autocompleteResultsHeader.label "Your Results">
<!ENTITY autocompleteSearchesHeader.label "Internet Searches">
<!ENTITY selectHelper.done "Done">
<!ENTITY downloadsHeader.label "Downloads">
<!ENTITY downloadShowPage.label "Go to Page">
<!ENTITY downloadShow2.label "Find">
@ -76,26 +60,31 @@
<!ENTITY consoleErrLine.label "Line:">
<!ENTITY consoleErrColumn.label "Column:">
<!ENTITY contextOpenInNewTab.label "Open Link in New Tab">
<!ENTITY contextViewInNewTab.label "View in New Tab">
<!ENTITY contextSaveImage.label "Save Image">
<!ENTITY contextSaveImageTo.label "Save Image To">
<!ENTITY contextCopyLink.label "Copy Link">
<!ENTITY contextCopyEmail.label "Copy Email Address">
<!ENTITY contextCopyPhone.label "Copy Phone Number">
<!ENTITY contextCopyImage.label "Copy Image">
<!ENTITY contextShareLink.label "Share Link">
<!ENTITY contextShareImage.label "Share Image">
<!ENTITY contextBookmarkLink.label "Bookmark Link">
<!ENTITY contextSaveVideo.label "Save Video">
<!ENTITY contextSaveVideoTo.label "Save Video To">
<!ENTITY contextShareVideo.label "Share Video">
<!ENTITY contextPlayMedia.label "Play">
<!ENTITY contextPauseMedia.label "Pause">
<!ENTITY contextVideoTab.label "Open In New Tab">
<!ENTITY contextEditBookmark.label "Edit">
<!ENTITY contextRemoveBookmark.label "Remove">
<!ENTITY contextShortcutBookmark.label "Add to Home Screen">
<!-- TEXT CONTEXT MENU -->
<!ENTITY contextTextCopy.label "Copy">
<!ENTITY contextTextPaste.label "Paste">
<!-- unique item that is only added to the url bar context menu -->
<!ENTITY contextTextPasteAndGo.label "Paste &amp; go">
<!ENTITY contextTextSelect.label "Select">
<!ENTITY contextTextSelectAll.label "Select all">
<!-- LINK CONTEXT MENU -->
<!ENTITY contextOpenLinkTab.label "Open link in new tab">
<!ENTITY contextCopyLinkHref.label "Copy link">
<!ENTITY contextBookmarkLinkHref.label "Bookmark link">
<!-- IMAGE CONTEXT MENU -->
<!-- l10n: contextSaveImageLib saves an image to the users "pictures library"
(Explorer -> left hand side navigation ppane -> Libraries -> Pictures) -->
<!ENTITY contextSaveImageLib.label "Save to picture library">
<!ENTITY contextCopyImage.label "Copy image">
<!ENTITY contextCopyImageLocation.label "Copy image location">
<!ENTITY contextOpenImageTab.label "Open image in new tab">
<!-- VIDEO CONTEXT MENU -->
<!ENTITY contextSaveVideoLib.label "Save to video library">
<!ENTITY contextCopyVideoLocation.label "Copy video location">
<!ENTITY contextOpenVideoTab.label "Open video in new tab">
<!ENTITY pageactions.password.forget "Forget Password">
<!ENTITY pageactions.reset "Clear Site Preferences">

View File

@ -10,6 +10,9 @@ browser.search.order.1=Bing
browser.search.order.2=Google
browser.search.order.3=Yahoo
# l10n: search context menu item text will be: |Search (browser.search.defaultenginename) for ".."
browser.search.contextTextSearchLabel=Search %S for ".."
# Settings Charms
aboutCharm1=About
optionsCharm=Options
@ -135,5 +138,6 @@ browser.menu.showCharacterEncoding=false
# values for charsets that the user can select from in the Character Encoding menu.
intl.charsetmenu.browser.static=iso-8859-1,utf-8,x-gbk,big5,iso-2022-jp,shift_jis,euc-jp
#Text Selection
# Selection alerts
selectionHelper.textCopied=Text copied to clipboard
selectionHelper.linkCopied=Link copied to clipboard

View File

@ -22,7 +22,7 @@ pref("metro.debug.selection.dumpRanges", false);
pref("metro.debug.selection.dumpEvents", false);
// Form helper options: 0 = disabled, 1 = enabled, 2 = dynamic depending on screen size
pref("formhelper.mode", 1);
pref("formhelper.mode", 0);
// Auto zoom to form elements when they take focus
pref("formhelper.autozoom", true);
// Auto zoom to the caret

View File

@ -20,6 +20,7 @@
#include <strsafe.h>
#include <io.h>
#include <shellapi.h>
#include <wininet.h>
#ifdef SHOW_CONSOLE
#define DEBUG_DELAY_SHUTDOWN 1
@ -438,6 +439,46 @@ bool CExecuteCommandVerb::IsTargetBrowser()
return false;
}
namespace {
const FORMATETC kPlainTextFormat =
{CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
const FORMATETC kPlainTextWFormat =
{CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
}
bool HasPlainText(IDataObject* aDataObj) {
return SUCCEEDED(aDataObj->QueryGetData((FORMATETC*)&kPlainTextWFormat)) ||
SUCCEEDED(aDataObj->QueryGetData((FORMATETC*)&kPlainTextFormat));
}
bool GetPlainText(IDataObject* aDataObj, CStringW& cstrText)
{
if (!HasPlainText(aDataObj))
return false;
STGMEDIUM store;
// unicode text
if (SUCCEEDED(aDataObj->GetData((FORMATETC*)&kPlainTextWFormat, &store))) {
// makes a copy
cstrText = static_cast<LPCWSTR>(GlobalLock(store.hGlobal));
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
return true;
}
// ascii text
if (SUCCEEDED(aDataObj->GetData((FORMATETC*)&kPlainTextFormat, &store))) {
// makes a copy
cstrText = static_cast<char*>(GlobalLock(store.hGlobal));
GlobalUnlock(store.hGlobal);
ReleaseStgMedium(&store);
return true;
}
return false;
}
/*
* Updates the current target based on the contents of
* a shell item.
@ -447,15 +488,42 @@ bool CExecuteCommandVerb::SetTargetPath(IShellItem* aItem)
if (!aItem)
return false;
CString cstrText;
CComPtr<IDataObject> object;
// Check the underlying data object first to insure we get
// absolute uri. See chromium bug 157184.
if (SUCCEEDED(aItem->BindToHandler(NULL, BHID_DataObject,
IID_IDataObject,
reinterpret_cast<void**>(&object))) &&
GetPlainText(object, cstrText)) {
wchar_t scheme[16];
URL_COMPONENTS components = {0};
components.lpszScheme = scheme;
components.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
components.dwStructSize = sizeof(components);
// note, more advanced use may have issues with paths with spaces.
if (!InternetCrackUrlW(cstrText, 0, 0, &components)) {
Log(L"Failed to identify object text '%s'", cstrText);
return false;
}
mTargetIsFileSystemLink = (components.nScheme == INTERNET_SCHEME_FILE);
mTarget = cstrText;
return true;
}
Log(L"No data object or data object has no text.");
// Use the shell item display name
LPWSTR str = NULL;
mTargetIsFileSystemLink = true;
if (FAILED(aItem->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
mTargetIsFileSystemLink = false;
if (FAILED(aItem->GetDisplayName(SIGDN_URL, &str))) {
Log(L"Failed to get parameter string.");
return false;
}
mTargetIsFileSystemLink = false;
}
mTarget = str;
CoTaskMemFree(str);
return true;
@ -477,7 +545,9 @@ void CExecuteCommandVerb::LaunchDesktopBrowser()
CStringW params;
if (!IsTargetBrowser()) {
params += "-url ";
params += "\"";
params += mTarget;
params += "\"";
}
Log(L"Desktop Launch: verb:%s exe:%s params:%s", mVerb, browserPath, params);

View File

@ -35,6 +35,7 @@ OS_LIBS = \
shlwapi.lib \
propsys.lib \
advapi32.lib \
wininet.lib \
$(NULL)
DEFINES += -DUNICODE -D_UNICODE -DNS_NO_XPCOM

View File

@ -125,7 +125,7 @@ select[size][multiple],
/* For both mouse and touch, single-selects are handled by the SelectHelper popup.
* Suppress mouse events on the popup itself. See also ../base/content/cursor.css */
select[size=1] :-moz-any(option, optgroup),
select[size="1"] :-moz-any(option, optgroup),
select:not([size]):not([multiple]) :-moz-any(option, optgroup) {
pointer-events: none;
}

View File

@ -9,7 +9,7 @@
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
%include ../browserShared.inc
%include ../shared/browser.inc
%filter substitution
%define toolbarHighlight rgba(255,255,255,.3)
%define selectedTabHighlight rgba(255,255,255,.8) 1px, rgba(255,255,255,.5) 3px
@ -1972,135 +1972,6 @@ toolbar[mode="text"] toolbarbutton.chevron > .toolbarbutton-icon {
margin-left: 1em;
}
/* Highlighter */
.highlighter-outline {
box-shadow: 0 0 0 1px black;
outline: 1px dashed white;
outline-offset: -1px;
}
.highlighter-outline[locked] {
box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
outline-color: rgba(255,255,255,0.7);
}
/* Developer toolbar */
#developer-toolbar {
border-top: 1px solid hsla(210, 8%, 5%, .65);
}
/* Highlighter - Node Infobar */
.highlighter-nodeinfobar {
color: hsl(200, 100%, 65%);
border: 1px solid hsla(210, 19%, 63%, .5);
border-radius: 3px;
background: linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
}
/* Highlighter - Node Infobar - text */
.highlighter-nodeinfobar-text {
/* 100% - size of the buttons and margins */
max-width: calc(100% - 2 * (26px + 6px));
padding-bottom: 1px;
}
html|*.highlighter-nodeinfobar-tagname {
color: white;
}
html|*.highlighter-nodeinfobar-id {
color: hsl(90, 79%, 52%);
}
html|*.highlighter-nodeinfobar-pseudo-classes {
color: hsl(20, 100%, 70%);
}
/* Highlighter - Node Infobar - buttons */
.highlighter-nodeinfobar-button {
-moz-appearance: none;
border: 0 solid hsla(210,8%,5%,.45);
padding: 0;
width: 26px;
min-height: 26px;
}
.highlighter-nodeinfobar-inspectbutton {
-moz-border-end-width: 1px;
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-end: 6px;
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
.highlighter-nodeinfobar-inspectbutton:-moz-locale-dir(rtl) {
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-inspectbutton:active:hover,
.highlighter-nodeinfobar-container:not([locked]) > .highlighter-nodeinfobar > .highlighter-nodeinfobar-inspectbutton {
-moz-image-region: rect(0px 32px 16px 16px);
}
.highlighter-nodeinfobar-menu {
-moz-border-start-width: 1px;
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-start: 6px;
}
.highlighter-nodeinfobar-menu:-moz-locale-dir(rtl) {
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-menu > .toolbarbutton-menu-dropmarker {
-moz-appearance: none !important;
list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-moz-box-align: center;
-moz-margin-start: -1px;
}
/* Highlighter - Node Infobar - box & arrow */
.highlighter-nodeinfobar-arrow {
width: 14px;
height: 14px;
-moz-margin-start: calc(50% - 7px);
transform: rotate(-45deg);
border: 1px solid transparent;
background-clip: padding-box;
background-repeat: no-repeat;
}
.highlighter-nodeinfobar-arrow-top {
margin-bottom: -8px;
margin-top: 8px;
border-right-color: hsla(210, 19%, 63%, .5);
border-top-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to top right, transparent 50%, hsl(209, 18%, 30%) 50%);
}
.highlighter-nodeinfobar-arrow-bottom {
margin-top: -8px;
margin-bottom: 8px;
border-left-color: hsla(210, 19%, 63%, .5);
border-bottom-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to bottom left, transparent 50%, hsl(210, 24%, 16%) 50%);
}
.highlighter-nodeinfobar-container[position="top"] > .highlighter-nodeinfobar,
.highlighter-nodeinfobar-container[position="overlap"] > .highlighter-nodeinfobar {
box-shadow: 0 1px 0 hsla(0, 0%, 100%, .1) inset;
}
.highlighter-nodeinfobar-container[hide-arrow] > .highlighter-nodeinfobar {
margin: 7px 0;
}
#full-screen-warning-message {
background-color: hsl(0,0%,15%);
color: white;
@ -2127,149 +1998,35 @@ html|*.highlighter-nodeinfobar-pseudo-classes {
font-size: 120%;
}
html|*#gcli-tooltip-frame,
html|*#gcli-output-frame {
padding: 0;
border-width: 0;
background-color: transparent;
/* Developer toolbar */
#developer-toolbar {
border-top: 1px solid hsla(210, 8%, 5%, .65);
}
%include ../shared/devtools/responsivedesign.inc.css
%include ../shared/devtools/highlighter.inc.css
%include ../shared/devtools/commandline.inc.css
.gcli-panel {
padding: 0;
}
#gcli-output,
#gcli-tooltip {
border-width: 0;
background-color: transparent;
-moz-appearance: none;
margin-bottom: -2px;
}
.gclitoolbar-input-node,
.gclitoolbar-complete-node,
.gclitoolbar-prompt {
margin: 0;
-moz-margin-end: 5px;
-moz-box-align: center;
padding-top: 0;
padding-bottom: 0;
padding-right: 4px;
border: 1px solid transparent;
border-radius: 3px;
text-shadow: none;
}
.gclitoolbar-input-node {
padding-left: 20px;
background-color: transparent;
-moz-appearance: none;
border-color: hsl(210,11%,10%);
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
}
.gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
background-color: hsl(210,30%,85%);
color: hsl(210,11%,16%);
text-shadow: none;
}
.gclitoolbar-complete-node {
padding-left: 21px;
background-color: transparent;
color: transparent;
}
.gclitoolbar-prompt {
padding-left: 4px;
padding-bottom: 2px;
font-size: 150%;
font-weight: bold;
color: hsl(210,30%,85%);
background-color: hsl(210,11%,16%);
}
.gclitoolbar-prompt-label,
.gcli-in-incomplete,
.gcli-in-error,
.gcli-in-ontab,
.gcli-in-todo,
.gcli-in-closebrace,
.gcli-in-param,
.gcli-in-valid {
margin: 0;
padding: 0;
}
.gcli-in-incomplete {
border-bottom: 2px dotted #999;
}
.gcli-in-error {
border-bottom: 2px dotted #F00;
}
.gcli-in-ontab {
color: hsl(210,0%,35%);
}
.gcli-in-todo {
color: hsl(210,50%,35%);
}
.gcli-in-closebrace {
color: hsl(0,0%,80%);
}
/* Responsive Mode */
.browserContainer[responsivemode] {
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
padding: 0 20px 20px 20px;
}
.browserStack[responsivemode] {
box-shadow: 0 0 7px black;
}
.devtools-responsiveui-toolbar {
background: transparent;
margin: 10px 0;
padding: 0;
box-shadow: none;
}
.devtools-responsiveui-toolbar > menulist,
.devtools-responsiveui-toolbar > toolbarbutton {
min-width: 22px;
border-radius: 0;
}
.devtools-responsiveui-toolbar:-moz-locale-dir(ltr) > *:first-child,
.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) > *:last-child {
margin-left: 0;
}
.devtools-responsiveui-resizebar {
width: 7px;
height: 24px;
cursor: ew-resize;
transform: translate(12px, -12px);
background-image: url("chrome://browser/skin/devtools/responsive-vertical-resizer.png");
}
.devtools-responsiveui-resizehandle {
width: 16px;
height: 16px;
cursor: se-resize;
transform: translate(12px, 12px);
background-image: url("chrome://browser/skin/devtools/responsive-se-resizer.png");
}
/* Web Console */
.web-console-frame {
@ -2396,152 +2153,39 @@ html|*#gcli-output-frame {
padding: 0;
}
.chat-status-icon {
max-height: 16px;
max-width: 16px;
padding: 0;
}
.chat-toolbarbutton {
-moz-appearance: none;
border: none;
padding: 0;
margin: 0;
background: none;
}
.chat-toolbarbutton > .toolbarbutton-text {
display: none;
}
.chat-close-button {
list-style-image: url('chrome://browser/skin/social/chat-close.png');
-moz-image-region: rect(0, 14px, 14px, 0);
}
.chat-close-button:hover:active {
-moz-image-region: rect(14px, 14px, 28px, 0);
}
.chat-close-button:hover {
-moz-image-region: rect(28px, 14px, 42px, 0);
}
.chat-title {
font-weight: bold;
color: black;
text-shadow: none;
cursor: inherit;
}
%include ../shared/social/chat.inc.css
.chat-titlebar {
background-color: #d9d9d9;
background-image: linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
height: 20px;
min-height: 20px;
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid #ccc;
cursor: pointer;
}
.chat-titlebar[minimized="true"] {
border-bottom: none;
}
.chat-titlebar[selected] {
background-color: #f0f0f0;
}
.chat-titlebar[activity] {
background-image: radial-gradient(ellipse closest-side at center, rgb(255,255,255), rgba(255,255,255,0));
background-repeat: no-repeat;
background-size: 100% 20px;
background-position: 0 -10px;
}
.chat-frame {
padding: 0;
margin: 0;
overflow: hidden;
}
.chatbar-button {
-moz-appearance: none;
background-color: #d9d9d9;
list-style-image: url("chrome://browser/skin/social/social.png");
border: none;
margin: 0;
padding: 2px;
height: 21px;
width: 21px;
border-top: 1px solid #ccc;
-moz-border-end: 1px solid #ccc;
}
.chatbar-button > .toolbarbutton-icon {
opacity: .6;
-moz-margin-end: 0;
}
.chatbar-button:hover > .toolbarbutton-icon,
.chatbar-button[open="true"] > .toolbarbutton-icon {
opacity: 1;
}
.chatbar-button[open="true"] {
background-color: #f0f0f0;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
}
.chatbar-button > .toolbarbutton-text,
.chatbar-button > .toolbarbutton-menu-dropmarker {
display: none;
}
.chatbar-button[activity] {
background-image: radial-gradient(circle farthest-corner at center 3px, rgb(233,242,252) 3%, rgba(172,206,255,0.75) 40%, rgba(87,151,201,0.5) 80%, rgba(87,151,201,0));
}
.chatbar-button > menupopup > menuitem[activity] {
font-weight: bold;
}
.chatbar-button > menupopup > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
width: auto;
height: auto;
max-height: 16px;
max-width: 16px;
}
.chatbar-innerbox {
background: transparent;
margin: -285px -1px 0 -1px;
overflow: hidden;
}
chatbar {
-moz-margin-end: 20px;
}
chatbox {
height: 285px;
width: 260px;
-moz-margin-start: 4px;
background-color: white;
border: 1px solid #ccc;
border-bottom: none;
border-top-left-radius: 2.5px;
border-top-right-radius: 2.5px;
}
chatbox[minimized="true"] {
width: 160px;
height: 20px;
}
.click-to-play-plugins-notification-content {
margin: -10px;
}

View File

@ -3405,38 +3405,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
margin-left: 1em;
}
/* Highlighter */
.highlighter-outline {
box-shadow: 0 0 0 1px black;
outline: 1px dashed white;
outline-offset: -1px;
}
.highlighter-outline[locked] {
box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
outline-color: rgba(255,255,255,0.7);
}
/* Developer toolbar */
#developer-toolbar {
border-top: 1px solid hsla(210, 8%, 5%, .65);
padding-top: 4px;
padding-bottom: 4px;
}
#developer-toolbar:-moz-locale-dir(ltr) {
padding-left: 2px;
padding-right: 16px; /* use -moz-padding-end when/if bug 631729 gets fixed */
}
#developer-toolbar:-moz-locale-dir(rtl) {
padding-left: 4px;
padding-right: 18px; /* use -moz-padding-end when/if bug 631729 gets fixed */
}
/* Lion Fullscreen window styling */
@media (-moz-mac-lion-theme) {
#navigator-toolbox[inFullscreen][tabsontop="true"]:not(:-moz-lwtheme)::before {
@ -3451,117 +3419,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
}
/* Highlighter - Node Infobar */
.highlighter-nodeinfobar {
color: hsl(200, 100%, 65%);
border: 1px solid hsla(210, 19%, 63%, .5);
border-radius: 3px;
background: linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
}
/* Highlighter - Node Infobar - text */
.highlighter-nodeinfobar-text {
/* 100% - size of the buttons + margins */
max-width: calc(100% - 2 * (26px + 6px));
padding-bottom: 1px;
}
html|*.highlighter-nodeinfobar-tagname {
color: white;
}
html|*.highlighter-nodeinfobar-id {
color: hsl(90, 79%, 52%);
}
html|*.highlighter-nodeinfobar-pseudo-classes {
color: hsl(20, 100%, 70%);
}
/* Highlighter - Node Infobar - buttons */
.highlighter-nodeinfobar-button {
-moz-appearance: none;
border: 0 solid hsla(210,8%,5%,.45);
padding: 0;
width: 26px;
min-height: 26px;
background-color: transparent;
}
.highlighter-nodeinfobar-inspectbutton {
-moz-border-end-width: 1px;
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-end: 6px;
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
.highlighter-nodeinfobar-inspectbutton:-moz-locale-dir(rtl) {
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-inspectbutton:active:hover,
.highlighter-nodeinfobar-container:not([locked]) > .highlighter-nodeinfobar > .highlighter-nodeinfobar-inspectbutton {
-moz-image-region: rect(0px 32px 16px 16px);
}
.highlighter-nodeinfobar-menu {
-moz-border-start-width: 1px;
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-start: 6px;
}
.highlighter-nodeinfobar-menu:-moz-locale-dir(rtl) {
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-menu > .toolbarbutton-menu-dropmarker {
-moz-appearance: none !important;
list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-moz-box-align: center;
-moz-margin-start: -1px;
}
/* Highlighter - Node Infobar - box & arrow */
.highlighter-nodeinfobar-arrow {
width: 14px;
height: 14px;
-moz-margin-start: calc(50% - 7px);
transform: rotate(-45deg);
border: 1px solid transparent;
background-clip: padding-box;
background-repeat: no-repeat;
}
.highlighter-nodeinfobar-arrow-top {
margin-bottom: -8px;
margin-top: 8px;
border-right-color: hsla(210, 19%, 63%, .5);
border-top-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to top right, transparent 50%, hsl(209, 18%, 30%) 50%);
}
.highlighter-nodeinfobar-arrow-bottom {
margin-top: -8px;
margin-bottom: 8px;
border-left-color: hsla(210, 19%, 63%, .5);
border-bottom-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to bottom left, transparent 50%, hsl(210, 24%, 16%) 50%);
}
.highlighter-nodeinfobar-container[position="top"] > .highlighter-nodeinfobar,
.highlighter-nodeinfobar-container[position="overlap"] > .highlighter-nodeinfobar {
box-shadow: 0 1px 0 hsla(0, 0%, 100%, .1) inset;
}
.highlighter-nodeinfobar-container[hide-arrow] > .highlighter-nodeinfobar {
margin: 7px 0;
}
#full-screen-warning-message {
background-color: hsl(0,0%,15%);
color: white;
@ -3588,145 +3445,49 @@ html|*.highlighter-nodeinfobar-pseudo-classes {
font-size: 120%;
}
html|*#gcli-tooltip-frame,
html|*#gcli-output-frame {
padding: 0;
border-width: 0;
background-color: transparent;
/* Developer toolbar */
#developer-toolbar {
border-top: 1px solid hsla(210, 8%, 5%, .65);
padding-top: 4px;
padding-bottom: 4px;
}
#gcli-output,
#gcli-tooltip {
border-width: 0;
background-color: transparent;
-moz-appearance: none;
margin-bottom: -2px;
#developer-toolbar:-moz-locale-dir(ltr) {
padding-left: 2px;
padding-right: 16px; /* use -moz-padding-end when/if bug 631729 gets fixed */
}
#developer-toolbar:-moz-locale-dir(rtl) {
padding-left: 4px;
padding-right: 18px; /* use -moz-padding-end when/if bug 631729 gets fixed */
}
%include ../shared/devtools/responsivedesign.inc.css
%include ../shared/devtools/highlighter.inc.css
%include ../shared/devtools/commandline.inc.css
.gclitoolbar-input-node,
.gclitoolbar-complete-node,
.gclitoolbar-prompt {
margin: 0;
-moz-margin-end: 5px;
-moz-box-align: center;
padding-top: 0;
padding-bottom: 0;
padding-right: 4px;
border: 1px solid transparent;
border-radius: @toolbarbuttonCornerRadius@;
text-shadow: none;
}
.gclitoolbar-input-node {
padding-left: 20px;
background-color: transparent;
-moz-appearance: none;
border-color: hsl(210,11%,10%);
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
box-shadow: 0 1px 1px hsla(210,8%,5%,.3) inset,
0 0 0 1px hsla(210,16%,76%,.1) inset,
0 1px 0 hsla(210,16%,76%,.15);
}
.gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
background-color: hsl(210,30%,85%);
color: hsl(210,11%,16%);
text-shadow: none;
}
.gclitoolbar-complete-node {
padding-left: 21px;
background-color: transparent;
color: transparent;
}
.gclitoolbar-prompt {
padding-left: 4px;
padding-bottom: 2px;
font-size: 150%;
font-weight: bold;
color: hsl(210,30%,85%);
background-color: hsl(210,11%,16%);
}
.gclitoolbar-prompt-label,
.gcli-in-incomplete,
.gcli-in-error,
.gcli-in-ontab,
.gcli-in-todo,
.gcli-in-closebrace,
.gcli-in-param,
.gcli-in-valid {
margin: 0;
padding: 0;
}
.gcli-in-incomplete {
border-bottom: 2px dotted #999;
}
.gcli-in-error {
border-bottom: 2px dotted #F00;
}
.gcli-in-ontab {
color: hsl(210,0%,35%);
}
.gcli-in-todo {
color: hsl(210,50%,35%);
}
.gcli-in-closebrace {
color: hsl(0,0%,80%);
}
/* Responsive Mode */
.browserContainer[responsivemode] {
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
padding: 0 20px 20px 20px;
}
.browserStack[responsivemode] {
box-shadow: 0 0 7px black;
}
.devtools-responsiveui-toolbar {
background: transparent;
margin: 10px 0;
padding: 0;
box-shadow: none;
}
.devtools-responsiveui-toolbar > menulist,
.devtools-responsiveui-toolbar > toolbarbutton {
min-width: 22px;
border-radius: 0;
}
.devtools-responsiveui-toolbar:-moz-locale-dir(ltr) > *:first-child,
.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) > *:last-child {
margin-left: 0;
}
.devtools-responsiveui-resizebar {
width: 7px;
height: 24px;
cursor: ew-resize;
transform: translate(12px, -12px);
background-image: url("chrome://browser/skin/devtools/responsive-vertical-resizer.png");
}
.devtools-responsiveui-resizehandle {
width: 16px;
height: 16px;
cursor: se-resize;
transform: translate(12px, 12px);
background-image: url("chrome://browser/skin/devtools/responsive-se-resizer.png");
}
/* Web Console */
.web-console-frame {
@ -3872,150 +3633,34 @@ toolbar[mode="icons"] > *|* > .social-notification-container > .toolbarbutton-1[
/* === end of social toolbar provider menu === */
.chat-status-icon {
max-height: 16px;
max-width: 16px;
padding: 0;
}
.chat-toolbarbutton {
-moz-appearance: none;
border: none;
padding: 0;
margin: 0;
background: none;
}
.chat-toolbarbutton > .toolbarbutton-text {
display: none;
}
.chat-close-button {
list-style-image: url('chrome://browser/skin/social/chat-close.png');
-moz-image-region: rect(0, 14px, 14px, 0);
}
.chat-close-button:hover:active {
-moz-image-region: rect(14px, 14px, 28px, 0);
}
.chat-close-button:hover {
-moz-image-region: rect(28px, 14px, 42px, 0);
}
.chat-title {
font-weight: bold;
color: black;
text-shadow: none;
cursor: inherit;
}
%include ../shared/social/chat.inc.css
.chat-titlebar {
background-color: #d9d9d9;
background-image: linear-gradient(rgba(255,255,255,.43), rgba(255,255,255,0));
height: 20px;
min-height: 20px;
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid #ccc;
cursor: pointer;
}
.chat-titlebar[minimized="true"] {
border-bottom: none;
}
.chat-titlebar[activity] {
background-image: radial-gradient(ellipse closest-side at center, rgb(255,255,255), rgba(255,255,255,0));
background-repeat: no-repeat;
background-size: 100% 20px;
background-position: 0 -10px;
}
.chat-titlebar[selected] {
background-color: #f0f0f0;
}
.chat-frame {
padding: 0;
margin: 0;
overflow: hidden;
}
.chatbar-button {
background-color: #d9d9d9;
list-style-image: url("chrome://browser/skin/social/social.png");
border: none;
margin: 0;
padding: 2px;
height: 21px;
width: 21px;
border-top: 1px solid #ccc;
-moz-border-end: 1px solid #ccc;
}
.chatbar-button > .toolbarbutton-icon {
opacity: .6;
}
.chatbar-button:hover > .toolbarbutton-icon,
.chatbar-button[open="true"] > .toolbarbutton-icon {
opacity: 1;
}
.chatbar-button[open="true"] {
background-color: #f0f0f0;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
}
.chatbar-button > .toolbarbutton-text,
.chatbar-button > .toolbarbutton-menu-dropmarker {
display: none;
}
.chatbar-button[activity] {
background-image: radial-gradient(circle farthest-corner at center 2px, rgb(254,254,255) 3%, rgba(210,235,255,0.9) 12%, rgba(148,205,253,0.6) 30%, rgba(148,205,253,0.2) 70%);
}
.chatbar-button > menupopup > menuitem[activity] {
font-weight: bold;
}
.chatbar-button > menupopup > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
width: auto;
height: auto;
max-height: 16px;
max-width: 16px;
}
.chatbar-innerbox {
background: transparent;
margin: -285px 0 0;
overflow: hidden;
}
chatbar {
-moz-margin-end: 20px;
}
chatbox {
height: 285px;
width: 260px;
-moz-margin-start: 4px;
background-color: white;
border: 1px solid #ccc;
border-bottom: none;
border-top-left-radius: @toolbarbuttonCornerRadius@;
border-top-right-radius: @toolbarbuttonCornerRadius@;
}
chatbox[minimized="true"] {
width: 160px;
height: 20px;
}
panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="top"],
panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .panel-arrowbox > .panel-arrow[side="bottom"] {
list-style-image: url("chrome://global/skin/arrow/panelarrow-light-vertical.png");

View File

@ -1,5 +1,5 @@
%include ../../../toolkit/themes/pinstripe/global/shared.inc
%include ../browserShared.inc
%include ../shared/browser.inc
%define hudButton -moz-appearance: none; color: #434343; border-radius: 4px; border: 1px solid #b5b5b5; background: -moz-linear-gradient(#fff, #f2f2f2); box-shadow: inset 0 1px rgba(255,255,255,.8), inset 0 0 1px rgba(255,255, 255,.25), 0 1px rgba(255,255,255,.3); background-clip: padding-box; background-origin: padding-box; padding: 2px 6px;
%define hudButtonPressed box-shadow: inset 0 1px 4px -3px #000, 0 1px rgba(255,255,255,.3);

View File

@ -0,0 +1,98 @@
%if 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/. */
%endif
html|*#gcli-tooltip-frame,
html|*#gcli-output-frame {
padding: 0;
border-width: 0;
background-color: transparent;
}
#gcli-output,
#gcli-tooltip {
border-width: 0;
background-color: transparent;
-moz-appearance: none;
margin-bottom: -2px;
}
.gclitoolbar-input-node,
.gclitoolbar-complete-node,
.gclitoolbar-prompt {
margin: 0;
-moz-margin-end: 5px;
-moz-box-align: center;
padding-top: 0;
padding-bottom: 0;
padding-right: 4px;
border: 1px solid transparent;
border-radius: 3px;
text-shadow: none;
}
.gclitoolbar-input-node {
padding-left: 20px;
background-color: transparent;
-moz-appearance: none;
border-color: hsl(210,24%,10%);
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
box-shadow: inset 0 1px 0 hsla(211,68%,6%,.05),
0 0 0 1px hsla(210,40%,83%,.1);
}
.gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
background-color: hsl(210,30%,85%);
color: hsl(210,24%,16%);
text-shadow: none;
}
.gclitoolbar-complete-node {
padding-left: 21px;
background-color: transparent;
color: transparent;
}
.gclitoolbar-prompt {
padding-left: 4px;
padding-bottom: 2px;
font-size: 150%;
font-weight: bold;
color: hsl(210,30%,85%);
background-color: hsl(210,24%,16%);
}
.gclitoolbar-prompt-label,
.gcli-in-incomplete,
.gcli-in-error,
.gcli-in-ontab,
.gcli-in-todo,
.gcli-in-closebrace,
.gcli-in-param,
.gcli-in-valid {
margin: 0;
padding: 0;
}
.gcli-in-incomplete {
border-bottom: 2px dotted #999;
}
.gcli-in-error {
border-bottom: 2px dotted #F00;
}
.gcli-in-ontab {
color: hsl(210,0%,35%);
}
.gcli-in-todo {
color: hsl(210,50%,35%);
}
.gcli-in-closebrace {
color: hsl(0,0%,80%);
}

View File

@ -0,0 +1,131 @@
%if 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/. */
%endif
/* Highlighter */
.highlighter-outline {
box-shadow: 0 0 0 1px black;
outline: 1px dashed white;
outline-offset: -1px;
}
.highlighter-outline[locked] {
box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
outline-color: rgba(255,255,255,0.7);
}
/* Highlighter - Node Infobar */
.highlighter-nodeinfobar {
color: hsl(200, 100%, 65%);
border: 1px solid hsla(210, 19%, 63%, .5);
border-radius: 3px;
background: linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
}
/* Highlighter - Node Infobar - text */
.highlighter-nodeinfobar-text {
/* 100% - size of the buttons and margins */
max-width: calc(100% - 2 * (26px + 6px));
padding-bottom: 1px;
}
html|*.highlighter-nodeinfobar-tagname {
color: white;
}
html|*.highlighter-nodeinfobar-id {
color: hsl(90, 79%, 52%);
}
html|*.highlighter-nodeinfobar-pseudo-classes {
color: hsl(20, 100%, 70%);
}
/* Highlighter - Node Infobar - buttons */
.highlighter-nodeinfobar-button {
-moz-appearance: none;
border: 0 solid hsla(210,8%,5%,.45);
padding: 0;
width: 26px;
min-height: 26px;
%ifndef XP_LINUX
background-color: transparent;
%endif
}
.highlighter-nodeinfobar-inspectbutton {
-moz-border-end-width: 1px;
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-end: 6px;
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
.highlighter-nodeinfobar-inspectbutton:-moz-locale-dir(rtl) {
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-inspectbutton:active:hover,
.highlighter-nodeinfobar-container:not([locked]) > .highlighter-nodeinfobar > .highlighter-nodeinfobar-inspectbutton {
-moz-image-region: rect(0px 32px 16px 16px);
}
.highlighter-nodeinfobar-menu {
-moz-border-start-width: 1px;
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-start: 6px;
}
.highlighter-nodeinfobar-menu:-moz-locale-dir(rtl) {
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-menu > .toolbarbutton-menu-dropmarker {
-moz-appearance: none !important;
list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-moz-box-align: center;
-moz-margin-start: -1px;
}
/* Highlighter - Node Infobar - box & arrow */
.highlighter-nodeinfobar-arrow {
width: 14px;
height: 14px;
-moz-margin-start: calc(50% - 7px);
transform: rotate(-45deg);
border: 1px solid transparent;
background-clip: padding-box;
background-repeat: no-repeat;
}
.highlighter-nodeinfobar-arrow-top {
margin-bottom: -8px;
margin-top: 8px;
border-right-color: hsla(210, 19%, 63%, .5);
border-top-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to top right, transparent 50%, hsl(209, 18%, 30%) 50%);
}
.highlighter-nodeinfobar-arrow-bottom {
margin-top: -8px;
margin-bottom: 8px;
border-left-color: hsla(210, 19%, 63%, .5);
border-bottom-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to bottom left, transparent 50%, hsl(210, 24%, 16%) 50%);
}
.highlighter-nodeinfobar-container[position="top"] > .highlighter-nodeinfobar,
.highlighter-nodeinfobar-container[position="overlap"] > .highlighter-nodeinfobar {
box-shadow: 0 1px 0 hsla(0, 0%, 100%, .1) inset;
}
.highlighter-nodeinfobar-container[hide-arrow] > .highlighter-nodeinfobar {
margin: 7px 0;
}

View File

@ -0,0 +1,53 @@
%if 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/. */
%endif
/* Responsive Mode */
.browserContainer[responsivemode] {
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
padding: 0 20px 20px 20px;
}
.browserStack[responsivemode] {
box-shadow: 0 0 7px black;
}
.devtools-responsiveui-toolbar {
background: transparent;
margin: 10px 0;
padding: 0;
box-shadow: none;
%ifdef XP_WIN
border-bottom-width: 0;
%endif
}
.devtools-responsiveui-toolbar > menulist,
.devtools-responsiveui-toolbar > toolbarbutton {
min-width: 22px;
border-radius: 0;
}
.devtools-responsiveui-toolbar:-moz-locale-dir(ltr) > *:first-child,
.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) > *:last-child {
margin-left: 0;
}
.devtools-responsiveui-resizebar {
width: 7px;
height: 24px;
cursor: ew-resize;
transform: translate(12px, -12px);
background-image: url("chrome://browser/skin/devtools/responsive-vertical-resizer.png");
}
.devtools-responsiveui-resizehandle {
width: 16px;
height: 16px;
cursor: se-resize;
transform: translate(12px, 12px);
background-image: url("chrome://browser/skin/devtools/responsive-se-resizer.png");
}

View File

@ -0,0 +1,137 @@
%if 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/. */
%endif
.chat-status-icon {
max-height: 16px;
max-width: 16px;
padding: 0;
}
.chat-toolbarbutton {
-moz-appearance: none;
border: none;
padding: 0;
margin: 0;
background: none;
}
.chat-toolbarbutton > .toolbarbutton-text {
display: none;
}
.chat-close-button {
list-style-image: url('chrome://browser/skin/social/chat-close.png');
-moz-image-region: rect(0, 14px, 14px, 0);
}
.chat-close-button:hover:active {
-moz-image-region: rect(14px, 14px, 28px, 0);
}
.chat-close-button:hover {
-moz-image-region: rect(28px, 14px, 42px, 0);
}
.chat-title {
font-weight: bold;
color: black;
text-shadow: none;
cursor: inherit;
}
.chat-titlebar {
height: 20px;
min-height: 20px;
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid #ccc;
cursor: pointer;
}
.chat-titlebar[minimized="true"] {
border-bottom: none;
}
.chat-titlebar[activity] {
background-image: radial-gradient(ellipse closest-side at center, rgb(255,255,255), rgba(255,255,255,0));
background-repeat: no-repeat;
background-size: 100% 20px;
background-position: 0 -10px;
}
.chat-frame {
padding: 0;
margin: 0;
overflow: hidden;
}
.chatbar-button {
/* XXX get a real image for this */
list-style-image: url("chrome://browser/skin/social/social.png");
border: none;
margin: 0;
padding: 2px;
height: 21px;
width: 21px;
border-top: 1px solid #ccc;
-moz-border-end: 1px solid #ccc;
}
.chatbar-button > menupopup > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
width: auto;
height: auto;
max-height: 16px;
max-width: 16px;
}
.chatbar-button > .toolbarbutton-icon {
opacity: .6;
}
.chatbar-button:hover > .toolbarbutton-icon,
.chatbar-button[open="true"] > .toolbarbutton-icon {
opacity: 1;
}
.chatbar-button[open="true"] {
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
}
.chatbar-button > .toolbarbutton-text,
.chatbar-button > .toolbarbutton-menu-dropmarker {
display: none;
}
.chatbar-button > menupopup > menuitem[activity] {
font-weight: bold;
}
.chatbar-innerbox {
background: transparent;
margin: -285px 0 0;
overflow: hidden;
}
chatbar {
-moz-margin-end: 20px;
}
chatbox {
height: 285px;
width: 260px;
-moz-margin-start: 4px;
background-color: white;
border: 1px solid #ccc;
border-bottom: none;
}
chatbox[minimized="true"] {
width: 160px;
height: 20px;
}

View File

@ -7,7 +7,7 @@
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
%include ../browserShared.inc
%include ../shared/browser.inc
%filter substitution
%define toolbarHighlight rgba(255,255,255,.5)
%define selectedTabHighlight rgba(255,255,255,.7)
@ -2548,136 +2548,6 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
margin-left: 1em;
}
/* Highlighter */
.highlighter-outline {
box-shadow: 0 0 0 1px black;
outline: 1px dashed white;
outline-offset: -1px;
}
.highlighter-outline[locked] {
box-shadow: 0 0 0 1px rgba(0,0,0,0.3);
outline-color: rgba(255,255,255,0.7);
}
/* Developer toolbar */
#developer-toolbar {
border-top: 1px solid hsla(211,68%,6%,.65) !important;
}
/* Highlighter - Node Infobar */
.highlighter-nodeinfobar {
color: hsl(200, 100%, 65%);
border: 1px solid hsla(210, 19%, 63%, .5);
border-radius: 3px;
background: linear-gradient(hsl(209, 18%, 30%), hsl(210, 24%, 16%)) no-repeat padding-box;
}
/* Highlighter - Node Infobar - text */
.highlighter-nodeinfobar-text {
/* 100% - size of the buttons and margins */
max-width: calc(100% - 2 * (26px + 6px));
padding-bottom: 1px;
}
html|*.highlighter-nodeinfobar-tagname {
color: white;
}
html|*.highlighter-nodeinfobar-id {
color: hsl(90, 79%, 52%);
}
html|*.highlighter-nodeinfobar-pseudo-classes {
color: hsl(20, 100%, 70%);
}
/* Highlighter - Node Infobar - buttons */
.highlighter-nodeinfobar-button {
-moz-appearance: none;
border: 0 solid hsla(210,8%,5%,.45);
padding: 0;
width: 26px;
min-height: 26px;
background-color: transparent;
}
.highlighter-nodeinfobar-inspectbutton {
-moz-border-end-width: 1px;
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-end: 6px;
list-style-image: url("chrome://browser/skin/devtools/inspect-button.png");
-moz-image-region: rect(0px 16px 16px 0px);
}
.highlighter-nodeinfobar-inspectbutton:-moz-locale-dir(rtl) {
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-inspectbutton:active:hover,
.highlighter-nodeinfobar-container:not([locked]) > .highlighter-nodeinfobar > .highlighter-nodeinfobar-inspectbutton {
-moz-image-region: rect(0px 32px 16px 16px);
}
.highlighter-nodeinfobar-menu {
-moz-border-start-width: 1px;
box-shadow: -1px 0 0 hsla(210,16%,76%,.15), 1px 0 0 hsla(210,16%,76%,.15) inset;
-moz-margin-start: 6px;
}
.highlighter-nodeinfobar-menu:-moz-locale-dir(rtl) {
box-shadow: 1px 0 0 hsla(210,16%,76%,.15), -1px 0 0 hsla(210,16%,76%,.15) inset;
}
.highlighter-nodeinfobar-menu > .toolbarbutton-menu-dropmarker {
-moz-appearance: none !important;
list-style-image: url("chrome://browser/skin/devtools/dropmarker.png");
-moz-box-align: center;
-moz-margin-start: -1px;
}
/* Highlighter - Node Infobar - box & arrow */
.highlighter-nodeinfobar-arrow {
width: 14px;
height: 14px;
-moz-margin-start: calc(50% - 7px);
transform: rotate(-45deg);
border: 1px solid transparent;
background-clip: padding-box;
background-repeat: no-repeat;
}
.highlighter-nodeinfobar-arrow-top {
margin-bottom: -8px;
margin-top: 8px;
border-right-color: hsla(210, 19%, 63%, .5);
border-top-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to top right, transparent 50%, hsl(209, 18%, 30%) 50%);
}
.highlighter-nodeinfobar-arrow-bottom {
margin-top: -8px;
margin-bottom: 8px;
border-left-color: hsla(210, 19%, 63%, .5);
border-bottom-color: hsla(210, 19%, 63%, .5);
background-image: linear-gradient(to bottom left, transparent 50%, hsl(210, 24%, 16%) 50%);
}
.highlighter-nodeinfobar-container[position="top"] > .highlighter-nodeinfobar,
.highlighter-nodeinfobar-container[position="overlap"] > .highlighter-nodeinfobar {
box-shadow: 0 1px 0 hsla(0, 0%, 100%, .1) inset;
}
.highlighter-nodeinfobar-container[hide-arrow] > .highlighter-nodeinfobar {
margin: 7px 0;
}
#full-screen-warning-message {
background-color: hsl(0,0%,15%);
color: white;
@ -2704,145 +2574,22 @@ html|*.highlighter-nodeinfobar-pseudo-classes {
font-size: 120%;
}
html|*#gcli-tooltip-frame,
html|*#gcli-output-frame {
padding: 0;
border-width: 0;
background-color: transparent;
/* Developer toolbar */
#developer-toolbar {
border-top: 1px solid hsla(211,68%,6%,.65) !important;
}
#gcli-output,
#gcli-tooltip {
border-width: 0;
background-color: transparent;
-moz-appearance: none;
margin-bottom: -2px;
}
.gclitoolbar-input-node,
.gclitoolbar-complete-node,
.gclitoolbar-prompt {
margin: 0;
-moz-margin-end: 5px;
-moz-box-align: center;
padding-top: 0;
padding-bottom: 0;
padding-right: 4px;
border: 1px solid transparent;
border-radius: 3px;
text-shadow: none;
}
%include ../shared/devtools/responsivedesign.inc.css
%include ../shared/devtools/highlighter.inc.css
%include ../shared/devtools/commandline.inc.css
.gclitoolbar-input-node {
padding-left: 20px;
background-color: transparent;
-moz-appearance: none;
border-color: hsl(210,24%,10%);
color: hsl(210,30%,85%);
text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);
box-shadow: inset 0 1px 0 hsla(211,68%,6%,.05),
0 0 0 1px hsla(210,40%,83%,.1);
}
.gclitoolbar-input-node > .textbox-input-box > html|*.textbox-input::-moz-selection {
background-color: hsl(210,30%,85%);
color: hsl(210,24%,16%);
text-shadow: none;
}
.gclitoolbar-complete-node {
padding-left: 21px;
background-color: transparent;
color: transparent;
}
.gclitoolbar-prompt {
padding-left: 4px;
padding-bottom: 2px;
font-size: 150%;
font-weight: bold;
color: hsl(210,30%,85%);
background-color: hsl(210,24%,16%);
}
.gclitoolbar-prompt-label,
.gcli-in-incomplete,
.gcli-in-error,
.gcli-in-ontab,
.gcli-in-todo,
.gcli-in-closebrace,
.gcli-in-param,
.gcli-in-valid {
margin: 0;
padding: 0;
}
.gcli-in-incomplete {
border-bottom: 2px dotted #999;
}
.gcli-in-error {
border-bottom: 2px dotted #F00;
}
.gcli-in-ontab {
color: hsl(210,0%,35%);
}
.gcli-in-todo {
color: hsl(210,50%,35%);
}
.gcli-in-closebrace {
color: hsl(0,0%,80%);
}
/* Responsive Mode */
.browserContainer[responsivemode] {
background: #222 url("chrome://browser/skin/devtools/responsive-background.png");
padding: 0 20px 20px 20px;
}
.browserStack[responsivemode] {
box-shadow: 0 0 7px black;
}
.devtools-responsiveui-toolbar {
background: transparent;
margin: 10px 0;
padding: 0;
box-shadow: none;
border-bottom-width: 0;
}
.devtools-responsiveui-toolbar > menulist,
.devtools-responsiveui-toolbar > toolbarbutton {
min-width: 22px;
border-radius: 0;
}
.devtools-responsiveui-toolbar:-moz-locale-dir(ltr) > *:first-child,
.devtools-responsiveui-toolbar:-moz-locale-dir(rtl) > *:last-child {
margin-left: 0;
}
.devtools-responsiveui-resizebar {
width: 7px;
height: 24px;
cursor: ew-resize;
transform: translate(12px, -12px);
background-image: url("chrome://browser/skin/devtools/responsive-vertical-resizer.png");
}
.devtools-responsiveui-resizehandle {
width: 16px;
height: 16px;
cursor: se-resize;
transform: translate(12px, 12px);
background-image: url("chrome://browser/skin/devtools/responsive-se-resizer.png");
}
/* Web Console */
.web-console-frame {
@ -3011,153 +2758,39 @@ html|*#gcli-output-frame {
border-radius: inherit;
}
.chat-status-icon {
max-height: 16px;
max-width: 16px;
padding: 0;
}
.chat-toolbarbutton {
-moz-appearance: none;
border: none;
padding: 0;
margin: 0;
background: none;
}
.chat-toolbarbutton > .toolbarbutton-text {
display: none;
}
.chat-close-button {
list-style-image: url('chrome://browser/skin/social/chat-close.png');
-moz-image-region: rect(0, 14px, 14px, 0);
}
.chat-close-button:hover:active {
-moz-image-region: rect(14px, 14px, 28px, 0);
}
.chat-close-button:hover {
-moz-image-region: rect(28px, 14px, 42px, 0);
}
.chat-title {
font-weight: bold;
color: black;
text-shadow: none;
cursor: inherit;
}
%include ../shared/social/chat.inc.css
.chat-titlebar {
background-color: #c4cfde;
background-image: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,0));
height: 20px;
min-height: 20px;
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid #ccc;
cursor: pointer;
}
.chat-titlebar[minimized="true"] {
border-bottom: none;
}
.chat-titlebar[selected] {
background-color: #dae3f0;
}
.chat-titlebar[activity] {
background-image: radial-gradient(ellipse closest-side at center, rgb(255,255,255), rgba(255,255,255,0));
background-repeat: no-repeat;
background-size: 100% 20px;
background-position: 0 -10px;
}
.chat-frame {
padding: 0;
margin: 0;
overflow: hidden;
}
.chatbar-button {
/* XXX get a real image for this */
-moz-appearance: none;
list-style-image: url("chrome://browser/skin/social/social.png");
background-color: #c4cfde;
border: none;
margin: 0;
padding: 2px;
height: 21px;
width: 21px;
border-top: 1px solid #ccc;
-moz-border-end: 1px solid #ccc;
}
.chatbar-button > menupopup > .menuitem-iconic > .menu-iconic-left > .menu-iconic-icon {
width: auto;
height: auto;
max-height: 16px;
max-width: 16px;
}
.chatbar-button > .toolbarbutton-icon {
opacity: .6;
-moz-margin-end: 0;
}
.chatbar-button:hover > .toolbarbutton-icon,
.chatbar-button[open="true"] > .toolbarbutton-icon {
opacity: 1;
}
.chatbar-button[open="true"] {
background-color: #dae3f0;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6), 0 1px rgba(255,255,255,0.2);
}
.chatbar-button > .toolbarbutton-text,
.chatbar-button > .toolbarbutton-menu-dropmarker {
display: none;
}
.chatbar-button[activity]:not([open="true"]) {
background-image: radial-gradient(circle farthest-corner at center 3px, rgb(255,255,255) 3%, rgba(186,221,251,0.75) 40%, rgba(127,179,255,0.5) 80%, rgba(127,179,255,0.25));
}
.chatbar-button > menupopup > menuitem[activity] {
font-weight: bold;
}
.chatbar-innerbox {
background: transparent;
margin: -285px 0 0;
overflow: hidden;
}
chatbar {
-moz-margin-end: 20px;
}
chatbox {
height: 285px;
width: 260px;
-moz-margin-start: 4px;
background-color: white;
border: 1px solid #ccc;
border-bottom: none;
border-top-left-radius: 2.5px;
border-top-right-radius: 2.5px;
}
chatbox[minimized="true"] {
width: 160px;
height: 20px;
}
.click-to-play-plugins-notification-content {
margin: -10px;
border-radius: 4px;

View File

@ -20,6 +20,9 @@ public interface Actions {
/** Blocks until the event has been received. Subsequent calls will return immediately. */
public void blockForEvent();
/** Blocks until the event has been received and returns data associated with the event. */
public String blockForEventData();
/** Polls to see if the event has been received. Once this returns true, subsequent calls will also return true. */
public boolean eventReceived();
}

View File

@ -96,7 +96,7 @@ public class FennecNativeActions implements Actions {
}
FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
"Waking up on "+methodName);
mEventExpecter.notifyOfEvent();
mEventExpecter.notifyOfEvent(args);
return null;
}
}
@ -105,6 +105,7 @@ public class FennecNativeActions implements Actions {
private final String mGeckoEvent;
private final Object[] mRegistrationParams;
private boolean mEventReceived;
private String mEventData;
private static final int MAX_WAIT_MS = 90000;
GeckoEventExpecter(String geckoEvent, Object[] registrationParams) {
@ -190,15 +191,21 @@ public class FennecNativeActions implements Actions {
"unblocked on expecter for " + mGeckoEvent);
}
public synchronized String blockForEventData() {
blockForEvent();
return mEventData;
}
public synchronized boolean eventReceived() {
return mEventReceived;
}
void notifyOfEvent() {
void notifyOfEvent(Object[] args) {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
"received event " + mGeckoEvent);
synchronized (this) {
mEventReceived = true;
mEventData = args[1].toString();
this.notifyAll();
}
}
@ -247,7 +254,7 @@ public class FennecNativeActions implements Actions {
if ("drawFinished".equals(methodName)) {
FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
"Received drawFinished notification");
mPaintExpecter.notifyOfEvent();
mPaintExpecter.notifyOfEvent(args);
} else if ("toString".equals(methodName)) {
return "DrawListenerProxy";
} else if ("equals".equals(methodName)) {
@ -269,7 +276,7 @@ public class FennecNativeActions implements Actions {
mSetDrawListener.invoke(mRobocopApi, proxy);
}
void notifyOfEvent() {
void notifyOfEvent(Object[] args) {
synchronized (this) {
mPaintDone = true;
this.notifyAll();
@ -300,6 +307,11 @@ public class FennecNativeActions implements Actions {
}
}
public synchronized String blockForEventData() {
blockForEvent();
return null;
}
public synchronized boolean eventReceived() {
return mPaintDone;
}

View File

@ -20,7 +20,7 @@ from automationutils import getDebuggerInfo, addCommonOptions
PORT = 8888
PROFILE_DIRECTORY = os.path.abspath(os.path.join(SCRIPT_DIR, "./pgoprofile"))
MOZ_JAR_LOG_DIR = os.path.abspath(os.getenv("JARLOG_DIR"))
MOZ_JAR_LOG_FILE = os.path.abspath(os.getenv("JARLOG_FILE"))
os.chdir(SCRIPT_DIR)
class EasyServer(SocketServer.TCPServer):
@ -47,7 +47,7 @@ if __name__ == '__main__':
automation.initializeProfile(PROFILE_DIRECTORY)
browserEnv = automation.environment()
browserEnv["XPCOM_DEBUG_BREAK"] = "warn"
browserEnv["MOZ_JAR_LOG_DIR"] = MOZ_JAR_LOG_DIR
browserEnv["MOZ_JAR_LOG_FILE"] = MOZ_JAR_LOG_FILE
url = "http://localhost:%d/index.html" % PORT
appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)

View File

@ -203,7 +203,8 @@ endif
profiledbuild::
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_GENERATE=1 MOZ_PGO_INSTRUMENTED=1
$(MAKE) -C $(PGO_OBJDIR) package MOZ_PGO_INSTRUMENTED=1 MOZ_INTERNAL_SIGNING_FORMAT= MOZ_EXTERNAL_SIGNING_FORMAT=
MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_DIR=${PGO_OBJDIR}/jarlog/en-US $(PROFILE_GEN_SCRIPT)
rm -f ${PGO_OBJDIR}/jarlog/en-US.log
MOZ_PGO_INSTRUMENTED=1 OBJDIR=${PGO_OBJDIR} JARLOG_FILE=${PGO_OBJDIR}/jarlog/en-US.log $(PROFILE_GEN_SCRIPT)
$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
$(MAKE) -f $(TOPSRCDIR)/client.mk realbuild MOZ_PROFILE_USE=1

View File

@ -1207,17 +1207,9 @@ ifneq (,$(DIST_SUBDIR)$(XPI_NAME)$(LIBXUL_SDK))
PREF_DIR = defaults/preferences
endif
ifneq ($(PREF_JS_EXPORTS),)
# on win32, pref files need CRLF line endings... see bug 206029
ifeq (WINNT,$(OS_ARCH))
PREF_PPFLAGS = --line-endings=crlf
endif
ifndef NO_DIST_INSTALL
PREF_JS_EXPORTS_PATH := $(FINAL_TARGET)/$(PREF_DIR)
PREF_JS_EXPORTS_FLAGS := $(PREF_PPFLAGS)
PP_TARGETS += PREF_JS_EXPORTS
endif
PREF_PPFLAGS += --line-endings=crlf
endif
# Set a flag that can be used in pref files to disable features if
@ -1226,6 +1218,14 @@ ifeq (,$(findstring a,$(GRE_MILESTONE)))
PREF_PPFLAGS += -DRELEASE_BUILD
endif
ifneq ($(PREF_JS_EXPORTS),)
ifndef NO_DIST_INSTALL
PREF_JS_EXPORTS_PATH := $(FINAL_TARGET)/$(PREF_DIR)
PREF_JS_EXPORTS_FLAGS := $(PREF_PPFLAGS)
PP_TARGETS += PREF_JS_EXPORTS
endif
endif
################################################################################
# Copy each element of AUTOCFG_JS_EXPORTS to $(FINAL_TARGET)/defaults/autoconfig

Some files were not shown because too many files have changed in this diff Show More