Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e34a5dc329 | ||
|
|
e622797ed5 |
No files matched your search
@@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Clobber for libvpx changes
|
||||
Switching to C++17 requires CLOBBER to pick up compiler conf. (Issue #2281)
|
||||
@@ -19,13 +19,6 @@ If you are interested in the development and building side of things, some
|
||||
information will be available on the [Pale Moon developer site](http://developer.palemoon.org).
|
||||
You are also always welcome to get in touch with our community on the [Pale Moon forum](https://forum.palemoon.org/).
|
||||
|
||||
### Code search
|
||||
|
||||
While our repo has basic code searching capabilities (via `git grep`), you are strongly
|
||||
encouraged to instead use the dedicated code search and cross-referencing site:
|
||||
[https://xref.palemoon.org/](https://xref.palemoon.org/)
|
||||
This repo and a copy of the front-end are amalgamated in the `goanna-central` index.
|
||||
|
||||
### A note about trademarks and branding
|
||||
|
||||
Although this repository is primarily licensed under Mozilla Public License v2.0, the
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Platform.h"
|
||||
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsIGSettingsService.h"
|
||||
#include "nsIGConfService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMai.h"
|
||||
#include "AtkSocketAccessible.h"
|
||||
@@ -360,22 +360,13 @@ dbus_done:
|
||||
return sShouldEnable;
|
||||
#endif
|
||||
|
||||
// check GSettings
|
||||
#define GSETINGS_A11Y_INTERFACE "org.gnome.desktop.interface"
|
||||
#define GSETINGS_A11Y_KEY "toolkit-accessibility"
|
||||
nsCOMPtr<nsIGSettingsService> gsettings =
|
||||
do_GetService(NS_GSETTINGSSERVICE_CONTRACTID);
|
||||
nsCOMPtr<nsIGSettingsCollection> a11y_settings;
|
||||
|
||||
if (gsettings) {
|
||||
gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(GSETINGS_A11Y_INTERFACE),
|
||||
getter_AddRefs(a11y_settings));
|
||||
|
||||
if (a11y_settings) {
|
||||
a11y_settings->GetBoolean(NS_LITERAL_CSTRING(GSETINGS_A11Y_KEY),
|
||||
&sShouldEnable);
|
||||
}
|
||||
}
|
||||
//check gconf-2 setting
|
||||
#define GCONF_A11Y_KEY "/desktop/gnome/interface/accessibility"
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIGConfService> gconf =
|
||||
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && gconf)
|
||||
gconf->GetBool(NS_LITERAL_CSTRING(GCONF_A11Y_KEY), &sShouldEnable);
|
||||
|
||||
return sShouldEnable;
|
||||
}
|
||||
@@ -80,7 +80,7 @@ StyleInfo::TextIndent(nsAString& aValue)
|
||||
}
|
||||
|
||||
void
|
||||
StyleInfo::Margin(Side aSide, nsAString& aValue)
|
||||
StyleInfo::Margin(css::Side aSide, nsAString& aValue)
|
||||
{
|
||||
MOZ_ASSERT(mElement->GetPrimaryFrame(), " mElement->GetPrimaryFrame() needs to be valid pointer");
|
||||
aValue.Truncate();
|
||||
|
||||
@@ -44,9 +44,7 @@
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/a11y/Compatibility.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
#include "HTMLWin32ObjectAccessible.h"
|
||||
#endif
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#endif
|
||||
|
||||
@@ -57,10 +55,8 @@
|
||||
#include "nsImageFrame.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
#include "nsPluginFrame.h"
|
||||
#endif
|
||||
#include "SVGGeometryFrame.h"
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsTreeBodyFrame.h"
|
||||
#include "nsTreeColumns.h"
|
||||
#include "nsTreeUtils.h"
|
||||
@@ -83,7 +79,7 @@
|
||||
#include "XULTabAccessible.h"
|
||||
#include "XULTreeGridAccessibleWrap.h"
|
||||
|
||||
#if (defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)) && defined(MOZ_ENABLE_NPAPI)
|
||||
#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#endif
|
||||
|
||||
@@ -435,7 +431,6 @@ private:
|
||||
NS_IMPL_ISUPPORTS(PluginTimerCallBack, nsITimerCallback)
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
already_AddRefed<Accessible>
|
||||
nsAccessibilityService::CreatePluginAccessible(nsPluginFrame* aFrame,
|
||||
nsIContent* aContent,
|
||||
@@ -498,7 +493,6 @@ nsAccessibilityService::CreatePluginAccessible(nsPluginFrame* aFrame,
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
#endif // MOZ_ENABLE_NPAPI
|
||||
|
||||
void
|
||||
nsAccessibilityService::DeckPanelSwitched(nsIPresShell* aPresShell,
|
||||
@@ -1165,8 +1159,8 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
|
||||
|
||||
if (!newAcc) {
|
||||
if (content->IsSVGElement()) {
|
||||
SVGGeometryFrame* geometryFrame = do_QueryFrame(frame);
|
||||
if (geometryFrame) {
|
||||
nsSVGPathGeometryFrame* pathGeometryFrame = do_QueryFrame(frame);
|
||||
if (pathGeometryFrame) {
|
||||
// A graphic elements: rect, circle, ellipse, line, path, polygon,
|
||||
// polyline and image. A 'use' and 'text' graphic elements require
|
||||
// special support.
|
||||
@@ -1644,13 +1638,11 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
|
||||
case eOuterDocType:
|
||||
newAcc = new OuterDocAccessible(aContent, document);
|
||||
break;
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
case ePluginType: {
|
||||
nsPluginFrame* pluginFrame = do_QueryFrame(aFrame);
|
||||
newAcc = CreatePluginAccessible(pluginFrame, aContent, aContext);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case eTextLeafType:
|
||||
newAcc = new TextLeafAccessibleWrap(aContent, document);
|
||||
break;
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
class nsImageFrame;
|
||||
class nsIArray;
|
||||
class nsIPersistentProperties;
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
class nsPluginFrame;
|
||||
#endif
|
||||
class nsITreeView;
|
||||
|
||||
namespace mozilla {
|
||||
@@ -89,11 +87,9 @@ public:
|
||||
|
||||
Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
|
||||
bool aCanCreate);
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
already_AddRefed<Accessible>
|
||||
CreatePluginAccessible(nsPluginFrame* aFrame, nsIContent* aContent,
|
||||
Accessible* aContext);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Adds/remove ATK root accessible for gtk+ native window to/from children
|
||||
|
||||
@@ -157,7 +157,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DocAccessible, Accessible)
|
||||
tmp->mARIAOwnsHash.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DocAccessible)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DocAccessible)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
|
||||
@@ -76,7 +76,7 @@ HyperTextAccessible::NativeState()
|
||||
{
|
||||
uint64_t states = AccessibleWrap::NativeState();
|
||||
|
||||
if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_READWRITE)) {
|
||||
if (mContent->AsElement()->State().HasState(NS_EVENT_STATE_MOZ_READWRITE)) {
|
||||
states |= states::EDITABLE;
|
||||
|
||||
} else if (mContent->IsHTMLElement(nsGkAtoms::article)) {
|
||||
|
||||
@@ -486,14 +486,13 @@ DocAccessibleParent::SetCOMProxy(const RefPtr<IAccessible>& aCOMProxy)
|
||||
IAccessibleHolder holder(Move(ptr));
|
||||
Unused << SendParentCOMProxy(holder);
|
||||
}
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
|
||||
bool
|
||||
DocAccessibleParent::RecvGetWindowedPluginIAccessible(
|
||||
const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
|
||||
@@ -143,11 +143,10 @@ public:
|
||||
|
||||
#if defined(XP_WIN)
|
||||
void SetCOMProxy(const RefPtr<IAccessible>& aCOMProxy);
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
|
||||
virtual bool RecvGetWindowedPluginIAccessible(
|
||||
const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy) override;
|
||||
#endif // MOZ_ENABLE_NPAPI
|
||||
#endif // XP_WIN
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -61,10 +61,8 @@ parent:
|
||||
*/
|
||||
async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
|
||||
|
||||
#ifdef MOZ_ENABLE_NPAPI
|
||||
sync GetWindowedPluginIAccessible(WindowsHandle aHwnd)
|
||||
returns (IAccessibleHolder aPluginCOMProxy);
|
||||
#endif
|
||||
|
||||
child:
|
||||
async ParentCOMProxy(IAccessibleHolder aParentCOMProxy);
|
||||
|
||||
@@ -8,7 +8,7 @@ if CONFIG['COMPILE_ENVIRONMENT']:
|
||||
|
||||
# With --disable-accessibility, we need to compile PDocAccessible.ipdl (which
|
||||
# also depends on COMPtrTypes.h), but not the C++.
|
||||
PREPROCESSED_IPDL_SOURCES += ['PDocAccessible.ipdl']
|
||||
IPDL_SOURCES += ['PDocAccessible.ipdl']
|
||||
EXPORTS.mozilla.a11y += ['COMPtrTypes.h']
|
||||
|
||||
if CONFIG['ACCESSIBILITY']:
|
||||
|
||||
@@ -340,9 +340,9 @@ this.AccessFu = { // jshint ignore:line
|
||||
case 'remote-browser-shown':
|
||||
case 'inprocess-browser-shown':
|
||||
{
|
||||
// Ignore notifications that aren't from a Browser
|
||||
// Ignore notifications that aren't from a BrowserOrApp
|
||||
let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
|
||||
if (!frameLoader.ownerIsMozBrowserFrame) {
|
||||
if (!frameLoader.ownerIsMozBrowserOrAppFrame) {
|
||||
return;
|
||||
}
|
||||
this._handleMessageManager(frameLoader.messageManager);
|
||||
|
||||
@@ -38,13 +38,6 @@ SOURCES += [
|
||||
'XULTreeGridAccessibleWrap.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_ENABLE_NPAPI']:
|
||||
SOURCES += [
|
||||
'HTMLWin32ObjectAccessible.cpp',
|
||||
]
|
||||
|
||||
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/base',
|
||||
'/accessible/generic',
|
||||
|
||||
@@ -30,7 +30,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(xpcAccessibleDocument,
|
||||
tmp->mCache.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleDocument)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(xpcAccessibleDocument)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleHyperText)
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ XULTreeAccessible::~XULTreeAccessible()
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeAccessible, Accessible,
|
||||
mTree, mAccessibleCache)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeAccessible)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(Accessible)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(XULTreeAccessible, Accessible)
|
||||
@@ -709,9 +709,12 @@ XULTreeItemAccessibleBase::~XULTreeItemAccessibleBase()
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessibleBase, Accessible,
|
||||
mTree)
|
||||
|
||||
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessibleBase,
|
||||
Accessible,
|
||||
XULTreeItemAccessibleBase)
|
||||
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessibleBase)
|
||||
NS_INTERFACE_TABLE_INHERITED(XULTreeItemAccessibleBase,
|
||||
XULTreeItemAccessibleBase)
|
||||
NS_INTERFACE_TABLE_TAIL_INHERITING(Accessible)
|
||||
NS_IMPL_ADDREF_INHERITED(XULTreeItemAccessibleBase, Accessible)
|
||||
NS_IMPL_RELEASE_INHERITED(XULTreeItemAccessibleBase, Accessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XULTreeItemAccessibleBase: Accessible
|
||||
@@ -1081,7 +1084,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessible,
|
||||
XULTreeItemAccessibleBase,
|
||||
mColumn)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeItemAccessible)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeItemAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(XULTreeItemAccessibleBase)
|
||||
NS_IMPL_ADDREF_INHERITED(XULTreeItemAccessible, XULTreeItemAccessibleBase)
|
||||
NS_IMPL_RELEASE_INHERITED(XULTreeItemAccessible, XULTreeItemAccessibleBase)
|
||||
|
||||
@@ -263,7 +263,7 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridRowAccessible,
|
||||
XULTreeItemAccessibleBase,
|
||||
mAccessibleCache)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridRowAccessible)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeGridRowAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(XULTreeItemAccessibleBase)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(XULTreeGridRowAccessible,
|
||||
@@ -447,7 +447,7 @@ XULTreeGridCellAccessible::~XULTreeGridCellAccessible()
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible, LeafAccessible,
|
||||
mTree, mColumn)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULTreeGridCellAccessible)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(XULTreeGridCellAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(LeafAccessible)
|
||||
NS_IMPL_ADDREF_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(XULTreeGridCellAccessible, LeafAccessible)
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,80 +0,0 @@
|
||||
dnl Map old names of Autoconf macros to new regularized names.
|
||||
dnl This file is part of Autoconf.
|
||||
dnl Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2, or (at your option)
|
||||
dnl any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl General macros.
|
||||
dnl
|
||||
define(AC_WARN, [indir([AC_MSG_WARN], $@)])dnl
|
||||
define(AC_ERROR, [indir([AC_MSG_ERROR], $@)])dnl
|
||||
AC_DEFUN(AC_PROGRAM_CHECK, [indir([AC_CHECK_PROG], $@)])dnl
|
||||
AC_DEFUN(AC_PROGRAM_PATH, [indir([AC_PATH_PROG], $@)])dnl
|
||||
AC_DEFUN(AC_PROGRAMS_CHECK, [indir([AC_CHECK_PROGS], $@)])dnl
|
||||
AC_DEFUN(AC_PROGRAMS_PATH, [indir([AC_PATH_PROGS], $@)])dnl
|
||||
AC_DEFUN(AC_PREFIX, [indir([AC_PREFIX_PROGRAM], $@)])dnl
|
||||
AC_DEFUN(AC_HEADER_EGREP, [indir([AC_EGREP_HEADER], $@)])dnl
|
||||
AC_DEFUN(AC_PROGRAM_EGREP, [indir([AC_EGREP_CPP], $@)])dnl
|
||||
AC_DEFUN(AC_TEST_PROGRAM, [indir([AC_TRY_RUN], $@)])dnl
|
||||
AC_DEFUN(AC_TEST_CPP, [indir([AC_TRY_CPP], $@)])dnl
|
||||
AC_DEFUN(AC_HEADER_CHECK, [indir([AC_CHECK_HEADER], $@)])dnl
|
||||
AC_DEFUN(AC_FUNC_CHECK, [indir([AC_CHECK_FUNC], $@)])dnl
|
||||
AC_DEFUN(AC_HAVE_FUNCS, [indir([AC_CHECK_FUNCS], $@)])dnl
|
||||
AC_DEFUN(AC_HAVE_HEADERS, [indir([AC_CHECK_HEADERS], $@)])dnl
|
||||
AC_DEFUN(AC_SIZEOF_TYPE, [indir([AC_CHECK_SIZEOF], $@)])dnl
|
||||
dnl
|
||||
dnl Specific macros.
|
||||
dnl
|
||||
AC_DEFUN(AC_GCC_TRADITIONAL, [indir([AC_PROG_GCC_TRADITIONAL])])dnl
|
||||
AC_DEFUN(AC_MINUS_C_MINUS_O, [indir([AC_PROG_CC_C_O])])dnl
|
||||
AC_DEFUN(AC_SET_MAKE, [indir([AC_PROG_MAKE_SET])])dnl
|
||||
AC_DEFUN(AC_YYTEXT_POINTER, [indir([AC_DECL_YYTEXT])])dnl
|
||||
AC_DEFUN(AC_LN_S, [indir([AC_PROG_LN_S])])dnl
|
||||
AC_DEFUN(AC_STDC_HEADERS, [indir([AC_HEADER_STDC])])dnl
|
||||
AC_DEFUN(AC_MAJOR_HEADER, [indir([AC_HEADER_MAJOR])])dnl
|
||||
AC_DEFUN(AC_STAT_MACROS_BROKEN, [indir([AC_HEADER_STAT])])dnl
|
||||
AC_DEFUN(AC_SYS_SIGLIST_DECLARED, [indir([AC_DECL_SYS_SIGLIST])])dnl
|
||||
AC_DEFUN(AC_GETGROUPS_T, [indir([AC_TYPE_GETGROUPS])])dnl
|
||||
AC_DEFUN(AC_UID_T, [indir([AC_TYPE_UID_T])])dnl
|
||||
AC_DEFUN(AC_SIZE_T, [indir([AC_TYPE_SIZE_T])])dnl
|
||||
AC_DEFUN(AC_PID_T, [indir([AC_TYPE_PID_T])])dnl
|
||||
AC_DEFUN(AC_OFF_T, [indir([AC_TYPE_OFF_T])])dnl
|
||||
AC_DEFUN(AC_MODE_T, [indir([AC_TYPE_MODE_T])])dnl
|
||||
AC_DEFUN(AC_RETSIGTYPE, [indir([AC_TYPE_SIGNAL])])dnl
|
||||
AC_DEFUN(AC_MMAP, [indir([AC_FUNC_MMAP])])dnl
|
||||
AC_DEFUN(AC_VPRINTF, [indir([AC_FUNC_VPRINTF])])dnl
|
||||
AC_DEFUN(AC_VFORK, [indir([AC_FUNC_VFORK])])dnl
|
||||
AC_DEFUN(AC_WAIT3, [indir([AC_FUNC_WAIT3])])dnl
|
||||
AC_DEFUN(AC_ALLOCA, [indir([AC_FUNC_ALLOCA])])dnl
|
||||
AC_DEFUN(AC_GETLOADAVG, [indir([AC_FUNC_GETLOADAVG])])dnl
|
||||
AC_DEFUN(AC_UTIME_NULL, [indir([AC_FUNC_UTIME_NULL])])dnl
|
||||
AC_DEFUN(AC_STRCOLL, [indir([AC_FUNC_STRCOLL])])dnl
|
||||
AC_DEFUN(AC_SETVBUF_REVERSED, [indir([AC_FUNC_SETVBUF_REVERSED])])dnl
|
||||
AC_DEFUN(AC_TIME_WITH_SYS_TIME, [indir([AC_HEADER_TIME])])dnl
|
||||
AC_DEFUN(AC_TIMEZONE, [indir([AC_STRUCT_TIMEZONE])])dnl
|
||||
AC_DEFUN(AC_ST_BLOCKS, [indir([AC_STRUCT_ST_BLOCKS])])dnl
|
||||
AC_DEFUN(AC_ST_BLKSIZE, [indir([AC_STRUCT_ST_BLKSIZE])])dnl
|
||||
AC_DEFUN(AC_ST_RDEV, [indir([AC_STRUCT_ST_RDEV])])dnl
|
||||
AC_DEFUN(AC_CROSS_CHECK, [indir([AC_C_CROSS])])dnl
|
||||
AC_DEFUN(AC_CHAR_UNSIGNED, [indir([AC_C_CHAR_UNSIGNED])])dnl
|
||||
AC_DEFUN(AC_LONG_DOUBLE, [indir([AC_C_LONG_DOUBLE])])dnl
|
||||
AC_DEFUN(AC_WORDS_BIGENDIAN, [indir([AC_C_BIGENDIAN])])dnl
|
||||
AC_DEFUN(AC_INLINE, [indir([AC_C_INLINE])])dnl
|
||||
AC_DEFUN(AC_CONST, [indir([AC_C_CONST])])dnl
|
||||
AC_DEFUN(AC_LONG_FILE_NAMES, [indir([AC_SYS_LONG_FILE_NAMES])])dnl
|
||||
AC_DEFUN(AC_RESTARTABLE_SYSCALLS, [indir([AC_SYS_RESTARTABLE_SYSCALLS])])dnl
|
||||
AC_DEFUN(AC_FIND_X, [indir([AC_PATH_X])])dnl
|
||||
AC_DEFUN(AC_FIND_XTRA, [indir([AC_PATH_XTRA])])dnl
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,28 +0,0 @@
|
||||
dnl Driver that loads the Autoconf macro files.
|
||||
dnl Requires GNU m4.
|
||||
dnl This file is part of Autoconf.
|
||||
dnl Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2, or (at your option)
|
||||
dnl any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
dnl 02111-1307, USA.
|
||||
dnl
|
||||
dnl Written by David MacKenzie.
|
||||
dnl
|
||||
include(acgeneral.m4)dnl
|
||||
builtin(include, acspecific.m4)dnl
|
||||
builtin(include, acoldnames.m4)dnl
|
||||
dnl Do not sinclude acsite.m4 here, because it may not be installed
|
||||
dnl yet when Autoconf is frozen.
|
||||
dnl Do not sinclude ./aclocal.m4 here, to prevent it from being frozen.
|
||||
@@ -1,159 +0,0 @@
|
||||
#! @SHELL@
|
||||
# autoconf -- create `configure' using m4 macros
|
||||
# Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
# If given no args, create `configure' from template file `configure.in'.
|
||||
# With one arg, create a configure script on standard output from
|
||||
# the given template file.
|
||||
|
||||
usage="\
|
||||
Usage: autoconf [-h] [--help] [-m dir] [--macrodir=dir]
|
||||
[-l dir] [--localdir=dir] [--version] [template-file]"
|
||||
|
||||
# NLS nuisances.
|
||||
# Only set these to C if already set. These must not be set unconditionally
|
||||
# because not all systems understand e.g. LANG=C (notably SCO).
|
||||
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
|
||||
# Non-C LC_CTYPE values break the ctype check.
|
||||
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
|
||||
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
|
||||
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
|
||||
if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
|
||||
|
||||
: ${AC_MACRODIR=@datadir@}
|
||||
: ${M4=@M4@}
|
||||
: ${AWK=@AWK@}
|
||||
case "${M4}" in
|
||||
/*) # Handle the case that m4 has moved since we were configured.
|
||||
# It may have been found originally in a build directory.
|
||||
test -f "${M4}" || M4=m4 ;;
|
||||
esac
|
||||
|
||||
: ${TMPDIR=/tmp}
|
||||
tmpout=${TMPDIR}/acout.$$
|
||||
localdir=
|
||||
show_version=no
|
||||
|
||||
while test $# -gt 0 ; do
|
||||
case "${1}" in
|
||||
-h | --help | --h* )
|
||||
echo "${usage}" 1>&2; exit 0 ;;
|
||||
--localdir=* | --l*=* )
|
||||
localdir="`echo \"${1}\" | sed -e 's/^[^=]*=//'`"
|
||||
shift ;;
|
||||
-l | --localdir | --l*)
|
||||
shift
|
||||
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
|
||||
localdir="${1}"
|
||||
shift ;;
|
||||
--macrodir=* | --m*=* )
|
||||
AC_MACRODIR="`echo \"${1}\" | sed -e 's/^[^=]*=//'`"
|
||||
shift ;;
|
||||
-m | --macrodir | --m* )
|
||||
shift
|
||||
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
|
||||
AC_MACRODIR="${1}"
|
||||
shift ;;
|
||||
--version | --v* )
|
||||
show_version=yes; shift ;;
|
||||
-- ) # Stop option processing
|
||||
shift; break ;;
|
||||
- ) # Use stdin as input.
|
||||
break ;;
|
||||
-* )
|
||||
echo "${usage}" 1>&2; exit 1 ;;
|
||||
* )
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test $show_version = yes; then
|
||||
version=`sed -n 's/define.AC_ACVERSION.[ ]*\([0-9.]*\).*/\1/p' \
|
||||
$AC_MACRODIR/acgeneral.m4`
|
||||
echo "Autoconf version $version"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
case $# in
|
||||
0) infile=configure.in ;;
|
||||
1) infile="$1" ;;
|
||||
*) echo "$usage" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
trap 'rm -f $tmpin $tmpout; exit 1' 1 2 15
|
||||
|
||||
tmpin=${TMPDIR}/acin.$$ # Always set this, to avoid bogus errors from some rm's.
|
||||
if test z$infile = z-; then
|
||||
infile=$tmpin
|
||||
cat > $infile
|
||||
elif test ! -r "$infile"; then
|
||||
echo "autoconf: ${infile}: No such file or directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -n "$localdir"; then
|
||||
use_localdir="-I$localdir -DAC_LOCALDIR=$localdir"
|
||||
else
|
||||
use_localdir=
|
||||
fi
|
||||
|
||||
# Use the frozen version of Autoconf if available.
|
||||
r= f=
|
||||
# Some non-GNU m4's don't reject the --help option, so give them /dev/null.
|
||||
case `$M4 --help < /dev/null 2>&1` in
|
||||
*reload-state*) test -r $AC_MACRODIR/autoconf.m4f && { r=--reload f=f; } ;;
|
||||
*traditional*) ;;
|
||||
*) echo Autoconf requires GNU m4 1.1 or later >&2; rm -f $tmpin; exit 1 ;;
|
||||
esac
|
||||
|
||||
$M4 -I$AC_MACRODIR $use_localdir $r autoconf.m4$f $infile > $tmpout ||
|
||||
{ rm -f $tmpin $tmpout; exit 2; }
|
||||
|
||||
# You could add your own prefixes to pattern if you wanted to check for
|
||||
# them too, e.g. pattern='\(AC_\|ILT_\)', except that UNIX sed doesn't do
|
||||
# alternation.
|
||||
pattern="AC_"
|
||||
|
||||
status=0
|
||||
if grep "^[^#]*${pattern}" $tmpout > /dev/null 2>&1; then
|
||||
echo "autoconf: Undefined macros:" >&2
|
||||
sed -n "s/^[^#]*\\(${pattern}[_A-Za-z0-9]*\\).*/\\1/p" $tmpout |
|
||||
while read macro; do
|
||||
grep -n "^[^#]*$macro" $infile /dev/null
|
||||
test $? -eq 1 && echo >&2 "***BUG in Autoconf--please report*** $macro"
|
||||
done | sort -u >&2
|
||||
status=1
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
exec 4> configure; chmod +x configure
|
||||
else
|
||||
exec 4>&1
|
||||
fi
|
||||
|
||||
# Put the real line numbers into configure to make config.log more helpful.
|
||||
$AWK '
|
||||
/__oline__/ { printf "%d:", NR + 1 }
|
||||
{ print }
|
||||
' $tmpout | sed '
|
||||
/__oline__/s/^\([0-9][0-9]*\):\(.*\)__oline__/\2\1/
|
||||
' >&4
|
||||
|
||||
rm -f $tmpout
|
||||
|
||||
exit $status
|
||||
@@ -179,22 +179,20 @@ if test "$GNU_CC"; then
|
||||
CFLAGS="$CFLAGS -fno-math-errno -pipe"
|
||||
CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-math-errno -pipe"
|
||||
|
||||
case "${host_cpu}" in
|
||||
i*86)
|
||||
CFLAGS="$CFLAGS -msse2 -mfpmath=sse"
|
||||
CXXFLAGS="$CXXFLAGS -msse2 -mfpmath=sse"
|
||||
;;
|
||||
esac
|
||||
if test "$CPU_ARCH" = "x86" -o "$CPU_ARCH" = "x86_64"; then
|
||||
CFLAGS="$CFLAGS -msse2 -mfpmath=sse"
|
||||
CXXFLAGS="$CXXFLAGS -msse2 -mfpmath=sse"
|
||||
fi
|
||||
|
||||
if test -z "$CLANG_CC"; then
|
||||
case "$CC_VERSION" in
|
||||
4.* | 5.* | 6.* | 7.* | 8.*)
|
||||
4.* | 5.* | 6.*)
|
||||
AC_MSG_ERROR([Unsupported GCC version.])
|
||||
;;
|
||||
*)
|
||||
# Lifetime Dead Store Elimination level 2 (default in GCC) breaks Goanna.
|
||||
# Instead of completely disabling this optimization, we force level 1
|
||||
# optimization instead with -flifetime-dse=1.
|
||||
# Lifetime Dead Store Elimination level 2 (default in GCC6+) breaks Gecko.
|
||||
# Instead of completely disabling this optimization on newer GCC's,
|
||||
# we'll force them to use level 1 optimization with -flifetime-dse=1.
|
||||
# Add it first so that a mozconfig can override by setting CFLAGS/CXXFLAGS.
|
||||
CFLAGS="-flifetime-dse=1 $CFLAGS"
|
||||
CXXFLAGS="-flifetime-dse=1 $CXXFLAGS"
|
||||
|
||||
Vendored
-3
@@ -982,9 +982,6 @@ EOF
|
||||
k1om:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
loongarch64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
|
||||
@@ -375,9 +375,6 @@ def split_triplet(triplet):
|
||||
elif cpu.startswith('aarch64'):
|
||||
canonical_cpu = 'aarch64'
|
||||
endianness = 'little'
|
||||
elif cpu.startswith('loongarch64'):
|
||||
canonical_cpu = 'loongarch64'
|
||||
endianness = 'little'
|
||||
else:
|
||||
die('Unknown CPU type: %s' % cpu)
|
||||
|
||||
|
||||
@@ -11,14 +11,9 @@ def moz_jemalloc4(value):
|
||||
|
||||
option('--enable-jemalloc', env='MOZ_MEMORY',
|
||||
help='Replace system memory allocator with jemalloc')
|
||||
option('--enable-mimalloc',
|
||||
help='Replace system memory allocator with mimalloc')
|
||||
|
||||
@depends('--enable-jemalloc', '--enable-mimalloc', target, build_project,
|
||||
c_compiler)
|
||||
def jemalloc(value, mimalloc, target, build_project, c_compiler):
|
||||
if value and mimalloc:
|
||||
die('--enable-jemalloc and --enable-mimalloc cannot be used together')
|
||||
@depends('--enable-jemalloc', target, build_project, c_compiler)
|
||||
def jemalloc(value, target, build_project, c_compiler):
|
||||
if value.origin != 'default':
|
||||
return bool(value) or None
|
||||
|
||||
@@ -35,38 +30,11 @@ def jemalloc(value, mimalloc, target, build_project, c_compiler):
|
||||
if target.kernel == 'Linux':
|
||||
return True
|
||||
|
||||
@depends('--enable-mimalloc', '--enable-jemalloc', target)
|
||||
def mimalloc(value, jemalloc, target):
|
||||
if value and jemalloc:
|
||||
die('--enable-jemalloc and --enable-mimalloc cannot be used together')
|
||||
if value.origin != 'default':
|
||||
if not value:
|
||||
return None
|
||||
if target.kernel not in ('Darwin', 'WINNT', 'Linux', 'kFreeBSD', 'FreeBSD',
|
||||
'NetBSD', 'OpenBSD', 'DragonFly'):
|
||||
die('--enable-mimalloc is not supported on %s', target.kernel)
|
||||
return True
|
||||
|
||||
@depends('--enable-mimalloc', '--enable-jemalloc')
|
||||
def mimalloc_requires_disable(mimalloc, jemalloc):
|
||||
if not mimalloc:
|
||||
return
|
||||
if jemalloc or jemalloc.origin not in ('command-line', 'mozconfig'):
|
||||
die('--enable-mimalloc requires --disable-jemalloc to be passed explicitly')
|
||||
|
||||
|
||||
set_config('MOZ_MEMORY', jemalloc)
|
||||
set_define('MOZ_MEMORY', jemalloc)
|
||||
add_old_configure_assignment('MOZ_MEMORY', jemalloc)
|
||||
|
||||
@depends(mimalloc)
|
||||
def mimalloc_config(mimalloc):
|
||||
return True if mimalloc else False
|
||||
|
||||
set_config('MOZ_MIMALLOC', mimalloc_config)
|
||||
set_define('MOZ_MIMALLOC', mimalloc)
|
||||
add_old_configure_assignment('MOZ_MIMALLOC', mimalloc_config)
|
||||
|
||||
|
||||
# Because --enable-jemalloc doesn't use a default because of the dependency
|
||||
# on the target, we can't use a js_option for it to propagate to js/src
|
||||
|
||||
@@ -10,28 +10,66 @@ def encoded_open(path, mode):
|
||||
return codecs.open(path, mode, encoding)
|
||||
|
||||
|
||||
m4 = check_prog(
|
||||
"M4",
|
||||
(
|
||||
"gm4",
|
||||
"m4",
|
||||
),
|
||||
)
|
||||
option(env='AUTOCONF', nargs=1, help='Path to autoconf 2.13')
|
||||
|
||||
@depends('OLD_CONFIGURE', mozconfig, awk, m4, check_build_environment, shell,
|
||||
@depends(mozconfig, 'AUTOCONF')
|
||||
@checking('for autoconf')
|
||||
@imports(_from='os.path', _import='exists')
|
||||
@imports('re')
|
||||
def autoconf(mozconfig, autoconf):
|
||||
mozconfig_autoconf = None
|
||||
if mozconfig['path']:
|
||||
make_extra = mozconfig['make_extra']
|
||||
if make_extra:
|
||||
for assignment in make_extra:
|
||||
m = re.match('(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$',
|
||||
assignment)
|
||||
if m:
|
||||
mozconfig_autoconf = m.group(1)
|
||||
|
||||
autoconf = autoconf[0] if autoconf else None
|
||||
|
||||
for ac in (mozconfig_autoconf, autoconf, 'autoconf-2.13', 'autoconf2.13',
|
||||
'autoconf213'):
|
||||
if ac:
|
||||
autoconf = find_program(ac)
|
||||
if autoconf:
|
||||
break
|
||||
else:
|
||||
fink = find_program('fink')
|
||||
if fink:
|
||||
autoconf = os.path.normpath(os.path.join(
|
||||
fink, '..', '..', 'lib', 'autoconf2.13', 'bin', 'autoconf'))
|
||||
else:
|
||||
brew = find_program('brew')
|
||||
if brew:
|
||||
autoconf = os.path.normpath(os.path.join(
|
||||
brew, '..', '..', 'Cellar', 'autoconf213', '2.13', 'bin',
|
||||
'autoconf213'))
|
||||
|
||||
if not autoconf:
|
||||
die('Could not find autoconf 2.13')
|
||||
|
||||
if not exists(autoconf):
|
||||
die('Could not find autoconf 2.13 at %s', autoconf)
|
||||
|
||||
return autoconf
|
||||
|
||||
set_config('AUTOCONF', autoconf)
|
||||
|
||||
|
||||
@depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell,
|
||||
old_configure_assignments, build_project)
|
||||
@imports(_from='__builtin__', _import='open')
|
||||
@imports(_from='__builtin__', _import='print')
|
||||
@imports('glob')
|
||||
@imports('sys')
|
||||
@imports('itertools')
|
||||
@imports('subprocess')
|
||||
# Import getmtime without overwriting the sandbox os.path.
|
||||
@imports(_from='os.path', _import='getmtime')
|
||||
@imports(_from='os.path', _import='exists')
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
@imports(_from='os', _import='environ')
|
||||
def prepare_configure(old_configure, mozconfig, awk, m4, build_env, shell,
|
||||
def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
|
||||
old_configure_assignments, build_project):
|
||||
# os.path.abspath in the sandbox will ensure forward slashes on Windows,
|
||||
# which is actually necessary because this path actually ends up literally
|
||||
@@ -60,22 +98,11 @@ def prepare_configure(old_configure, mozconfig, awk, m4, build_env, shell,
|
||||
refresh = False
|
||||
|
||||
if refresh:
|
||||
autoconf = os.path.join(build_env.topsrcdir, 'build', 'autoconf', 'autoconf.sh')
|
||||
log.info('Refreshing %s with %s', old_configure, autoconf)
|
||||
env = dict(environ)
|
||||
env['M4'] = m4
|
||||
env['AWK'] = awk
|
||||
env['AC_MACRODIR'] = os.path.join(build_env.topsrcdir, 'build', 'autoconf')
|
||||
my_env = env
|
||||
# Handle Python 2.7 not allowing unicode in the environment on Windows
|
||||
if sys.platform == 'win32':
|
||||
my_env = dict()
|
||||
for e in env:
|
||||
my_env[e.encode('ascii','ignore')] = env[e].encode('ascii','ignore')
|
||||
script = subprocess.check_output([
|
||||
shell, autoconf,
|
||||
'--localdir=%s' % os.path.dirname(old_configure),
|
||||
old_configure + '.in'], env=my_env)
|
||||
old_configure + '.in'])
|
||||
|
||||
# Make old-configure append to config.log, where we put our own log.
|
||||
# This could be done with a m4 macro, but it's way easier this way
|
||||
@@ -100,6 +127,10 @@ def prepare_configure(old_configure, mozconfig, awk, m4, build_env, shell,
|
||||
for key in mozconfig[t]['removed'].keys():
|
||||
inject("unset %s" % key)
|
||||
|
||||
# Autoconf is special, because it might be passed from
|
||||
# mozconfig['make_extra'], which we don't pass automatically above.
|
||||
inject('export AUTOCONF=%s' % quote(autoconf))
|
||||
|
||||
for assignment in old_configure_assignments:
|
||||
inject(assignment)
|
||||
|
||||
@@ -127,6 +158,7 @@ def old_configure_options(*options):
|
||||
'--enable-alsa',
|
||||
'--enable-appcompat-guid',
|
||||
'--enable-av1',
|
||||
'--enable-jxl',
|
||||
'--enable-b2g-bt',
|
||||
'--enable-b2g-camera',
|
||||
'--enable-b2g-ril',
|
||||
@@ -152,7 +184,10 @@ def old_configure_options(*options):
|
||||
'--enable-faststripe',
|
||||
'--enable-feeds',
|
||||
'--enable-gamepad',
|
||||
'--enable-gconf',
|
||||
'--enable-gczeal',
|
||||
'--enable-gio',
|
||||
'--enable-gnomeui',
|
||||
'--enable-gold',
|
||||
'--enable-hardware-aec-ns',
|
||||
'--enable-icf',
|
||||
@@ -172,7 +207,6 @@ def old_configure_options(*options):
|
||||
'--enable-necko-wifi',
|
||||
'--enable-negotiateauth',
|
||||
'--enable-nfc',
|
||||
'--enable-npapi',
|
||||
'--enable-nspr-build',
|
||||
'--enable-official-branding',
|
||||
'--enable-official-vendor',
|
||||
@@ -277,7 +311,6 @@ def old_configure_options(*options):
|
||||
'--enable-incomplete-external-linkage',
|
||||
'--enable-mailnews',
|
||||
'--enable-mailnews-oauth2',
|
||||
'--enable-classic-account-wizard',
|
||||
|
||||
# Below are configure flags used by Pale Moon
|
||||
'--disable-browser-statusbar',
|
||||
|
||||
@@ -695,9 +695,9 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
||||
# Check the compiler version here instead of in `compiler_version` so
|
||||
# that the `checking` message doesn't pretend the compiler can be used
|
||||
# to then bail out one line later.
|
||||
if info.type == 'gcc' and info.version < '9.1.0':
|
||||
if info.type == 'gcc' and info.version < '7.1.0':
|
||||
raise FatalCheckError(
|
||||
'Only GCC 9.1 or newer is supported (found version %s).'
|
||||
'Only GCC 7.1 or newer is supported (found version %s).'
|
||||
% info.version)
|
||||
|
||||
# If you want to bump the version check here search for
|
||||
|
||||
@@ -88,7 +88,7 @@ var decompressedJQuery = function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(par
|
||||
for documentation and information on getting the source.
|
||||
*/
|
||||
|
||||
var decompressedDojo = function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('if(V z=="1k"){(B(){if(V D["1o"]=="1k"){D.1o={}}if((!D["1z"])||(!1z["ca"])){D.1z={}}A cn=["rA","rz","1K","ry","rx","9f","rw","rv","ru","rt","rs","rr","rq","ro","rn","rm"];A i=0,24;1s(24=cn[i++]){if(!1z[24]){1z[24]=B(){}}}if(V D["z"]=="1k"){D.z={}}z.1W=D;A d3={im:U,rl:U,rk:"",rj:"",ri:"",rh:K,rg:U};R(A 8z in d3){if(V 1o[8z]=="1k"){1o[8z]=d3[8z]}}A jK=["rf","rd","rc","rb"];A t;1s(t=jK.3a()){z["is"+t]=U}})();z.8h=1o.8h;z.cY={jJ:0,jI:9,jH:0,jG:"",jF:2V("$ra: r9 $".1f(/[0-9]+/)[0]),2i:B(){4G(z.cY){C jJ+"."+jI+"."+jH+jG+" ("+jF+")"}}};z.d1=B(jE,jD,1V){A 2h=1V||z.1W;R(A i=0,p;2h&&(p=jE[i]);i++){2h=(p in 2h?2h[p]:(jD?2h[p]={}:1k))}C 2h};z.88=B(jC,jA,jB){A d2=jC.1A("."),p=d2.8q(),M=z.d1(d2,K,jB);C(M&&p?(M[p]=jA):1k)};z.6q=B(jz,jy,jx){C z.d1(jz.1A("."),jy,jx)};z.r8=B(jw,M){C!!z.6q(jw,U,M)};z["3u"]=B(d0){C z.1W.3u?z.1W.3u(d0):3u(d0)};z.ia=B(jv,cZ,cX){A 8y="r7: "+jv;if(cZ){8y+=" "+cZ}if(cX){8y+=" -- r6 be r5 in cY: "+cX}1z.1K(8y)};z.r4=B(ju,cW){A cV="r3: "+ju+" -- r2 r1 4F r0 qZ qY.";if(cW){cV+=" "+cW}1z.1K(cV)};(B(){A cR={53:{},6p:0,1h:{},8k:{z:{1p:"z",1Z:"."},cU:{1p:"cU",1Z:"../qX/cU"},cT:{1p:"cT",1Z:"cT"}},cN:B(cS){A mp=D.8k;C jp(mp[cS]&&mp[cS].1Z)},jk:B(8x){A mp=D.8k;if(D.cN(8x)){C mp[8x].1Z}C 8x},8v:[],6t:U,56:[],8t:[],8u:U};R(A cQ in cR){z[cQ]=cR[cQ]}})();z.jg=B(8w,cP,cb){A 1g=(((8w.2s(0)=="/"||8w.1f(/^\\w+:/)))?"":D.51)+8w;if(1o.jt&&z.c8){1g+="?"+67(1o.jt).2f(/\\W+/g,"")}1u{C!cP?D.cO(1g,cb):D.jq(1g,cP,cb)}1y(e){1z.1K(e);C U}};z.cO=B(1g,cb){if(D.8v[1g]){C K}A 6u=D.iR(1g,K);if(!6u){C U}D.8v[1g]=K;D.8v.Y(1g);if(cb){6u="("+6u+")"}A jr=z["3u"](6u+"\\r\\n//@ qW="+1g);if(cb){cb(jr)}C K};z.jq=B(1g,jo,cb){A ok=U;1u{ok=D.cO(1g,cb)}1y(e){1z.1K("qV je ",1g," 4G 9f: ",e)}C jp(ok&&D.53[jo])};z.6m=B(){D.8u=K;D.6t=K;A 57=D.56;D.56=[];R(A x=0;x<57.G;x++){57[x]()}D.8u=U;if(z.6t&&z.6p==0&&D.56.G>0){z.8s()}};z.ck=B(){A 57=D.8t;1s(57.G){(57.8q())()}};z.qU=B(M,jn){A d=z;if(P.G==1){d.56.Y(M)}I{if(P.G>1){d.56.Y(B(){M[jn]()})}}if(d.6t&&d.6p==0&&!d.8u){d.8s()}};z.dW=B(M,jm){A d=z;if(P.G==1){d.8t.Y(M)}I{if(P.G>1){d.8t.Y(B(){M[jm]()})}}};z.iM=B(){if(D.6t){C}if(D.6p>0){1z.1K("qT qS in qR!");C}z.8s()};z.8s=B(){if(V 5c=="8b"||(1o["qQ"]&&z.2M)){5c("z.6m();",0)}I{z.6m()}};z.cF=B(jl){A 4v=jl.1A(".");R(A i=4v.G;i>0;i--){A 8r=4v.2w(0,i).22(".");if((i==1)&&!D.cN(8r)){4v[0]="../"+4v[0]}I{A cM=D.jk(8r);if(cM!=8r){4v.3S(0,i,cM);3f}}}C 4v};z.jj=U;z.8m=B(2T,qP,55){55=D.jj||55;A 54=D.53[2T];if(54){C 54}A cL=2T.1A(".");A 3L=D.cF(2T);A jh=((3L[0].2s(0)!="/")&&!3L[0].1f(/^\\w+:/));A ji=3L[3L.G-1];A 3m;if(ji=="*"){2T=cL.2w(0,-1).22(".");3L.8q();3m=3L.22("/")+"/"+(1o["qO"]||"qN")+".js";if(jh&&3m.2s(0)=="/"){3m=3m.2w(1)}}I{3m=3L.22("/")+".js";2T=cL.22(".")}A jf=(!55)?2T:L;A ok=D.jg(3m,jf);if((!ok)&&(!55)){2m S 1O("qM 3O 4E \'"+2T+"\'; 72 qL \'"+3m+"\'")}if((!55)&&(!D["qK"])){54=D.53[2T];if(!54){2m S 1O("qJ \'"+2T+"\' is 3O qI a8 je \'"+3m+"\'")}}C 54};z.8c=z.8m;z.1Q=B(cK){A cJ=cK+"";A 8p=cJ;A 6s=cK.1A(/\\./);if(6s[6s.G-1]=="*"){6s.8q();8p=6s.22(".")}A 8o=z.6q(8p,K);D.53[cJ]=8o;D.53[8p]=8o;C 8o};z.qH=B(8n){A jd=8n["qG"]||[];A cI=jd.3U(8n[z.j4]||8n["aY"]||[]);R(A x=0;x<cI.G;x++){A 8l=cI[x];if(8l.1P==4e){z.8m.14(z,8l)}I{z.8m(8l)}}};z.jb=B(jc,qF){if(jc===K){A cH=[];R(A i=1;i<P.G;i++){cH.Y(P[i])}z.8c.14(z,cH)}};z.qE=z.jb;z.io=B(cG,ja){D.8k[cG]={1p:cG,1Z:ja}};z.qD=B(qC,qB,qA,qz){z.8c("z.j9");z.j9.qy.14(z.qx,P)};(B(){A j7=S 9G("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\\\?([^#]*))?(#(.*))?$");A j6=S 9G("^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$");z.4r=B(){A n=L;A 1V=P;A 1g=1V[0];R(A i=1;i<1V.G;i++){if(!1V[i]){6c}A 1t=S z.4r(1V[i]+"");A 4u=S z.4r(1g+"");if((1t.28=="")&&(!1t.4t)&&(!1t.3l)&&(!1t.1r)){if(1t.52!=n){4u.52=1t.52}1t=4u}I{if(!1t.4t){1t.4t=4u.4t;if(!1t.3l){1t.3l=4u.3l;if(1t.28.2s(0)!="/"){A j8=4u.28.21(0,4u.28.31("/")+1)+1t.28;A 1X=j8.1A("/");R(A j=0;j<1X.G;j++){if(1X[j]=="."){if(j==1X.G-1){1X[j]=""}I{1X.3S(j,1);j--}}I{if(j>0&&!(j==1&&1X[0]=="")&&1X[j]==".."&&1X[j-1]!=".."){if(j==(1X.G-1)){1X.3S(j,1);1X[j-1]=""}I{1X.3S(j-1,2);j-=2}}}}1t.28=1X.22("/")}}}}1g="";if(1t.4t){1g+=1t.4t+":"}if(1t.3l){1g+="//"+1t.3l}1g+=1t.28;if(1t.1r){1g+="?"+1t.1r}if(1t.52){1g+="#"+1t.52}}D.1g=1g.2i();A r=D.1g.1f(j7);D.4t=r[2]||(r[1]?"":n);D.3l=r[4]||(r[3]?"":n);D.28=r[5];D.1r=r[7]||(r[6]?"":n);D.52=r[9]||(r[8]?"":n);if(D.3l!=n){r=D.3l.1f(j6);D.8X=r[3]||n;D.8W=r[4]||n;D.qw=r[5];D.qv=r[7]||n}};z.4r.1C.2i=B(){C D.1g}})();z.qu=B(j5,2E){A 2B=z.cF(j5).22("/");if(!2B){C L}if(2B.31("/")!=2B.G-1){2B+="/"}A cE=2B.T(":");if(2B.2s(0)!="/"&&(cE==-1||cE>2B.T("/"))){2B=z.51+2B}C S z.4r(2B,2E)};if(V 26!="1k"){z.c8=K;z.j4="qt";(B(){A d=z;if(1q&&1q.4I){A 8j=1q.4I("ak");A j3=/z(\\.qs)?\\.js([\\?\\.]|$)/i;R(A i=0;i<8j.G;i++){A 4X=8j[i].5t("4X");if(!4X){6c}A m=4X.1fLine truncated
|
||||
var decompressedDojo = function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('if(V z=="1k"){(B(){if(V D["1o"]=="1k"){D.1o={}}if((!D["1z"])||(!1z["ca"])){D.1z={}}A cn=["rA","rz","1K","ry","rx","9f","rw","rv","ru","rt","rs","rr","rq","ro","rn","rm"];A i=0,24;1s(24=cn[i++]){if(!1z[24]){1z[24]=B(){}}}if(V D["z"]=="1k"){D.z={}}z.1W=D;A d3={im:U,rl:U,rk:"",rj:"",ri:"",rh:K,rg:U};R(A 8z in d3){if(V 1o[8z]=="1k"){1o[8z]=d3[8z]}}A jK=["rf","rd","rc","rb"];A t;1s(t=jK.3a()){z["is"+t]=U}})();z.8h=1o.8h;z.cY={jJ:0,jI:9,jH:0,jG:"",jF:2V("$ra: r9 $".1f(/[0-9]+/)[0]),2i:B(){4G(z.cY){C jJ+"."+jI+"."+jH+jG+" ("+jF+")"}}};z.d1=B(jE,jD,1V){A 2h=1V||z.1W;R(A i=0,p;2h&&(p=jE[i]);i++){2h=(p in 2h?2h[p]:(jD?2h[p]={}:1k))}C 2h};z.88=B(jC,jA,jB){A d2=jC.1A("."),p=d2.8q(),M=z.d1(d2,K,jB);C(M&&p?(M[p]=jA):1k)};z.6q=B(jz,jy,jx){C z.d1(jz.1A("."),jy,jx)};z.r8=B(jw,M){C!!z.6q(jw,U,M)};z["3u"]=B(d0){C z.1W.3u?z.1W.3u(d0):3u(d0)};z.ia=B(jv,cZ,cX){A 8y="r7: "+jv;if(cZ){8y+=" "+cZ}if(cX){8y+=" -- r6 be r5 in cY: "+cX}1z.1K(8y)};z.r4=B(ju,cW){A cV="r3: "+ju+" -- r2 r1 4F r0 qZ qY.";if(cW){cV+=" "+cW}1z.1K(cV)};(B(){A cR={53:{},6p:0,1h:{},8k:{z:{1p:"z",1Z:"."},cU:{1p:"cU",1Z:"../qX/cU"},cT:{1p:"cT",1Z:"cT"}},cN:B(cS){A mp=D.8k;C jp(mp[cS]&&mp[cS].1Z)},jk:B(8x){A mp=D.8k;if(D.cN(8x)){C mp[8x].1Z}C 8x},8v:[],6t:U,56:[],8t:[],8u:U};R(A cQ in cR){z[cQ]=cR[cQ]}})();z.jg=B(8w,cP,cb){A 1g=(((8w.2s(0)=="/"||8w.1f(/^\\w+:/)))?"":D.51)+8w;if(1o.jt&&z.c8){1g+="?"+67(1o.jt).2f(/\\W+/g,"")}1u{C!cP?D.cO(1g,cb):D.jq(1g,cP,cb)}1y(e){1z.1K(e);C U}};z.cO=B(1g,cb){if(D.8v[1g]){C K}A 6u=D.iR(1g,K);if(!6u){C U}D.8v[1g]=K;D.8v.Y(1g);if(cb){6u="("+6u+")"}A jr=z["3u"](6u+"\\r\\n//@ qW="+1g);if(cb){cb(jr)}C K};z.jq=B(1g,jo,cb){A ok=U;1u{ok=D.cO(1g,cb)}1y(e){1z.1K("qV je ",1g," 4G 9f: ",e)}C jp(ok&&D.53[jo])};z.6m=B(){D.8u=K;D.6t=K;A 57=D.56;D.56=[];R(A x=0;x<57.G;x++){57[x]()}D.8u=U;if(z.6t&&z.6p==0&&D.56.G>0){z.8s()}};z.ck=B(){A 57=D.8t;1s(57.G){(57.8q())()}};z.qU=B(M,jn){A d=z;if(P.G==1){d.56.Y(M)}I{if(P.G>1){d.56.Y(B(){M[jn]()})}}if(d.6t&&d.6p==0&&!d.8u){d.8s()}};z.dW=B(M,jm){A d=z;if(P.G==1){d.8t.Y(M)}I{if(P.G>1){d.8t.Y(B(){M[jm]()})}}};z.iM=B(){if(D.6t){C}if(D.6p>0){1z.1K("qT qS in qR!");C}z.8s()};z.8s=B(){if(V 5c=="8b"||(1o["qQ"]&&z.2M)){5c("z.6m();",0)}I{z.6m()}};z.cF=B(jl){A 4v=jl.1A(".");R(A i=4v.G;i>0;i--){A 8r=4v.2w(0,i).22(".");if((i==1)&&!D.cN(8r)){4v[0]="../"+4v[0]}I{A cM=D.jk(8r);if(cM!=8r){4v.3S(0,i,cM);3f}}}C 4v};z.jj=U;z.8m=B(2T,qP,55){55=D.jj||55;A 54=D.53[2T];if(54){C 54}A cL=2T.1A(".");A 3L=D.cF(2T);A jh=((3L[0].2s(0)!="/")&&!3L[0].1f(/^\\w+:/));A ji=3L[3L.G-1];A 3m;if(ji=="*"){2T=cL.2w(0,-1).22(".");3L.8q();3m=3L.22("/")+"/"+(1o["qO"]||"qN")+".js";if(jh&&3m.2s(0)=="/"){3m=3m.2w(1)}}I{3m=3L.22("/")+".js";2T=cL.22(".")}A jf=(!55)?2T:L;A ok=D.jg(3m,jf);if((!ok)&&(!55)){2m S 1O("qM 3O 4E \'"+2T+"\'; 72 qL \'"+3m+"\'")}if((!55)&&(!D["qK"])){54=D.53[2T];if(!54){2m S 1O("qJ \'"+2T+"\' is 3O qI a8 je \'"+3m+"\'")}}C 54};z.8c=z.8m;z.1Q=B(cK){A cJ=cK+"";A 8p=cJ;A 6s=cK.1A(/\\./);if(6s[6s.G-1]=="*"){6s.8q();8p=6s.22(".")}A 8o=z.6q(8p,K);D.53[cJ]=8o;D.53[8p]=8o;C 8o};z.qH=B(8n){A jd=8n["qG"]||[];A cI=jd.3U(8n[z.j4]||8n["aY"]||[]);R(A x=0;x<cI.G;x++){A 8l=cI[x];if(8l.1P==4e){z.8m.14(z,8l)}I{z.8m(8l)}}};z.jb=B(jc,qF){if(jc===K){A cH=[];R(A i=1;i<P.G;i++){cH.Y(P[i])}z.8c.14(z,cH)}};z.qE=z.jb;z.io=B(cG,ja){D.8k[cG]={1p:cG,1Z:ja}};z.qD=B(qC,qB,qA,qz){z.8c("z.j9");z.j9.qy.14(z.qx,P)};(B(){A j7=S 9G("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\\\?([^#]*))?(#(.*))?$");A j6=S 9G("^((([^:]+:)?([^@]+))@)?([^:]*)(:([0-9]+))?$");z.4r=B(){A n=L;A 1V=P;A 1g=1V[0];R(A i=1;i<1V.G;i++){if(!1V[i]){6c}A 1t=S z.4r(1V[i]+"");A 4u=S z.4r(1g+"");if((1t.28=="")&&(!1t.4t)&&(!1t.3l)&&(!1t.1r)){if(1t.52!=n){4u.52=1t.52}1t=4u}I{if(!1t.4t){1t.4t=4u.4t;if(!1t.3l){1t.3l=4u.3l;if(1t.28.2s(0)!="/"){A j8=4u.28.21(0,4u.28.31("/")+1)+1t.28;A 1X=j8.1A("/");R(A j=0;j<1X.G;j++){if(1X[j]=="."){if(j==1X.G-1){1X[j]=""}I{1X.3S(j,1);j--}}I{if(j>0&&!(j==1&&1X[0]=="")&&1X[j]==".."&&1X[j-1]!=".."){if(j==(1X.G-1)){1X.3S(j,1);1X[j-1]=""}I{1X.3S(j-1,2);j-=2}}}}1t.28=1X.22("/")}}}}1g="";if(1t.4t){1g+=1t.4t+":"}if(1t.3l){1g+="//"+1t.3l}1g+=1t.28;if(1t.1r){1g+="?"+1t.1r}if(1t.52){1g+="#"+1t.52}}D.1g=1g.2i();A r=D.1g.1f(j7);D.4t=r[2]||(r[1]?"":n);D.3l=r[4]||(r[3]?"":n);D.28=r[5];D.1r=r[7]||(r[6]?"":n);D.52=r[9]||(r[8]?"":n);if(D.3l!=n){r=D.3l.1f(j6);D.8X=r[3]||n;D.8W=r[4]||n;D.qw=r[5];D.qv=r[7]||n}};z.4r.1C.2i=B(){C D.1g}})();z.qu=B(j5,2E){A 2B=z.cF(j5).22("/");if(!2B){C L}if(2B.31("/")!=2B.G-1){2B+="/"}A cE=2B.T(":");if(2B.2s(0)!="/"&&(cE==-1||cE>2B.T("/"))){2B=z.51+2B}C S z.4r(2B,2E)};if(V 26!="1k"){z.c8=K;z.j4="qt";(B(){A d=z;if(1q&&1q.4I){A 8j=1q.4I("ak");A j3=/z(\\.qs)?\\.js([\\?\\.]|$)/i;R(A i=0;i<8j.G;i++){A 4X=8j[i].5t("4X");if(!4X){6c}A m=4X.1fLine truncated
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+8
-21
@@ -343,8 +343,7 @@ OriginAttributes::IsFirstPartyEnabled()
|
||||
return sFirstPartyIsolation;
|
||||
}
|
||||
|
||||
BasePrincipal::BasePrincipal(PrincipalKind aKind)
|
||||
: mKind(aKind)
|
||||
BasePrincipal::BasePrincipal()
|
||||
{}
|
||||
|
||||
BasePrincipal::~BasePrincipal()
|
||||
@@ -561,23 +560,6 @@ BasePrincipal::GetCspJSON(nsAString& outCSPinJSON)
|
||||
return mCSP->ToJSON(outCSPinJSON);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) {
|
||||
*aRes = false;
|
||||
nsCOMPtr<nsIURI> prinURI;
|
||||
nsresult rv = GetURI(getter_AddRefs(prinURI));
|
||||
if (NS_FAILED(rv) || !prinURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
if (!ssm) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
;
|
||||
}
|
||||
*aRes = NS_SUCCEEDED(ssm->CheckSameOriginURI(prinURI, aURI, aIsPrivateWin));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetIsNullPrincipal(bool* aResult)
|
||||
{
|
||||
@@ -625,8 +607,13 @@ BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
|
||||
{
|
||||
// TODO: Remove GetAppStatus.
|
||||
*aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
if (AppId() == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
|
||||
NS_WARNING("Asking for app status on a principal with an unknown app id");
|
||||
*aAppStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aAppStatus = nsScriptSecurityManager::AppStatusForPrincipal(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
+9
-20
@@ -251,14 +251,7 @@ public:
|
||||
class BasePrincipal : public nsJSPrincipals
|
||||
{
|
||||
public:
|
||||
enum PrincipalKind {
|
||||
eNullPrincipal,
|
||||
eCodebasePrincipal,
|
||||
eExpandedPrincipal,
|
||||
eSystemPrincipal
|
||||
};
|
||||
|
||||
explicit BasePrincipal(PrincipalKind aKind);
|
||||
BasePrincipal();
|
||||
|
||||
enum DocumentDomainConsideration { DontConsiderDocumentDomain, ConsiderDocumentDomain};
|
||||
bool Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration);
|
||||
@@ -289,7 +282,6 @@ public:
|
||||
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId) final;
|
||||
NS_IMETHOD GetUserContextId(uint32_t* aUserContextId) final;
|
||||
NS_IMETHOD GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId) final;
|
||||
NS_IMETHOD IsSameOrigin(nsIURI* aURI, bool aIsPrivateWin, bool* aRes) override;
|
||||
|
||||
bool EqualsIgnoringAddonId(nsIPrincipal *aOther);
|
||||
|
||||
@@ -308,19 +300,17 @@ public:
|
||||
uint32_t PrivateBrowsingId() const { return mOriginAttributes.mPrivateBrowsingId; }
|
||||
bool IsInIsolatedMozBrowserElement() const { return mOriginAttributes.mInIsolatedMozBrowser; }
|
||||
|
||||
PrincipalKind Kind() const { return mKind; }
|
||||
enum PrincipalKind {
|
||||
eNullPrincipal,
|
||||
eCodebasePrincipal,
|
||||
eExpandedPrincipal,
|
||||
eSystemPrincipal
|
||||
};
|
||||
|
||||
virtual PrincipalKind Kind() = 0;
|
||||
|
||||
already_AddRefed<BasePrincipal> CloneStrippingUserContextIdAndFirstPartyDomain();
|
||||
|
||||
/**
|
||||
* Returns true if this principal's CSP should override a document's CSP for
|
||||
* loads that it triggers. Currently true only for expanded principals which
|
||||
* subsume the document principal.
|
||||
*/
|
||||
bool OverridesCSP(nsIPrincipal* aDocumentPrincipal) {
|
||||
return mKind == eExpandedPrincipal && Subsumes(aDocumentPrincipal, DontConsiderDocumentDomain);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~BasePrincipal();
|
||||
|
||||
@@ -342,7 +332,6 @@ protected:
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
|
||||
PrincipalOriginAttributes mOriginAttributes;
|
||||
PrincipalKind mKind;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -223,12 +223,6 @@ interface nsIPrincipal : nsISerializable
|
||||
*/
|
||||
readonly attribute AUTF8String originSuffix;
|
||||
|
||||
/**
|
||||
* Uses NS_Security Compare to determine if the
|
||||
* other URI is same-origin as the uri of the Principal
|
||||
*/
|
||||
bool IsSameOrigin(in nsIURI otherURI, in bool aIsPrivateWin);
|
||||
|
||||
/**
|
||||
* The base domain of the codebase URI to which this principal pertains
|
||||
* (generally the document URI), handling null principals and
|
||||
@@ -303,6 +297,15 @@ interface nsIPrincipal : nsISerializable
|
||||
*/
|
||||
[infallible] readonly attribute unsigned long privateBrowsingId;
|
||||
|
||||
/**
|
||||
* Returns true iff the principal is inside an isolated mozbrowser element.
|
||||
* <iframe mozbrowser mozapp> and <xul:browser> are not considered to be
|
||||
* mozbrowser elements. <iframe mozbrowser noisolation> does not count as
|
||||
* isolated since isolation is disabled. Isolation can only be disabled if
|
||||
* the containing document is chrome.
|
||||
*/
|
||||
[infallible] readonly attribute boolean isInIsolatedMozBrowserElement;
|
||||
|
||||
/**
|
||||
* Returns true if this principal has an unknown appId. This shouldn't
|
||||
* generally be used. We only expose it due to not providing the correct
|
||||
|
||||
@@ -36,9 +36,7 @@ public:
|
||||
// This should only be used by deserialization, and the factory constructor.
|
||||
// Other consumers should use the Create and CreateWithInheritedAttributes
|
||||
// methods.
|
||||
nsNullPrincipal()
|
||||
: BasePrincipal(eNullPrincipal)
|
||||
{}
|
||||
nsNullPrincipal() {}
|
||||
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
||||
@@ -62,6 +60,8 @@ public:
|
||||
|
||||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||
|
||||
PrincipalKind Kind() override { return eNullPrincipal; }
|
||||
|
||||
protected:
|
||||
virtual ~nsNullPrincipal() {}
|
||||
|
||||
|
||||
+4
-16
@@ -31,6 +31,8 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
#include "nsIAppsService.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
static bool gCodeBasePrincipalSupport = false;
|
||||
@@ -64,11 +66,10 @@ nsPrincipal::InitializeStatics()
|
||||
}
|
||||
|
||||
nsPrincipal::nsPrincipal()
|
||||
: BasePrincipal(eCodebasePrincipal)
|
||||
, mCodebaseImmutable(false)
|
||||
: mCodebaseImmutable(false)
|
||||
, mDomainImmutable(false)
|
||||
, mInitialized(false)
|
||||
{}
|
||||
{ }
|
||||
|
||||
nsPrincipal::~nsPrincipal()
|
||||
{
|
||||
@@ -464,18 +465,6 @@ nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
rv = aStream->WriteStringZ(suffix.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This is an ugly hack to prevent re-entrancy calls into nsPrincipal::Write()
|
||||
// because of repeat CSP processing.
|
||||
// We refcount the context and if found 3+ refcounts on the same, skip writing
|
||||
// the mCSP compound object.
|
||||
// TODO: figure out exactly why this happens and fix the root cause.
|
||||
nsCSPContext* CSPContext = static_cast<nsCSPContext*>(mCSP.get());
|
||||
if(CSPContext) {
|
||||
auto CSPDepth = CSPContext->AddRef();
|
||||
CSPContext->Release();
|
||||
if(CSPDepth > 2) return NS_OK;
|
||||
}
|
||||
|
||||
rv = NS_WriteOptionalCompoundObject(aStream, mCSP,
|
||||
NS_GET_IID(nsIContentSecurityPolicy),
|
||||
true);
|
||||
@@ -527,7 +516,6 @@ struct OriginComparator
|
||||
|
||||
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const PrincipalOriginAttributes& aAttrs)
|
||||
: BasePrincipal(eExpandedPrincipal)
|
||||
{
|
||||
// We force the principals to be sorted by origin so that nsExpandedPrincipal
|
||||
// origins can have a canonical form.
|
||||
|
||||
@@ -46,6 +46,8 @@ public:
|
||||
*/
|
||||
static void InitializeStatics();
|
||||
|
||||
PrincipalKind Kind() override { return eCodebasePrincipal; }
|
||||
|
||||
nsCOMPtr<nsIURI> mDomain;
|
||||
nsCOMPtr<nsIURI> mCodebase;
|
||||
// If mCodebaseImmutable is true, mCodebase is non-null and immutable
|
||||
@@ -80,6 +82,8 @@ public:
|
||||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
PrincipalKind Kind() override { return eExpandedPrincipal; }
|
||||
|
||||
protected:
|
||||
virtual ~nsExpandedPrincipal();
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "xpcpublic.h"
|
||||
#include "XPCWrapper.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIInputStreamChannel.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@@ -54,6 +55,7 @@
|
||||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "mozIApplication.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
@@ -74,7 +76,6 @@ nsIIOService *nsScriptSecurityManager::sIOService = nullptr;
|
||||
nsIStringBundle *nsScriptSecurityManager::sStrBundle = nullptr;
|
||||
JSContext *nsScriptSecurityManager::sContext = nullptr;
|
||||
bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
|
||||
bool nsScriptSecurityManager::sSameOriginPolicy = true;
|
||||
|
||||
///////////////////////////
|
||||
// Convenience Functions //
|
||||
@@ -238,6 +239,68 @@ nsScriptSecurityManager::SecurityHashURI(nsIURI* aURI)
|
||||
return NS_SecurityHashURI(aURI);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
nsScriptSecurityManager::AppStatusForPrincipal(nsIPrincipal *aPrin)
|
||||
{
|
||||
uint32_t appId = aPrin->GetAppId();
|
||||
|
||||
// After bug 1238160, the principal no longer knows how to answer "is this a
|
||||
// browser element", which is really what this code path wants. Currently,
|
||||
// desktop is the only platform where we intend to disable isolation on a
|
||||
// browser frame, so non-desktop should be able to assume that
|
||||
// inIsolatedMozBrowser is true for all mozbrowser frames. Additionally,
|
||||
// apps are no longer used on desktop, so appId is always NO_APP_ID. We use
|
||||
// a release assertion in nsFrameLoader::OwnerIsIsolatedMozBrowserFrame so
|
||||
// that platforms with apps can assume inIsolatedMozBrowser is true for all
|
||||
// mozbrowser frames.
|
||||
bool inIsolatedMozBrowser = aPrin->GetIsInIsolatedMozBrowserElement();
|
||||
|
||||
NS_WARNING_ASSERTION(
|
||||
appId != nsIScriptSecurityManager::UNKNOWN_APP_ID,
|
||||
"Asking for app status on a principal with an unknown app id");
|
||||
|
||||
// Installed apps have a valid app id (not NO_APP_ID or UNKNOWN_APP_ID)
|
||||
// and they are not inside a mozbrowser.
|
||||
if (appId == nsIScriptSecurityManager::NO_APP_ID ||
|
||||
appId == nsIScriptSecurityManager::UNKNOWN_APP_ID ||
|
||||
inIsolatedMozBrowser)
|
||||
{
|
||||
return nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(appsService, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
nsCOMPtr<mozIApplication> app;
|
||||
appsService->GetAppByLocalId(appId, getter_AddRefs(app));
|
||||
NS_ENSURE_TRUE(app, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
uint16_t status = nsIPrincipal::APP_STATUS_INSTALLED;
|
||||
NS_ENSURE_SUCCESS(app->GetAppStatus(&status),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
nsString appOrigin;
|
||||
NS_ENSURE_SUCCESS(app->GetOrigin(appOrigin),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
nsCOMPtr<nsIURI> appURI;
|
||||
NS_ENSURE_SUCCESS(NS_NewURI(getter_AddRefs(appURI), appOrigin),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
|
||||
// The app could contain a cross-origin iframe - make sure that the content
|
||||
// is actually same-origin with the app.
|
||||
MOZ_ASSERT(inIsolatedMozBrowser == false, "Checked this above");
|
||||
nsAutoCString suffix;
|
||||
PrincipalOriginAttributes attrs;
|
||||
NS_ENSURE_TRUE(attrs.PopulateFromOrigin(NS_ConvertUTF16toUTF8(appOrigin), suffix),
|
||||
nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
attrs.mAppId = appId;
|
||||
attrs.mInIsolatedMozBrowser = false;
|
||||
nsCOMPtr<nsIPrincipal> appPrin = BasePrincipal::CreateCodebasePrincipal(appURI, attrs);
|
||||
NS_ENSURE_TRUE(appPrin, nsIPrincipal::APP_STATUS_NOT_INSTALLED);
|
||||
return aPrin->Equals(appPrin) ? status
|
||||
: nsIPrincipal::APP_STATUS_NOT_INSTALLED;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetChannelResultPrincipal will return the principal that the resource
|
||||
* returned by this channel will use. For example, if the resource is in
|
||||
@@ -472,8 +535,7 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager,
|
||||
///////////////// Security Checks /////////////////
|
||||
|
||||
bool
|
||||
nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx,
|
||||
JS::HandleValue aValue)
|
||||
nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
|
||||
@@ -496,23 +558,12 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx,
|
||||
}
|
||||
|
||||
if (reportViolation) {
|
||||
JS::Rooted<JSString*> jsString(cx, JS::ToString(cx, aValue));
|
||||
if (NS_WARN_IF(!jsString)) {
|
||||
JS_ClearPendingException(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoJSString scriptSample;
|
||||
if (NS_WARN_IF(!scriptSample.init(cx, jsString))) {
|
||||
JS_ClearPendingException(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::AutoFilename scriptFilename;
|
||||
nsAutoString fileName;
|
||||
unsigned lineNum = 0;
|
||||
unsigned columnNum = 0;
|
||||
if (JS::DescribeScriptedCaller(cx, &scriptFilename, &lineNum, &columnNum)) {
|
||||
NS_NAMED_LITERAL_STRING(scriptSample, "call to eval() or related function blocked by CSP");
|
||||
|
||||
JS::AutoFilename scriptFilename;
|
||||
if (JS::DescribeScriptedCaller(cx, &scriptFilename, &lineNum)) {
|
||||
if (const char *file = scriptFilename.get()) {
|
||||
CopyUTF8toUTF16(nsDependentCString(file), fileName);
|
||||
}
|
||||
@@ -523,7 +574,6 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx,
|
||||
fileName,
|
||||
scriptSample,
|
||||
lineNum,
|
||||
columnNum,
|
||||
EmptyString(),
|
||||
EmptyString());
|
||||
}
|
||||
@@ -544,7 +594,7 @@ nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
|
||||
nsIURI* aTargetURI,
|
||||
bool reportError)
|
||||
{
|
||||
if (sSameOriginPolicy && !SecurityCompareURIs(aSourceURI, aTargetURI))
|
||||
if (!SecurityCompareURIs(aSourceURI, aTargetURI))
|
||||
{
|
||||
if (reportError) {
|
||||
ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"),
|
||||
@@ -1371,13 +1421,10 @@ nsScriptSecurityManager::CanGetService(JSContext *cx,
|
||||
const char sJSEnabledPrefName[] = "javascript.enabled";
|
||||
const char sFileOriginPolicyPrefName[] =
|
||||
"security.fileuri.strict_origin_policy";
|
||||
const char sSameOriginPolicyPrefName[] =
|
||||
"security.same_origin_policy.enabled";
|
||||
|
||||
static const char* kObservedPrefs[] = {
|
||||
sJSEnabledPrefName,
|
||||
sFileOriginPolicyPrefName,
|
||||
sSameOriginPolicyPrefName,
|
||||
"capability.policy.",
|
||||
nullptr
|
||||
};
|
||||
@@ -1533,8 +1580,6 @@ nsScriptSecurityManager::ScriptSecurityPrefChanged()
|
||||
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
|
||||
sStrictFileOriginPolicy =
|
||||
Preferences::GetBool(sFileOriginPolicyPrefName, false);
|
||||
sSameOriginPolicy =
|
||||
Preferences::GetBool(sSameOriginPolicyPrefName, true);
|
||||
mFileURIWhitelist.reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ private:
|
||||
|
||||
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
||||
static bool
|
||||
ContentSecurityPolicyPermitsJSAction(JSContext *cx, JS::HandleValue aValue);
|
||||
ContentSecurityPolicyPermitsJSAction(JSContext *cx);
|
||||
|
||||
static bool
|
||||
JSPrincipalsSubsume(JSPrincipals *first, JSPrincipals *second);
|
||||
@@ -152,7 +152,6 @@ private:
|
||||
}
|
||||
|
||||
static bool sStrictFileOriginPolicy;
|
||||
static bool sSameOriginPolicy;
|
||||
|
||||
static nsIIOService *sIOService;
|
||||
static nsIStringBundle *sStrBundle;
|
||||
|
||||
@@ -36,9 +36,7 @@ public:
|
||||
NS_IMETHOD GetBaseDomain(nsACString& aBaseDomain) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
nsSystemPrincipal()
|
||||
: BasePrincipal(eSystemPrincipal)
|
||||
{}
|
||||
nsSystemPrincipal() {}
|
||||
|
||||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||
|
||||
@@ -54,6 +52,8 @@ protected:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PrincipalKind Kind() override { return eSystemPrincipal; }
|
||||
};
|
||||
|
||||
#endif // nsSystemPrincipal_h__
|
||||
@@ -4,6 +4,7 @@ support-files =
|
||||
file_disableScript.html
|
||||
!/js/xpconnect/tests/mochitest/file_empty.html
|
||||
|
||||
[test_app_principal_equality.html]
|
||||
[test_bug246699.html]
|
||||
[test_bug292789.html]
|
||||
[test_bug423375.html]
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=777467
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test app principal's equality</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=777467">Mozilla Bug 777467</a>
|
||||
<p id="display"></p>
|
||||
<script>
|
||||
|
||||
/** Test for app principal's equality **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var permissions = new Promise(resolve => {
|
||||
SpecialPowers.pushPermissions(
|
||||
[{ type: "browser", allow: true, context: document },
|
||||
{ type: "embed-apps", allow: true, context: document }],
|
||||
resolve);
|
||||
});
|
||||
|
||||
permissions.then(() => {
|
||||
$('content').innerHTML =
|
||||
'<iframe src="error404"></iframe>\n' +
|
||||
'<iframe mozbrowser src="error404"></iframe>\n' +
|
||||
'<iframe mozapp="http://example.org/manifest.webapp" mozbrowser src="error404"></iframe>';
|
||||
|
||||
var iframes = document.getElementsByTagName("iframe");
|
||||
var promises = []
|
||||
for (var i = 0; i < promises.length; ++i) {
|
||||
promises.push(new Promise(resolve => {
|
||||
iframes[i].addEventListener("load", resolve);
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
});
|
||||
|
||||
var prefs = new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ set: [[ "dom.mozBrowserFramesEnabled", true ],
|
||||
[ "dom.ipc.browser_frames.oop_by_default", false ]] },
|
||||
resolve);
|
||||
});
|
||||
</script>
|
||||
<div id="content" style="display: none;">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
function canAccessDocument(win) {
|
||||
var result = true;
|
||||
try {
|
||||
win.document;
|
||||
} catch(e) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var loaded = new Promise(resolve => addLoadEvent(resolve));
|
||||
|
||||
Promise.all([ permissions, prefs, loaded ]).then(runTest);
|
||||
|
||||
function runTest() {
|
||||
// Test the witness frame (we can access same-origin frame).
|
||||
is(canAccessDocument(frames[0]), true,
|
||||
"should be able to access the first frame");
|
||||
|
||||
// Test different app/browserElement frames.
|
||||
for (var i=1; i<frames.length; ++i) {
|
||||
is(canAccessDocument(frames[i]), false,
|
||||
"should not be able to access the other frames");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
+1
-20
@@ -18,30 +18,20 @@ sources = [
|
||||
'/intl/icu/source/common/dictionarydata.cpp',
|
||||
'/intl/icu/source/common/dtintrv.cpp',
|
||||
'/intl/icu/source/common/edits.cpp',
|
||||
'/intl/icu/source/common/emojiprops.cpp',
|
||||
'/intl/icu/source/common/errorcode.cpp',
|
||||
'/intl/icu/source/common/filteredbrk.cpp',
|
||||
'/intl/icu/source/common/filterednormalizer2.cpp',
|
||||
'/intl/icu/source/common/fixedstring.cpp',
|
||||
'/intl/icu/source/common/loadednormalizer2impl.cpp',
|
||||
'/intl/icu/source/common/localebuilder.cpp',
|
||||
'/intl/icu/source/common/localematcher.cpp',
|
||||
'/intl/icu/source/common/localeprioritylist.cpp',
|
||||
'/intl/icu/source/common/locavailable.cpp',
|
||||
'/intl/icu/source/common/locbased.cpp',
|
||||
'/intl/icu/source/common/locdispnames.cpp',
|
||||
'/intl/icu/source/common/locdistance.cpp',
|
||||
'/intl/icu/source/common/locdspnm.cpp',
|
||||
'/intl/icu/source/common/locid.cpp',
|
||||
'/intl/icu/source/common/loclikely.cpp',
|
||||
'/intl/icu/source/common/loclikelysubtags.cpp',
|
||||
'/intl/icu/source/common/locmap.cpp',
|
||||
'/intl/icu/source/common/locresdata.cpp',
|
||||
'/intl/icu/source/common/locutil.cpp',
|
||||
'/intl/icu/source/common/lsr.cpp',
|
||||
'/intl/icu/source/common/lstmbe.cpp',
|
||||
'/intl/icu/source/common/messagepattern.cpp',
|
||||
'/intl/icu/source/common/mlbe.cpp',
|
||||
'/intl/icu/source/common/normalizer2.cpp',
|
||||
'/intl/icu/source/common/normalizer2impl.cpp',
|
||||
'/intl/icu/source/common/normlzr.cpp',
|
||||
@@ -61,7 +51,6 @@ sources = [
|
||||
'/intl/icu/source/common/rbbitblb.cpp',
|
||||
'/intl/icu/source/common/resbund.cpp',
|
||||
'/intl/icu/source/common/resource.cpp',
|
||||
'/intl/icu/source/common/restrace.cpp',
|
||||
'/intl/icu/source/common/ruleiter.cpp',
|
||||
'/intl/icu/source/common/schriter.cpp',
|
||||
'/intl/icu/source/common/serv.cpp',
|
||||
@@ -121,8 +110,6 @@ sources = [
|
||||
'/intl/icu/source/common/uloc.cpp',
|
||||
'/intl/icu/source/common/uloc_keytype.cpp',
|
||||
'/intl/icu/source/common/uloc_tag.cpp',
|
||||
'/intl/icu/source/common/ulocale.cpp',
|
||||
'/intl/icu/source/common/ulocbuilder.cpp',
|
||||
'/intl/icu/source/common/umapfile.cpp',
|
||||
'/intl/icu/source/common/umath.cpp',
|
||||
'/intl/icu/source/common/umutablecptrie.cpp',
|
||||
@@ -164,7 +151,6 @@ sources = [
|
||||
'/intl/icu/source/common/utext.cpp',
|
||||
'/intl/icu/source/common/utf_impl.cpp',
|
||||
'/intl/icu/source/common/util.cpp',
|
||||
'/intl/icu/source/common/util_props.cpp',
|
||||
'/intl/icu/source/common/utrace.cpp',
|
||||
'/intl/icu/source/common/utrie.cpp',
|
||||
'/intl/icu/source/common/utrie2.cpp',
|
||||
@@ -204,6 +190,7 @@ other_sources = [
|
||||
'/intl/icu/source/common/usc_impl.cpp',
|
||||
'/intl/icu/source/common/ushape.cpp',
|
||||
'/intl/icu/source/common/ustr_wcs.cpp',
|
||||
'/intl/icu/source/common/util_props.cpp',
|
||||
]
|
||||
EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/appendable.h',
|
||||
@@ -225,8 +212,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/icudataver.h',
|
||||
'/intl/icu/source/common/unicode/icuplug.h',
|
||||
'/intl/icu/source/common/unicode/idna.h',
|
||||
'/intl/icu/source/common/unicode/localebuilder.h',
|
||||
'/intl/icu/source/common/unicode/localematcher.h',
|
||||
'/intl/icu/source/common/unicode/localpointer.h',
|
||||
'/intl/icu/source/common/unicode/locdspnm.h',
|
||||
'/intl/icu/source/common/unicode/locid.h',
|
||||
@@ -274,8 +259,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/uiter.h',
|
||||
'/intl/icu/source/common/unicode/uldnames.h',
|
||||
'/intl/icu/source/common/unicode/uloc.h',
|
||||
'/intl/icu/source/common/unicode/ulocale.h',
|
||||
'/intl/icu/source/common/unicode/ulocbuilder.h',
|
||||
'/intl/icu/source/common/unicode/umachine.h',
|
||||
'/intl/icu/source/common/unicode/umisc.h',
|
||||
'/intl/icu/source/common/unicode/umutablecptrie.h',
|
||||
@@ -303,8 +286,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/common/unicode/utf32.h',
|
||||
'/intl/icu/source/common/unicode/utf8.h',
|
||||
'/intl/icu/source/common/unicode/utf_old.h',
|
||||
'/intl/icu/source/common/unicode/utfiterator.h',
|
||||
'/intl/icu/source/common/unicode/utfstring.h',
|
||||
'/intl/icu/source/common/unicode/utrace.h',
|
||||
'/intl/icu/source/common/unicode/utypes.h',
|
||||
'/intl/icu/source/common/unicode/uvernum.h',
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
-22
@@ -3,15 +3,12 @@
|
||||
# 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/.
|
||||
|
||||
# Also see <http://www.icu-project.org/repos/icu/tags/latest/icu4c/readme.html#RecBuild> for the
|
||||
# recommended build options when compiling ICU.
|
||||
DEFINES.update(
|
||||
# Don't use icu namespace automatically in client code.
|
||||
U_USING_ICU_NAMESPACE = 0,
|
||||
|
||||
# Don't include obsolete header files.
|
||||
U_NO_DEFAULT_INCLUDE_UTF_HEADERS = 1,
|
||||
U_HIDE_OBSOLETE_UTF_OLD_H = 1,
|
||||
|
||||
# Remove chunks of the library that we don't need (yet).
|
||||
UCONFIG_NO_LEGACY_CONVERSION = True,
|
||||
@@ -20,13 +17,6 @@ DEFINES.update(
|
||||
|
||||
# We don't need to pass data to and from legacy char* APIs.
|
||||
U_CHARSET_IS_UTF8 = True,
|
||||
|
||||
# Add 'explicit' keyword to UnicodeString constructors.
|
||||
UNISTR_FROM_CHAR_EXPLICIT = 'explicit',
|
||||
UNISTR_FROM_STRING_EXPLICIT = 'explicit',
|
||||
|
||||
# Disable dynamic loading of ICU data as a loadable library.
|
||||
U_ENABLE_DYLOAD = 0,
|
||||
)
|
||||
|
||||
if not CONFIG['HAVE_LANGINFO_CODESET']:
|
||||
@@ -48,24 +38,12 @@ ALLOW_COMPILER_WARNINGS = True
|
||||
# warnings that get triggered for every file.
|
||||
if CONFIG['CLANG_CL']:
|
||||
CFLAGS += [
|
||||
'-Wno-c++20-compat',
|
||||
'-Wno-comma',
|
||||
'-Wno-implicit-const-int-float-conversion',
|
||||
'-Wno-macro-redefined',
|
||||
'-Wno-microsoft-include',
|
||||
'-Wno-tautological-unsigned-enum-zero-compare',
|
||||
'-Wno-unreachable-code-loop-increment',
|
||||
'-Wno-unreachable-code-return',
|
||||
]
|
||||
CXXFLAGS += [
|
||||
'-Wno-c++20-compat',
|
||||
'-Wno-comma',
|
||||
'-Wno-implicit-const-int-float-conversion',
|
||||
'-Wno-macro-redefined',
|
||||
'-Wno-microsoft-include',
|
||||
'-Wno-tautological-unsigned-enum-zero-compare',
|
||||
'-Wno-unreachable-code-loop-increment',
|
||||
'-Wno-unreachable-code-return',
|
||||
]
|
||||
|
||||
if CONFIG['_MSC_VER'] and not CONFIG['CLANG_CL']:
|
||||
|
||||
+5
-47
@@ -42,14 +42,13 @@ sources = [
|
||||
'/intl/icu/source/i18n/decContext.cpp',
|
||||
'/intl/icu/source/i18n/decimfmt.cpp',
|
||||
'/intl/icu/source/i18n/decNumber.cpp',
|
||||
'/intl/icu/source/i18n/displayoptions.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-bignum-dtoa.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-bignum.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-cached-powers.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-double-to-string.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-diy-fp.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-fast-dtoa.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-string-to-double.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion-strtod.cpp',
|
||||
'/intl/icu/source/i18n/double-conversion.cpp',
|
||||
'/intl/icu/source/i18n/dtfmtsym.cpp',
|
||||
'/intl/icu/source/i18n/dtitvfmt.cpp',
|
||||
'/intl/icu/source/i18n/dtitvinf.cpp',
|
||||
@@ -59,10 +58,6 @@ sources = [
|
||||
'/intl/icu/source/i18n/ethpccal.cpp',
|
||||
'/intl/icu/source/i18n/fmtable.cpp',
|
||||
'/intl/icu/source/i18n/format.cpp',
|
||||
'/intl/icu/source/i18n/formatted_string_builder.cpp',
|
||||
'/intl/icu/source/i18n/formattedval_iterimpl.cpp',
|
||||
'/intl/icu/source/i18n/formattedval_sbimpl.cpp',
|
||||
'/intl/icu/source/i18n/formattedvalue.cpp',
|
||||
'/intl/icu/source/i18n/fphdlimp.cpp',
|
||||
'/intl/icu/source/i18n/fpositer.cpp',
|
||||
'/intl/icu/source/i18n/gregocal.cpp',
|
||||
@@ -70,28 +65,16 @@ sources = [
|
||||
'/intl/icu/source/i18n/hebrwcal.cpp',
|
||||
'/intl/icu/source/i18n/indiancal.cpp',
|
||||
'/intl/icu/source/i18n/islamcal.cpp',
|
||||
'/intl/icu/source/i18n/iso8601cal.cpp',
|
||||
'/intl/icu/source/i18n/japancal.cpp',
|
||||
'/intl/icu/source/i18n/listformatter.cpp',
|
||||
'/intl/icu/source/i18n/measfmt.cpp',
|
||||
'/intl/icu/source/i18n/measunit.cpp',
|
||||
'/intl/icu/source/i18n/measunit_extra.cpp',
|
||||
'/intl/icu/source/i18n/measure.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_arguments.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_checker.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_data_model.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_errors.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_evaluation.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_formattable.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_formatter.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_function_registry.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_parser.cpp',
|
||||
'/intl/icu/source/i18n/messageformat2_serializer.cpp',
|
||||
'/intl/icu/source/i18n/msgfmt.cpp',
|
||||
'/intl/icu/source/i18n/nfrs.cpp',
|
||||
'/intl/icu/source/i18n/nfrule.cpp',
|
||||
'/intl/icu/source/i18n/nfsubs.cpp',
|
||||
'/intl/icu/source/i18n/nounit.cpp',
|
||||
'/intl/icu/source/i18n/number_affixutils.cpp',
|
||||
'/intl/icu/source/i18n/number_asformat.cpp',
|
||||
'/intl/icu/source/i18n/number_capi.cpp',
|
||||
@@ -108,16 +91,13 @@ sources = [
|
||||
'/intl/icu/source/i18n/number_modifiers.cpp',
|
||||
'/intl/icu/source/i18n/number_multiplier.cpp',
|
||||
'/intl/icu/source/i18n/number_notation.cpp',
|
||||
'/intl/icu/source/i18n/number_output.cpp',
|
||||
'/intl/icu/source/i18n/number_padding.cpp',
|
||||
'/intl/icu/source/i18n/number_patternmodifier.cpp',
|
||||
'/intl/icu/source/i18n/number_patternstring.cpp',
|
||||
'/intl/icu/source/i18n/number_rounding.cpp',
|
||||
'/intl/icu/source/i18n/number_scientific.cpp',
|
||||
'/intl/icu/source/i18n/number_simple.cpp',
|
||||
'/intl/icu/source/i18n/number_skeletons.cpp',
|
||||
'/intl/icu/source/i18n/number_symbolswrapper.cpp',
|
||||
'/intl/icu/source/i18n/number_usageprefs.cpp',
|
||||
'/intl/icu/source/i18n/number_stringbuilder.cpp',
|
||||
'/intl/icu/source/i18n/number_utils.cpp',
|
||||
'/intl/icu/source/i18n/numfmt.cpp',
|
||||
'/intl/icu/source/i18n/numparse_affixes.cpp',
|
||||
@@ -127,15 +107,14 @@ sources = [
|
||||
'/intl/icu/source/i18n/numparse_impl.cpp',
|
||||
'/intl/icu/source/i18n/numparse_parsednumber.cpp',
|
||||
'/intl/icu/source/i18n/numparse_scientific.cpp',
|
||||
'/intl/icu/source/i18n/numparse_stringsegment.cpp',
|
||||
'/intl/icu/source/i18n/numparse_symbols.cpp',
|
||||
'/intl/icu/source/i18n/numparse_validators.cpp',
|
||||
'/intl/icu/source/i18n/numrange_capi.cpp',
|
||||
'/intl/icu/source/i18n/numrange_fluent.cpp',
|
||||
'/intl/icu/source/i18n/numrange_impl.cpp',
|
||||
'/intl/icu/source/i18n/numsys.cpp',
|
||||
'/intl/icu/source/i18n/olsontz.cpp',
|
||||
'/intl/icu/source/i18n/persncal.cpp',
|
||||
'/intl/icu/source/i18n/pluralranges.cpp',
|
||||
'/intl/icu/source/i18n/plurfmt.cpp',
|
||||
'/intl/icu/source/i18n/plurrule.cpp',
|
||||
'/intl/icu/source/i18n/quantityformatter.cpp',
|
||||
@@ -154,7 +133,6 @@ sources = [
|
||||
'/intl/icu/source/i18n/smpdtfst.cpp',
|
||||
'/intl/icu/source/i18n/sortkey.cpp',
|
||||
'/intl/icu/source/i18n/standardplural.cpp',
|
||||
'/intl/icu/source/i18n/string_segment.cpp',
|
||||
'/intl/icu/source/i18n/stsearch.cpp',
|
||||
'/intl/icu/source/i18n/taiwncal.cpp',
|
||||
'/intl/icu/source/i18n/timezone.cpp',
|
||||
@@ -179,10 +157,6 @@ sources = [
|
||||
'/intl/icu/source/i18n/uitercollationiterator.cpp',
|
||||
'/intl/icu/source/i18n/ulistformatter.cpp',
|
||||
'/intl/icu/source/i18n/umsg.cpp',
|
||||
'/intl/icu/source/i18n/units_complexconverter.cpp',
|
||||
'/intl/icu/source/i18n/units_converter.cpp',
|
||||
'/intl/icu/source/i18n/units_data.cpp',
|
||||
'/intl/icu/source/i18n/units_router.cpp',
|
||||
'/intl/icu/source/i18n/unum.cpp',
|
||||
'/intl/icu/source/i18n/unumsys.cpp',
|
||||
'/intl/icu/source/i18n/upluralrules.cpp',
|
||||
@@ -271,7 +245,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/datefmt.h',
|
||||
'/intl/icu/source/i18n/unicode/dcfmtsym.h',
|
||||
'/intl/icu/source/i18n/unicode/decimfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/displayoptions.h',
|
||||
'/intl/icu/source/i18n/unicode/dtfmtsym.h',
|
||||
'/intl/icu/source/i18n/unicode/dtitvfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/dtitvinf.h',
|
||||
@@ -280,8 +253,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/fieldpos.h',
|
||||
'/intl/icu/source/i18n/unicode/fmtable.h',
|
||||
'/intl/icu/source/i18n/unicode/format.h',
|
||||
'/intl/icu/source/i18n/unicode/formattednumber.h',
|
||||
'/intl/icu/source/i18n/unicode/formattedvalue.h',
|
||||
'/intl/icu/source/i18n/unicode/fpositer.h',
|
||||
'/intl/icu/source/i18n/unicode/gender.h',
|
||||
'/intl/icu/source/i18n/unicode/gregocal.h',
|
||||
@@ -289,12 +260,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/measfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/measunit.h',
|
||||
'/intl/icu/source/i18n/unicode/measure.h',
|
||||
'/intl/icu/source/i18n/unicode/messageformat2.h',
|
||||
'/intl/icu/source/i18n/unicode/messageformat2_arguments.h',
|
||||
'/intl/icu/source/i18n/unicode/messageformat2_data_model.h',
|
||||
'/intl/icu/source/i18n/unicode/messageformat2_data_model_names.h',
|
||||
'/intl/icu/source/i18n/unicode/messageformat2_formattable.h',
|
||||
'/intl/icu/source/i18n/unicode/messageformat2_function_registry.h',
|
||||
'/intl/icu/source/i18n/unicode/msgfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/nounit.h',
|
||||
'/intl/icu/source/i18n/unicode/numberformatter.h',
|
||||
@@ -311,7 +276,6 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/scientificnumberformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/search.h',
|
||||
'/intl/icu/source/i18n/unicode/selfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/simplenumberformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/simpletz.h',
|
||||
'/intl/icu/source/i18n/unicode/smpdtfmt.h',
|
||||
'/intl/icu/source/i18n/unicode/sortkey.h',
|
||||
@@ -333,11 +297,8 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/udat.h',
|
||||
'/intl/icu/source/i18n/unicode/udateintervalformat.h',
|
||||
'/intl/icu/source/i18n/unicode/udatpg.h',
|
||||
'/intl/icu/source/i18n/unicode/udisplayoptions.h',
|
||||
'/intl/icu/source/i18n/unicode/ufieldpositer.h',
|
||||
'/intl/icu/source/i18n/unicode/uformattable.h',
|
||||
'/intl/icu/source/i18n/unicode/uformattednumber.h',
|
||||
'/intl/icu/source/i18n/unicode/uformattedvalue.h',
|
||||
'/intl/icu/source/i18n/unicode/ugender.h',
|
||||
'/intl/icu/source/i18n/unicode/ulistformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/ulocdata.h',
|
||||
@@ -345,15 +306,12 @@ EXPORTS.unicode += [
|
||||
'/intl/icu/source/i18n/unicode/unirepl.h',
|
||||
'/intl/icu/source/i18n/unicode/unum.h',
|
||||
'/intl/icu/source/i18n/unicode/unumberformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/unumberoptions.h',
|
||||
'/intl/icu/source/i18n/unicode/unumberrangeformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/unumsys.h',
|
||||
'/intl/icu/source/i18n/unicode/upluralrules.h',
|
||||
'/intl/icu/source/i18n/unicode/uregex.h',
|
||||
'/intl/icu/source/i18n/unicode/uregion.h',
|
||||
'/intl/icu/source/i18n/unicode/ureldatefmt.h',
|
||||
'/intl/icu/source/i18n/unicode/usearch.h',
|
||||
'/intl/icu/source/i18n/unicode/usimplenumberformatter.h',
|
||||
'/intl/icu/source/i18n/unicode/uspoof.h',
|
||||
'/intl/icu/source/i18n/unicode/utmscale.h',
|
||||
'/intl/icu/source/i18n/unicode/utrans.h',
|
||||
|
||||
Vendored
+3
-2
@@ -41,11 +41,12 @@ if CONFIG['CPU_ARCH'] == 'arm':
|
||||
if CONFIG['MOZ_FFVPX']:
|
||||
external_dirs += ['media/ffvpx']
|
||||
|
||||
if CONFIG["MOZ_JXL"]:
|
||||
external_dirs += ["media/libjxl", "media/highway"]
|
||||
|
||||
external_dirs += [
|
||||
'media/highway',
|
||||
'media/kiss_fft',
|
||||
'media/libcubeb',
|
||||
'media/libjxl',
|
||||
'media/libnestegg',
|
||||
'media/libogg',
|
||||
'media/libopus',
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
# Referenced by milestone.py.
|
||||
#--------------------------------------------------------
|
||||
|
||||
6.8.1
|
||||
6.5.0
|
||||
@@ -155,10 +155,8 @@ endif
|
||||
# Interdependencies that moz.build world don't know about yet for compilation.
|
||||
# Note some others are hardcoded or "guessed" in recursivemake.py and emitter.py
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk3)
|
||||
ifdef MOZ_ENABLE_NPAPI
|
||||
toolkit/library/target: widget/gtk/mozgtk/gtk3/target
|
||||
endif
|
||||
endif
|
||||
ifdef MOZ_LDAP_XPCOM
|
||||
ldap/target: security/target mozglue/build/target
|
||||
toolkit/library/target: ldap/target
|
||||
|
||||
@@ -348,7 +348,11 @@ ifdef SHARED_LIBRARY
|
||||
ifdef IS_COMPONENT
|
||||
EXTRA_DSO_LDOPTS += -bundle
|
||||
else
|
||||
ifdef MOZ_IOS
|
||||
_LOADER_PATH := @rpath
|
||||
else
|
||||
_LOADER_PATH := @executable_path
|
||||
endif
|
||||
EXTRA_DSO_LDOPTS += -dynamiclib -install_name $(_LOADER_PATH)/$(SHARED_LIBRARY) -compatibility_version 1 -current_version 1 -single_module
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -424,6 +424,7 @@ fstream
|
||||
fstream.h
|
||||
ft2build.h
|
||||
fts.h
|
||||
gconf/gconf-client.h
|
||||
Gdiplus.h
|
||||
gdk/gdk.h
|
||||
gdk/gdkkeysyms.h
|
||||
@@ -1032,6 +1033,9 @@ X11/Xutil.h
|
||||
zmouse.h
|
||||
soundtouch/SoundTouch.h
|
||||
soundtouch/SoundTouchFactory.h
|
||||
#if MOZ_LIBAV_FFT==1
|
||||
libavcodec/avfft.h
|
||||
#endif
|
||||
#if MOZ_SYSTEM_ZLIB==1
|
||||
zlib.h
|
||||
#endif
|
||||
@@ -1049,7 +1053,9 @@ hunspell.hxx
|
||||
#if MOZ_SYSTEM_BZ2==1
|
||||
bzlib.h
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_GIO
|
||||
gio/gio.h
|
||||
#endif
|
||||
sys/event.h
|
||||
#ifdef MOZ_ENABLE_LIBPROXY
|
||||
proxy.h
|
||||
|
||||
+34
-9
@@ -1,14 +1,39 @@
|
||||
This is the SQLite amalgamation.
|
||||
Check sqlite3.h for the version number and source id.
|
||||
This directory contains source code to
|
||||
|
||||
See http://www.sqlite.org/ for more info.
|
||||
SQLite: An Embeddable SQL Database Engine
|
||||
|
||||
We have a UXP-specific moz.build in src/ (normally not there) that we
|
||||
use to build. Additionally, src/ contains sqlite.symbols which lists
|
||||
all explicitly exported symbols from the library to expose.
|
||||
To compile the project, first create a directory in which to place
|
||||
the build products. It is recommended, but not required, that the
|
||||
build directory be separate from the source directory. Cd into the
|
||||
build directory and then from the build directory run the configure
|
||||
script found at the root of the source tree. Then run "make".
|
||||
|
||||
To move to a new version:
|
||||
For example:
|
||||
|
||||
Copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite.
|
||||
tar xzf sqlite.tar.gz ;# Unpack the source tree into "sqlite"
|
||||
mkdir bld ;# Build will occur in a sibling directory
|
||||
cd bld ;# Change to the build directory
|
||||
../sqlite/configure ;# Run the configure script
|
||||
make ;# Run the makefile.
|
||||
make install ;# (Optional) Install the build products
|
||||
|
||||
Be sure to update SQLITE_VERSION accordingly in $(topsrcdir)/old-configure.in.
|
||||
The configure script uses autoconf 2.61 and libtool. If the configure
|
||||
script does not work out for you, there is a generic makefile named
|
||||
"Makefile.linux-gcc" in the top directory of the source tree that you
|
||||
can copy and edit to suit your needs. Comments on the generic makefile
|
||||
show what changes are needed.
|
||||
|
||||
The linux binaries on the website are created using the generic makefile,
|
||||
not the configure script. The windows binaries on the website are created
|
||||
using MinGW32 configured as a cross-compiler running under Linux. For
|
||||
details, see the ./publish.sh script at the top-level of the source tree.
|
||||
The developers do not use teh configure script.
|
||||
|
||||
SQLite does not require TCL to run, but a TCL installation is required
|
||||
by the makefiles. SQLite contains a lot of generated code and TCL is
|
||||
used to do much of that code generation. The makefile also requires
|
||||
AWK.
|
||||
|
||||
Contacts:
|
||||
|
||||
http://www.sqlite.org/
|
||||
@@ -0,0 +1,13 @@
|
||||
This is the SQLite amalgamation.
|
||||
Check sqlite3.h for the version number and source id.
|
||||
|
||||
See http://www.sqlite.org/ for more info.
|
||||
|
||||
We have a mozilla-specific Makefile.in in src/ (normally no
|
||||
Makefile.in there) that we use to build.
|
||||
|
||||
To move to a new version:
|
||||
|
||||
Copy the sqlite3.h and sqlite3.c files from the amalgamation of sqlite.
|
||||
|
||||
Be sure to update SQLITE_VERSION accordingly in $(topsrcdir)/configure.in.
|
||||
+11891
-27071
File diff suppressed because it is too large.
Load diff
+164
-869
File diff suppressed because it is too large.
Load diff
@@ -2397,7 +2397,7 @@ var Debugger =
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
/* 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,
|
||||
* 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/. */
|
||||
|
||||
var React = __webpack_require__(2);
|
||||
@@ -30019,166 +30019,166 @@ var Debugger =
|
||||
/* 266 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
(function(){
|
||||
var crypt = __webpack_require__(267),
|
||||
utf8 = __webpack_require__(268).utf8,
|
||||
isBuffer = __webpack_require__(269),
|
||||
bin = __webpack_require__(268).bin,
|
||||
|
||||
// The core
|
||||
md5 = function (message, options) {
|
||||
// Convert to byte array
|
||||
if (message.constructor == String)
|
||||
if (options && options.encoding === 'binary')
|
||||
message = bin.stringToBytes(message);
|
||||
else
|
||||
message = utf8.stringToBytes(message);
|
||||
else if (isBuffer(message))
|
||||
message = Array.prototype.slice.call(message, 0);
|
||||
else if (!Array.isArray(message))
|
||||
message = message.toString();
|
||||
// else, assume byte array already
|
||||
|
||||
var m = crypt.bytesToWords(message),
|
||||
l = message.length * 8,
|
||||
a = 1732584193,
|
||||
b = -271733879,
|
||||
c = -1732584194,
|
||||
d = 271733878;
|
||||
|
||||
// Swap endian
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
|
||||
((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
|
||||
}
|
||||
|
||||
// Padding
|
||||
m[l >>> 5] |= 0x80 << (l % 32);
|
||||
m[(((l + 64) >>> 9) << 4) + 14] = l;
|
||||
|
||||
// Method shortcuts
|
||||
var FF = md5._ff,
|
||||
GG = md5._gg,
|
||||
HH = md5._hh,
|
||||
II = md5._ii;
|
||||
|
||||
for (var i = 0; i < m.length; i += 16) {
|
||||
|
||||
var aa = a,
|
||||
bb = b,
|
||||
cc = c,
|
||||
dd = d;
|
||||
|
||||
a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
|
||||
d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
|
||||
c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
|
||||
b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
|
||||
a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
|
||||
d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
|
||||
c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
|
||||
b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
|
||||
a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
|
||||
d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
|
||||
c = FF(c, d, a, b, m[i+10], 17, -42063);
|
||||
b = FF(b, c, d, a, m[i+11], 22, -1990404162);
|
||||
a = FF(a, b, c, d, m[i+12], 7, 1804603682);
|
||||
d = FF(d, a, b, c, m[i+13], 12, -40341101);
|
||||
c = FF(c, d, a, b, m[i+14], 17, -1502002290);
|
||||
b = FF(b, c, d, a, m[i+15], 22, 1236535329);
|
||||
|
||||
a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
|
||||
d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
|
||||
c = GG(c, d, a, b, m[i+11], 14, 643717713);
|
||||
b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
|
||||
a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
|
||||
d = GG(d, a, b, c, m[i+10], 9, 38016083);
|
||||
c = GG(c, d, a, b, m[i+15], 14, -660478335);
|
||||
b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
|
||||
a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
|
||||
d = GG(d, a, b, c, m[i+14], 9, -1019803690);
|
||||
c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
|
||||
b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
|
||||
a = GG(a, b, c, d, m[i+13], 5, -1444681467);
|
||||
d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
|
||||
c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
|
||||
b = GG(b, c, d, a, m[i+12], 20, -1926607734);
|
||||
|
||||
a = HH(a, b, c, d, m[i+ 5], 4, -378558);
|
||||
d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
|
||||
c = HH(c, d, a, b, m[i+11], 16, 1839030562);
|
||||
b = HH(b, c, d, a, m[i+14], 23, -35309556);
|
||||
a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
|
||||
d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
|
||||
c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
|
||||
b = HH(b, c, d, a, m[i+10], 23, -1094730640);
|
||||
a = HH(a, b, c, d, m[i+13], 4, 681279174);
|
||||
d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
|
||||
c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
|
||||
b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
|
||||
a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
|
||||
d = HH(d, a, b, c, m[i+12], 11, -421815835);
|
||||
c = HH(c, d, a, b, m[i+15], 16, 530742520);
|
||||
b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
|
||||
|
||||
a = II(a, b, c, d, m[i+ 0], 6, -198630844);
|
||||
d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
|
||||
c = II(c, d, a, b, m[i+14], 15, -1416354905);
|
||||
b = II(b, c, d, a, m[i+ 5], 21, -57434055);
|
||||
a = II(a, b, c, d, m[i+12], 6, 1700485571);
|
||||
d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
|
||||
c = II(c, d, a, b, m[i+10], 15, -1051523);
|
||||
b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
|
||||
a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
|
||||
d = II(d, a, b, c, m[i+15], 10, -30611744);
|
||||
c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
|
||||
b = II(b, c, d, a, m[i+13], 21, 1309151649);
|
||||
a = II(a, b, c, d, m[i+ 4], 6, -145523070);
|
||||
d = II(d, a, b, c, m[i+11], 10, -1120210379);
|
||||
c = II(c, d, a, b, m[i+ 2], 15, 718787259);
|
||||
b = II(b, c, d, a, m[i+ 9], 21, -343485551);
|
||||
|
||||
a = (a + aa) >>> 0;
|
||||
b = (b + bb) >>> 0;
|
||||
c = (c + cc) >>> 0;
|
||||
d = (d + dd) >>> 0;
|
||||
}
|
||||
|
||||
return crypt.endian([a, b, c, d]);
|
||||
};
|
||||
|
||||
// Auxiliary functions
|
||||
md5._ff = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b & c | ~b & d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
md5._gg = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b & d | c & ~d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
md5._hh = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b ^ c ^ d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
md5._ii = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
|
||||
// Package private blocksize
|
||||
md5._blocksize = 16;
|
||||
md5._digestsize = 16;
|
||||
|
||||
module.exports = function (message, options) {
|
||||
if (message === undefined || message === null)
|
||||
throw new Error('Illegal argument ' + message);
|
||||
|
||||
var digestbytes = crypt.wordsToBytes(md5(message, options));
|
||||
return options && options.asBytes ? digestbytes :
|
||||
options && options.asString ? bin.bytesToString(digestbytes) :
|
||||
crypt.bytesToHex(digestbytes);
|
||||
};
|
||||
|
||||
})();
|
||||
(function(){
|
||||
var crypt = __webpack_require__(267),
|
||||
utf8 = __webpack_require__(268).utf8,
|
||||
isBuffer = __webpack_require__(269),
|
||||
bin = __webpack_require__(268).bin,
|
||||
|
||||
// The core
|
||||
md5 = function (message, options) {
|
||||
// Convert to byte array
|
||||
if (message.constructor == String)
|
||||
if (options && options.encoding === 'binary')
|
||||
message = bin.stringToBytes(message);
|
||||
else
|
||||
message = utf8.stringToBytes(message);
|
||||
else if (isBuffer(message))
|
||||
message = Array.prototype.slice.call(message, 0);
|
||||
else if (!Array.isArray(message))
|
||||
message = message.toString();
|
||||
// else, assume byte array already
|
||||
|
||||
var m = crypt.bytesToWords(message),
|
||||
l = message.length * 8,
|
||||
a = 1732584193,
|
||||
b = -271733879,
|
||||
c = -1732584194,
|
||||
d = 271733878;
|
||||
|
||||
// Swap endian
|
||||
for (var i = 0; i < m.length; i++) {
|
||||
m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF |
|
||||
((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00;
|
||||
}
|
||||
|
||||
// Padding
|
||||
m[l >>> 5] |= 0x80 << (l % 32);
|
||||
m[(((l + 64) >>> 9) << 4) + 14] = l;
|
||||
|
||||
// Method shortcuts
|
||||
var FF = md5._ff,
|
||||
GG = md5._gg,
|
||||
HH = md5._hh,
|
||||
II = md5._ii;
|
||||
|
||||
for (var i = 0; i < m.length; i += 16) {
|
||||
|
||||
var aa = a,
|
||||
bb = b,
|
||||
cc = c,
|
||||
dd = d;
|
||||
|
||||
a = FF(a, b, c, d, m[i+ 0], 7, -680876936);
|
||||
d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
|
||||
c = FF(c, d, a, b, m[i+ 2], 17, 606105819);
|
||||
b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
|
||||
a = FF(a, b, c, d, m[i+ 4], 7, -176418897);
|
||||
d = FF(d, a, b, c, m[i+ 5], 12, 1200080426);
|
||||
c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
|
||||
b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
|
||||
a = FF(a, b, c, d, m[i+ 8], 7, 1770035416);
|
||||
d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
|
||||
c = FF(c, d, a, b, m[i+10], 17, -42063);
|
||||
b = FF(b, c, d, a, m[i+11], 22, -1990404162);
|
||||
a = FF(a, b, c, d, m[i+12], 7, 1804603682);
|
||||
d = FF(d, a, b, c, m[i+13], 12, -40341101);
|
||||
c = FF(c, d, a, b, m[i+14], 17, -1502002290);
|
||||
b = FF(b, c, d, a, m[i+15], 22, 1236535329);
|
||||
|
||||
a = GG(a, b, c, d, m[i+ 1], 5, -165796510);
|
||||
d = GG(d, a, b, c, m[i+ 6], 9, -1069501632);
|
||||
c = GG(c, d, a, b, m[i+11], 14, 643717713);
|
||||
b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
|
||||
a = GG(a, b, c, d, m[i+ 5], 5, -701558691);
|
||||
d = GG(d, a, b, c, m[i+10], 9, 38016083);
|
||||
c = GG(c, d, a, b, m[i+15], 14, -660478335);
|
||||
b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
|
||||
a = GG(a, b, c, d, m[i+ 9], 5, 568446438);
|
||||
d = GG(d, a, b, c, m[i+14], 9, -1019803690);
|
||||
c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
|
||||
b = GG(b, c, d, a, m[i+ 8], 20, 1163531501);
|
||||
a = GG(a, b, c, d, m[i+13], 5, -1444681467);
|
||||
d = GG(d, a, b, c, m[i+ 2], 9, -51403784);
|
||||
c = GG(c, d, a, b, m[i+ 7], 14, 1735328473);
|
||||
b = GG(b, c, d, a, m[i+12], 20, -1926607734);
|
||||
|
||||
a = HH(a, b, c, d, m[i+ 5], 4, -378558);
|
||||
d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
|
||||
c = HH(c, d, a, b, m[i+11], 16, 1839030562);
|
||||
b = HH(b, c, d, a, m[i+14], 23, -35309556);
|
||||
a = HH(a, b, c, d, m[i+ 1], 4, -1530992060);
|
||||
d = HH(d, a, b, c, m[i+ 4], 11, 1272893353);
|
||||
c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
|
||||
b = HH(b, c, d, a, m[i+10], 23, -1094730640);
|
||||
a = HH(a, b, c, d, m[i+13], 4, 681279174);
|
||||
d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
|
||||
c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
|
||||
b = HH(b, c, d, a, m[i+ 6], 23, 76029189);
|
||||
a = HH(a, b, c, d, m[i+ 9], 4, -640364487);
|
||||
d = HH(d, a, b, c, m[i+12], 11, -421815835);
|
||||
c = HH(c, d, a, b, m[i+15], 16, 530742520);
|
||||
b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
|
||||
|
||||
a = II(a, b, c, d, m[i+ 0], 6, -198630844);
|
||||
d = II(d, a, b, c, m[i+ 7], 10, 1126891415);
|
||||
c = II(c, d, a, b, m[i+14], 15, -1416354905);
|
||||
b = II(b, c, d, a, m[i+ 5], 21, -57434055);
|
||||
a = II(a, b, c, d, m[i+12], 6, 1700485571);
|
||||
d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
|
||||
c = II(c, d, a, b, m[i+10], 15, -1051523);
|
||||
b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
|
||||
a = II(a, b, c, d, m[i+ 8], 6, 1873313359);
|
||||
d = II(d, a, b, c, m[i+15], 10, -30611744);
|
||||
c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
|
||||
b = II(b, c, d, a, m[i+13], 21, 1309151649);
|
||||
a = II(a, b, c, d, m[i+ 4], 6, -145523070);
|
||||
d = II(d, a, b, c, m[i+11], 10, -1120210379);
|
||||
c = II(c, d, a, b, m[i+ 2], 15, 718787259);
|
||||
b = II(b, c, d, a, m[i+ 9], 21, -343485551);
|
||||
|
||||
a = (a + aa) >>> 0;
|
||||
b = (b + bb) >>> 0;
|
||||
c = (c + cc) >>> 0;
|
||||
d = (d + dd) >>> 0;
|
||||
}
|
||||
|
||||
return crypt.endian([a, b, c, d]);
|
||||
};
|
||||
|
||||
// Auxiliary functions
|
||||
md5._ff = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b & c | ~b & d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
md5._gg = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b & d | c & ~d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
md5._hh = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (b ^ c ^ d) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
md5._ii = function (a, b, c, d, x, s, t) {
|
||||
var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
|
||||
return ((n << s) | (n >>> (32 - s))) + b;
|
||||
};
|
||||
|
||||
// Package private blocksize
|
||||
md5._blocksize = 16;
|
||||
md5._digestsize = 16;
|
||||
|
||||
module.exports = function (message, options) {
|
||||
if (message === undefined || message === null)
|
||||
throw new Error('Illegal argument ' + message);
|
||||
|
||||
var digestbytes = crypt.wordsToBytes(md5(message, options));
|
||||
return options && options.asBytes ? digestbytes :
|
||||
options && options.asString ? bin.bytesToString(digestbytes) :
|
||||
crypt.bytesToHex(digestbytes);
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
|
||||
/***/ },
|
||||
|
||||
@@ -612,6 +612,7 @@ menuseparator {
|
||||
}
|
||||
|
||||
.autocomplete .results * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -772,6 +773,7 @@ menuseparator {
|
||||
}
|
||||
.tree {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
@@ -818,6 +820,7 @@ html[dir="rtl"] .tree .node > div {
|
||||
}
|
||||
|
||||
.sources-panel * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -831,6 +834,7 @@ html[dir="rtl"] .tree .node > div {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -912,6 +916,7 @@ html[dir="rtl"] .worker svg {
|
||||
|
||||
.tree {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
@@ -961,6 +966,7 @@ html[dir="rtl"] .worker svg {
|
||||
right: 1px;
|
||||
opacity: 1;
|
||||
z-index: 100;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -973,6 +979,7 @@ html[dir="rtl"] .source-footer .command-bar {
|
||||
}
|
||||
|
||||
.source-footer .command-bar * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1179,6 +1186,7 @@ html[dir="rtl"] .editor-mount {
|
||||
background-color: var(--theme-tab-toolbar-background);
|
||||
font-weight: lighter;
|
||||
z-index: 100;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1205,6 +1213,7 @@ html[dir="rtl"] .editor-mount {
|
||||
outline-width: 0;
|
||||
}
|
||||
.breakpoints-list * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1387,6 +1396,7 @@ html .arrow.expanded svg {
|
||||
*/
|
||||
|
||||
.frames ul li * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1439,6 +1449,7 @@ html .arrow.expanded svg {
|
||||
width: 100%;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
@@ -1464,6 +1475,7 @@ html .arrow.expanded svg {
|
||||
}
|
||||
|
||||
.right-siderbar * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1538,6 +1550,7 @@ html[dir="rtl"] .command-bar .stepOut {
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 0.5em;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -1559,6 +1572,7 @@ span.pause-exceptions.all {
|
||||
}
|
||||
|
||||
.source-header * {
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
@@ -0,0 +1,94 @@
|
||||
/* 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/. */
|
||||
|
||||
window {
|
||||
-moz-appearance: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#doorhanger-container {
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
#top-panel {
|
||||
padding: 20px;
|
||||
background: #343c45; /* toolbars */
|
||||
color: #8fa1b2; /* body text */
|
||||
/*
|
||||
* Sloppy preprocessing since UNIX_BUT_NOT_MAC is only defined
|
||||
* in `browser/app/profile/firefox.js`, which this file cannot
|
||||
* depend on. Must style font-size to target linux.
|
||||
*/
|
||||
%ifdef XP_UNIX
|
||||
%ifndef XP_MACOSX
|
||||
font-size: 13px;
|
||||
%else
|
||||
font-size: 15px;
|
||||
%endif
|
||||
%else
|
||||
font-size: 15px;
|
||||
%endif
|
||||
line-height: 19px;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
#top-panel h1 {
|
||||
font-weight: bold;
|
||||
font-family: Open Sans, sans-serif;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
#top-panel p {
|
||||
font-family: Open Sans, sans-serif;
|
||||
font-size: 0.9em;
|
||||
width: 300px;
|
||||
display: block;
|
||||
margin: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
#icon {
|
||||
background-image: url("chrome://devtools/content/framework/dev-edition-promo/dev-edition-logo.png");
|
||||
background-size: 64px 64px;
|
||||
background-repeat: no-repeat;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
#lower-panel {
|
||||
padding: 20px;
|
||||
background-color: #252c33; /* tab toolbars */
|
||||
min-height: 75px;
|
||||
border-top: 1px solid #292e33; /* text high contrast (light) */
|
||||
}
|
||||
|
||||
#button-container {
|
||||
margin: auto 20px;
|
||||
}
|
||||
|
||||
#button-container button {
|
||||
font: message-box !important;
|
||||
font-size: 16px !important;
|
||||
cursor: pointer;
|
||||
width: 125px;
|
||||
opacity: 1;
|
||||
position: static;
|
||||
-moz-appearance: none;
|
||||
border-radius: 5px;
|
||||
height: 30px;
|
||||
width: 450px;
|
||||
/* Override embossed borders on Windows/Linux */
|
||||
border: none;
|
||||
}
|
||||
|
||||
#close {
|
||||
background-color: transparent;
|
||||
color: #8fa1b2; /* body text */
|
||||
}
|
||||
|
||||
#go {
|
||||
margin-left: 100px;
|
||||
background-color: #70bf53; /* green */
|
||||
color: #f5f7fa; /* selection text color */
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % toolboxDTD SYSTEM "chrome://devtools/locale/toolbox.dtd" >
|
||||
%toolboxDTD;
|
||||
]>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet rel="stylesheet" href="chrome://devtools/content/framework/dev-edition-promo/dev-edition-promo.css" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="dev-edition-promo">
|
||||
<vbox id="doorhanger-container">
|
||||
<hbox flex="1" id="top-panel">
|
||||
<image id="icon" />
|
||||
<vbox id="info">
|
||||
<h1>Using Developer Tools in your browser?</h1>
|
||||
<p>Download Firefox Developer Edition, our first browser made just for you.</p>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<hbox id="lower-panel" flex="1">
|
||||
<hbox id="button-container" flex="1">
|
||||
<button id="close"
|
||||
flex="1"
|
||||
standalone="true"
|
||||
label="No thanks">
|
||||
</button>
|
||||
<button id="go"
|
||||
flex="1"
|
||||
standalone="true"
|
||||
label="Learn more »">
|
||||
</button>
|
||||
</hbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</window>
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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/. */
|
||||
:root{
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
#options-panel-container {
|
||||
|
||||
@@ -46,6 +46,8 @@ loader.lazyRequireGetter(this, "InspectorFront",
|
||||
"devtools/shared/fronts/inspector", true);
|
||||
loader.lazyRequireGetter(this, "flags",
|
||||
"devtools/shared/flags");
|
||||
loader.lazyRequireGetter(this, "showDoorhanger",
|
||||
"devtools/client/shared/doorhanger", true);
|
||||
loader.lazyRequireGetter(this, "createPerformanceFront",
|
||||
"devtools/shared/fronts/performance", true);
|
||||
loader.lazyRequireGetter(this, "system",
|
||||
@@ -115,6 +117,7 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId) {
|
||||
this._saveSplitConsoleHeight = this._saveSplitConsoleHeight.bind(this);
|
||||
this._onFocus = this._onFocus.bind(this);
|
||||
this._onBrowserMessage = this._onBrowserMessage.bind(this);
|
||||
this._showDevEditionPromo = this._showDevEditionPromo.bind(this);
|
||||
this._updateTextBoxMenuItems = this._updateTextBoxMenuItems.bind(this);
|
||||
this._onBottomHostMinimized = this._onBottomHostMinimized.bind(this);
|
||||
this._onBottomHostMaximized = this._onBottomHostMaximized.bind(this);
|
||||
@@ -146,6 +149,8 @@ function Toolbox(target, selectedTool, hostType, contentWindow, frameId) {
|
||||
this.on("host-changed", this._refreshHostTitle);
|
||||
this.on("select", this._refreshHostTitle);
|
||||
|
||||
this.on("ready", this._showDevEditionPromo);
|
||||
|
||||
gDevTools.on("tool-registered", this._toolRegistered);
|
||||
gDevTools.on("tool-unregistered", this._toolUnregistered);
|
||||
|
||||
@@ -2090,6 +2095,7 @@ Toolbox.prototype = {
|
||||
this._target.off("frame-update", this._updateFrames);
|
||||
this.off("select", this._refreshHostTitle);
|
||||
this.off("host-changed", this._refreshHostTitle);
|
||||
this.off("ready", this._showDevEditionPromo);
|
||||
|
||||
gDevTools.off("tool-registered", this._toolRegistered);
|
||||
gDevTools.off("tool-unregistered", this._toolUnregistered);
|
||||
@@ -2182,16 +2188,14 @@ Toolbox.prototype = {
|
||||
.then(() => {
|
||||
this._removeHostListeners();
|
||||
|
||||
// `location` may already be invalid if the toolbox document is
|
||||
// already in process of destruction. Otherwise if it is still
|
||||
// around, ensure releasing toolbox document and triggering cleanup
|
||||
// thanks to unload event. We do that precisely here, before
|
||||
// nullifying the target as various cleanup code depends on the
|
||||
// target attribute to be still defined.
|
||||
try {
|
||||
// `location` may already be null if the toolbox document is already
|
||||
// in process of destruction. Otherwise if it is still around, ensure
|
||||
// releasing toolbox document and triggering cleanup thanks to unload
|
||||
// event. We do that precisely here, before nullifying the target as
|
||||
// various cleanup code depends on the target attribute to be still
|
||||
// defined.
|
||||
if (win.location) {
|
||||
win.location.replace("about:blank");
|
||||
} catch (e) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
// Targets need to be notified that the toolbox is being torn down.
|
||||
@@ -2247,6 +2251,18 @@ Toolbox.prototype = {
|
||||
this.emit("highlighter-hide");
|
||||
},
|
||||
|
||||
/**
|
||||
* For displaying the promotional Doorhanger on first opening of
|
||||
* the developer tools, promoting the Developer Edition.
|
||||
*/
|
||||
_showDevEditionPromo: function () {
|
||||
// Do not display in browser toolbox
|
||||
if (this.target.chrome) {
|
||||
return;
|
||||
}
|
||||
showDoorhanger({ window: this.win, type: "deveditionpromo" });
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable / disable necessary textbox menu items using globalOverlay.js.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
padding: 5px;
|
||||
transition: all 0.25s ease;
|
||||
width: 100%;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.accordion ._header:hover {
|
||||
|
||||
@@ -37,6 +37,8 @@ const {AutocompletePopup} = require("devtools/client/shared/autocomplete-popup")
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
|
||||
const PREF_DEFAULT_COLOR_UNIT = "devtools.defaultColorUnit";
|
||||
const PREF_ENABLE_MDN_DOCS_TOOLTIP =
|
||||
"devtools.inspector.mdnDocsTooltip.enabled";
|
||||
const FILTER_CHANGED_TIMEOUT = 150;
|
||||
|
||||
// This is used to parse user input when filtering.
|
||||
@@ -155,8 +157,11 @@ function CssRuleView(inspector, document, store, pageStyle) {
|
||||
this._prefObserver.on(PREF_ORIG_SOURCES, this._onSourcePrefChanged);
|
||||
this._prefObserver.on(PREF_UA_STYLES, this._handlePrefChange);
|
||||
this._prefObserver.on(PREF_DEFAULT_COLOR_UNIT, this._handlePrefChange);
|
||||
this._prefObserver.on(PREF_ENABLE_MDN_DOCS_TOOLTIP, this._handlePrefChange);
|
||||
|
||||
this.showUserAgentStyles = Services.prefs.getBoolPref(PREF_UA_STYLES);
|
||||
this.enableMdnDocsTooltip =
|
||||
Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
|
||||
// The popup will be attached to the toolbox document.
|
||||
this.popup = new AutocompletePopup(inspector._toolbox.doc, {
|
||||
|
||||
@@ -85,6 +85,9 @@ support-files =
|
||||
[browser_rules_content_01.js]
|
||||
[browser_rules_content_02.js]
|
||||
skip-if = e10s && debug # Bug 1250058 - Docshell leak on debug e10s
|
||||
[browser_rules_context-menu-show-mdn-docs-01.js]
|
||||
[browser_rules_context-menu-show-mdn-docs-02.js]
|
||||
[browser_rules_context-menu-show-mdn-docs-03.js]
|
||||
[browser_rules_copy_styles.js]
|
||||
subsuite = clipboard
|
||||
[browser_rules_cssom.js]
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the code that integrates the Style Inspector's rule view
|
||||
* with the MDN docs tooltip.
|
||||
*
|
||||
* If you display the context click on a property name in the rule view, you
|
||||
* should see a menu item "Show MDN Docs". If you click that item, the MDN
|
||||
* docs tooltip should be shown, containing docs from MDN for that property.
|
||||
*
|
||||
* This file tests that the context menu item is shown when it should be
|
||||
* shown and hidden when it should be hidden.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The test document tries to confuse the context menu
|
||||
* code by having a tag called "padding" and a property
|
||||
* value called "margin".
|
||||
*/
|
||||
|
||||
const { PrefObserver } = require("devtools/client/shared/prefs");
|
||||
const PREF_ENABLE_MDN_DOCS_TOOLTIP =
|
||||
"devtools.inspector.mdnDocsTooltip.enabled";
|
||||
|
||||
const TEST_URI = `
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
padding {font-family: margin;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<padding>MDN tooltip testing</padding>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
info("Ensure the pref is true to begin with");
|
||||
let initial = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (initial != true) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, true);
|
||||
}
|
||||
|
||||
yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("padding", inspector);
|
||||
yield testMdnContextMenuItemVisibility(view);
|
||||
|
||||
info("Ensure the pref is reset to its initial value");
|
||||
let eventual = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (eventual != initial) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, initial);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Set a boolean pref, and wait for the pref observer to
|
||||
* trigger, so that code listening for the pref change
|
||||
* has had a chance to update itself.
|
||||
*
|
||||
* @param pref {string} Name of the pref to change
|
||||
* @param state {boolean} Desired value of the pref.
|
||||
*
|
||||
* Note that if the pref already has the value in `state`,
|
||||
* then the prefObserver will not trigger. So you should only
|
||||
* call this function if you know the pref's current value is
|
||||
* not `state`.
|
||||
*/
|
||||
function* setBooleanPref(pref, state) {
|
||||
let oncePrefChanged = defer();
|
||||
let prefObserver = new PrefObserver("devtools.");
|
||||
prefObserver.on(pref, oncePrefChanged.resolve);
|
||||
|
||||
info("Set the pref " + pref + " to: " + state);
|
||||
Services.prefs.setBoolPref(pref, state);
|
||||
|
||||
info("Wait for prefObserver to call back so the UI can update");
|
||||
yield oncePrefChanged.promise;
|
||||
prefObserver.off(pref, oncePrefChanged.resolve);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the MDN context menu item is shown when it should be,
|
||||
* and hidden when it should be.
|
||||
* - iterate through every node in the rule view
|
||||
* - set that node as popupNode (the node that the context menu
|
||||
* is shown for)
|
||||
* - update the context menu's state
|
||||
* - test that the MDN context menu item is hidden, or not,
|
||||
* depending on popupNode
|
||||
*/
|
||||
function* testMdnContextMenuItemVisibility(view) {
|
||||
info("Test that MDN context menu item is shown only when it should be.");
|
||||
|
||||
let root = rootElement(view);
|
||||
for (let node of iterateNodes(root)) {
|
||||
info("Setting " + node + " as popupNode");
|
||||
info("Creating context menu with " + node + " as popupNode");
|
||||
let allMenuItems = openStyleContextMenuAndGetAllItems(view, node);
|
||||
let menuitemShowMdnDocs = allMenuItems.find(item => item.label ===
|
||||
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"));
|
||||
|
||||
let isVisible = menuitemShowMdnDocs.visible;
|
||||
let shouldBeVisible = isPropertyNameNode(node);
|
||||
let message = shouldBeVisible ? "shown" : "hidden";
|
||||
is(isVisible, shouldBeVisible,
|
||||
"The MDN context menu item is " + message + " ; content : " +
|
||||
node.textContent + " ; type : " + node.nodeType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a node is a property name.
|
||||
*/
|
||||
function isPropertyNameNode(node) {
|
||||
return node.textContent === "font-family";
|
||||
}
|
||||
|
||||
/**
|
||||
* A generator that iterates recursively through all child nodes of baseNode.
|
||||
*/
|
||||
function* iterateNodes(baseNode) {
|
||||
yield baseNode;
|
||||
|
||||
for (let child of baseNode.childNodes) {
|
||||
yield* iterateNodes(child);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root element for the rule view.
|
||||
*/
|
||||
var rootElement = view => (view.element) ? view.element : view.styleDocument;
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the code that integrates the Style Inspector's rule view
|
||||
* with the MDN docs tooltip.
|
||||
*
|
||||
* If you display the context click on a property name in the rule view, you
|
||||
* should see a menu item "Show MDN Docs". If you click that item, the MDN
|
||||
* docs tooltip should be shown, containing docs from MDN for that property.
|
||||
*
|
||||
* This file tests that:
|
||||
* - clicking the context menu item shows the tooltip
|
||||
* - the tooltip content matches the property name for which the context menu was opened
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {setBaseCssDocsUrl} =
|
||||
require("devtools/client/shared/widgets/MdnDocsWidget");
|
||||
|
||||
const PROPERTYNAME = "color";
|
||||
|
||||
const TEST_DOC = `
|
||||
<html>
|
||||
<body>
|
||||
<div style="color: red">
|
||||
Test "Show MDN Docs" context menu option
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_DOC));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
setBaseCssDocsUrl(URL_ROOT);
|
||||
|
||||
info("Setting the popupNode for the MDN docs tooltip");
|
||||
|
||||
let {nameSpan} = getRuleViewProperty(view, "element", PROPERTYNAME);
|
||||
|
||||
let allMenuItems = openStyleContextMenuAndGetAllItems(view, nameSpan.firstChild);
|
||||
let menuitemShowMdnDocs = allMenuItems.find(item => item.label ===
|
||||
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"));
|
||||
|
||||
let cssDocs = view.tooltips.cssDocs;
|
||||
|
||||
info("Showing the MDN docs tooltip");
|
||||
let onShown = cssDocs.tooltip.once("shown");
|
||||
menuitemShowMdnDocs.click();
|
||||
yield onShown;
|
||||
ok(true, "The MDN docs tooltip was shown");
|
||||
|
||||
info("Quick check that the tooltip contents are set");
|
||||
let h1 = cssDocs.tooltip.container.querySelector(".mdn-property-name");
|
||||
is(h1.textContent, PROPERTYNAME, "The MDN docs tooltip h1 is correct");
|
||||
});
|
||||
@@ -0,0 +1,117 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the "devtools.inspector.mdnDocsTooltip.enabled" preference,
|
||||
* that we use to enable/disable the MDN tooltip in the Inspector.
|
||||
*
|
||||
* The desired behavior is:
|
||||
* - if the preference is true, show the "Show MDN Docs" context menu item
|
||||
* - if the preference is false, don't show the item
|
||||
* - listen for changes to the pref, so we can show/hide the item dynamically
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PrefObserver } = require("devtools/client/styleeditor/utils");
|
||||
const PREF_ENABLE_MDN_DOCS_TOOLTIP =
|
||||
"devtools.inspector.mdnDocsTooltip.enabled";
|
||||
const PROPERTY_NAME_CLASS = "ruleview-propertyname";
|
||||
|
||||
const TEST_DOC = `
|
||||
<html>
|
||||
<body>
|
||||
<div style="color: red">
|
||||
Test the pref to enable/disable the "Show MDN Docs" context menu option
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
add_task(function* () {
|
||||
info("Ensure the pref is true to begin with");
|
||||
let initial = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (initial != true) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, true);
|
||||
}
|
||||
|
||||
yield addTab("data:text/html;charset=utf8," + encodeURIComponent(TEST_DOC));
|
||||
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("div", inspector);
|
||||
yield testMdnContextMenuItemVisibility(view, true);
|
||||
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, false);
|
||||
yield testMdnContextMenuItemVisibility(view, false);
|
||||
|
||||
info("Close the Inspector");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
yield gDevTools.closeToolbox(target);
|
||||
|
||||
({inspector, view} = yield openRuleView());
|
||||
yield selectNode("div", inspector);
|
||||
yield testMdnContextMenuItemVisibility(view, false);
|
||||
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, true);
|
||||
yield testMdnContextMenuItemVisibility(view, true);
|
||||
|
||||
info("Ensure the pref is reset to its initial value");
|
||||
let eventual = Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP);
|
||||
if (eventual != initial) {
|
||||
yield setBooleanPref(PREF_ENABLE_MDN_DOCS_TOOLTIP, initial);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Set a boolean pref, and wait for the pref observer to
|
||||
* trigger, so that code listening for the pref change
|
||||
* has had a chance to update itself.
|
||||
*
|
||||
* @param pref {string} Name of the pref to change
|
||||
* @param state {boolean} Desired value of the pref.
|
||||
*
|
||||
* Note that if the pref already has the value in `state`,
|
||||
* then the prefObserver will not trigger. So you should only
|
||||
* call this function if you know the pref's current value is
|
||||
* not `state`.
|
||||
*/
|
||||
function* setBooleanPref(pref, state) {
|
||||
let oncePrefChanged = defer();
|
||||
let prefObserver = new PrefObserver("devtools.");
|
||||
prefObserver.on(pref, oncePrefChanged.resolve);
|
||||
|
||||
info("Set the pref " + pref + " to: " + state);
|
||||
Services.prefs.setBoolPref(pref, state);
|
||||
|
||||
info("Wait for prefObserver to call back so the UI can update");
|
||||
yield oncePrefChanged.promise;
|
||||
prefObserver.off(pref, oncePrefChanged.resolve);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the MDN tooltip context menu item is visible when it should be.
|
||||
*
|
||||
* @param view The rule view
|
||||
* @param shouldBeVisible {boolean} Whether we expect the context
|
||||
* menu item to be visible or not.
|
||||
*/
|
||||
function* testMdnContextMenuItemVisibility(view, shouldBeVisible) {
|
||||
let message = shouldBeVisible ? "shown" : "hidden";
|
||||
info("Test that MDN context menu item is " + message);
|
||||
|
||||
info("Set a CSS property name as popupNode");
|
||||
let root = rootElement(view);
|
||||
let node = root.querySelector("." + PROPERTY_NAME_CLASS).firstChild;
|
||||
let allMenuItems = openStyleContextMenuAndGetAllItems(view, node);
|
||||
let menuitemShowMdnDocs = allMenuItems.find(item => item.label ===
|
||||
STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"));
|
||||
|
||||
let isVisible = menuitemShowMdnDocs.visible;
|
||||
is(isVisible, shouldBeVisible,
|
||||
"The MDN context menu item is " + message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root element for the rule view.
|
||||
*/
|
||||
var rootElement = view => (view.element) ? view.element : view.styleDocument;
|
||||
@@ -25,6 +25,9 @@ const STYLE_INSPECTOR_PROPERTIES = "devtools/shared/locales/styleinspector.prope
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
|
||||
|
||||
const PREF_ENABLE_MDN_DOCS_TOOLTIP =
|
||||
"devtools.inspector.mdnDocsTooltip.enabled";
|
||||
|
||||
/**
|
||||
* Style inspector context menu
|
||||
*
|
||||
@@ -53,6 +56,7 @@ function StyleInspectorMenu(view, options) {
|
||||
this._onCopySelector = this._onCopySelector.bind(this);
|
||||
this._onCopyUrl = this._onCopyUrl.bind(this);
|
||||
this._onSelectAll = this._onSelectAll.bind(this);
|
||||
this._onShowMdnDocs = this._onShowMdnDocs.bind(this);
|
||||
this._onToggleOrigSources = this._onToggleOrigSources.bind(this);
|
||||
}
|
||||
|
||||
@@ -225,6 +229,19 @@ StyleInspectorMenu.prototype = {
|
||||
});
|
||||
menu.append(menuitemAddRule);
|
||||
|
||||
// Show MDN Docs
|
||||
let mdnDocsAccessKey = "styleinspector.contextmenu.showMdnDocs.accessKey";
|
||||
let menuitemShowMdnDocs = new MenuItem({
|
||||
label: STYLE_INSPECTOR_L10N.getStr("styleinspector.contextmenu.showMdnDocs"),
|
||||
accesskey: STYLE_INSPECTOR_L10N.getStr(mdnDocsAccessKey),
|
||||
click: () => {
|
||||
this._onShowMdnDocs();
|
||||
},
|
||||
visible: (Services.prefs.getBoolPref(PREF_ENABLE_MDN_DOCS_TOOLTIP) &&
|
||||
this._isPropertyName()),
|
||||
});
|
||||
menu.append(menuitemShowMdnDocs);
|
||||
|
||||
// Show Original Sources
|
||||
let sourcesAccessKey = "styleinspector.contextmenu.toggleOrigSources.accessKey";
|
||||
let menuitemSources = new MenuItem({
|
||||
@@ -390,6 +407,16 @@ StyleInspectorMenu.prototype = {
|
||||
clipboardHelper.copyString(message);
|
||||
}),
|
||||
|
||||
/**
|
||||
* Show docs from MDN for a CSS property.
|
||||
*/
|
||||
_onShowMdnDocs: function () {
|
||||
let cssPropertyName = this.styleDocument.popupNode.textContent;
|
||||
let anchor = this.styleDocument.popupNode.parentNode;
|
||||
let cssDocsTooltip = this.view.tooltips.cssDocs;
|
||||
cssDocsTooltip.show(anchor, cssPropertyName);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new rule to the current element.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ const {
|
||||
} = require("devtools/client/inspector/shared/node-types");
|
||||
const { getColor } = require("devtools/client/shared/theme");
|
||||
const { getCssProperties } = require("devtools/shared/fronts/css-properties");
|
||||
const CssDocsTooltip = require("devtools/client/shared/widgets/tooltip/CssDocsTooltip");
|
||||
const { HTMLTooltip } = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
|
||||
const {
|
||||
getImageDimensions,
|
||||
@@ -81,6 +82,9 @@ TooltipsOverlay.prototype = {
|
||||
this.previewTooltip.startTogglingOnHover(this.view.element,
|
||||
this._onPreviewTooltipTargetHover.bind(this));
|
||||
|
||||
// MDN CSS help tooltip
|
||||
this.cssDocs = new CssDocsTooltip(toolbox.doc);
|
||||
|
||||
if (this.isRuleView) {
|
||||
// Color picker tooltip
|
||||
this.colorPicker = new SwatchColorPickerTooltip(toolbox.doc,
|
||||
@@ -116,6 +120,10 @@ TooltipsOverlay.prototype = {
|
||||
this.cubicBezier.destroy();
|
||||
}
|
||||
|
||||
if (this.cssDocs) {
|
||||
this.cssDocs.destroy();
|
||||
}
|
||||
|
||||
if (this.filterEditor) {
|
||||
this.filterEditor.destroy();
|
||||
}
|
||||
@@ -143,7 +151,7 @@ TooltipsOverlay.prototype = {
|
||||
// Font preview tooltip
|
||||
if (type === VIEW_NODE_VALUE_TYPE && prop.property === "font-family") {
|
||||
let value = prop.value.toLowerCase();
|
||||
if (value !== "inherit" && value !== "unset" && value !== "initial" && value !== "revert") {
|
||||
if (value !== "inherit" && value !== "unset" && value !== "initial") {
|
||||
tooltipType = TOOLTIP_FONTFAMILY_TYPE;
|
||||
}
|
||||
}
|
||||
@@ -183,6 +191,10 @@ TooltipsOverlay.prototype = {
|
||||
this.cubicBezier.hide();
|
||||
}
|
||||
|
||||
if (this.isRuleView && this.cssDocs.tooltip.isVisible()) {
|
||||
this.cssDocs.hide();
|
||||
}
|
||||
|
||||
if (this.isRuleView && this.filterEditor.tooltip.isVisible()) {
|
||||
this.filterEditor.revert();
|
||||
this.filterEdtior.hide();
|
||||
@@ -283,6 +295,10 @@ TooltipsOverlay.prototype = {
|
||||
this.cubicBezier.hide();
|
||||
}
|
||||
|
||||
if (this.cssDocs) {
|
||||
this.cssDocs.hide();
|
||||
}
|
||||
|
||||
if (this.filterEditor) {
|
||||
this.filterEditor.hide();
|
||||
}
|
||||
|
||||
@@ -111,12 +111,16 @@ devtools.jar:
|
||||
content/framework/options-panel.css (framework/options-panel.css)
|
||||
content/framework/toolbox-process-window.xul (framework/toolbox-process-window.xul)
|
||||
* content/framework/toolbox-process-window.js (framework/toolbox-process-window.js)
|
||||
content/framework/dev-edition-promo/dev-edition-promo.xul (framework/dev-edition-promo/dev-edition-promo.xul)
|
||||
* content/framework/dev-edition-promo/dev-edition-promo.css (framework/dev-edition-promo/dev-edition-promo.css)
|
||||
content/framework/dev-edition-promo/dev-edition-logo.png (framework/dev-edition-promo/dev-edition-logo.png)
|
||||
content/inspector/inspector.xhtml (inspector/inspector.xhtml)
|
||||
content/framework/connect/connect.xhtml (framework/connect/connect.xhtml)
|
||||
content/framework/connect/connect.css (framework/connect/connect.css)
|
||||
content/framework/connect/connect.js (framework/connect/connect.js)
|
||||
content/shared/widgets/graphs-frame.xhtml (shared/widgets/graphs-frame.xhtml)
|
||||
content/shared/widgets/cubic-bezier.css (shared/widgets/cubic-bezier.css)
|
||||
content/shared/widgets/mdn-docs.css (shared/widgets/mdn-docs.css)
|
||||
content/shared/widgets/filter-widget.css (shared/widgets/filter-widget.css)
|
||||
content/shared/widgets/spectrum.css (shared/widgets/spectrum.css)
|
||||
content/aboutdebugging/aboutdebugging.xhtml (aboutdebugging/aboutdebugging.xhtml)
|
||||
|
||||
@@ -39,8 +39,9 @@ function ConverterObserver() {
|
||||
|
||||
ConverterObserver.prototype = {
|
||||
initialize: function () {
|
||||
// Only the DevEdition has this feature available by default.
|
||||
// Users need to manually flip 'devtools.jsonview.enabled' preference
|
||||
// to have it available.
|
||||
// to have it available in other distributions.
|
||||
if (this.isEnabled()) {
|
||||
this.register();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
padding-top: 8px;
|
||||
padding-bottom: 4px;
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.headersPanelBox .netInfoParamValue {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
padding: 0 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,14 @@ eyedropper.disabled.title=Unavailable in non-HTML documents
|
||||
#LOCALIZATION NOTE: Used in the image preview tooltip when the image could not be loaded
|
||||
eventsTooltip.openInDebugger=Open in Debugger
|
||||
|
||||
# LOCALIZATION NOTE (docsTooltip.visitMDN): Shown in the tooltip that displays
|
||||
# help from MDN. This is a link to the complete MDN documentation page.
|
||||
docsTooltip.visitMDN=Visit MDN page
|
||||
|
||||
# LOCALIZATION NOTE (docsTooltip.visitMDN): Shown in the docs tooltip when the MDN page
|
||||
# could not be loaded (for example, because of a connectivity problem).
|
||||
docsTooltip.loadDocsError=Could not load docs page.
|
||||
|
||||
# LOCALIZATION NOTE (inspector.collapsePane): This is the tooltip for the button
|
||||
# that collapses the right panel (rules, computed, box-model, etc...) in the
|
||||
# inspector UI.
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
# 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/.
|
||||
|
||||
// Developer edition promo preferences
|
||||
pref("devtools.devedition.promo.shown", false);
|
||||
pref("devtools.devedition.promo.url", "https://www.mozilla.org/firefox/developer/?utm_source=firefox-dev-tools&utm_medium=firefox-browser&utm_content=betadoorhanger");
|
||||
|
||||
// Only potentially show in beta release
|
||||
#if MOZ_UPDATE_CHANNEL == beta
|
||||
pref("devtools.devedition.promo.enabled", true);
|
||||
#else
|
||||
pref("devtools.devedition.promo.enabled", false);
|
||||
#endif
|
||||
|
||||
// DevTools development workflow
|
||||
pref("devtools.loader.hotreload", false);
|
||||
|
||||
@@ -47,6 +58,8 @@ pref("devtools.inspector.imagePreviewTooltipSize", 300);
|
||||
pref("devtools.inspector.showUserAgentStyles", false);
|
||||
// Show all native anonymous content (like controls in <video> tags)
|
||||
pref("devtools.inspector.showAllAnonymousContent", false);
|
||||
// Enable the MDN docs tooltip
|
||||
pref("devtools.inspector.mdnDocsTooltip.enabled", false);
|
||||
|
||||
// Enable the Font Inspector
|
||||
pref("devtools.fontinspector.enabled", true);
|
||||
|
||||
@@ -78,7 +78,7 @@ html, body {
|
||||
}
|
||||
|
||||
select {
|
||||
appearance: none;
|
||||
-moz-appearance: none;
|
||||
background-color: var(--theme-toolbar-background);
|
||||
background-image: var(--viewport-selection-arrow);
|
||||
background-position: 100% 50%;
|
||||
@@ -140,7 +140,7 @@ select > option.divider {
|
||||
margin: 0 0 15px 0;
|
||||
padding: 4px 5px;
|
||||
display: inline-flex;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
#global-toolbar > .title {
|
||||
@@ -196,7 +196,7 @@ select > option.divider {
|
||||
|
||||
#global-dpr-selector {
|
||||
margin: 0 8px;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
color: var(--viewport-color);
|
||||
font-size: 11px;
|
||||
height: 15px;
|
||||
@@ -295,7 +295,7 @@ select > option.divider {
|
||||
.browser {
|
||||
display: block;
|
||||
border: 0;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.browser:-moz-focusring {
|
||||
@@ -383,7 +383,7 @@ select > option.divider {
|
||||
}
|
||||
|
||||
.viewport-dimension-separator {
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ const Cu = Components.utils;
|
||||
|
||||
var {loader, require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var Telemetry = require("devtools/client/shared/telemetry");
|
||||
var {showDoorhanger} = require("devtools/client/shared/doorhanger");
|
||||
var {TouchEventSimulator} = require("devtools/shared/touch/simulator");
|
||||
var {Task} = require("devtools/shared/task");
|
||||
var promise = require("promise");
|
||||
@@ -254,6 +255,14 @@ ResponsiveUI.prototype = {
|
||||
yield this.connectToServer();
|
||||
this.userAgentInput.hidden = false;
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger.
|
||||
// Only displayed once.
|
||||
showDoorhanger({
|
||||
window: this.mainWindow,
|
||||
type: "deveditionpromo",
|
||||
anchor: this.chromeDoc.querySelector("#content")
|
||||
});
|
||||
|
||||
// Notify that responsive mode is on.
|
||||
this._telemetry.toolOpened("responsive");
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
|
||||
@@ -209,9 +209,6 @@ SplitView.prototype = {
|
||||
this._nav.appendChild(aSummary);
|
||||
|
||||
aSummary.addEventListener("click", (aEvent) => {
|
||||
if (aEvent.button != 0) {
|
||||
return;
|
||||
}
|
||||
aEvent.stopPropagation();
|
||||
this.activeSummary = aSummary;
|
||||
}, false);
|
||||
|
||||
@@ -97,9 +97,6 @@ AutocompletePopup.prototype = {
|
||||
},
|
||||
|
||||
onClick: function (e) {
|
||||
if (e.button != 0) {
|
||||
return;
|
||||
}
|
||||
let item = e.target.closest(".autocomplete-item");
|
||||
if (item && typeof item.dataset.index !== "undefined") {
|
||||
this.selectedIndex = parseInt(item.dataset.index, 10);
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
|
||||
.treeTable .treeHeaderCell {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
padding: 0 !important;
|
||||
background: linear-gradient(
|
||||
|
||||
@@ -9,8 +9,7 @@ const {CSS_ANGLEUNIT} = require("devtools/shared/css/properties-db");
|
||||
const SPECIALVALUES = new Set([
|
||||
"initial",
|
||||
"inherit",
|
||||
"unset",
|
||||
"revert"
|
||||
"unset"
|
||||
]);
|
||||
|
||||
const {getCSSLexer} = require("devtools/shared/css/lexer");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
|
||||
* Copyright (C) 2011 Google Inc. All rights reserved.
|
||||
* Copyright (C) 2009 Mozilla Foundation. All rights reserved.
|
||||
* Copyright (C) 2022, 2023, 2025 Moonchild Productions. All rights reserved.
|
||||
* Copyright (C) 2022, 2023 Moonchild Productions. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -60,11 +60,17 @@ const Curl = {
|
||||
generateCommand: function (data) {
|
||||
const utils = CurlUtils;
|
||||
|
||||
let commandParts = [];
|
||||
let command = ["curl"];
|
||||
|
||||
// Make sure to use the following helpers to sanitize arguments before execution.
|
||||
const escapeStringifNeeded = value => {
|
||||
return /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
|
||||
const addParam = value => {
|
||||
const safe = /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
|
||||
command.push(safe);
|
||||
};
|
||||
|
||||
const addPostData = value => {
|
||||
const safe = /^[a-zA-Z-]+$/.test(value) ? value : escapeString(value);
|
||||
postData.push(safe);
|
||||
};
|
||||
|
||||
let ignoredHeaders = new Set();
|
||||
@@ -75,13 +81,7 @@ const Curl = {
|
||||
utils.escapeStringWin : utils.escapeStringPosix;
|
||||
|
||||
// Add URL.
|
||||
commandParts.push(data.url);
|
||||
|
||||
// Disable globbing if the URL contains brackets.
|
||||
// cURL also globs braces but they are already percent-encoded.
|
||||
if (data.url.includes("[") || data.url.includes("]")) {
|
||||
commandParts.push("--globoff");
|
||||
}
|
||||
addParam(data.url);
|
||||
|
||||
let postDataText = null;
|
||||
let multipartRequest = utils.isMultipartRequest(data);
|
||||
@@ -91,16 +91,15 @@ const Curl = {
|
||||
if (utils.isUrlEncodedRequest(data) ||
|
||||
["PUT", "POST", "PATCH"].includes(data.method)) {
|
||||
postDataText = data.postDataText;
|
||||
postData.push("--data-raw");
|
||||
let text =utils.writePostDataTextParams(postDataText);
|
||||
postData.push(escapeStringifNeeded(text));
|
||||
addPostData("--data-raw");
|
||||
addPostData(utils.writePostDataTextParams(postDataText));
|
||||
ignoredHeaders.add("content-length");
|
||||
} else if (multipartRequest) {
|
||||
postDataText = data.postDataText;
|
||||
postData.push("--data-binary");
|
||||
addPostData("--data-binary");
|
||||
let boundary = utils.getMultipartBoundary(data);
|
||||
let text = utils.removeBinaryDataFromMultipartText(postDataText, boundary);
|
||||
postData.push(escapeStringifNeeded(text));
|
||||
addPostData(text);
|
||||
ignoredHeaders.add("content-length");
|
||||
}
|
||||
|
||||
@@ -108,15 +107,15 @@ const Curl = {
|
||||
// For GET and POST requests this is not necessary as GET is the
|
||||
// default. If --data or --binary is added POST is the default.
|
||||
if (!(data.method == "GET" || data.method == "POST")) {
|
||||
commandParts.push("-X");
|
||||
commandParts.push(data.method);
|
||||
addParam("-X");
|
||||
addParam(data.method);
|
||||
}
|
||||
|
||||
// Add -I (HEAD)
|
||||
// For servers that supports HEAD.
|
||||
// This will fetch the header of a document only.
|
||||
if (data.method == "HEAD") {
|
||||
commandParts.push("-I");
|
||||
addParam("-I");
|
||||
}
|
||||
|
||||
// Add http version.
|
||||
@@ -127,7 +126,7 @@ const Curl = {
|
||||
// data.httpVersion are HTTP/1.0, HTTP/1.1 and HTTP/2.0
|
||||
// So in case of HTTP/2.0 (which should ideally be HTTP/2) we are using
|
||||
// only major version, and full version in other cases
|
||||
commandParts.push("--http" + (version == "2.0" ? version.split(".")[0] : version));
|
||||
addParam("--http" + (version == "2.0" ? version.split(".")[0] : version));
|
||||
}
|
||||
|
||||
// Add request headers.
|
||||
@@ -146,26 +145,14 @@ const Curl = {
|
||||
if (ignoredHeaders.has(header.name.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
commandParts.push("-H");
|
||||
let text = header.name + ": " + header.value;
|
||||
commandParts.push(escapeStringifNeeded(text));
|
||||
addParam("-H");
|
||||
addParam(header.name + ": " + header.value);
|
||||
}
|
||||
|
||||
// Add post data.
|
||||
commandParts = commandParts.concat(postData);
|
||||
command = command.concat(postData);
|
||||
|
||||
// Format with line breaks if the command has more than 2 parts
|
||||
// e.g
|
||||
// Command with 2 parts - curl https://foo.com
|
||||
// Commands with more than 2 parts -
|
||||
// curl https://foo.com
|
||||
// -X POST
|
||||
// -H "Accept : */*"
|
||||
// -H "accept-language: en-US"
|
||||
const joinStr = Services.appinfo.OS == "WINNT" ? " ^\n " : " \\\n ";
|
||||
return (
|
||||
"curl " + commandParts.join(commandParts.length >= 3 ? joinStr : " ")
|
||||
);
|
||||
return command.join(" ");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -413,43 +400,53 @@ const CurlUtils = {
|
||||
* Escape util function for Windows systems.
|
||||
*/
|
||||
escapeStringWin: function (str) {
|
||||
/*
|
||||
Because the cmd.exe parser and the MS Crt arguments parsers use some
|
||||
of the same escape characters, they can interact with each other in
|
||||
terrible ways, meaning the order of operations is critical here.
|
||||
|
||||
1. Replace \ with \\ first, because it is an escape character for
|
||||
certain conditions in both parsers.
|
||||
|
||||
2. Replace double quote chars with two double quotes (not by escaping
|
||||
with \") because it is recognized by both the cmd.exe and MS Crt
|
||||
arguments parsers.
|
||||
|
||||
3. Escape ` and $ so commands do not get executed, e.g $(calc.exe) or
|
||||
`\$(calc.exe)
|
||||
|
||||
4. Escape all characters we are not sure about with ^, to ensure it
|
||||
gets to the MS Crt arguments parser safely.
|
||||
|
||||
5. The % character is special because the MS Crt arguments parser will
|
||||
try and look for environment variables and fill them in, in-place. We
|
||||
cannot escape them with % and cannot escape them with ^ (because it's
|
||||
cmd.exe's escape, not the MS Crt arguments parser). So, we can get the
|
||||
cmd.exe parser to escape the character after it, if it is followed by
|
||||
a valid starting character of an environment variable.
|
||||
This ensures we do not try and double-escape another ^ if it was placed
|
||||
by the previous replace.
|
||||
|
||||
6. We replace \r and \r\n with \n; this allows us to consistently
|
||||
escape all new lines in the next replace.
|
||||
|
||||
7. Lastly, we replace new lines with ^ and TWO new lines, because the
|
||||
first new line is there to enact the escape command, and the second is
|
||||
the character to escape (in this case new line).
|
||||
The extra " enables escaping new lines with ^ within quotes in cmd.exe.
|
||||
*/
|
||||
const encapsChars = '"';
|
||||
return (
|
||||
encapsChars +
|
||||
str
|
||||
// Replace \ with \\ first because it is an escape character for certain
|
||||
// conditions in both parsers.
|
||||
.replace(/\\/g, "\\\\")
|
||||
// Replace double quote chars with two double quotes (not by escaping with \")
|
||||
// because it is recognized by both cmd.exe and MS CRT arguments parser.
|
||||
.replace(/"/g, '""')
|
||||
// Escape ` and $ so commands do not get executed e.g $(calc.exe) or `\$(calc.exe)
|
||||
.replace(/[`$]/g, "\\$&")
|
||||
// Then escape all characters we are not sure about with ^ to ensure it
|
||||
// gets to the MS CRT parser safely.
|
||||
// Note: Do not escape unicode control non-printable characters (0000-001f + 007f-009f)
|
||||
.replace(/[^a-zA-Z0-9\s_\-:=+~\/.',?;()*\$&\\{}\"`\u0000-\u001f\u007f-\u009f]/g, "^$&")
|
||||
// The % character is special because MS CRT parser will try and look for
|
||||
// ENV variables and fill them in its place. We cannot escape them with %
|
||||
// and cannot escape them with ^ (because it's cmd.exe's escape not MS CRT
|
||||
// parser); So we can get cmd.exe parser to escape the character after it,
|
||||
// if it is followed by a valid beginning character of an ENV variable.
|
||||
// This ensures we do not try and double escape another ^ if it was placed
|
||||
// by the previous replace.
|
||||
.replace(/[^a-zA-Z0-9\s_\-:=+~\/.',?;()*\$&\\{}\"`]/g, "^$&")
|
||||
.replace(/%(?=[a-zA-Z0-9_])/g, "%^")
|
||||
// All other whitespace characters are replaced with a single space, as there
|
||||
// is no way to enter their literal values in a command line, and they do break
|
||||
// the command sequence, allowing for injection.
|
||||
// Since want to keep line breaks, we need to exclude them in the regex (`[^\r\n]`),
|
||||
// and use double negations to get the other whitespace chars (`[^\S]` translates
|
||||
// to "not not whitespace")
|
||||
.replace(/[^\S\r\n]/g, " ")
|
||||
// Lastly we replace new lines with ^ and TWO new lines because the first
|
||||
// new line is there to enact the escape command the second is the character
|
||||
// to escape (in this case new line).
|
||||
.replace(/\r?\n|\r/g, "^\n\n")
|
||||
+ encapsChars
|
||||
);
|
||||
.replace(/\r\n?/g, "\n")
|
||||
.replace(/\n/g, '"^\r\n\r\n"')
|
||||
+ encapsChars);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { Ci, Cc } = require("chrome");
|
||||
const Services = require("Services");
|
||||
const { DOMHelpers } = require("resource://devtools/client/shared/DOMHelpers.jsm");
|
||||
const { Task } = require("devtools/shared/task");
|
||||
const defer = require("devtools/shared/defer");
|
||||
const { getMostRecentBrowserWindow } = require("sdk/window/utils");
|
||||
|
||||
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const DEV_EDITION_PROMO_URL = "chrome://devtools/content/framework/dev-edition-promo/dev-edition-promo.xul";
|
||||
const DEV_EDITION_PROMO_ENABLED_PREF = "devtools.devedition.promo.enabled";
|
||||
const DEV_EDITION_PROMO_SHOWN_PREF = "devtools.devedition.promo.shown";
|
||||
const DEV_EDITION_PROMO_URL_PREF = "devtools.devedition.promo.url";
|
||||
const LOCALE = Cc["@mozilla.org/chrome/chrome-registry;1"]
|
||||
.getService(Ci.nsIXULChromeRegistry)
|
||||
.getSelectedLocale("global");
|
||||
|
||||
/**
|
||||
* Only show Dev Edition promo if it's enabled (beta channel),
|
||||
* if it has not been shown before, and it's a locale build
|
||||
* for `en-US`
|
||||
*/
|
||||
function shouldDevEditionPromoShow() {
|
||||
return Services.prefs.getBoolPref(DEV_EDITION_PROMO_ENABLED_PREF) &&
|
||||
!Services.prefs.getBoolPref(DEV_EDITION_PROMO_SHOWN_PREF) &&
|
||||
LOCALE === "en-US";
|
||||
}
|
||||
|
||||
var TYPES = {
|
||||
// The Developer Edition promo doorhanger, called by
|
||||
// opening the toolbox, browser console, WebIDE, or responsive design mode
|
||||
// in Beta releases. Only displayed once per profile.
|
||||
deveditionpromo: {
|
||||
predicate: shouldDevEditionPromoShow,
|
||||
success: () => {
|
||||
return Services.prefs.setBoolPref(DEV_EDITION_PROMO_SHOWN_PREF, true);
|
||||
},
|
||||
action: () => {
|
||||
let url = Services.prefs.getCharPref(DEV_EDITION_PROMO_URL_PREF);
|
||||
getGBrowser().selectedTab = getGBrowser().addTab(url);
|
||||
},
|
||||
url: DEV_EDITION_PROMO_URL
|
||||
}
|
||||
};
|
||||
|
||||
var panelAttrs = {
|
||||
orient: "vertical",
|
||||
hidden: "false",
|
||||
consumeoutsideclicks: "true",
|
||||
noautofocus: "true",
|
||||
align: "start",
|
||||
role: "alert"
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to call a doorhanger, defined in `TYPES`, with defined conditions,
|
||||
* success handlers and loads its own XUL in a frame. Takes an object with
|
||||
* several properties:
|
||||
*
|
||||
* @param {XULWindow} window
|
||||
* The window that should house the doorhanger.
|
||||
* @param {String} type
|
||||
* The type of doorhanger to be displayed is, using the `TYPES`
|
||||
* definition.
|
||||
* @param {String} selector
|
||||
* The selector that the doorhanger should be appended to within
|
||||
* `window`. Defaults to a XUL Document's `window` element.
|
||||
*/
|
||||
exports.showDoorhanger = Task.async(function* ({ window, type, anchor }) {
|
||||
let { predicate, success, url, action } = TYPES[type];
|
||||
// Abort if predicate fails
|
||||
if (!predicate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Call success function to set preferences/cleanup immediately,
|
||||
// so if triggered multiple times, only happens once (Windows/Linux)
|
||||
success();
|
||||
|
||||
// Wait 200ms to prevent flickering where the popup is displayed
|
||||
// before the underlying window (Windows 7, 64bit)
|
||||
yield wait(200);
|
||||
|
||||
let document = window.document;
|
||||
|
||||
let panel = document.createElementNS(XULNS, "panel");
|
||||
let frame = document.createElementNS(XULNS, "iframe");
|
||||
let parentEl = document.querySelector("window");
|
||||
|
||||
frame.setAttribute("src", url);
|
||||
let close = () => parentEl.removeChild(panel);
|
||||
|
||||
setDoorhangerStyle(panel, frame);
|
||||
|
||||
panel.appendChild(frame);
|
||||
parentEl.appendChild(panel);
|
||||
|
||||
yield onFrameLoad(frame);
|
||||
|
||||
panel.openPopup(anchor);
|
||||
|
||||
let closeBtn = frame.contentDocument.querySelector("#close");
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener("click", close);
|
||||
}
|
||||
|
||||
let goBtn = frame.contentDocument.querySelector("#go");
|
||||
if (goBtn) {
|
||||
goBtn.addEventListener("click", () => {
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
close();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function setDoorhangerStyle(panel, frame) {
|
||||
Object.keys(panelAttrs).forEach(prop => {
|
||||
return panel.setAttribute(prop, panelAttrs[prop]);
|
||||
});
|
||||
panel.style.margin = "20px";
|
||||
panel.style.borderRadius = "5px";
|
||||
panel.style.border = "none";
|
||||
panel.style.MozAppearance = "none";
|
||||
panel.style.backgroundColor = "transparent";
|
||||
|
||||
frame.style.borderRadius = "5px";
|
||||
frame.setAttribute("flex", "1");
|
||||
frame.setAttribute("width", "450");
|
||||
frame.setAttribute("height", "179");
|
||||
}
|
||||
|
||||
function onFrameLoad(frame) {
|
||||
let { resolve, promise } = defer();
|
||||
|
||||
if (frame.contentWindow) {
|
||||
let domHelper = new DOMHelpers(frame.contentWindow);
|
||||
domHelper.onceDOMReady(resolve);
|
||||
} else {
|
||||
let callback = () => {
|
||||
frame.removeEventListener("DOMContentLoaded", callback);
|
||||
resolve();
|
||||
};
|
||||
frame.addEventListener("DOMContentLoaded", callback);
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function getGBrowser() {
|
||||
return getMostRecentBrowserWindow().gBrowser;
|
||||
}
|
||||
|
||||
function wait(n) {
|
||||
let { resolve, promise } = defer();
|
||||
setTimeout(resolve, n);
|
||||
return promise;
|
||||
}
|
||||
@@ -26,6 +26,7 @@ DevToolsModules(
|
||||
'devices.js',
|
||||
'devtools-file-watcher.js',
|
||||
'DOMHelpers.jsm',
|
||||
'doorhanger.js',
|
||||
'file-watcher-worker.js',
|
||||
'file-watcher.js',
|
||||
'getjson.js',
|
||||
|
||||
@@ -13,6 +13,11 @@ support-files =
|
||||
helper_color_data.js
|
||||
helper_html_tooltip.js
|
||||
helper_inplace_editor.js
|
||||
html-mdn-css-basic-testing.html
|
||||
html-mdn-css-no-summary.html
|
||||
html-mdn-css-no-summary-or-syntax.html
|
||||
html-mdn-css-no-syntax.html
|
||||
html-mdn-css-syntax-old-style.html
|
||||
leakhunt.js
|
||||
test-actor.js
|
||||
test-actor-registry.js
|
||||
@@ -135,6 +140,9 @@ skip-if = e10s # Bug 1221911, bug 1222289, frequent e10s timeouts
|
||||
skip-if = e10s # Layouthelpers test should not run in a content page.
|
||||
[browser_layoutHelpers-getBoxQuads.js]
|
||||
skip-if = e10s # Layouthelpers test should not run in a content page.
|
||||
[browser_mdn-docs-01.js]
|
||||
[browser_mdn-docs-02.js]
|
||||
[browser_mdn-docs-03.js]
|
||||
[browser_num-l10n.js]
|
||||
[browser_options-view-01.js]
|
||||
[browser_outputparser.js]
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the MdnDocsWidget object, and specifically its
|
||||
* loadCssDocs() function.
|
||||
*
|
||||
* The MdnDocsWidget is initialized with a document which has a specific
|
||||
* structure. You then call loadCssDocs(), passing in a CSS property name.
|
||||
* MdnDocsWidget then fetches docs for that property by making an XHR to
|
||||
* a docs page, and loads the results into the document. While the XHR is
|
||||
* still not resolved the document is put into an "initializing" state in
|
||||
* which the devtools throbber is displayed.
|
||||
*
|
||||
* In this file we test:
|
||||
* - the initial state of the document before the docs have loaded
|
||||
* - the state of the document after the docs have loaded
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {setBaseCssDocsUrl, MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget");
|
||||
|
||||
/**
|
||||
* Test properties
|
||||
*
|
||||
* In the real tooltip, a CSS property name is used to look up an MDN page
|
||||
* for that property.
|
||||
* In the test code, the names defined here is used to look up a page
|
||||
* served by the test server.
|
||||
*/
|
||||
const BASIC_TESTING_PROPERTY = "html-mdn-css-basic-testing.html";
|
||||
|
||||
const BASIC_EXPECTED_SUMMARY = "A summary of the property.";
|
||||
const BASIC_EXPECTED_SYNTAX = [{type: "comment", text: "/* The part we want */"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "this"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "is-the-part-we-want"},
|
||||
{type: "text", text: ";"}];
|
||||
|
||||
const URI_PARAMS =
|
||||
"?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default";
|
||||
|
||||
add_task(function* () {
|
||||
setBaseCssDocsUrl(TEST_URI_ROOT);
|
||||
|
||||
yield addTab("about:blank");
|
||||
let [host, win] = yield createHost("bottom", "data:text/html," +
|
||||
"<div class='mdn-container'></div>");
|
||||
let widget = new MdnDocsWidget(win.document.querySelector("div"));
|
||||
|
||||
yield testTheBasics(widget);
|
||||
|
||||
host.destroy();
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test all the basics
|
||||
* - initial content, before docs have loaded, is as expected
|
||||
* - throbber is set before docs have loaded
|
||||
* - contents are as expected after docs have loaded
|
||||
* - throbber is gone after docs have loaded
|
||||
* - mdn link text is correct and onclick behavior is correct
|
||||
*/
|
||||
function* testTheBasics(widget) {
|
||||
info("Test all the basic functionality in the widget");
|
||||
|
||||
info("Get the widget state before docs have loaded");
|
||||
let promise = widget.loadCssDocs(BASIC_TESTING_PROPERTY);
|
||||
|
||||
info("Check initial contents before docs have loaded");
|
||||
checkTooltipContents(widget.elements, {
|
||||
propertyName: BASIC_TESTING_PROPERTY,
|
||||
summary: "",
|
||||
syntax: ""
|
||||
});
|
||||
|
||||
// throbber is set
|
||||
ok(widget.elements.info.classList.contains("devtools-throbber"),
|
||||
"Throbber is set");
|
||||
|
||||
info("Now let the widget finish loading");
|
||||
yield promise;
|
||||
|
||||
info("Check contents after docs have loaded");
|
||||
checkTooltipContents(widget.elements, {
|
||||
propertyName: BASIC_TESTING_PROPERTY,
|
||||
summary: BASIC_EXPECTED_SUMMARY,
|
||||
syntax: BASIC_EXPECTED_SYNTAX
|
||||
});
|
||||
|
||||
// throbber is gone
|
||||
ok(!widget.elements.info.classList.contains("devtools-throbber"),
|
||||
"Throbber is not set");
|
||||
|
||||
info("Check that MDN link text is correct and onclick behavior is correct");
|
||||
|
||||
let mdnLink = widget.elements.linkToMdn;
|
||||
let expectedHref = TEST_URI_ROOT + BASIC_TESTING_PROPERTY + URI_PARAMS;
|
||||
is(mdnLink.href, expectedHref, "MDN link href is correct");
|
||||
|
||||
let uri = yield checkLinkClick(mdnLink);
|
||||
is(uri, expectedHref, "New tab opened with the expected URI");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicking the "Visit MDN Page" in the tooltip panel
|
||||
* should open a new browser tab with the page loaded.
|
||||
*
|
||||
* To test this we'll listen for a new tab opening, and
|
||||
* when it does, add a listener to that new tab to tell
|
||||
* us when it has loaded.
|
||||
*
|
||||
* Then we click the link.
|
||||
*
|
||||
* In the tab's load listener, we'll resolve the promise
|
||||
* with the URI, which is expected to match the href
|
||||
* in the orginal link.
|
||||
*
|
||||
* One complexity is that when you open a new tab,
|
||||
* "about:blank" is first loaded into the tab before the
|
||||
* actual page. So we ignore that first load event, and keep
|
||||
* listening until "load" is triggered for a different URI.
|
||||
*/
|
||||
function checkLinkClick(link) {
|
||||
function loadListener(tab) {
|
||||
let browser = getBrowser().getBrowserForTab(tab);
|
||||
let uri = browser.currentURI.spec;
|
||||
|
||||
info("New browser tab has loaded");
|
||||
gBrowser.removeTab(tab);
|
||||
info("Resolve promise with new tab URI");
|
||||
deferred.resolve(uri);
|
||||
}
|
||||
|
||||
function newTabListener(e) {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", newTabListener);
|
||||
let tab = e.target;
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, url => url != "about:blank")
|
||||
.then(url => loadListener(tab));
|
||||
}
|
||||
|
||||
let deferred = defer();
|
||||
info("Check that clicking the link opens a new tab with the correct URI");
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", newTabListener, false);
|
||||
info("Click the link to MDN");
|
||||
link.click();
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to check content of the tooltip.
|
||||
*/
|
||||
function checkTooltipContents(doc, expected) {
|
||||
is(doc.heading.textContent,
|
||||
expected.propertyName,
|
||||
"Property name is correct");
|
||||
|
||||
is(doc.summary.textContent,
|
||||
expected.summary,
|
||||
"Summary is correct");
|
||||
|
||||
checkCssSyntaxHighlighterOutput(expected.syntax, doc.syntax);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the MdnDocsWidget object, and specifically its
|
||||
* loadCssDocs() function.
|
||||
*
|
||||
* The MdnDocsWidget is initialized with a document which has a specific
|
||||
* structure. You then call loadCssDocs(), passing in a CSS property name.
|
||||
* MdnDocsWidget then fetches docs for that property by making an XHR to
|
||||
* a docs page, and loads the results into the document.
|
||||
*
|
||||
* In this file we test that the tooltip can properly handle the different
|
||||
* structures that the docs page might have, including variant structures and
|
||||
* error conditions like parts of the document being missing.
|
||||
*
|
||||
* We also test that the tooltip properly handles the case where the page
|
||||
* doesn't exist at all.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
setBaseCssDocsUrl,
|
||||
MdnDocsWidget
|
||||
} = require("devtools/client/shared/widgets/MdnDocsWidget");
|
||||
|
||||
const BASIC_EXPECTED_SUMMARY = "A summary of the property.";
|
||||
const BASIC_EXPECTED_SYNTAX = [{type: "comment", text: "/* The part we want */"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "this"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "is-the-part-we-want"},
|
||||
{type: "text", text: ";"}];
|
||||
|
||||
const ERROR_MESSAGE = "Could not load docs page.";
|
||||
|
||||
/**
|
||||
* Test properties
|
||||
*
|
||||
* In the real tooltip, a CSS property name is used to look up an MDN page
|
||||
* for that property.
|
||||
* In the test code, the names defined here are used to look up a page
|
||||
* served by the test server. We have different properties to test
|
||||
* different ways that the docs pages might be constructed, including errors
|
||||
* like pages that don't include docs where we expect.
|
||||
*/
|
||||
const SYNTAX_OLD_STYLE = "html-mdn-css-syntax-old-style.html";
|
||||
const NO_SUMMARY = "html-mdn-css-no-summary.html";
|
||||
const NO_SYNTAX = "html-mdn-css-no-syntax.html";
|
||||
const NO_SUMMARY_OR_SYNTAX = "html-mdn-css-no-summary-or-syntax.html";
|
||||
|
||||
const TEST_DATA = [{
|
||||
desc: "Test a property for which we don't have a page",
|
||||
docsPageUrl: "i-dont-exist.html",
|
||||
expectedContents: {
|
||||
propertyName: "i-dont-exist.html",
|
||||
summary: ERROR_MESSAGE,
|
||||
syntax: []
|
||||
}
|
||||
}, {
|
||||
desc: "Test a property whose syntax section is specified using an old-style page",
|
||||
docsPageUrl: SYNTAX_OLD_STYLE,
|
||||
expectedContents: {
|
||||
propertyName: SYNTAX_OLD_STYLE,
|
||||
summary: BASIC_EXPECTED_SUMMARY,
|
||||
syntax: BASIC_EXPECTED_SYNTAX
|
||||
}
|
||||
}, {
|
||||
desc: "Test a property whose page doesn't have a summary",
|
||||
docsPageUrl: NO_SUMMARY,
|
||||
expectedContents: {
|
||||
propertyName: NO_SUMMARY,
|
||||
summary: "",
|
||||
syntax: BASIC_EXPECTED_SYNTAX
|
||||
}
|
||||
}, {
|
||||
desc: "Test a property whose page doesn't have a syntax",
|
||||
docsPageUrl: NO_SYNTAX,
|
||||
expectedContents: {
|
||||
propertyName: NO_SYNTAX,
|
||||
summary: BASIC_EXPECTED_SUMMARY,
|
||||
syntax: []
|
||||
}
|
||||
}, {
|
||||
desc: "Test a property whose page doesn't have a summary or a syntax",
|
||||
docsPageUrl: NO_SUMMARY_OR_SYNTAX,
|
||||
expectedContents: {
|
||||
propertyName: NO_SUMMARY_OR_SYNTAX,
|
||||
summary: ERROR_MESSAGE,
|
||||
syntax: []
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
add_task(function* () {
|
||||
setBaseCssDocsUrl(TEST_URI_ROOT);
|
||||
|
||||
yield addTab("about:blank");
|
||||
let [host, win] = yield createHost("bottom", "data:text/html," +
|
||||
"<div class='mdn-container'></div>");
|
||||
let widget = new MdnDocsWidget(win.document.querySelector("div"));
|
||||
|
||||
for (let {desc, docsPageUrl, expectedContents} of TEST_DATA) {
|
||||
info(desc);
|
||||
yield widget.loadCssDocs(docsPageUrl);
|
||||
checkTooltipContents(widget.elements, expectedContents);
|
||||
}
|
||||
host.destroy();
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
/*
|
||||
* Utility function to check content of the tooltip.
|
||||
*/
|
||||
function checkTooltipContents(doc, expected) {
|
||||
is(doc.heading.textContent,
|
||||
expected.propertyName,
|
||||
"Property name is correct");
|
||||
|
||||
is(doc.summary.textContent,
|
||||
expected.summary,
|
||||
"Summary is correct");
|
||||
|
||||
checkCssSyntaxHighlighterOutput(expected.syntax, doc.syntax);
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This file tests the CSS syntax highlighter in the MdnDocsWidget object.
|
||||
*
|
||||
* The CSS syntax highlighter accepts:
|
||||
* - a string containing CSS
|
||||
* - a DOM node
|
||||
*
|
||||
* It parses the string and creates a collection of DOM nodes for different
|
||||
* CSS token types. These DOM nodes have CSS classes applied to them,
|
||||
* to apply the right style for that particular token type. The DOM nodes
|
||||
* are returned as children of the node that was passed to the function.
|
||||
*
|
||||
* This test code defines a number of different strings containing valid and
|
||||
* invalid CSS in various forms. For each string it defines the DOM nodes
|
||||
* that it expects to get from the syntax highlighter.
|
||||
*
|
||||
* It then calls the syntax highlighter, and checks that the resulting
|
||||
* collection of DOM nodes is what we expected.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const {appendSyntaxHighlightedCSS} = require("devtools/client/shared/widgets/MdnDocsWidget");
|
||||
|
||||
/**
|
||||
* An array containing the actual test cases.
|
||||
*
|
||||
* The test code tests every case in the array. If you want to add more
|
||||
* test cases, just add more items to the array.
|
||||
*
|
||||
* Each test case consists of:
|
||||
* - description: string describing the salient features of this test case
|
||||
* - example: the string to test
|
||||
* - expected: an array of objects, one for each DOM node we expect, that
|
||||
* captures the information about the node that we expect to test.
|
||||
*/
|
||||
const TEST_DATA = [{
|
||||
description: "Valid syntax, string value.",
|
||||
example: "name: stringValue;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, numeric value.",
|
||||
example: "name: 1;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "1"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, url value.",
|
||||
example: "name: url(./name);",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "url(./name)"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, space before ':'.",
|
||||
example: "name : stringValue;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: " "},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, space before ';'.",
|
||||
example: "name: stringValue ;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: " "},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, trailing space.",
|
||||
example: "name: stringValue; ",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"},
|
||||
{type: "text", text: " "}
|
||||
]}, {
|
||||
description: "Valid syntax, leading space.",
|
||||
example: " name: stringValue;",
|
||||
expected: [{type: "text", text: " "},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, two spaces.",
|
||||
example: "name: stringValue;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, no spaces.",
|
||||
example: "name:stringValue;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, two-part value.",
|
||||
example: "name: stringValue 1;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "1"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, two declarations.",
|
||||
example: "name: stringValue;\n" +
|
||||
"name: 1;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "1"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, commented, numeric value.",
|
||||
example: "/* comment */\n" +
|
||||
"name: 1;",
|
||||
expected: [{type: "comment", text: "/* comment */"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "1"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, multiline commented, string value.",
|
||||
example: "/* multiline \n" +
|
||||
"comment */\n" +
|
||||
"name: stringValue;",
|
||||
expected: [{type: "comment", text: "/* multiline \ncomment */"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, commented, two declarations.",
|
||||
example: "/* comment 1 */\n" +
|
||||
"name: 1;\n" +
|
||||
"/* comment 2 */\n" +
|
||||
"name: stringValue;",
|
||||
expected: [{type: "comment", text: "/* comment 1 */"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "1"},
|
||||
{type: "text", text: ";"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "comment", text: "/* comment 2 */"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, multiline.",
|
||||
example: "name: \n" +
|
||||
"stringValue;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " \n"},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Valid syntax, multiline, two declarations.",
|
||||
example: "name: \n" +
|
||||
"stringValue \n" +
|
||||
"stringValue2;",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " \n"},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: " \n"},
|
||||
{type: "property-value", text: "stringValue2"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Invalid: not CSS at all.",
|
||||
example: "not CSS at all",
|
||||
expected: [{type: "property-name", text: "not"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-name", text: "CSS"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-name", text: "at"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-name", text: "all"}
|
||||
]}, {
|
||||
description: "Invalid: switched ':' and ';'.",
|
||||
example: "name; stringValue:",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ";"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-name", text: "stringValue"},
|
||||
{type: "text", text: ":"}
|
||||
]}, {
|
||||
description: "Invalid: unterminated comment.",
|
||||
example: "/* unterminated comment\n" +
|
||||
"name: stringValue;",
|
||||
expected: [{type: "comment", text: "/* unterminated comment\nname: stringValue;"}
|
||||
]}, {
|
||||
description: "Invalid: bad comment syntax.",
|
||||
example: "// invalid comment\n" +
|
||||
"name: stringValue;",
|
||||
expected: [{type: "text", text: "/"},
|
||||
{type: "text", text: "/"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-name", text: "invalid"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-name", text: "comment"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: ";"}
|
||||
]}, {
|
||||
description: "Invalid: no trailing ';'.",
|
||||
example: "name: stringValue\n" +
|
||||
"name: stringValue2",
|
||||
expected: [{type: "property-name", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue"},
|
||||
{type: "text", text: "\n"},
|
||||
{type: "property-value", text: "name"},
|
||||
{type: "text", text: ":"},
|
||||
{type: "text", text: " "},
|
||||
{type: "property-value", text: "stringValue2"},
|
||||
]}
|
||||
];
|
||||
|
||||
/**
|
||||
* Iterate through every test case, calling the syntax highlighter,
|
||||
* then calling a helper function to check the output.
|
||||
*/
|
||||
add_task(function* () {
|
||||
let doc = gBrowser.selectedTab.ownerDocument;
|
||||
let parent = doc.createElement("div");
|
||||
info("Testing all CSS syntax highlighter test cases");
|
||||
for (let {description, example, expected} of TEST_DATA) {
|
||||
info("Testing: " + description);
|
||||
appendSyntaxHighlightedCSS(example, parent);
|
||||
checkCssSyntaxHighlighterOutput(expected, parent);
|
||||
while (parent.firstChild) {
|
||||
parent.firstChild.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -242,3 +242,105 @@ Task.async(function* (widget, name, value) {
|
||||
|
||||
yield onRender;
|
||||
});
|
||||
|
||||
/**
|
||||
* Utility function for testing CSS code samples that have been
|
||||
* syntax-highlighted.
|
||||
*
|
||||
* The CSS syntax highlighter emits a collection of DOM nodes that have
|
||||
* CSS classes applied to them. This function checks that those nodes
|
||||
* are what we expect.
|
||||
*
|
||||
* @param {array} expectedNodes
|
||||
* A representation of the nodes we expect to see.
|
||||
* Each node is an object containing two properties:
|
||||
* - type: a string which can be one of:
|
||||
* - text, comment, property-name, property-value
|
||||
* - text: the textContent of the node
|
||||
*
|
||||
* For example, given a string like this:
|
||||
* "<comment> The part we want </comment>\n this: is-the-part-we-want;"
|
||||
*
|
||||
* we would represent the expected output like this:
|
||||
* [{type: "comment", text: "<comment> The part we want </comment>"},
|
||||
* {type: "text", text: "\n"},
|
||||
* {type: "property-name", text: "this"},
|
||||
* {type: "text", text: ":"},
|
||||
* {type: "text", text: " "},
|
||||
* {type: "property-value", text: "is-the-part-we-want"},
|
||||
* {type: "text", text: ";"}];
|
||||
*
|
||||
* @param {Node} parent
|
||||
* The DOM node whose children are the output of the syntax highlighter.
|
||||
*/
|
||||
function checkCssSyntaxHighlighterOutput(expectedNodes, parent) {
|
||||
/**
|
||||
* The classes applied to the output nodes by the syntax highlighter.
|
||||
* These must be same as the definitions in MdnDocsWidget.js.
|
||||
*/
|
||||
const PROPERTY_NAME_COLOR = "theme-fg-color5";
|
||||
const PROPERTY_VALUE_COLOR = "theme-fg-color1";
|
||||
const COMMENT_COLOR = "theme-comment";
|
||||
|
||||
/**
|
||||
* Check the type and content of a single node.
|
||||
*/
|
||||
function checkNode(expected, actual) {
|
||||
ok(actual.textContent == expected.text,
|
||||
"Check that node has the expected textContent");
|
||||
info("Expected text content: [" + expected.text + "]");
|
||||
info("Actual text content: [" + actual.textContent + "]");
|
||||
|
||||
info("Check that node has the expected type");
|
||||
if (expected.type == "text") {
|
||||
ok(actual.nodeType == 3, "Check that node is a text node");
|
||||
} else {
|
||||
ok(actual.tagName.toUpperCase() == "SPAN", "Check that node is a SPAN");
|
||||
}
|
||||
|
||||
info("Check that node has the expected className");
|
||||
|
||||
let expectedClassName = null;
|
||||
let actualClassName = null;
|
||||
|
||||
switch (expected.type) {
|
||||
case "property-name":
|
||||
expectedClassName = PROPERTY_NAME_COLOR;
|
||||
break;
|
||||
case "property-value":
|
||||
expectedClassName = PROPERTY_VALUE_COLOR;
|
||||
break;
|
||||
case "comment":
|
||||
expectedClassName = COMMENT_COLOR;
|
||||
break;
|
||||
default:
|
||||
ok(!actual.classList, "No className expected");
|
||||
return;
|
||||
}
|
||||
|
||||
ok(actual.classList.length == 1, "One className expected");
|
||||
actualClassName = actual.classList[0];
|
||||
|
||||
ok(expectedClassName == actualClassName, "Check className value");
|
||||
info("Expected className: " + expectedClassName);
|
||||
info("Actual className: " + actualClassName);
|
||||
}
|
||||
|
||||
info("Logging the actual nodes we have:");
|
||||
for (let j = 0; j < parent.childNodes.length; j++) {
|
||||
let n = parent.childNodes[j];
|
||||
info(j + " / " +
|
||||
"nodeType: " + n.nodeType + " / " +
|
||||
"textContent: " + n.textContent);
|
||||
}
|
||||
|
||||
ok(parent.childNodes.length == parent.childNodes.length,
|
||||
"Check we have the expected number of nodes");
|
||||
info("Expected node count " + expectedNodes.length);
|
||||
info("Actual node count " + expectedNodes.length);
|
||||
|
||||
for (let i = 0; i < expectedNodes.length; i++) {
|
||||
info("Check node " + i);
|
||||
checkNode(expectedNodes[i], parent.childNodes[i]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h2 id="Summary">Summary</h2>
|
||||
|
||||
<p>A summary of the property.</p>
|
||||
|
||||
<h2 id="Syntax">Syntax</h2>
|
||||
|
||||
<pre>/* The part we want */
|
||||
this: is-the-part-we-want;</pre>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<p>This is not the summary or the syntax.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<p>This is not the summary.</p>
|
||||
|
||||
<h2 id="Syntax">Syntax</h2>
|
||||
|
||||
<pre>To be ignored.</pre>
|
||||
|
||||
<pre>/* The part we want */
|
||||
this: is-the-part-we-want;</pre>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h2 id="Summary">Summary</h2>
|
||||
|
||||
<p>A summary of the property.</p>
|
||||
|
||||
<p>This is not the syntax.</p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h2 id="Summary">Summary</h2>
|
||||
|
||||
<p>A summary of the property.</p>
|
||||
|
||||
<h2 id="Syntax">Syntax</h2>
|
||||
|
||||
<pre>The part we should ignore</pre>
|
||||
|
||||
<pre>/* The part we want */
|
||||
this: is-the-part-we-want;</pre>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -99,7 +99,7 @@ const filterList = [
|
||||
];
|
||||
|
||||
// Valid values that shouldn't be parsed for filters.
|
||||
const SPECIAL_VALUES = new Set(["none", "unset", "initial", "inherit", "revert"]);
|
||||
const SPECIAL_VALUES = new Set(["none", "unset", "initial", "inherit"]);
|
||||
|
||||
/**
|
||||
* A CSS Filter editor widget used to add/remove/modify
|
||||
|
||||
@@ -0,0 +1,510 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This file contains functions to retrieve docs content from
|
||||
* MDN (developer.mozilla.org) for particular items, and to display
|
||||
* the content in a tooltip.
|
||||
*
|
||||
* At the moment it only supports fetching content for CSS properties,
|
||||
* but it might support other types of content in the future
|
||||
* (Web APIs, for example).
|
||||
*
|
||||
* It's split into two parts:
|
||||
*
|
||||
* - functions like getCssDocs that just fetch content from MDN,
|
||||
* without any constraints on what to do with the content. If you
|
||||
* want to embed the content in some custom way, use this.
|
||||
*
|
||||
* - the MdnDocsWidget class, that manages and updates a tooltip
|
||||
* document whose content is taken from MDN. If you want to embed
|
||||
* the content in a tooltip, use this in conjunction with Tooltip.js.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const defer = require("devtools/shared/defer");
|
||||
const {getCSSLexer} = require("devtools/shared/css/lexer");
|
||||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const {gDevTools} = require("devtools/client/framework/devtools");
|
||||
|
||||
const {LocalizationHelper} = require("devtools/shared/l10n");
|
||||
const L10N = new LocalizationHelper("devtools/client/locales/inspector.properties");
|
||||
|
||||
const XHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
|
||||
// Parameters for the XHR request
|
||||
// see https://developer.mozilla.org/en-US/docs/MDN/Kuma/API#Document_parameters
|
||||
const XHR_PARAMS = "?raw¯os";
|
||||
// URL for the XHR request
|
||||
var XHR_CSS_URL = "https://developer.mozilla.org/en-US/docs/Web/CSS/";
|
||||
|
||||
// Parameters for the link to MDN in the tooltip, so
|
||||
// so we know which MDN visits come from this feature
|
||||
const PAGE_LINK_PARAMS =
|
||||
"?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default";
|
||||
// URL for the page link omits locale, so a locale-specific page will be loaded
|
||||
var PAGE_LINK_URL = "https://developer.mozilla.org/docs/Web/CSS/";
|
||||
exports.PAGE_LINK_URL = PAGE_LINK_URL;
|
||||
|
||||
const PROPERTY_NAME_COLOR = "theme-fg-color5";
|
||||
const PROPERTY_VALUE_COLOR = "theme-fg-color1";
|
||||
const COMMENT_COLOR = "theme-comment";
|
||||
|
||||
/**
|
||||
* Turns a string containing a series of CSS declarations into
|
||||
* a series of DOM nodes, with classes applied to provide syntax
|
||||
* highlighting.
|
||||
*
|
||||
* It uses the CSS tokenizer to generate a stream of CSS tokens.
|
||||
* https://dxr.mozilla.org/mozilla-central/source/dom/webidl/CSSLexer.webidl
|
||||
* lists all the token types.
|
||||
*
|
||||
* - "whitespace", "comment", and "symbol" tokens are appended as TEXT nodes,
|
||||
* and will inherit the default style for text.
|
||||
*
|
||||
* - "ident" tokens that we think are property names are considered to be
|
||||
* a property name, and are appended as SPAN nodes with a distinct color class.
|
||||
*
|
||||
* - "ident" nodes which we do not think are property names, and nodes
|
||||
* of all other types ("number", "url", "percentage", ...) are considered
|
||||
* to be part of a property value, and are appended as SPAN nodes with
|
||||
* a different color class.
|
||||
*
|
||||
* @param {Document} doc
|
||||
* Used to create nodes.
|
||||
*
|
||||
* @param {String} syntaxText
|
||||
* The CSS input. This is assumed to consist of a series of
|
||||
* CSS declarations, with trailing semicolons.
|
||||
*
|
||||
* @param {DOM node} syntaxSection
|
||||
* This is the parent for the output nodes. Generated nodes
|
||||
* are appended to this as children.
|
||||
*/
|
||||
function appendSyntaxHighlightedCSS(cssText, parentElement) {
|
||||
let doc = parentElement.ownerDocument;
|
||||
let identClass = PROPERTY_NAME_COLOR;
|
||||
let lexer = getCSSLexer(cssText);
|
||||
|
||||
/**
|
||||
* Create a SPAN node with the given text content and class.
|
||||
*/
|
||||
function createStyledNode(textContent, className) {
|
||||
let newNode = doc.createElementNS(XHTML_NS, "span");
|
||||
newNode.classList.add(className);
|
||||
newNode.textContent = textContent;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the symbol is ":", we will expect the next
|
||||
* "ident" token to be part of a property value.
|
||||
*
|
||||
* If the symbol is ";", we will expect the next
|
||||
* "ident" token to be a property name.
|
||||
*/
|
||||
function updateIdentClass(tokenText) {
|
||||
if (tokenText === ":") {
|
||||
identClass = PROPERTY_VALUE_COLOR;
|
||||
} else if (tokenText === ";") {
|
||||
identClass = PROPERTY_NAME_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the appropriate node for this token type.
|
||||
*
|
||||
* If this token is a symbol, also update our expectations
|
||||
* for what the next "ident" token represents.
|
||||
*/
|
||||
function tokenToNode(token, tokenText) {
|
||||
switch (token.tokenType) {
|
||||
case "ident":
|
||||
return createStyledNode(tokenText, identClass);
|
||||
case "symbol":
|
||||
updateIdentClass(tokenText);
|
||||
return doc.createTextNode(tokenText);
|
||||
case "whitespace":
|
||||
return doc.createTextNode(tokenText);
|
||||
case "comment":
|
||||
return createStyledNode(tokenText, COMMENT_COLOR);
|
||||
default:
|
||||
return createStyledNode(tokenText, PROPERTY_VALUE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
let token = lexer.nextToken();
|
||||
while (token) {
|
||||
let tokenText = cssText.slice(token.startOffset, token.endOffset);
|
||||
let newNode = tokenToNode(token, tokenText);
|
||||
parentElement.appendChild(newNode);
|
||||
token = lexer.nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
exports.appendSyntaxHighlightedCSS = appendSyntaxHighlightedCSS;
|
||||
|
||||
/**
|
||||
* Fetch an MDN page.
|
||||
*
|
||||
* @param {string} pageUrl
|
||||
* URL of the page to fetch.
|
||||
*
|
||||
* @return {promise}
|
||||
* The promise is resolved with the page as an XML document.
|
||||
*
|
||||
* The promise is rejected with an error message if
|
||||
* we could not load the page.
|
||||
*/
|
||||
function getMdnPage(pageUrl) {
|
||||
let deferred = defer();
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.addEventListener("load", onLoaded, false);
|
||||
xhr.addEventListener("error", onError, false);
|
||||
|
||||
xhr.open("GET", pageUrl);
|
||||
xhr.responseType = "document";
|
||||
xhr.send();
|
||||
|
||||
function onLoaded(e) {
|
||||
if (xhr.status != 200) {
|
||||
deferred.reject({page: pageUrl, status: xhr.status});
|
||||
} else {
|
||||
deferred.resolve(xhr.responseXML);
|
||||
}
|
||||
}
|
||||
|
||||
function onError(e) {
|
||||
deferred.reject({page: pageUrl, status: xhr.status});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets some docs for the given CSS property.
|
||||
* Loads an MDN page for the property and gets some
|
||||
* information about the property.
|
||||
*
|
||||
* @param {string} cssProperty
|
||||
* The property for which we want docs.
|
||||
*
|
||||
* @return {promise}
|
||||
* The promise is resolved with an object containing:
|
||||
* - summary: a short summary of the property
|
||||
* - syntax: some example syntax
|
||||
*
|
||||
* The promise is rejected with an error message if
|
||||
* we could not load the page.
|
||||
*/
|
||||
function getCssDocs(cssProperty) {
|
||||
let deferred = defer();
|
||||
let pageUrl = XHR_CSS_URL + cssProperty + XHR_PARAMS;
|
||||
|
||||
getMdnPage(pageUrl).then(parseDocsFromResponse, handleRejection);
|
||||
|
||||
function parseDocsFromResponse(responseDocument) {
|
||||
let theDocs = {};
|
||||
theDocs.summary = getSummary(responseDocument);
|
||||
theDocs.syntax = getSyntax(responseDocument);
|
||||
if (theDocs.summary || theDocs.syntax) {
|
||||
deferred.resolve(theDocs);
|
||||
} else {
|
||||
deferred.reject("Couldn't find the docs in the page.");
|
||||
}
|
||||
}
|
||||
|
||||
function handleRejection(e) {
|
||||
deferred.reject(e.status);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
exports.getCssDocs = getCssDocs;
|
||||
|
||||
/**
|
||||
* The MdnDocsWidget is used by tooltip code that needs to display docs
|
||||
* from MDN in a tooltip.
|
||||
*
|
||||
* In the constructor, the widget does some general setup that's not
|
||||
* dependent on the particular item we need docs for.
|
||||
*
|
||||
* After that, when the tooltip code needs to display docs for an item, it
|
||||
* asks the widget to retrieve the docs and update the document with them.
|
||||
*
|
||||
* @param {Element} tooltipContainer
|
||||
* A DOM element where the MdnDocs widget markup should be created.
|
||||
*/
|
||||
function MdnDocsWidget(tooltipContainer) {
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
tooltipContainer.innerHTML =
|
||||
`<header>
|
||||
<h1 class="mdn-property-name theme-fg-color5"></h1>
|
||||
</header>
|
||||
<div class="mdn-property-info">
|
||||
<div class="mdn-summary"></div>
|
||||
<pre class="mdn-syntax devtools-monospace"></pre>
|
||||
</div>
|
||||
<footer>
|
||||
<a class="mdn-visit-page theme-link" href="#">Visit MDN (placeholder)</a>
|
||||
</footer>`;
|
||||
|
||||
// fetch all the bits of the document that we will manipulate later
|
||||
this.elements = {
|
||||
heading: tooltipContainer.querySelector(".mdn-property-name"),
|
||||
summary: tooltipContainer.querySelector(".mdn-summary"),
|
||||
syntax: tooltipContainer.querySelector(".mdn-syntax"),
|
||||
info: tooltipContainer.querySelector(".mdn-property-info"),
|
||||
linkToMdn: tooltipContainer.querySelector(".mdn-visit-page")
|
||||
};
|
||||
|
||||
// get the localized string for the link text
|
||||
this.elements.linkToMdn.textContent = L10N.getStr("docsTooltip.visitMDN");
|
||||
|
||||
// listen for clicks and open in the browser window instead
|
||||
let mainWindow = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
|
||||
this.elements.linkToMdn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
mainWindow.openUILinkIn(e.target.href, "tab");
|
||||
this.emit("visitlink");
|
||||
});
|
||||
}
|
||||
|
||||
exports.MdnDocsWidget = MdnDocsWidget;
|
||||
|
||||
MdnDocsWidget.prototype = {
|
||||
/**
|
||||
* This is called just before the tooltip is displayed, and is
|
||||
* passed the CSS property for which we want to display help.
|
||||
*
|
||||
* Its job is to make sure the document contains the docs
|
||||
* content for that CSS property.
|
||||
*
|
||||
* First, it initializes the document, setting the things it can
|
||||
* set synchronously, resetting the things it needs to get
|
||||
* asynchronously, and making sure the throbber is throbbing.
|
||||
*
|
||||
* Then it tries to get the content asynchronously, updating
|
||||
* the document with the content or with an error message.
|
||||
*
|
||||
* It returns immediately, so the caller can display the tooltip
|
||||
* without waiting for the asynch operation to complete.
|
||||
*
|
||||
* @param {string} propertyName
|
||||
* The name of the CSS property for which we need to display help.
|
||||
*/
|
||||
loadCssDocs: function (propertyName) {
|
||||
/**
|
||||
* Do all the setup we can do synchronously, and get the document in
|
||||
* a state where it can be displayed while we are waiting for the
|
||||
* MDN docs content to be retrieved.
|
||||
*/
|
||||
function initializeDocument(propName) {
|
||||
// set property name heading
|
||||
elements.heading.textContent = propName;
|
||||
|
||||
// set link target
|
||||
elements.linkToMdn.setAttribute("href",
|
||||
PAGE_LINK_URL + propName + PAGE_LINK_PARAMS);
|
||||
|
||||
// clear docs summary and syntax
|
||||
elements.summary.textContent = "";
|
||||
while (elements.syntax.firstChild) {
|
||||
elements.syntax.firstChild.remove();
|
||||
}
|
||||
|
||||
// reset the scroll position
|
||||
elements.info.scrollTop = 0;
|
||||
elements.info.scrollLeft = 0;
|
||||
|
||||
// show the throbber
|
||||
elements.info.classList.add("devtools-throbber");
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called if we successfully got the docs content.
|
||||
* Finishes setting up the tooltip content, and disables the throbber.
|
||||
*/
|
||||
function finalizeDocument({summary, syntax}) {
|
||||
// set docs summary and syntax
|
||||
elements.summary.textContent = summary;
|
||||
appendSyntaxHighlightedCSS(syntax, elements.syntax);
|
||||
|
||||
// hide the throbber
|
||||
elements.info.classList.remove("devtools-throbber");
|
||||
|
||||
deferred.resolve(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called if we failed to get the docs content.
|
||||
* Sets the content to contain an error message, and disables the throbber.
|
||||
*/
|
||||
function gotError(error) {
|
||||
// show error message
|
||||
elements.summary.textContent = L10N.getStr("docsTooltip.loadDocsError");
|
||||
|
||||
// hide the throbber
|
||||
elements.info.classList.remove("devtools-throbber");
|
||||
|
||||
// although gotError is called when there's an error, we have handled
|
||||
// the error, so call resolve not reject.
|
||||
deferred.resolve(this);
|
||||
}
|
||||
|
||||
let deferred = defer();
|
||||
let elements = this.elements;
|
||||
|
||||
initializeDocument(propertyName);
|
||||
getCssDocs(propertyName).then(finalizeDocument, gotError);
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this.elements = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether a node is all whitespace.
|
||||
*
|
||||
* @return {boolean}
|
||||
* True if the node all whitespace, otherwise false.
|
||||
*/
|
||||
function isAllWhitespace(node) {
|
||||
return !(/[^\t\n\r ]/.test(node.textContent));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a node is a comment or whitespace node.
|
||||
*
|
||||
* @return {boolean}
|
||||
* True if the node is a comment node or is all whitespace, otherwise false.
|
||||
*/
|
||||
function isIgnorable(node) {
|
||||
// Comment nodes (8), text nodes (3) or whitespace
|
||||
return (node.nodeType == 8) ||
|
||||
((node.nodeType == 3) && isAllWhitespace(node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next node, skipping comments and whitespace.
|
||||
*
|
||||
* @return {node}
|
||||
* The next sibling node that is not a comment or whitespace, or null if
|
||||
* there isn't one.
|
||||
*/
|
||||
function nodeAfter(sib) {
|
||||
while ((sib = sib.nextSibling)) {
|
||||
if (!isIgnorable(sib)) {
|
||||
return sib;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the argument `node` is a node whose tag is `tagName`.
|
||||
*
|
||||
* @param {node} node
|
||||
* The code to test. May be null.
|
||||
*
|
||||
* @param {string} tagName
|
||||
* The tag name to test against.
|
||||
*
|
||||
* @return {boolean}
|
||||
* True if the node is not null and has the tag name `tagName`,
|
||||
* otherwise false.
|
||||
*/
|
||||
function hasTagName(node, tagName) {
|
||||
return node && node.tagName &&
|
||||
node.tagName.toLowerCase() == tagName.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an MDN page, get the "summary" portion.
|
||||
*
|
||||
* This is the textContent of the first non-whitespace
|
||||
* element in the #Summary section of the document.
|
||||
*
|
||||
* It's expected to be a <P> element.
|
||||
*
|
||||
* @param {Document} mdnDocument
|
||||
* The document in which to look for the "summary" section.
|
||||
*
|
||||
* @return {string}
|
||||
* The summary section as a string, or null if it could not be found.
|
||||
*/
|
||||
function getSummary(mdnDocument) {
|
||||
let summary = mdnDocument.getElementById("Summary");
|
||||
if (!hasTagName(summary, "H2")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let firstParagraph = nodeAfter(summary);
|
||||
if (!hasTagName(firstParagraph, "P")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return firstParagraph.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an MDN page, get the "syntax" portion.
|
||||
*
|
||||
* First we get the #Syntax section of the document. The syntax
|
||||
* section we want is somewhere inside there.
|
||||
*
|
||||
* If the page is in the old structure, then the *first two*
|
||||
* non-whitespace elements in the #Syntax section will be <PRE>
|
||||
* nodes, and the second of these will be the syntax section.
|
||||
*
|
||||
* If the page is in the new structure, then the only the *first*
|
||||
* non-whitespace element in the #Syntax section will be a <PRE>
|
||||
* node, and it will be the syntax section.
|
||||
*
|
||||
* @param {Document} mdnDocument
|
||||
* The document in which to look for the "syntax" section.
|
||||
*
|
||||
* @return {string}
|
||||
* The syntax section as a string, or null if it could not be found.
|
||||
*/
|
||||
function getSyntax(mdnDocument) {
|
||||
let syntax = mdnDocument.getElementById("Syntax");
|
||||
if (!hasTagName(syntax, "H2")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let firstParagraph = nodeAfter(syntax);
|
||||
if (!hasTagName(firstParagraph, "PRE")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let secondParagraph = nodeAfter(firstParagraph);
|
||||
if (hasTagName(secondParagraph, "PRE")) {
|
||||
return secondParagraph.textContent;
|
||||
}
|
||||
return firstParagraph.textContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a different URL for CSS docs pages. Used only for testing.
|
||||
*
|
||||
* @param {string} baseUrl
|
||||
* The baseURL to use.
|
||||
*/
|
||||
function setBaseCssDocsUrl(baseUrl) {
|
||||
PAGE_LINK_URL = baseUrl;
|
||||
XHR_CSS_URL = baseUrl;
|
||||
}
|
||||
|
||||
exports.setBaseCssDocsUrl = setBaseCssDocsUrl;
|
||||
@@ -240,9 +240,6 @@ Spectrum.prototype = {
|
||||
},
|
||||
|
||||
onElementClick: function (e) {
|
||||
if (e.button != 0) {
|
||||
return;
|
||||
}
|
||||
e.stopPropagation();
|
||||
},
|
||||
|
||||
|
||||
@@ -1480,9 +1480,6 @@ Column.prototype = {
|
||||
* for sorting.
|
||||
*/
|
||||
onClick: function (event) {
|
||||
if (event.button != 0) {
|
||||
return;
|
||||
}
|
||||
let target = event.originalTarget;
|
||||
|
||||
if (target.nodeType !== target.ELEMENT_NODE || target == this.column) {
|
||||
|
||||
Loaded 100 of 12325 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user