зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c.
This commit is contained in:
Коммит
f88ec242eb
|
@ -3101,6 +3101,15 @@ HTMLInputElement::Focus(ErrorResult& aError)
|
|||
NS_IMETHODIMP
|
||||
HTMLInputElement::Select()
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_NUMBER) {
|
||||
nsNumberControlFrame* numberControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame());
|
||||
if (numberControlFrame) {
|
||||
return numberControlFrame->HandleSelectCall();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsSingleLineTextControl(false)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ interface nsIMarkupDocumentViewer;
|
|||
|
||||
[ref] native nsIMarkupDocumentViewerTArray(nsTArray<nsCOMPtr<nsIMarkupDocumentViewer> >);
|
||||
|
||||
[scriptable, uuid(6acfadef-22ee-4924-be6c-776e8def6e1b)]
|
||||
[scriptable, uuid(3528324f-f5d3-4724-bd8d-9233a7114112)]
|
||||
interface nsIMarkupDocumentViewer : nsISupports
|
||||
{
|
||||
|
||||
|
@ -64,51 +64,6 @@ interface nsIMarkupDocumentViewer : nsISupports
|
|||
*/
|
||||
void getContentSize(out long width, out long height);
|
||||
|
||||
/**
|
||||
* Options for Bidi presentation.
|
||||
*
|
||||
* Use these attributes to access the individual Bidi options.
|
||||
*/
|
||||
|
||||
/**
|
||||
* bidiTextDirection: the default direction for the layout of bidirectional text.
|
||||
* 1 - left to right
|
||||
* 2 - right to left
|
||||
*/
|
||||
attribute octet bidiTextDirection;
|
||||
|
||||
/**
|
||||
* bidiTextType: the ordering of bidirectional text. This may be either "logical"
|
||||
* or "visual". Logical text will be reordered for presentation using the Unicode
|
||||
* Bidi Algorithm. Visual text will be displayed without reordering.
|
||||
* 1 - the default order for the charset
|
||||
* 2 - logical order
|
||||
* 3 - visual order
|
||||
*/
|
||||
attribute octet bidiTextType;
|
||||
|
||||
/**
|
||||
* bidiNumeral: the type of numerals to display.
|
||||
* 1 - depending on context, default is Arabic numerals
|
||||
* 2 - depending on context, default is Hindi numerals
|
||||
* 3 - Arabic numerals
|
||||
* 4 - Hindi numerals
|
||||
*/
|
||||
attribute octet bidiNumeral;
|
||||
|
||||
/**
|
||||
* bidiSupport: whether to use platform bidi support or Mozilla's bidi support
|
||||
* 1 - Use Mozilla's bidi support
|
||||
* 2 - Use the platform bidi support
|
||||
* 3 - Disable bidi support
|
||||
*/
|
||||
attribute octet bidiSupport;
|
||||
|
||||
/**
|
||||
* Use this attribute to access all the Bidi options in one operation
|
||||
*/
|
||||
attribute uint32_t bidiOptions;
|
||||
|
||||
/** The minimum font size */
|
||||
attribute long minFontSize;
|
||||
|
||||
|
|
|
@ -132,6 +132,14 @@ static_assert(MAX_WORKERS_PER_DOMAIN >= 1,
|
|||
#define PREF_JIT_HARDENING "jit_hardening"
|
||||
#define PREF_GCZEAL "gcZeal"
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
#define DUMP_CONTROLLED_BY_PREF 1
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
#endif
|
||||
|
||||
#define PREF_PROMISE_ENABLED "dom.promise.enabled"
|
||||
#define PREF_WORKERS_LATEST_JS_VERSION "dom.workers.latestJSVersion"
|
||||
|
||||
namespace {
|
||||
|
||||
const uint32_t kNoIndex = uint32_t(-1);
|
||||
|
@ -175,13 +183,6 @@ const char* gStringChars[] = {
|
|||
static_assert(NS_ARRAY_LENGTH(gStringChars) == ID_COUNT,
|
||||
"gStringChars should have the right length.");
|
||||
|
||||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
#define DUMP_CONTROLLED_BY_PREF 1
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
#endif
|
||||
|
||||
#define PREF_PROMISE_ENABLED "dom.promise.enabled"
|
||||
|
||||
class LiteralRebindingCString : public nsDependentCString
|
||||
{
|
||||
public:
|
||||
|
@ -875,9 +876,9 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
|||
|
||||
js::SetCTypesActivityCallback(aRuntime, CTypesActivityCallback);
|
||||
|
||||
JS::ContextOptionsRef(workerCx) = aWorkerPrivate->IsChromeWorker()
|
||||
? settings.chrome.options
|
||||
: settings.content.options;
|
||||
JS::ContextOptionsRef(workerCx) =
|
||||
aWorkerPrivate->IsChromeWorker() ? settings.chrome.contextOptions
|
||||
: settings.content.contextOptions;
|
||||
|
||||
JS_SetJitHardening(aRuntime, settings.jitHardening);
|
||||
|
||||
|
@ -1593,9 +1594,10 @@ RuntimeService::Init()
|
|||
|
||||
// Initialize JSSettings.
|
||||
if (!sDefaultJSSettings.gcSettings[0].IsSet()) {
|
||||
sDefaultJSSettings.chrome.options = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.contextOptions = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.maxScriptRuntime = -1;
|
||||
sDefaultJSSettings.content.options = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.chrome.compartmentOptions.setVersion(JSVERSION_LATEST);
|
||||
sDefaultJSSettings.content.contextOptions = kRequiredJSContextOptions;
|
||||
sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC;
|
||||
#ifdef JS_GC_ZEAL
|
||||
sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ;
|
||||
|
@ -1670,21 +1672,25 @@ RuntimeService::Init()
|
|||
#endif
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr))) {
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
JSVersionChanged,
|
||||
PREF_WORKERS_LATEST_JS_VERSION,
|
||||
nullptr))) {
|
||||
NS_WARNING("Failed to register pref callbacks!");
|
||||
}
|
||||
|
||||
|
@ -1834,19 +1840,24 @@ RuntimeService::Cleanup()
|
|||
NS_ASSERTION(!mWindowMap.Count(), "All windows should have been released!");
|
||||
|
||||
if (mObserved) {
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
if (NS_FAILED(Preferences::UnregisterCallback(JSVersionChanged,
|
||||
PREF_WORKERS_LATEST_JS_VERSION,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::UnregisterCallback(WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
#ifdef JS_GC_ZEAL
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
|
@ -2224,8 +2235,8 @@ void
|
|||
RuntimeService::UpdateAllWorkerJSContextOptions()
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdateJSContextOptions,
|
||||
sDefaultJSSettings.content.options,
|
||||
sDefaultJSSettings.chrome.options);
|
||||
sDefaultJSSettings.content.contextOptions,
|
||||
sDefaultJSSettings.chrome.contextOptions);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2333,3 +2344,13 @@ RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
|
|||
rts->UpdateAllWorkerPreference(key, sDefaultPreferences[key]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::JSVersionChanged(const char* /* aPrefName */, void* /* aClosure */)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
bool useLatest = Preferences::GetBool(PREF_WORKERS_LATEST_JS_VERSION, false);
|
||||
JS::CompartmentOptions& options = sDefaultJSSettings.content.compartmentOptions;
|
||||
options.setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT);
|
||||
}
|
||||
|
|
|
@ -194,8 +194,8 @@ public:
|
|||
const JS::ContextOptions& aChromeOptions)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
sDefaultJSSettings.content.options = aContentOptions;
|
||||
sDefaultJSSettings.chrome.options = aChromeOptions;
|
||||
sDefaultJSSettings.content.contextOptions = aContentOptions;
|
||||
sDefaultJSSettings.chrome.contextOptions = aChromeOptions;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -295,6 +295,9 @@ private:
|
|||
|
||||
static void
|
||||
WorkerPrefChanged(const char* aPrefName, void* aClosure);
|
||||
|
||||
static void
|
||||
JSVersionChanged(const char* aPrefName, void* aClosure);
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
|
|
@ -2816,16 +2816,17 @@ WorkerPrivateParent<Derived>::GetInnerWindowId()
|
|||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdateJSContextOptions(JSContext* aCx,
|
||||
const JS::ContextOptions& aContentOptions,
|
||||
const JS::ContextOptions& aChromeOptions)
|
||||
WorkerPrivateParent<Derived>::UpdateJSContextOptions(
|
||||
JSContext* aCx,
|
||||
const JS::ContextOptions& aContentOptions,
|
||||
const JS::ContextOptions& aChromeOptions)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mJSSettings.content.options = aContentOptions;
|
||||
mJSSettings.chrome.options = aChromeOptions;
|
||||
mJSSettings.content.contextOptions = aContentOptions;
|
||||
mJSSettings.chrome.contextOptions = aChromeOptions;
|
||||
}
|
||||
|
||||
nsRefPtr<UpdateJSContextOptionsRunnable> runnable =
|
||||
|
@ -5449,14 +5450,7 @@ WorkerPrivate::CreateGlobalScope(JSContext* aCx)
|
|||
globalScope = new DedicatedWorkerGlobalScope(this);
|
||||
}
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
if (IsChromeWorker()) {
|
||||
options.setVersion(JSVERSION_LATEST);
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx,
|
||||
globalScope->WrapGlobalObject(aCx, options,
|
||||
GetWorkerPrincipal()));
|
||||
JS::Rooted<JSObject*> global(aCx, globalScope->WrapGlobalObject(aCx));
|
||||
NS_ENSURE_TRUE(global, nullptr);
|
||||
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
|
|
|
@ -377,7 +377,6 @@ private:
|
|||
ErrorResult& aRv);
|
||||
|
||||
public:
|
||||
|
||||
virtual JSObject*
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -696,6 +695,14 @@ public:
|
|||
aSettings = mJSSettings;
|
||||
}
|
||||
|
||||
void
|
||||
CopyJSCompartmentOptions(JS::CompartmentOptions& aOptions)
|
||||
{
|
||||
mozilla::MutexAutoLock lock(mMutex);
|
||||
aOptions = IsChromeWorker() ? mJSSettings.chrome.compartmentOptions
|
||||
: mJSSettings.content.compartmentOptions;
|
||||
}
|
||||
|
||||
// The ability to be a chrome worker is orthogonal to the type of
|
||||
// worker [Dedicated|Shared].
|
||||
bool
|
||||
|
|
|
@ -6,11 +6,6 @@
|
|||
|
||||
#include "WorkerScope.h"
|
||||
|
||||
#include "Location.h"
|
||||
#include "Navigator.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
#include "mozilla/dom/DedicatedWorkerGlobalScopeBinding.h"
|
||||
|
@ -20,7 +15,12 @@
|
|||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#include "RuntimeService.h" // For WorkersDumpEnabled().
|
||||
#include "Location.h"
|
||||
#include "Navigator.h"
|
||||
#include "Principal.h"
|
||||
#include "RuntimeService.h"
|
||||
#include "ScriptLoader.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
#define UNWRAP_WORKER_OBJECT(Interface, obj, value) \
|
||||
UnwrapObject<prototypes::id::Interface##_workers, \
|
||||
|
@ -261,19 +261,20 @@ DedicatedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
|
|||
}
|
||||
|
||||
JSObject*
|
||||
DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
|
||||
JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal)
|
||||
DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker());
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
mWorkerPrivate->CopyJSCompartmentOptions(options);
|
||||
|
||||
// We're wrapping the global, so the scope is undefined.
|
||||
JS::Rooted<JSObject*> scope(aCx);
|
||||
|
||||
return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, scope, this,
|
||||
this, aOptions,
|
||||
aPrincipal);
|
||||
this, options,
|
||||
GetWorkerPrincipal());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -301,18 +302,20 @@ SharedWorkerGlobalScope::Visible(JSContext* aCx, JSObject* aObj)
|
|||
}
|
||||
|
||||
JSObject*
|
||||
SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
|
||||
JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal)
|
||||
SharedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx)
|
||||
{
|
||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(mWorkerPrivate->IsSharedWorker());
|
||||
|
||||
JS::CompartmentOptions options;
|
||||
mWorkerPrivate->CopyJSCompartmentOptions(options);
|
||||
|
||||
// We're wrapping the global, so the scope is undefined.
|
||||
JS::Rooted<JSObject*> scope(aCx);
|
||||
|
||||
return SharedWorkerGlobalScopeBinding_workers::Wrap(aCx, scope, this, this,
|
||||
aOptions, aPrincipal);
|
||||
options,
|
||||
GetWorkerPrincipal());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -40,8 +40,7 @@ public:
|
|||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
|
||||
|
||||
virtual JSObject*
|
||||
WrapGlobalObject(JSContext* aCx, JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal) = 0;
|
||||
WrapGlobalObject(JSContext* aCx) = 0;
|
||||
|
||||
virtual JSObject*
|
||||
GetGlobalJSObject(void) MOZ_OVERRIDE
|
||||
|
@ -115,8 +114,7 @@ public:
|
|||
Visible(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
virtual JSObject*
|
||||
WrapGlobalObject(JSContext* aCx, JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal) MOZ_OVERRIDE;
|
||||
WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void
|
||||
PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
|
@ -139,8 +137,7 @@ public:
|
|||
Visible(JSContext* aCx, JSObject* aObj);
|
||||
|
||||
virtual JSObject*
|
||||
WrapGlobalObject(JSContext* aCx, JS::CompartmentOptions& aOptions,
|
||||
JSPrincipals* aPrincipal) MOZ_OVERRIDE;
|
||||
WrapGlobalObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
void GetName(DOMString& aName) const {
|
||||
aName.AsAString() = mName;
|
||||
|
|
|
@ -95,11 +95,12 @@ struct JSSettings
|
|||
// Settings that change based on chrome/content context.
|
||||
struct JSContentChromeSettings
|
||||
{
|
||||
JS::ContextOptions options;
|
||||
JS::ContextOptions contextOptions;
|
||||
JS::CompartmentOptions compartmentOptions;
|
||||
int32_t maxScriptRuntime;
|
||||
|
||||
JSContentChromeSettings()
|
||||
: options(), maxScriptRuntime(0)
|
||||
: contextOptions(), compartmentOptions(), maxScriptRuntime(0)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
onmessage = function(evt) {
|
||||
if (evt.data != 0) {
|
||||
var worker = new Worker('jsversion_worker.js');
|
||||
worker.onmessage = function(evt) {
|
||||
postMessage(evt.data);
|
||||
}
|
||||
|
||||
worker.postMessage(evt.data - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
let foo = 'bar';
|
||||
postMessage(true);
|
||||
}
|
|
@ -56,6 +56,7 @@ support-files =
|
|||
xhr_implicit_cancel_worker.js
|
||||
xhr_worker.js
|
||||
url_exceptions_worker.js
|
||||
jsversion_worker.js
|
||||
|
||||
[test_404.html]
|
||||
[test_atob.html]
|
||||
|
@ -113,3 +114,4 @@ support-files =
|
|||
[test_xhr_system.html]
|
||||
[test_xhr_system.js]
|
||||
[test_url_exceptions.html]
|
||||
[test_jsversion.html]
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for JSVersion in workers - Bug 487070</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" language="javascript">
|
||||
|
||||
var gExpectedError = false;
|
||||
|
||||
onerror = function(evt) {
|
||||
ok(gExpectedError, "Error expected!");
|
||||
runTest();
|
||||
}
|
||||
|
||||
function doMagic() {
|
||||
var worker = new Worker('jsversion_worker.js');
|
||||
worker.onmessage = function(evt) {
|
||||
ok(evt.data, 'All the tests passed');
|
||||
runTest();
|
||||
}
|
||||
worker.postMessage(1);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
// No custom version
|
||||
function() {
|
||||
gExpectedError = true;
|
||||
SpecialPowers.pushPrefEnv({"set":[['dom.workers.latestJSVersion', false]]},
|
||||
function() { doMagic(true); });
|
||||
},
|
||||
|
||||
// Enable latest JS Version
|
||||
function() {
|
||||
gExpectedError = false;
|
||||
SpecialPowers.pushPrefEnv({"set":[['dom.workers.latestJSVersion', true]]},
|
||||
function() { doMagic(false); });
|
||||
}
|
||||
];
|
||||
|
||||
function runTest() {
|
||||
if (!tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var test = tests.shift();
|
||||
test();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runTest();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -250,13 +250,15 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
|
|||
size,
|
||||
gfx::ContentForFormat(aSurface->GetFormat()),
|
||||
WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
|
||||
FlagsToGLFlags(aFlags));
|
||||
FlagsToGLFlags(aFlags),
|
||||
SurfaceFormatToImageFormat(aSurface->GetFormat()));
|
||||
} else {
|
||||
mTexImage = CreateBasicTextureImage(mGL,
|
||||
size,
|
||||
gfx::ContentForFormat(aSurface->GetFormat()),
|
||||
WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
|
||||
FlagsToGLFlags(aFlags));
|
||||
FlagsToGLFlags(aFlags),
|
||||
SurfaceFormatToImageFormat(aSurface->GetFormat()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ gfxDWriteFontFamily::LocalizedName(nsAString &aLocalizedName)
|
|||
}
|
||||
UINT32 idx = 0;
|
||||
BOOL exists;
|
||||
hr = names->FindLocaleName(localeName.BeginReading(),
|
||||
hr = names->FindLocaleName(localeName.get(),
|
||||
&idx,
|
||||
&exists);
|
||||
if (FAILED(hr)) {
|
||||
|
|
|
@ -44,8 +44,9 @@ gfxDWriteShaper::ShapeText(gfxContext *aContext,
|
|||
* in a single call, so we cannot exceed that limit.
|
||||
*/
|
||||
UINT32 length = aLength;
|
||||
char16ptr_t text = aText;
|
||||
|
||||
TextAnalysis analysis(aText, length, nullptr, readingDirection);
|
||||
TextAnalysis analysis(text, length, nullptr, readingDirection);
|
||||
TextAnalysis::Run *runHead;
|
||||
hr = analysis.GenerateResults(analyzer, &runHead);
|
||||
|
||||
|
@ -80,7 +81,7 @@ trymoreglyphs:
|
|||
|
||||
UINT32 actualGlyphs;
|
||||
|
||||
hr = analyzer->GetGlyphs(aText, length,
|
||||
hr = analyzer->GetGlyphs(text, length,
|
||||
font->GetFontFace(), FALSE,
|
||||
readingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT,
|
||||
&runHead->mScript, nullptr, nullptr, nullptr, nullptr, 0,
|
||||
|
@ -107,7 +108,7 @@ trymoreglyphs:
|
|||
|
||||
if (!static_cast<gfxDWriteFont*>(mFont)->mUseSubpixelPositions) {
|
||||
hr = analyzer->GetGdiCompatibleGlyphPlacements(
|
||||
aText,
|
||||
text,
|
||||
clusters.Elements(),
|
||||
textProperties.Elements(),
|
||||
length,
|
||||
|
@ -129,7 +130,7 @@ trymoreglyphs:
|
|||
advances.Elements(),
|
||||
glyphOffsets.Elements());
|
||||
} else {
|
||||
hr = analyzer->GetGlyphPlacements(aText,
|
||||
hr = analyzer->GetGlyphPlacements(text,
|
||||
clusters.Elements(),
|
||||
textProperties.Elements(),
|
||||
length,
|
||||
|
|
|
@ -90,7 +90,7 @@ gfxGDIFont::CopyWithAntialiasOption(AntialiasOption anAAOption)
|
|||
|
||||
static bool
|
||||
UseUniscribe(gfxShapedText *aShapedText,
|
||||
const PRUnichar *aText,
|
||||
char16ptr_t aText,
|
||||
uint32_t aLength)
|
||||
{
|
||||
uint32_t flags = aShapedText->Flags();
|
||||
|
|
|
@ -323,7 +323,7 @@ GDIFontEntry::TestCharacterMap(uint32_t aCh)
|
|||
HFONT hfont = font->GetHFONT();
|
||||
HFONT oldFont = (HFONT)SelectObject(dc, hfont);
|
||||
|
||||
PRUnichar str[1] = { (PRUnichar)aCh };
|
||||
wchar_t str[1] = { aCh };
|
||||
WORD glyph[1];
|
||||
|
||||
bool hasGlyph = false;
|
||||
|
|
|
@ -31,7 +31,7 @@ gfxGDIShaper::ShapeText(gfxContext *aContext,
|
|||
}
|
||||
WORD *glyphs = glyphArray.Elements();
|
||||
|
||||
DWORD ret = ::GetGlyphIndicesW(dc, aText, length,
|
||||
DWORD ret = ::GetGlyphIndicesW(dc, char16ptr_t(aText), length,
|
||||
glyphs, GGI_MARK_NONEXISTING_GLYPHS);
|
||||
if (ret == GDI_ERROR) {
|
||||
return false;
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
HRESULT rv;
|
||||
HDC shapeDC = nullptr;
|
||||
|
||||
const PRUnichar *str = mAlternativeString ? mAlternativeString : mItemString;
|
||||
char16ptr_t str = mAlternativeString ? mAlternativeString : mItemString;
|
||||
|
||||
mScriptItem->a.fLogicalOrder = true;
|
||||
SCRIPT_ANALYSIS sa = mScriptItem->a;
|
||||
|
@ -417,7 +417,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
const PRUnichar *mString;
|
||||
char16ptr_t mString;
|
||||
gfxShapedText *mShapedText;
|
||||
uint32_t mOffset;
|
||||
uint32_t mLength;
|
||||
|
|
|
@ -1118,7 +1118,7 @@ gfxWindowsPlatform::UseClearTypeAlways()
|
|||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::GetDLLVersion(const PRUnichar *aDLLPath, nsAString& aVersion)
|
||||
gfxWindowsPlatform::GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion)
|
||||
{
|
||||
DWORD versInfoSize, vers[4] = {0};
|
||||
// version info not available case
|
||||
|
|
|
@ -238,7 +238,7 @@ public:
|
|||
bool UseClearTypeForDownloadableFonts();
|
||||
bool UseClearTypeAlways();
|
||||
|
||||
static void GetDLLVersion(const PRUnichar *aDLLPath, nsAString& aVersion);
|
||||
static void GetDLLVersion(char16ptr_t aDLLPath, nsAString& aVersion);
|
||||
|
||||
// returns ClearType tuning information for each display
|
||||
static void GetCleartypeParams(nsTArray<ClearTypeParameterInfo>& aParams);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "vm/ArgumentsObject.h"
|
||||
#include "vm/ForkJoin.h"
|
||||
|
||||
#include "jsgcinlines.h"
|
||||
|
@ -64,7 +65,11 @@ StoreBuffer::WholeCellEdges::mark(JSTracer *trc)
|
|||
JS_ASSERT(tenured->isTenured());
|
||||
JSGCTraceKind kind = GetGCThingTraceKind(tenured);
|
||||
if (kind <= JSTRACE_OBJECT) {
|
||||
MarkChildren(trc, static_cast<JSObject *>(tenured));
|
||||
JSObject *object = static_cast<JSObject *>(tenured);
|
||||
if (object->is<ArgumentsObject>())
|
||||
ArgumentsObject::trace(trc, object);
|
||||
else
|
||||
MarkChildren(trc, object);
|
||||
return;
|
||||
}
|
||||
#ifdef JS_ION
|
||||
|
|
|
@ -2343,6 +2343,26 @@ BaselineCompiler::emitFormalArgAccess(uint32_t arg, bool get)
|
|||
} else {
|
||||
masm.patchableCallPreBarrier(argAddr, MIRType_Value);
|
||||
storeValue(frame.peek(-1), argAddr, R0);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// Fully sync the stack if post-barrier is needed.
|
||||
frame.syncStack(0);
|
||||
|
||||
// Reload the arguments object
|
||||
Register reg = R2.scratchReg();
|
||||
masm.loadPtr(Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfArgsObj()), reg);
|
||||
|
||||
Nursery &nursery = cx->runtime()->gcNursery;
|
||||
Label skipBarrier;
|
||||
Label isTenured;
|
||||
masm.branchPtr(Assembler::Below, reg, ImmWord(nursery.start()), &isTenured);
|
||||
masm.branchPtr(Assembler::Below, reg, ImmWord(nursery.heapEnd()), &skipBarrier);
|
||||
|
||||
masm.bind(&isTenured);
|
||||
masm.call(&postBarrierSlot_);
|
||||
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
}
|
||||
|
||||
masm.bind(&done);
|
||||
|
|
|
@ -9111,7 +9111,10 @@ IonBuilder::jsop_setarg(uint32_t arg)
|
|||
// If an arguments object is in use, and it aliases formals, then all SETARGs
|
||||
// must go through the arguments object.
|
||||
if (info().argsObjAliasesFormals()) {
|
||||
current->add(MSetArgumentsObjectArg::New(alloc(), current->argumentsObject(), GET_SLOTNO(pc), val));
|
||||
if (NeedsPostBarrier(info(), val))
|
||||
current->add(MPostWriteBarrier::New(alloc(), current->argumentsObject(), val));
|
||||
current->add(MSetArgumentsObjectArg::New(alloc(), current->argumentsObject(),
|
||||
GET_SLOTNO(pc), val));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3752,6 +3752,10 @@ nsCSSFrameConstructor::ConstructFrameFromItemInternal(FrameConstructionItem& aIt
|
|||
((bits & FCDATA_IS_LINE_PARTICIPANT) != 0),
|
||||
"Incorrectly set FCDATA_IS_LINE_PARTICIPANT bits");
|
||||
|
||||
if (aItem.mIsAnonymousContentCreatorContent) {
|
||||
primaryFrame->AddStateBits(NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT);
|
||||
}
|
||||
|
||||
// Even if mCreatingExtraFrames is set, we may need to SetPrimaryFrame for
|
||||
// generated content that doesn't have one yet. Note that we have to examine
|
||||
// the frame bit, because by this point mIsGeneratedContent has been cleared
|
||||
|
@ -3808,6 +3812,7 @@ nsCSSFrameConstructor::CreateAnonymousFrames(nsFrameConstructorState& aState,
|
|||
if (newFrame) {
|
||||
NS_ASSERTION(content->GetPrimaryFrame(),
|
||||
"Content must have a primary frame now");
|
||||
newFrame->AddStateBits(NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT);
|
||||
aChildItems.AddChild(newFrame);
|
||||
}
|
||||
else {
|
||||
|
@ -5357,6 +5362,8 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
|
|||
|
||||
item->mIsText = isText;
|
||||
item->mIsGeneratedContent = isGeneratedContent;
|
||||
item->mIsAnonymousContentCreatorContent =
|
||||
aFlags & ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT;
|
||||
if (isGeneratedContent) {
|
||||
NS_ADDREF(item->mContent);
|
||||
}
|
||||
|
@ -8172,6 +8179,12 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
|||
newFrame->AddStateBits(NS_FRAME_GENERATED_CONTENT);
|
||||
}
|
||||
|
||||
// A continuation of nsIAnonymousContentCreator content is also
|
||||
// nsIAnonymousContentCreator created content
|
||||
if (aFrame->GetStateBits() & NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT) {
|
||||
newFrame->AddStateBits(NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT);
|
||||
}
|
||||
|
||||
// A continuation of an out-of-flow is also an out-of-flow
|
||||
if (aFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
|
||||
newFrame->AddStateBits(NS_FRAME_OUT_OF_FLOW);
|
||||
|
@ -8631,6 +8644,27 @@ nsCSSFrameConstructor::RecreateFramesForContent(nsIContent* aContent,
|
|||
return RecreateFramesForContent(nonGeneratedAncestor->GetContent(), aAsyncInsert);
|
||||
}
|
||||
|
||||
if (frame->GetStateBits() & NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT) {
|
||||
// Recreate the frames for the entire nsIAnonymousContentCreator tree
|
||||
// since |frame| or one of its descendants may need an nsStyleContext
|
||||
// that associates it to a CSS pseudo-element, and only the
|
||||
// nsIAnonymousContentCreator that created this content knows how to make
|
||||
// that happen.
|
||||
nsIAnonymousContentCreator* acc = nullptr;
|
||||
nsIFrame* ancestor = frame->GetParent();
|
||||
while (!(acc = do_QueryFrame(ancestor))) {
|
||||
ancestor = ancestor->GetParent();
|
||||
}
|
||||
NS_ASSERTION(acc, "Where is the nsIAnonymousContentCreator? We may fail "
|
||||
"to recreate its content correctly");
|
||||
// nsSVGUseFrame is special, and we know this is unnecessary for it.
|
||||
if (ancestor->GetType() != nsGkAtoms::svgUseFrame) {
|
||||
NS_ASSERTION(aContent->IsInNativeAnonymousSubtree(),
|
||||
"Why is NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT set?");
|
||||
return RecreateFramesForContent(ancestor->GetContent(), aAsyncInsert);
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* parent = frame->GetParent();
|
||||
nsIContent* parentContent = parent ? parent->GetContent() : nullptr;
|
||||
// If the parent frame is a leaf then the subsequent insert will fail to
|
||||
|
@ -9207,7 +9241,8 @@ nsCSSFrameConstructor::AddFCItemsForAnonymousContent(
|
|||
anonChildren = &aAnonymousItems[i].mChildren;
|
||||
}
|
||||
|
||||
uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK | aExtraFlags;
|
||||
uint32_t flags = ITEM_ALLOW_XBL_BASE | ITEM_ALLOW_PAGE_BREAK |
|
||||
ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT | aExtraFlags;
|
||||
|
||||
AddFrameConstructionItemsInternal(aState, content, aFrame,
|
||||
content->Tag(), content->GetNameSpaceID(),
|
||||
|
|
|
@ -908,6 +908,7 @@ private:
|
|||
mPendingBinding(aPendingBinding), mStyleContext(aStyleContext),
|
||||
mSuppressWhiteSpaceOptimizations(aSuppressWhiteSpaceOptimizations),
|
||||
mIsText(false), mIsGeneratedContent(false),
|
||||
mIsAnonymousContentCreatorContent(false),
|
||||
mIsRootPopupgroup(false), mIsAllInline(false), mIsBlock(false),
|
||||
mHasInlineEnds(false), mIsPopup(false),
|
||||
mIsLineParticipant(false), mIsForSVGAElement(false)
|
||||
|
@ -975,6 +976,8 @@ private:
|
|||
// Whether this is a generated content container.
|
||||
// If it is, mContent is a strong pointer.
|
||||
bool mIsGeneratedContent;
|
||||
// Whether this is an item for nsIAnonymousContentCreator content.
|
||||
bool mIsAnonymousContentCreatorContent;
|
||||
// Whether this is an item for the root popupgroup.
|
||||
bool mIsRootPopupgroup;
|
||||
// Whether construction from this item will create only frames that are
|
||||
|
@ -1164,6 +1167,8 @@ private:
|
|||
#define ITEM_IS_WITHIN_SVG_TEXT 0x8
|
||||
/* The item allows items to be created for SVG <textPath> children. */
|
||||
#define ITEM_ALLOWS_TEXT_PATH_CHILD 0x10
|
||||
/* The item is content created by an nsIAnonymousContentCreator frame */
|
||||
#define ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT 0x20
|
||||
// The guts of AddFrameConstructionItems
|
||||
// aParentFrame might be null. If it is, that means it was an
|
||||
// inline frame.
|
||||
|
|
|
@ -107,7 +107,6 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset
|
|||
#include "nsIDOMEventListener.h"
|
||||
#include "nsISelectionController.h"
|
||||
|
||||
#include "nsBidiUtils.h"
|
||||
#include "nsISHEntry.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsISHistoryInternal.h"
|
||||
|
@ -3108,118 +3107,6 @@ nsDocumentViewer::SetHintCharacterSet(const nsACString& aHintCharacterSet)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
SetChildBidiOptions(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
||||
{
|
||||
aChild->SetBidiOptions(NS_PTR_TO_INT32(aClosure));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::SetBidiTextDirection(uint8_t aTextDirection)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
GetBidiOptions(&bidiOptions);
|
||||
SET_BIDI_OPTION_DIRECTION(bidiOptions, aTextDirection);
|
||||
SetBidiOptions(bidiOptions);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::GetBidiTextDirection(uint8_t* aTextDirection)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
if (aTextDirection) {
|
||||
GetBidiOptions(&bidiOptions);
|
||||
*aTextDirection = GET_BIDI_OPTION_DIRECTION(bidiOptions);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::SetBidiTextType(uint8_t aTextType)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
GetBidiOptions(&bidiOptions);
|
||||
SET_BIDI_OPTION_TEXTTYPE(bidiOptions, aTextType);
|
||||
SetBidiOptions(bidiOptions);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::GetBidiTextType(uint8_t* aTextType)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
if (aTextType) {
|
||||
GetBidiOptions(&bidiOptions);
|
||||
*aTextType = GET_BIDI_OPTION_TEXTTYPE(bidiOptions);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::SetBidiNumeral(uint8_t aNumeral)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
GetBidiOptions(&bidiOptions);
|
||||
SET_BIDI_OPTION_NUMERAL(bidiOptions, aNumeral);
|
||||
SetBidiOptions(bidiOptions);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::GetBidiNumeral(uint8_t* aNumeral)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
if (aNumeral) {
|
||||
GetBidiOptions(&bidiOptions);
|
||||
*aNumeral = GET_BIDI_OPTION_NUMERAL(bidiOptions);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::SetBidiSupport(uint8_t aSupport)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
GetBidiOptions(&bidiOptions);
|
||||
SET_BIDI_OPTION_SUPPORT(bidiOptions, aSupport);
|
||||
SetBidiOptions(bidiOptions);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::GetBidiSupport(uint8_t* aSupport)
|
||||
{
|
||||
uint32_t bidiOptions;
|
||||
|
||||
if (aSupport) {
|
||||
GetBidiOptions(&bidiOptions);
|
||||
*aSupport = GET_BIDI_OPTION_SUPPORT(bidiOptions);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::SetBidiOptions(uint32_t aBidiOptions)
|
||||
{
|
||||
if (mPresContext) {
|
||||
mPresContext->SetBidi(aBidiOptions, true); // could cause reflow
|
||||
}
|
||||
// now set bidi on all children of mContainer
|
||||
CallChildren(SetChildBidiOptions, NS_INT32_TO_PTR(aBidiOptions));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::GetBidiOptions(uint32_t* aBidiOptions)
|
||||
{
|
||||
if (aBidiOptions) {
|
||||
if (mPresContext) {
|
||||
*aBidiOptions = mPresContext->GetBidi();
|
||||
}
|
||||
else
|
||||
*aBidiOptions = IBMBIDI_DEFAULT_BIDI_OPTIONS;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
AppendChildSubtree(nsIMarkupDocumentViewer* aChild, void* aClosure)
|
||||
{
|
||||
|
|
|
@ -488,6 +488,12 @@ nsNumberControlFrame::HandleFocusEvent(WidgetEvent* aEvent)
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::HandleSelectCall()
|
||||
{
|
||||
return HTMLInputElement::FromContent(mTextField)->Select();
|
||||
}
|
||||
|
||||
#define STYLES_DISABLING_NATIVE_THEMING \
|
||||
NS_AUTHOR_SPECIFIED_BACKGROUND | \
|
||||
NS_AUTHOR_SPECIFIED_PADDING | \
|
||||
|
|
|
@ -129,6 +129,11 @@ public:
|
|||
|
||||
void HandleFocusEvent(WidgetEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Our element had HTMLInputElement::Select() called on it.
|
||||
*/
|
||||
nsresult HandleSelectCall();
|
||||
|
||||
virtual Element* GetPseudoElement(nsCSSPseudoElements::Type aType) MOZ_OVERRIDE;
|
||||
|
||||
bool ShouldUseNativeStyleForSpinner() const;
|
||||
|
|
|
@ -5306,6 +5306,9 @@ nsIFrame::ListGeneric(FILE* out, int32_t aIndent, uint32_t aFlags) const
|
|||
pseudoTag->ToString(atomString);
|
||||
fprintf(out, "%s", NS_LossyConvertUTF16toASCII(atomString).get());
|
||||
}
|
||||
if (mParent && mStyleContext->GetParent() != mParent->StyleContext()) {
|
||||
fprintf(out, ",parent=%p", mStyleContext->GetParent());
|
||||
}
|
||||
}
|
||||
fputs("]", out);
|
||||
}
|
||||
|
|
|
@ -143,6 +143,9 @@ typedef uint64_t nsFrameState;
|
|||
// continuation, e.g. a bidi continuation.
|
||||
#define NS_FRAME_IS_FLUID_CONTINUATION NS_FRAME_STATE_BIT(2)
|
||||
|
||||
// For nsIAnonymousContentCreator content that's created using ContentInfo.
|
||||
#define NS_FRAME_ANONYMOUSCONTENTCREATOR_CONTENT NS_FRAME_STATE_BIT(3)
|
||||
|
||||
// If this bit is set, then a reference to the frame is being held
|
||||
// elsewhere. The frame may want to send a notification when it is
|
||||
// destroyed to allow these references to be cleared.
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
|
||||
input {
|
||||
font-size: 30pt;
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<input type="number">
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<style>
|
||||
|
||||
input {
|
||||
font-size: 30pt;
|
||||
background-color: lightblue;
|
||||
}
|
||||
|
||||
</style>
|
||||
<script>
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.body.style.backgroundImage = "none";
|
||||
}, false);
|
||||
|
||||
function PostRebuildAllStyleDataEvent() {
|
||||
// trigger http://mxr.mozilla.org/mozilla-central/source/layout/base/RestyleManager.cpp?rev=a8b06549f680#1490
|
||||
var m = document.createElementNS("http://www.w3.org/1998/Math/MathML", "math");
|
||||
document.head.appendChild(m);
|
||||
document.head.removeChild(m);
|
||||
}
|
||||
|
||||
function reframe() {
|
||||
PostRebuildAllStyleDataEvent();
|
||||
document.documentElement.className = "";
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", function() {
|
||||
// Calling reframe now would be too early to reproduce the bug that we're
|
||||
// testing for. Note that in the event that we start faling this test this
|
||||
// timeout may make the failure seem intermittent when in fact we would
|
||||
// always fail if it was longer.
|
||||
setTimeout(reframe, 500);
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input type="number">
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", function() {
|
||||
document.getElementById("i").select();
|
||||
document.documentElement.className = "";
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input id="i" type="text" value="123">
|
||||
<!-- div to cover spin box area -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", function() {
|
||||
document.getElementById("i").select();
|
||||
document.documentElement.className = "";
|
||||
}, false);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<input id="i" type="number" value="123">
|
||||
<!-- div to cover spin box area -->
|
||||
<div style="display:block; position:absolute; background-color:black; width:200px; height:100px; top:0px; left:100px;">
|
||||
</body>
|
||||
</html>
|
|
@ -23,6 +23,14 @@ fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),64,4) fuzzy-if(cocoaWidget,63
|
|||
# focus
|
||||
needs-focus == focus-handling.html focus-handling-ref.html
|
||||
|
||||
# select
|
||||
== number-selected.html number-selected-ref.html
|
||||
|
||||
# pseudo-elements not usable from content:
|
||||
== number-pseudo-elements.html number-pseudo-elements-ref.html
|
||||
|
||||
# check that if the anonymous text control is reframed, we reframe the whole
|
||||
# number control (the fuzzy is for the top-right and bottom-left of the border
|
||||
# bevel which gets slightly different antialiasing after invalidation):
|
||||
fuzzy(128,4) == number-reframe-anon-text-field.html number-reframe-anon-text-field-ref.html
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
width: 50px;
|
||||
height: 200px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
}
|
||||
.hidden > .bigItem {
|
||||
/* To match the testcase's "overflow:hidden"-cropped flex item, we
|
||||
just use a smaller height that exactly fits the space remaining
|
||||
in our container, after wrapping */
|
||||
height: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- This testcase checks that we honor "flex-wrap" on a horizontal
|
||||
flex container that has "overflow:hidden". We use a large flex item,
|
||||
large enough that it overflows the container in the cross axis, to be
|
||||
sure that "overflow: hidden" is actually applying. -->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: Testing 'overflow' property on a horizontal flex container, with 'flex-wrap: wrap'</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#flex-wrap-property">
|
||||
<link rel="match" href="flexbox-overflow-horiz-4-ref.html">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
width: 50px;
|
||||
height: 200px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 50px;
|
||||
height: 20px;
|
||||
}
|
||||
.hidden { overflow: hidden }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: space-around;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
flex: none; /* prevent shrinking (so we can intentionally overflow) */
|
||||
width: 72px;
|
||||
height: 20px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.hidden > .bigItem {
|
||||
/* To match the testcase's "overflow:hidden"-cropped flex item, we
|
||||
just use a smaller width that exactly fits our container (and
|
||||
doesn't overflow). */
|
||||
width: 70px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- This testcase checks that we honor "align-content" on a horizontal
|
||||
flex container that has "overflow:hidden". We use a large flex item,
|
||||
large enough that it overflows the container in the main axis, to be
|
||||
sure that "overflow: hidden" is actually applying. -->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: Testing 'overflow' property on a horizontal flex container, with 'align-content: space-around'</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#align-content-property">
|
||||
<link rel="match" href="flexbox-overflow-horiz-5-ref.html">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: space-around;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
flex: none; /* prevent shrinking (so we can intentionally overflow) */
|
||||
width: 72px;
|
||||
height: 20px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.hidden { overflow: hidden }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
}
|
||||
.hidden > .bigItem {
|
||||
/* To match the testcase's "overflow:hidden"-cropped flex item, we
|
||||
just use a smaller width that exactly fits the space remaining
|
||||
in our container, after wrapping */
|
||||
width: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- This testcase checks that we honor "flex-wrap" on a vertical
|
||||
flex container that has "overflow:hidden". We use a large flex item,
|
||||
large enough that it overflows the container in the cross axis, to be
|
||||
sure that "overflow: hidden" is actually applying. -->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: Testing 'overflow' property on a vertical flex container, with 'flex-wrap: wrap'</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#flex-wrap-property">
|
||||
<link rel="match" href="flexbox-overflow-vert-4-ref.html">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 20px;
|
||||
height: 50px;
|
||||
}
|
||||
.hidden { overflow: hidden }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="smallItem"></div>
|
||||
<div class="bigItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,50 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
align-content: space-around;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
flex: none; /* prevent shrinking (so we can intentionally overflow) */
|
||||
width: 20px;
|
||||
height: 72px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.hidden > .bigItem {
|
||||
/* To match the testcase's "overflow:hidden"-cropped flex item, we
|
||||
just use a smaller height that exactly fits our container (and
|
||||
doesn't overflow). */
|
||||
height: 70px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!-- This testcase checks that we honor "align-content" on a vertical
|
||||
flex container that has "overflow:hidden". We use a large flex item,
|
||||
large enough that it overflows the container in the main axis, to be
|
||||
sure that "overflow: hidden" is actually applying. -->
|
||||
<html>
|
||||
<head>
|
||||
<title>CSS Test: Testing 'overflow' property on a vertical flex container, with 'align-content: space-around'</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="http://www.w3.org/TR/css3-flexbox/#align-content-property">
|
||||
<link rel="match" href="flexbox-overflow-vert-5-ref.html">
|
||||
<style>
|
||||
.flexContainer {
|
||||
background: purple;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
align-content: space-around;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.bigItem {
|
||||
background: blue;
|
||||
flex: none; /* prevent shrinking (so we can intentionally overflow) */
|
||||
width: 20px;
|
||||
height: 72px;
|
||||
}
|
||||
.smallItem {
|
||||
background: teal;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.hidden { overflow: hidden }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flexContainer"><!-- (overflow un-set) -->
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
<div class="flexContainer hidden">
|
||||
<div class="bigItem"></div>
|
||||
<div class="smallItem"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -106,9 +106,13 @@ fuzzy-if(Android,158,32) == flexbox-align-self-vert-rtl-1.xhtml flexbox-align-s
|
|||
== flexbox-overflow-horiz-1.html flexbox-overflow-horiz-1-ref.html
|
||||
== flexbox-overflow-horiz-2.html flexbox-overflow-horiz-2-ref.html
|
||||
== flexbox-overflow-horiz-3.html flexbox-overflow-horiz-3-ref.html
|
||||
== flexbox-overflow-horiz-4.html flexbox-overflow-horiz-4-ref.html
|
||||
== flexbox-overflow-horiz-5.html flexbox-overflow-horiz-5-ref.html
|
||||
== flexbox-overflow-vert-1.html flexbox-overflow-vert-1-ref.html
|
||||
== flexbox-overflow-vert-2.html flexbox-overflow-vert-2-ref.html
|
||||
== flexbox-overflow-vert-3.html flexbox-overflow-vert-3-ref.html
|
||||
== flexbox-overflow-vert-4.html flexbox-overflow-vert-4-ref.html
|
||||
== flexbox-overflow-vert-5.html flexbox-overflow-vert-5-ref.html
|
||||
|
||||
# Tests for the order in which we paint flex items
|
||||
== flexbox-paint-ordering-1.xhtml flexbox-paint-ordering-1-ref.xhtml
|
||||
|
|
|
@ -142,10 +142,10 @@
|
|||
-moz-column-gap: inherit;
|
||||
-moz-column-rule: inherit;
|
||||
/* CSS3 flexbox properties that apply to the flex container: */
|
||||
/* align-content: inherit; FIXME: not yet supported (bug 702508) */
|
||||
align-content: inherit;
|
||||
align-items: inherit;
|
||||
flex-direction: inherit;
|
||||
/* flex-wrap: inherit; FIXME: not yet supported (bug 702508) */
|
||||
flex-wrap: inherit;
|
||||
justify-content: inherit;
|
||||
/* Do not change these. nsCSSFrameConstructor depends on them to create a good
|
||||
frame tree. */
|
||||
|
|
|
@ -52,13 +52,6 @@ public class StringHelper {
|
|||
"Add to Home Screen"
|
||||
};
|
||||
|
||||
public static final String[] CONTEXT_MENU_ITEMS_IN_URL_BAR = new String[] {
|
||||
"Share",
|
||||
"Copy Address",
|
||||
"Edit Site Settings",
|
||||
"Add to Home Screen"
|
||||
};
|
||||
|
||||
public static final String TITLE_PLACE_HOLDER = "Enter Search or Address";
|
||||
|
||||
// Robocop page urls
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
package org.mozilla.gecko.tests;
|
||||
import android.view.View;
|
||||
|
||||
import org.mozilla.gecko.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* This patch tests the clear private data options:
|
||||
* - clear history option by: adding and checking that clear private
|
||||
* data option removes the history items but not the users bookmarks
|
||||
* - clear site settings and clear saved password by: checking
|
||||
* each option present in the doorhanger and clearing the settings from
|
||||
* the URL bar context menu and settings menu
|
||||
*/
|
||||
|
||||
public class testClearPrivateData extends PixelTest {
|
||||
private final int TEST_WAIT_MS = 10000;
|
||||
|
||||
|
@ -23,25 +14,21 @@ public class testClearPrivateData extends PixelTest {
|
|||
public void testClearPrivateData() {
|
||||
blockForGeckoReady();
|
||||
clearHistory();
|
||||
clearSiteSettings();
|
||||
clearPassword();
|
||||
}
|
||||
|
||||
private void clearHistory() {
|
||||
|
||||
// Loading a page and adding a second one as bookmark to have user made bookmarks and history
|
||||
String blank1 = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
|
||||
String blank2 = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_02_URL);
|
||||
String title = StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE;
|
||||
inputAndLoadUrl(blank1);
|
||||
verifyPageTitle(title);
|
||||
|
||||
loadAndPaint(blank1);
|
||||
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
|
||||
|
||||
mDatabaseHelper.addOrUpdateMobileBookmark(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE, blank2);
|
||||
|
||||
// Checking that the history list is not empty
|
||||
verifyHistoryCount(1);
|
||||
|
||||
//clear and check for device
|
||||
checkDevice(title);
|
||||
clearPrivateData();
|
||||
|
||||
// Checking that history list is empty
|
||||
verifyHistoryCount(0);
|
||||
|
@ -58,60 +45,4 @@ public class testClearPrivateData extends PixelTest {
|
|||
}, TEST_WAIT_MS);
|
||||
mAsserter.ok(match, "Checking that the number of history items is correct", String.valueOf(expectedCount) + " history items present in the database");
|
||||
}
|
||||
|
||||
public void clearSiteSettings() {
|
||||
String shareStrings[] = {"Share your location with", "Share", "Don't share", "There are no settings to clear"};
|
||||
String titleGeolocation = StringHelper.ROBOCOP_GEOLOCATION_TITLE;
|
||||
String url = getAbsoluteUrl(StringHelper.ROBOCOP_GEOLOCATION_URL);
|
||||
loadCheckDismiss(shareStrings[1], url, shareStrings[0]);
|
||||
checkOption(shareStrings[1], "Clear");
|
||||
checkOption(shareStrings[3], "Cancel");
|
||||
loadCheckDismiss(shareStrings[2], url, shareStrings[0]);
|
||||
checkOption(shareStrings[2], "Cancel");
|
||||
checkDevice(titleGeolocation);
|
||||
}
|
||||
|
||||
public void clearPassword(){
|
||||
String passwordStrings[] = {"Save password", "Save", "Don't save"};
|
||||
String title = StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE;
|
||||
String loginUrl = getAbsoluteUrl(StringHelper.ROBOCOP_LOGIN_URL);
|
||||
loadCheckDismiss(passwordStrings[1], loginUrl, passwordStrings[0]);
|
||||
checkOption(passwordStrings[1], "Clear");
|
||||
loadCheckDismiss(passwordStrings[2], loginUrl, passwordStrings[0]);
|
||||
checkDevice(title);
|
||||
}
|
||||
|
||||
// clear private data and verify the device type because for phone there is an extra back action to exit the settings menu
|
||||
public void checkDevice(String title) {
|
||||
clearPrivateData();
|
||||
if (mDevice.type.equals("phone")) {
|
||||
mActions.sendSpecialKey(Actions.SpecialKey.BACK);
|
||||
mAsserter.ok(waitForText(StringHelper.PRIVACY_SECTION_LABEL), "waiting to perform one back", "one back");
|
||||
mActions.sendSpecialKey(Actions.SpecialKey.BACK);
|
||||
verifyPageTitle(title);
|
||||
}
|
||||
else {
|
||||
mActions.sendSpecialKey(Actions.SpecialKey.BACK);
|
||||
verifyPageTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
// Load a URL, verify that the doorhanger appears and dismiss it
|
||||
public void loadCheckDismiss(String option, String url, String message) {
|
||||
inputAndLoadUrl(url);
|
||||
waitForText(message);
|
||||
mAsserter.is(mSolo.searchText(message), true, "Doorhanger:" + message + " has been displayed");
|
||||
mSolo.clickOnButton(option);
|
||||
mAsserter.is(mSolo.searchText(message), false, "Doorhanger:" + message + " has been hidden");
|
||||
}
|
||||
|
||||
//Verify if there are settings to be clear if so clear them from the URL bar context menu
|
||||
public void checkOption(String option, String button) {
|
||||
final View toolbarView = mSolo.getView("browser_toolbar");
|
||||
mSolo.clickLongOnView(toolbarView);
|
||||
mAsserter.ok(waitForText(StringHelper.CONTEXT_MENU_ITEMS_IN_URL_BAR[2]), "Waiting for the pop-up to open", "Pop up was openend");
|
||||
mSolo.clickOnText(StringHelper.CONTEXT_MENU_ITEMS_IN_URL_BAR[2]);
|
||||
mAsserter.ok(waitForText(option), "Verify that the option: " + option + " is in the list", "The option is in the list. There are settings to clear");
|
||||
mSolo.clickOnButton(button);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ from contextlib import contextmanager
|
|||
|
||||
from mach.mixin.logging import LoggingMixin
|
||||
|
||||
import mozpack.path as mozpath
|
||||
from ..preprocessor import Preprocessor
|
||||
from ..pythonutil import iter_modules_in_path
|
||||
from ..util import FileAvoidWrite
|
||||
from ..frontend.data import (
|
||||
|
@ -24,6 +26,7 @@ from ..frontend.data import (
|
|||
SandboxDerived,
|
||||
)
|
||||
from .configenvironment import ConfigEnvironment
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
||||
class BackendConsumeSummary(object):
|
||||
|
@ -128,12 +131,12 @@ class BuildBackend(LoggingMixin):
|
|||
self._backend_output_files = set()
|
||||
|
||||
# Previously generated files.
|
||||
self._backend_output_list_file = os.path.join(environment.topobjdir,
|
||||
self._backend_output_list_file = mozpath.join(environment.topobjdir,
|
||||
'backend.%s' % self.__class__.__name__)
|
||||
self._backend_output_list = set()
|
||||
if os.path.exists(self._backend_output_list_file):
|
||||
self._backend_output_list.update(open(self._backend_output_list_file) \
|
||||
.read().split('\n'))
|
||||
l = open(self._backend_output_list_file).read().split('\n')
|
||||
self._backend_output_list.update(mozpath.normsep(p) for p in l)
|
||||
|
||||
# Pull in all loaded Python as dependencies so any Python changes that
|
||||
# could influence our output result in a rescan.
|
||||
|
@ -162,7 +165,7 @@ class BuildBackend(LoggingMixin):
|
|||
"""
|
||||
environment = self._environments.get(obj.topobjdir, None)
|
||||
if not environment:
|
||||
config_status = os.path.join(obj.topobjdir, 'config.status')
|
||||
config_status = mozpath.join(obj.topobjdir, 'config.status')
|
||||
|
||||
environment = ConfigEnvironment.from_config_status(config_status)
|
||||
self._environments[obj.topobjdir] = environment
|
||||
|
@ -204,12 +207,12 @@ class BuildBackend(LoggingMixin):
|
|||
delete_files = self._backend_output_list - self._backend_output_files
|
||||
for path in delete_files:
|
||||
try:
|
||||
os.unlink(os.path.join(self.environment.topobjdir, path))
|
||||
os.unlink(mozpath.join(self.environment.topobjdir, path))
|
||||
self.summary.deleted_count += 1
|
||||
except OSError:
|
||||
pass
|
||||
# Remove now empty directories
|
||||
for dir in set(os.path.dirname(d) for d in delete_files):
|
||||
for dir in set(mozpath.dirname(d) for d in delete_files):
|
||||
try:
|
||||
os.removedirs(dir)
|
||||
except OSError:
|
||||
|
@ -263,7 +266,7 @@ class BuildBackend(LoggingMixin):
|
|||
else:
|
||||
assert fh is not None
|
||||
|
||||
dirname = os.path.dirname(fh.name)
|
||||
dirname = mozpath.dirname(fh.name)
|
||||
try:
|
||||
os.makedirs(dirname)
|
||||
except OSError as error:
|
||||
|
@ -272,7 +275,7 @@ class BuildBackend(LoggingMixin):
|
|||
|
||||
yield fh
|
||||
|
||||
self._backend_output_files.add(os.path.relpath(fh.name, self.environment.topobjdir))
|
||||
self._backend_output_files.add(mozpath.relpath(fh.name, self.environment.topobjdir))
|
||||
existed, updated = fh.close()
|
||||
if not existed:
|
||||
self.summary.created_count += 1
|
||||
|
@ -280,3 +283,23 @@ class BuildBackend(LoggingMixin):
|
|||
self.summary.updated_count += 1
|
||||
else:
|
||||
self.summary.unchanged_count += 1
|
||||
|
||||
@contextmanager
|
||||
def _get_preprocessor(self, obj):
|
||||
'''Returns a preprocessor with a few predefined values depending on
|
||||
the given BaseConfigSubstitution(-like) object, and all the substs
|
||||
in the current environment.'''
|
||||
pp = Preprocessor()
|
||||
srcdir = mozpath.dirname(obj.input_path)
|
||||
pp.context.update(self.environment.substs)
|
||||
pp.context.update(
|
||||
top_srcdir=self.environment.topsrcdir,
|
||||
srcdir=srcdir,
|
||||
relativesrcdir=mozpath.relpath(srcdir, self.environment.topsrcdir) or '.',
|
||||
DEPTH=mozpath.relpath(self.environment.topobjdir, mozpath.dirname(obj.output_path)) or '.',
|
||||
)
|
||||
pp.do_filter('attemptSubstitution')
|
||||
pp.setMarker(None)
|
||||
with self._write_file(obj.output_path) as fh:
|
||||
pp.out = fh
|
||||
yield pp
|
||||
|
|
|
@ -6,12 +6,17 @@ from __future__ import unicode_literals
|
|||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
from mozbuild.preprocessor import Preprocessor
|
||||
|
||||
from .base import BuildBackend
|
||||
|
||||
from ..frontend.data import (
|
||||
ConfigFileSubstitution,
|
||||
HeaderFileSubstitution,
|
||||
TestManifest,
|
||||
XPIDLFile,
|
||||
)
|
||||
|
@ -92,14 +97,69 @@ class CommonBackend(BuildBackend):
|
|||
self._test_manager.add(test, flavor=obj.flavor,
|
||||
topsrcdir=obj.topsrcdir)
|
||||
|
||||
if isinstance(obj, XPIDLFile):
|
||||
elif isinstance(obj, XPIDLFile):
|
||||
self._idl_manager.register_idl(obj.source_path, obj.module)
|
||||
|
||||
elif isinstance(obj, ConfigFileSubstitution):
|
||||
# Do not handle ConfigFileSubstitution for Makefiles. Leave that
|
||||
# to other
|
||||
if mozpath.basename(obj.output_path) == 'Makefile':
|
||||
return
|
||||
with self._get_preprocessor(obj) as pp:
|
||||
pp.do_include(obj.input_path)
|
||||
self.backend_input_files.add(obj.input_path)
|
||||
|
||||
elif isinstance(obj, HeaderFileSubstitution):
|
||||
self._create_config_header(obj)
|
||||
self.backend_input_files.add(obj.input_path)
|
||||
|
||||
else:
|
||||
return
|
||||
|
||||
obj.ack()
|
||||
|
||||
def consume_finished(self):
|
||||
if len(self._idl_manager.idls):
|
||||
self._handle_idl_manager(self._idl_manager)
|
||||
|
||||
# Write out a machine-readable file describing every test.
|
||||
path = os.path.join(self.environment.topobjdir, 'all-tests.json')
|
||||
path = mozpath.join(self.environment.topobjdir, 'all-tests.json')
|
||||
with self._write_file(path) as fh:
|
||||
json.dump(self._test_manager.tests_by_path, fh, sort_keys=True)
|
||||
|
||||
def _create_config_header(self, obj):
|
||||
'''Creates the given config header. A config header is generated by
|
||||
taking the corresponding source file and replacing some #define/#undef
|
||||
occurences:
|
||||
"#undef NAME" is turned into "#define NAME VALUE"
|
||||
"#define NAME" is unchanged
|
||||
"#define NAME ORIGINAL_VALUE" is turned into "#define NAME VALUE"
|
||||
"#undef UNKNOWN_NAME" is turned into "/* #undef UNKNOWN_NAME */"
|
||||
Whitespaces are preserved.
|
||||
'''
|
||||
with self._write_file(obj.output_path) as fh, \
|
||||
open(obj.input_path, 'rU') as input:
|
||||
r = re.compile('^\s*#\s*(?P<cmd>[a-z]+)(?:\s+(?P<name>\S+)(?:\s+(?P<value>\S+))?)?', re.U)
|
||||
for l in input:
|
||||
m = r.match(l)
|
||||
if m:
|
||||
cmd = m.group('cmd')
|
||||
name = m.group('name')
|
||||
value = m.group('value')
|
||||
if name:
|
||||
if name in self.environment.defines:
|
||||
if cmd == 'define' and value:
|
||||
l = l[:m.start('value')] \
|
||||
+ str(self.environment.defines[name]) \
|
||||
+ l[m.end('value'):]
|
||||
elif cmd == 'undef':
|
||||
l = l[:m.start('cmd')] \
|
||||
+ 'define' \
|
||||
+ l[m.end('cmd'):m.end('name')] \
|
||||
+ ' ' \
|
||||
+ str(self.environment.defines[name]) \
|
||||
+ l[m.end('name'):]
|
||||
elif cmd == 'undef':
|
||||
l = '/* ' + l[:m.end('name')] + ' */' + l[m.end('name'):]
|
||||
|
||||
fh.write(l)
|
||||
|
|
|
@ -2,21 +2,14 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import ntpath
|
||||
import os
|
||||
import posixpath
|
||||
import re
|
||||
import sys
|
||||
|
||||
from collections import Iterable
|
||||
from os.path import relpath
|
||||
from types import StringTypes
|
||||
|
||||
from mozbuild.preprocessor import Preprocessor
|
||||
import mozpack.path as mozpath
|
||||
|
||||
from ..util import (
|
||||
ensureParentDir,
|
||||
FileAvoidWrite,
|
||||
ReadOnlyDict,
|
||||
shell_quote,
|
||||
)
|
||||
|
@ -110,8 +103,8 @@ class ConfigEnvironment(object):
|
|||
|
||||
self.defines = ReadOnlyDict(defines)
|
||||
self.substs = dict(substs)
|
||||
self.topsrcdir = topsrcdir
|
||||
self.topobjdir = topobjdir
|
||||
self.topsrcdir = mozpath.normsep(topsrcdir)
|
||||
self.topobjdir = mozpath.normsep(topobjdir)
|
||||
global_defines = [name for name, value in defines
|
||||
if not name in non_global_defines]
|
||||
self.substs['ACDEFINES'] = ' '.join(['-D%s=%s' % (name,
|
||||
|
@ -162,132 +155,3 @@ class ConfigEnvironment(object):
|
|||
|
||||
return ConfigEnvironment(config.topsrcdir, config.topobjdir,
|
||||
config.defines, config.non_global_defines, config.substs)
|
||||
|
||||
def get_relative_srcdir(self, file):
|
||||
'''Returns the relative source directory for the given file, always
|
||||
using / as a path separator.
|
||||
'''
|
||||
assert(isinstance(file, basestring))
|
||||
dir = posixpath.dirname(relpath(file, self.topobjdir).replace(os.sep, '/'))
|
||||
if dir:
|
||||
return dir
|
||||
return '.'
|
||||
|
||||
def get_top_srcdir(self, file):
|
||||
'''Returns a normalized top_srcdir for the given file: if
|
||||
substs['top_srcdir'] is a relative path, it is relative to the
|
||||
topobjdir. Adjust it to be relative to the file path.'''
|
||||
top_srcdir = self.substs['top_srcdir']
|
||||
if posixpath.isabs(top_srcdir) or ntpath.isabs(top_srcdir):
|
||||
return top_srcdir
|
||||
return posixpath.normpath(posixpath.join(self.get_depth(file), top_srcdir))
|
||||
|
||||
def get_file_srcdir(self, file):
|
||||
'''Returns the srcdir for the given file, where srcdir is in msys
|
||||
format on windows, thus derived from top_srcdir.
|
||||
'''
|
||||
dir = self.get_relative_srcdir(file)
|
||||
top_srcdir = self.get_top_srcdir(file)
|
||||
return posixpath.normpath(posixpath.join(top_srcdir, dir))
|
||||
|
||||
def get_depth(self, file):
|
||||
'''Returns the DEPTH for the given file, that is, the path to the
|
||||
object directory relative to the directory containing the given file.
|
||||
Always uses / as a path separator.
|
||||
'''
|
||||
return relpath(self.topobjdir, os.path.dirname(file)).replace(os.sep, '/')
|
||||
|
||||
def get_input(self, file):
|
||||
'''Returns the input file path in the source tree that can be used
|
||||
to create the given config file or header.
|
||||
'''
|
||||
assert(isinstance(file, basestring))
|
||||
return os.path.normpath(os.path.join(self.topsrcdir, "%s.in" % relpath(file, self.topobjdir)))
|
||||
|
||||
def create_config_file(self, output, extra=None):
|
||||
'''Creates the given config file. A config file is generated by
|
||||
taking the corresponding source file and replacing occurences of
|
||||
"@VAR@" by the value corresponding to "VAR" in the substs dict.
|
||||
|
||||
Additional substs are defined according to the file being treated:
|
||||
"srcdir" for its the path to its source directory
|
||||
"relativesrcdir" for its source directory relative to the top
|
||||
"DEPTH" for the path to the top object directory
|
||||
'''
|
||||
path = output.name
|
||||
if os.path.basename(path) == 'Makefile':
|
||||
return self.create_makefile(output, extra=extra)
|
||||
pp = self._get_preprocessor(output, extra)
|
||||
pp.do_include(self.get_input(path))
|
||||
|
||||
def create_makefile(self, output, stub=False, extra=None):
|
||||
'''Creates the given makefile. Makefiles are treated the same as
|
||||
config files, but some additional header and footer is added to the
|
||||
output.
|
||||
|
||||
When the stub argument is True, no source file is used, and a stub
|
||||
makefile with the default header and footer only is created.
|
||||
'''
|
||||
pp = self._get_preprocessor(output, extra)
|
||||
pp.handleLine('# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.\n');
|
||||
pp.handleLine('DEPTH := @DEPTH@\n')
|
||||
pp.handleLine('topsrcdir := @top_srcdir@\n')
|
||||
pp.handleLine('srcdir := @srcdir@\n')
|
||||
pp.handleLine('VPATH := @srcdir@\n')
|
||||
pp.handleLine('relativesrcdir := @relativesrcdir@\n')
|
||||
pp.handleLine('include $(DEPTH)/config/autoconf.mk\n')
|
||||
if not stub:
|
||||
pp.do_include(self.get_input(output.name))
|
||||
# Empty line to avoid failures when last line in Makefile.in ends
|
||||
# with a backslash.
|
||||
pp.handleLine('\n')
|
||||
pp.handleLine('include $(topsrcdir)/config/recurse.mk\n')
|
||||
|
||||
def _get_preprocessor(self, output, extra):
|
||||
'''Returns a preprocessor for use by create_config_file and
|
||||
create_makefile.
|
||||
'''
|
||||
path = output.name
|
||||
pp = Preprocessor()
|
||||
pp.context.update(self.substs)
|
||||
pp.context.update(top_srcdir = self.get_top_srcdir(path))
|
||||
pp.context.update(srcdir = self.get_file_srcdir(path))
|
||||
pp.context.update(relativesrcdir = self.get_relative_srcdir(path))
|
||||
pp.context.update(DEPTH = self.get_depth(path))
|
||||
if extra:
|
||||
pp.context.update(extra)
|
||||
pp.do_filter('attemptSubstitution')
|
||||
pp.setMarker(None)
|
||||
|
||||
pp.out = output
|
||||
return pp
|
||||
|
||||
def create_config_header(self, output):
|
||||
'''Creates the given config header. A config header is generated by
|
||||
taking the corresponding source file and replacing some #define/#undef
|
||||
occurences:
|
||||
"#undef NAME" is turned into "#define NAME VALUE"
|
||||
"#define NAME" is unchanged
|
||||
"#define NAME ORIGINAL_VALUE" is turned into "#define NAME VALUE"
|
||||
"#undef UNKNOWN_NAME" is turned into "/* #undef UNKNOWN_NAME */"
|
||||
Whitespaces are preserved.
|
||||
'''
|
||||
with open(self.get_input(output.name), 'rU') as input:
|
||||
ensureParentDir(output.name)
|
||||
r = re.compile('^\s*#\s*(?P<cmd>[a-z]+)(?:\s+(?P<name>\S+)(?:\s+(?P<value>\S+))?)?', re.U)
|
||||
for l in input:
|
||||
m = r.match(l)
|
||||
if m:
|
||||
cmd = m.group('cmd')
|
||||
name = m.group('name')
|
||||
value = m.group('value')
|
||||
if name:
|
||||
if name in self.defines:
|
||||
if cmd == 'define' and value:
|
||||
l = l[:m.start('value')] + str(self.defines[name]) + l[m.end('value'):]
|
||||
elif cmd == 'undef':
|
||||
l = l[:m.start('cmd')] + 'define' + l[m.end('cmd'):m.end('name')] + ' ' + str(self.defines[name]) + l[m.end('name'):]
|
||||
elif cmd == 'undef':
|
||||
l = '/* ' + l[:m.end('name')] + ' */' + l[m.end('name'):]
|
||||
|
||||
output.write(l)
|
||||
|
|
|
@ -28,7 +28,6 @@ from ..frontend.data import (
|
|||
GeneratedEventWebIDLFile,
|
||||
GeneratedInclude,
|
||||
GeneratedWebIDLFile,
|
||||
HeaderFileSubstitution,
|
||||
HostProgram,
|
||||
HostSimpleProgram,
|
||||
InstallationTarget,
|
||||
|
@ -85,7 +84,7 @@ class BackendMakeFile(object):
|
|||
self.objdir = objdir
|
||||
self.relobjdir = objdir[len(environment.topobjdir) + 1:]
|
||||
self.environment = environment
|
||||
self.name = os.path.join(objdir, 'backend.mk')
|
||||
self.name = mozpath.join(objdir, 'backend.mk')
|
||||
|
||||
# XPIDLFiles attached to this file.
|
||||
self.idls = []
|
||||
|
@ -290,7 +289,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
|
||||
self._test_manifests = {}
|
||||
|
||||
self.backend_input_files.add(os.path.join(self.environment.topobjdir,
|
||||
self.backend_input_files.add(mozpath.join(self.environment.topobjdir,
|
||||
'config', 'autoconf.mk'))
|
||||
|
||||
self._install_manifests = {
|
||||
|
@ -324,29 +323,36 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
def consume_object(self, obj):
|
||||
"""Write out build files necessary to build with recursive make."""
|
||||
|
||||
CommonBackend.consume_object(self, obj)
|
||||
|
||||
if not isinstance(obj, SandboxDerived):
|
||||
return
|
||||
|
||||
if obj.srcdir not in self._backend_files:
|
||||
self._backend_files[obj.srcdir] = \
|
||||
if obj.objdir not in self._backend_files:
|
||||
self._backend_files[obj.objdir] = \
|
||||
BackendMakeFile(obj.srcdir, obj.objdir, self.get_environment(obj))
|
||||
backend_file = self._backend_files[obj.srcdir]
|
||||
backend_file = self._backend_files[obj.objdir]
|
||||
|
||||
CommonBackend.consume_object(self, obj)
|
||||
|
||||
# CommonBackend handles XPIDLFile and TestManifest, but we want to do
|
||||
# some extra things for them.
|
||||
if isinstance(obj, XPIDLFile):
|
||||
backend_file.idls.append(obj)
|
||||
backend_file.xpt_name = '%s.xpt' % obj.module
|
||||
|
||||
elif isinstance(obj, TestManifest):
|
||||
self._process_test_manifest(obj, backend_file)
|
||||
|
||||
# If CommonBackend acknowledged the object, we're done with it.
|
||||
if obj._ack:
|
||||
return
|
||||
|
||||
if isinstance(obj, DirectoryTraversal):
|
||||
self._process_directory_traversal(obj, backend_file)
|
||||
elif isinstance(obj, ConfigFileSubstitution):
|
||||
with self._write_file(obj.output_path) as fh:
|
||||
backend_file.environment.create_config_file(fh)
|
||||
self.backend_input_files.add(obj.input_path)
|
||||
elif isinstance(obj, HeaderFileSubstitution):
|
||||
with self._write_file(obj.output_path) as fh:
|
||||
backend_file.environment.create_config_header(fh)
|
||||
self.backend_input_files.add(obj.input_path)
|
||||
elif isinstance(obj, XPIDLFile):
|
||||
backend_file.idls.append(obj)
|
||||
backend_file.xpt_name = '%s.xpt' % obj.module
|
||||
# Other ConfigFileSubstitution should have been acked by
|
||||
# CommonBackend.
|
||||
assert os.path.basename(obj.output_path) == 'Makefile'
|
||||
self._create_makefile(obj)
|
||||
elif isinstance(obj, VariablePassthru):
|
||||
unified_suffixes = dict(
|
||||
UNIFIED_CSRCS='c',
|
||||
|
@ -440,9 +446,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
elif isinstance(obj, HostSimpleProgram):
|
||||
self._process_host_simple_program(obj.program, backend_file)
|
||||
|
||||
elif isinstance(obj, TestManifest):
|
||||
self._process_test_manifest(obj, backend_file)
|
||||
|
||||
elif isinstance(obj, LocalInclude):
|
||||
self._process_local_include(obj.path, backend_file)
|
||||
|
||||
|
@ -585,11 +588,11 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
root_mk.add_statement('$(call include_deps,root-deps.mk)')
|
||||
|
||||
with self._write_file(
|
||||
os.path.join(self.environment.topobjdir, 'root.mk')) as root:
|
||||
mozpath.join(self.environment.topobjdir, 'root.mk')) as root:
|
||||
root_mk.dump(root, removal_guard=False)
|
||||
|
||||
with self._write_file(
|
||||
os.path.join(self.environment.topobjdir, 'root-deps.mk')) as root_deps:
|
||||
mozpath.join(self.environment.topobjdir, 'root-deps.mk')) as root_deps:
|
||||
root_deps_mk.dump(root_deps, removal_guard=False)
|
||||
|
||||
def _add_unified_build_rules(self, makefile, files, output_directory,
|
||||
|
@ -643,7 +646,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
# blown away and we need to regenerate them. The rule doesn't correctly
|
||||
# handle source files being added/removed/renamed. Therefore, we
|
||||
# generate them here also to make sure everything's up-to-date.
|
||||
with self._write_file(os.path.join(output_directory, unified_file)) as f:
|
||||
with self._write_file(mozpath.join(output_directory, unified_file)) as f:
|
||||
f.write('#define MOZ_UNIFIED_BUILD\n')
|
||||
includeTemplate = '#include "%(cppfile)s"'
|
||||
if poison_windows_h:
|
||||
|
@ -680,10 +683,11 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
def consume_finished(self):
|
||||
CommonBackend.consume_finished(self)
|
||||
|
||||
for srcdir in sorted(self._backend_files.keys()):
|
||||
with self._write_file(fh=self._backend_files[srcdir]) as bf:
|
||||
makefile_in = os.path.join(srcdir, 'Makefile.in')
|
||||
makefile = os.path.join(bf.objdir, 'Makefile')
|
||||
for objdir, backend_file in sorted(self._backend_files.items()):
|
||||
srcdir = backend_file.srcdir
|
||||
with self._write_file(fh=backend_file) as bf:
|
||||
makefile_in = mozpath.join(srcdir, 'Makefile.in')
|
||||
makefile = mozpath.join(objdir, 'Makefile')
|
||||
|
||||
# If Makefile.in exists, use it as a template. Otherwise,
|
||||
# create a stub.
|
||||
|
@ -692,13 +696,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
self.log(logging.DEBUG, 'substitute_makefile',
|
||||
{'path': makefile}, 'Substituting makefile: {path}')
|
||||
|
||||
# Adding the Makefile.in here has the desired side-effect
|
||||
# that if the Makefile.in disappears, this will force
|
||||
# moz.build traversal. This means that when we remove empty
|
||||
# Makefile.in files, the old file will get replaced with
|
||||
# the autogenerated one automatically.
|
||||
self.backend_input_files.add(makefile_in)
|
||||
|
||||
for tier, skiplist in self._may_skip.items():
|
||||
if tier in ('compile', 'binaries'):
|
||||
continue
|
||||
|
@ -710,22 +707,24 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
|
||||
# Can't skip directories with a jar.mn for the 'libs' tier.
|
||||
if bf.relobjdir in self._may_skip['libs'] and \
|
||||
os.path.exists(os.path.join(srcdir, 'jar.mn')):
|
||||
os.path.exists(mozpath.join(srcdir, 'jar.mn')):
|
||||
self._may_skip['libs'].remove(bf.relobjdir)
|
||||
|
||||
with self._write_file(makefile) as fh:
|
||||
bf.environment.create_makefile(fh, stub=stub)
|
||||
obj = self.Substitution()
|
||||
obj.output_path = makefile
|
||||
obj.input_path = makefile_in
|
||||
self._create_makefile(obj, stub=stub)
|
||||
|
||||
# Write out a master list of all IPDL source files.
|
||||
ipdl_dir = os.path.join(self.environment.topobjdir, 'ipc', 'ipdl')
|
||||
ipdl_dir = mozpath.join(self.environment.topobjdir, 'ipc', 'ipdl')
|
||||
mk = mozmakeutil.Makefile()
|
||||
|
||||
sorted_ipdl_sources = list(sorted(self._ipdl_sources))
|
||||
mk.add_statement('ALL_IPDLSRCS := %s' % ' '.join(sorted_ipdl_sources))
|
||||
|
||||
def files_from(ipdl):
|
||||
base = os.path.basename(ipdl)
|
||||
root, ext = os.path.splitext(base)
|
||||
base = mozpath.basename(ipdl)
|
||||
root, ext = mozpath.splitext(base)
|
||||
|
||||
# Both .ipdl and .ipdlh become .cpp files
|
||||
files = ['%s.cpp' % root]
|
||||
|
@ -740,21 +739,21 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
unified_prefix='UnifiedProtocols',
|
||||
unified_files_makefile_variable='CPPSRCS')
|
||||
|
||||
mk.add_statement('IPDLDIRS := %s' % ' '.join(sorted(set(os.path.dirname(p)
|
||||
mk.add_statement('IPDLDIRS := %s' % ' '.join(sorted(set(mozpath.dirname(p)
|
||||
for p in self._ipdl_sources))))
|
||||
|
||||
with self._write_file(os.path.join(ipdl_dir, 'ipdlsrcs.mk')) as ipdls:
|
||||
with self._write_file(mozpath.join(ipdl_dir, 'ipdlsrcs.mk')) as ipdls:
|
||||
mk.dump(ipdls, removal_guard=False)
|
||||
|
||||
self._may_skip['compile'] -= set(['ipc/ipdl'])
|
||||
|
||||
# Write out master lists of WebIDL source files.
|
||||
bindings_dir = os.path.join(self.environment.topobjdir, 'dom', 'bindings')
|
||||
bindings_dir = mozpath.join(self.environment.topobjdir, 'dom', 'bindings')
|
||||
|
||||
mk = mozmakeutil.Makefile()
|
||||
|
||||
def write_var(variable, sources):
|
||||
files = [os.path.basename(f) for f in sorted(sources)]
|
||||
files = [mozpath.basename(f) for f in sorted(sources)]
|
||||
mk.add_statement('%s += %s' % (variable, ' '.join(files)))
|
||||
write_var('webidl_files', self._webidl_sources)
|
||||
write_var('generated_events_webidl_files', self._generated_events_webidl_sources)
|
||||
|
@ -767,7 +766,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
iter(self._generated_events_webidl_sources),
|
||||
iter(self._generated_webidl_sources),
|
||||
iter(self._preprocessed_webidl_sources))
|
||||
all_webidl_files = [os.path.basename(x) for x in all_webidl_files]
|
||||
all_webidl_files = [mozpath.basename(x) for x in all_webidl_files]
|
||||
all_webidl_sources = [re.sub(r'\.webidl$', 'Binding.cpp', x) for x in all_webidl_files]
|
||||
|
||||
self._add_unified_build_rules(mk, all_webidl_sources,
|
||||
|
@ -778,7 +777,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
|
||||
# Assume that Somebody Else has responsibility for correctly
|
||||
# specifying removal dependencies for |all_webidl_sources|.
|
||||
with self._write_file(os.path.join(bindings_dir, 'webidlsrcs.mk')) as webidls:
|
||||
with self._write_file(mozpath.join(bindings_dir, 'webidlsrcs.mk')) as webidls:
|
||||
mk.dump(webidls, removal_guard=False)
|
||||
|
||||
self._may_skip['compile'] -= set(['dom/bindings', 'dom/bindings/test'])
|
||||
|
@ -805,8 +804,8 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
# Make the master test manifest files.
|
||||
for flavor, t in self._test_manifests.items():
|
||||
install_prefix, manifests = t
|
||||
manifest_stem = os.path.join(install_prefix, '%s.ini' % flavor)
|
||||
self._write_master_test_manifest(os.path.join(
|
||||
manifest_stem = mozpath.join(install_prefix, '%s.ini' % flavor)
|
||||
self._write_master_test_manifest(mozpath.join(
|
||||
self.environment.topobjdir, '_tests', manifest_stem),
|
||||
manifests)
|
||||
|
||||
|
@ -818,7 +817,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
|
||||
self._write_manifests('install', self._install_manifests)
|
||||
|
||||
ensureParentDir(os.path.join(self.environment.topobjdir, 'dist', 'foo'))
|
||||
ensureParentDir(mozpath.join(self.environment.topobjdir, 'dist', 'foo'))
|
||||
|
||||
def _process_directory_traversal(self, obj, backend_file):
|
||||
"""Process a data.DirectoryTraversal instance."""
|
||||
|
@ -933,8 +932,8 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
namespace += '/'
|
||||
|
||||
for s in strings:
|
||||
source = os.path.normpath(os.path.join(obj.srcdir, s))
|
||||
dest = '%s%s' % (namespace, os.path.basename(s))
|
||||
source = mozpath.normpath(mozpath.join(obj.srcdir, s))
|
||||
dest = '%s%s' % (namespace, mozpath.basename(s))
|
||||
self._install_manifests['dist_include'].add_symlink(source, dest)
|
||||
|
||||
if not os.path.exists(source):
|
||||
|
@ -1009,18 +1008,15 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
# some processes (such as PGO at the time this was implemented) wipe
|
||||
# out dist/include without regard to our install manifests.
|
||||
|
||||
out_path = os.path.join(self.environment.topobjdir, 'config',
|
||||
obj = self.Substitution()
|
||||
obj.output_path = mozpath.join(self.environment.topobjdir, 'config',
|
||||
'makefiles', 'xpidl', 'Makefile')
|
||||
with self._write_file(out_path) as fh:
|
||||
self.environment.create_config_file(fh, extra=dict(
|
||||
xpidl_rules='\n'.join(rules),
|
||||
xpidl_modules=' '.join(xpt_modules),
|
||||
))
|
||||
|
||||
# The Makefile can't regenerate itself because of custom substitution.
|
||||
# We need to list it here to ensure changes cause regeneration.
|
||||
self.backend_input_files.add(os.path.join(self.environment.topsrcdir,
|
||||
'config', 'makefiles', 'xpidl', 'Makefile.in'))
|
||||
obj.input_path = mozpath.join(self.environment.topsrcdir, 'config',
|
||||
'makefiles', 'xpidl', 'Makefile.in')
|
||||
self._create_makefile(obj, extra=dict(
|
||||
xpidl_rules='\n'.join(rules),
|
||||
xpidl_modules=' '.join(xpt_modules),
|
||||
))
|
||||
|
||||
def _process_program(self, program, backend_file):
|
||||
backend_file.write('PROGRAM = %s\n' % program)
|
||||
|
@ -1035,12 +1031,12 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
backend_file.write('HOST_SIMPLE_PROGRAMS += %s\n' % program)
|
||||
|
||||
def _process_webidl_basename(self, basename):
|
||||
header = 'mozilla/dom/%sBinding.h' % os.path.splitext(basename)[0]
|
||||
header = 'mozilla/dom/%sBinding.h' % mozpath.splitext(basename)[0]
|
||||
self._install_manifests['dist_include'].add_optional_exists(header)
|
||||
|
||||
def _process_test_manifest(self, obj, backend_file):
|
||||
# Much of the logic in this function could be moved to CommonBackend.
|
||||
self.backend_input_files.add(os.path.join(obj.topsrcdir,
|
||||
self.backend_input_files.add(mozpath.join(obj.topsrcdir,
|
||||
obj.manifest_relpath))
|
||||
|
||||
# Duplicate manifests may define the same file. That's OK.
|
||||
|
@ -1093,7 +1089,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
(target, ' '.join(jar.sources)))
|
||||
if jar.generated_sources:
|
||||
backend_file.write('%s_PP_JAVAFILES := %s\n' %
|
||||
(target, ' '.join(os.path.join('generated', f) for f in jar.generated_sources)))
|
||||
(target, ' '.join(mozpath.join('generated', f) for f in jar.generated_sources)))
|
||||
if jar.extra_jars:
|
||||
backend_file.write('%s_EXTRA_JARS := %s\n' %
|
||||
(target, ' '.join(jar.extra_jars)))
|
||||
|
@ -1116,7 +1112,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
% (relpath, basename))
|
||||
|
||||
def _write_manifests(self, dest, manifests):
|
||||
man_dir = os.path.join(self.environment.topobjdir, '_build_manifests',
|
||||
man_dir = mozpath.join(self.environment.topobjdir, '_build_manifests',
|
||||
dest)
|
||||
|
||||
# We have a purger for the manifests themselves to ensure legacy
|
||||
|
@ -1126,7 +1122,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
for k, manifest in manifests.items():
|
||||
purger.add(k)
|
||||
|
||||
with self._write_file(os.path.join(man_dir, k)) as fh:
|
||||
with self._write_file(mozpath.join(man_dir, k)) as fh:
|
||||
manifest.write(fileobj=fh)
|
||||
|
||||
purger.purge(man_dir)
|
||||
|
@ -1138,3 +1134,42 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
|
||||
for manifest in sorted(manifests):
|
||||
master.write('[include:%s]\n' % manifest)
|
||||
|
||||
class Substitution(object):
|
||||
"""BaseConfigSubstitution-like class for use with _create_makefile."""
|
||||
__slots__ = (
|
||||
'input_path',
|
||||
'output_path',
|
||||
)
|
||||
|
||||
def _create_makefile(self, obj, stub=False, extra=None):
|
||||
'''Creates the given makefile. Makefiles are treated the same as
|
||||
config files, but some additional header and footer is added to the
|
||||
output.
|
||||
|
||||
When the stub argument is True, no source file is used, and a stub
|
||||
makefile with the default header and footer only is created.
|
||||
'''
|
||||
with self._get_preprocessor(obj) as pp:
|
||||
if extra:
|
||||
pp.context.update(extra)
|
||||
pp.handleLine(b'# THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT MODIFY BY HAND.\n');
|
||||
pp.handleLine(b'DEPTH := @DEPTH@\n')
|
||||
pp.handleLine(b'topsrcdir := @top_srcdir@\n')
|
||||
pp.handleLine(b'srcdir := @srcdir@\n')
|
||||
pp.handleLine(b'VPATH := @srcdir@\n')
|
||||
pp.handleLine(b'relativesrcdir := @relativesrcdir@\n')
|
||||
pp.handleLine(b'include $(DEPTH)/config/autoconf.mk\n')
|
||||
if not stub:
|
||||
pp.do_include(obj.input_path)
|
||||
# Empty line to avoid failures when last line in Makefile.in ends
|
||||
# with a backslash.
|
||||
pp.handleLine(b'\n')
|
||||
pp.handleLine(b'include $(topsrcdir)/config/recurse.mk\n')
|
||||
if not stub:
|
||||
# Adding the Makefile.in here has the desired side-effect
|
||||
# that if the Makefile.in disappears, this will force
|
||||
# moz.build traversal. This means that when we remove empty
|
||||
# Makefile.in files, the old file will get replaced with
|
||||
# the autogenerated one automatically.
|
||||
self.backend_input_files.add(obj.input_path)
|
||||
|
|
|
@ -24,6 +24,7 @@ from mozbuild.util import (
|
|||
shell_quote,
|
||||
StrictOrderingOnAppendList,
|
||||
)
|
||||
import mozpack.path as mozpath
|
||||
from .sandbox_symbols import FinalTargetValue
|
||||
|
||||
|
||||
|
@ -169,7 +170,7 @@ class XPIDLFile(SandboxDerived):
|
|||
SandboxDerived.__init__(self, sandbox)
|
||||
|
||||
self.source_path = source
|
||||
self.basename = os.path.basename(source)
|
||||
self.basename = mozpath.basename(source)
|
||||
self.module = module
|
||||
|
||||
class Defines(SandboxDerived):
|
||||
|
@ -397,7 +398,7 @@ class TestManifest(SandboxDerived):
|
|||
SandboxDerived.__init__(self, sandbox)
|
||||
|
||||
self.path = path
|
||||
self.directory = os.path.dirname(path)
|
||||
self.directory = mozpath.dirname(path)
|
||||
self.manifest = manifest
|
||||
self.flavor = flavor
|
||||
self.install_prefix = install_prefix
|
||||
|
|
|
@ -63,7 +63,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
self.config = config
|
||||
|
||||
# TODO add mozinfo into config or somewhere else.
|
||||
mozinfo_path = os.path.join(config.topobjdir, 'mozinfo.json')
|
||||
mozinfo_path = mozpath.join(config.topobjdir, 'mozinfo.json')
|
||||
if os.path.exists(mozinfo_path):
|
||||
self.mozinfo = json.load(open(mozinfo_path, 'rt'))
|
||||
else:
|
||||
|
@ -174,7 +174,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
|
||||
for symbol in ('SOURCES', 'HOST_SOURCES', 'UNIFIED_SOURCES'):
|
||||
for src in (sandbox[symbol] or []):
|
||||
if not os.path.exists(os.path.join(sandbox['SRCDIR'], src)):
|
||||
if not os.path.exists(mozpath.join(sandbox['SRCDIR'], src)):
|
||||
raise SandboxValidationError('Reference to a file that '
|
||||
'doesn\'t exist in %s (%s) in %s'
|
||||
% (symbol, src, sandbox['RELATIVEDIR']))
|
||||
|
@ -247,7 +247,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
if k in ('SOURCES', 'UNIFIED_SOURCES')))
|
||||
for variable, mapping in varmap.items():
|
||||
for f in sandbox[variable]:
|
||||
ext = os.path.splitext(f)[1]
|
||||
ext = mozpath.splitext(f)[1]
|
||||
if ext not in mapping:
|
||||
raise SandboxValidationError('%s has an unknown file type in %s' % (f, sandbox['RELATIVEDIR']))
|
||||
l = passthru.variables.setdefault(mapping[ext], [])
|
||||
|
@ -369,8 +369,8 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
path = path[1:]
|
||||
|
||||
sub = cls(sandbox)
|
||||
sub.input_path = os.path.join(sandbox['SRCDIR'], '%s.in' % path)
|
||||
sub.output_path = os.path.join(sandbox['OBJDIR'], path)
|
||||
sub.input_path = mozpath.join(sandbox['SRCDIR'], '%s.in' % path)
|
||||
sub.output_path = mozpath.join(sandbox['OBJDIR'], path)
|
||||
sub.relpath = path
|
||||
|
||||
return sub
|
||||
|
@ -378,7 +378,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
def _process_test_manifest(self, sandbox, info, manifest_path):
|
||||
flavor, install_prefix, filter_inactive = info
|
||||
|
||||
manifest_path = os.path.normpath(manifest_path)
|
||||
manifest_path = mozpath.normpath(manifest_path)
|
||||
path = mozpath.normpath(mozpath.join(sandbox['SRCDIR'], manifest_path))
|
||||
manifest_dir = mozpath.dirname(path)
|
||||
manifest_reldir = mozpath.dirname(mozpath.relpath(path,
|
||||
|
@ -441,7 +441,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
obj.installs[full] = mozpath.join(out_dir, pattern)
|
||||
|
||||
# We also copy the manifest into the output directory.
|
||||
out_path = mozpath.join(out_dir, os.path.basename(manifest_path))
|
||||
out_path = mozpath.join(out_dir, mozpath.basename(manifest_path))
|
||||
obj.installs[path] = out_path
|
||||
|
||||
# Some manifests reference files that are auto generated as
|
||||
|
|
|
@ -40,6 +40,8 @@ from mozbuild.util import (
|
|||
|
||||
from mozbuild.backend.configenvironment import ConfigEnvironment
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
from .data import (
|
||||
JavaJarData,
|
||||
)
|
||||
|
@ -82,8 +84,8 @@ def is_read_allowed(path, config):
|
|||
assert os.path.isabs(path)
|
||||
assert os.path.isabs(config.topsrcdir)
|
||||
|
||||
path = os.path.normpath(path)
|
||||
topsrcdir = os.path.normpath(config.topsrcdir)
|
||||
path = mozpath.normpath(path)
|
||||
topsrcdir = mozpath.normpath(config.topsrcdir)
|
||||
|
||||
if path.startswith(topsrcdir):
|
||||
return True
|
||||
|
@ -91,8 +93,8 @@ def is_read_allowed(path, config):
|
|||
external_dirs = config.substs.get('EXTERNAL_SOURCE_DIR', '').split()
|
||||
for external in external_dirs:
|
||||
if not os.path.isabs(external):
|
||||
external = os.path.join(config.topsrcdir, external)
|
||||
external = os.path.normpath(external)
|
||||
external = mozpath.join(config.topsrcdir, external)
|
||||
external = mozpath.normpath(external)
|
||||
|
||||
if path.startswith(external):
|
||||
return True
|
||||
|
@ -128,19 +130,19 @@ class MozbuildSandbox(Sandbox):
|
|||
self.config = config
|
||||
self.metadata = dict(metadata)
|
||||
|
||||
topobjdir = os.path.abspath(config.topobjdir)
|
||||
topobjdir = mozpath.abspath(config.topobjdir)
|
||||
topsrcdir = config.topsrcdir
|
||||
norm_topsrcdir = os.path.normpath(topsrcdir)
|
||||
norm_topsrcdir = mozpath.normpath(topsrcdir)
|
||||
|
||||
if not path.startswith(norm_topsrcdir):
|
||||
external_dirs = config.substs.get('EXTERNAL_SOURCE_DIR', '').split()
|
||||
for external in external_dirs:
|
||||
external = os.path.normpath(external)
|
||||
external = mozpath.normpath(external)
|
||||
|
||||
if not os.path.isabs(external):
|
||||
external = os.path.join(config.topsrcdir, external)
|
||||
external = mozpath.join(config.topsrcdir, external)
|
||||
|
||||
external = os.path.normpath(external)
|
||||
external = mozpath.normpath(external)
|
||||
|
||||
if not path.startswith(external):
|
||||
continue
|
||||
|
@ -152,27 +154,27 @@ class MozbuildSandbox(Sandbox):
|
|||
# is in play that the main build system is built in a
|
||||
# subdirectory of its topobjdir. Therefore, the topobjdir of
|
||||
# the external source directory is the parent of our topobjdir.
|
||||
topobjdir = os.path.dirname(topobjdir)
|
||||
topobjdir = mozpath.dirname(topobjdir)
|
||||
|
||||
# This is suboptimal because we load the config.status multiple
|
||||
# times. We should consider caching it, possibly by moving this
|
||||
# code up to the reader.
|
||||
config = ConfigEnvironment.from_config_status(
|
||||
os.path.join(topobjdir, 'config.status'))
|
||||
mozpath.join(topobjdir, 'config.status'))
|
||||
self.config = config
|
||||
break
|
||||
|
||||
self.topsrcdir = topsrcdir
|
||||
|
||||
relpath = os.path.relpath(path, topsrcdir).replace(os.sep, '/')
|
||||
reldir = os.path.dirname(relpath)
|
||||
relpath = mozpath.relpath(path, topsrcdir)
|
||||
reldir = mozpath.dirname(relpath)
|
||||
|
||||
with self._globals.allow_all_writes() as d:
|
||||
d['TOPSRCDIR'] = topsrcdir
|
||||
d['TOPOBJDIR'] = topobjdir
|
||||
d['RELATIVEDIR'] = reldir
|
||||
d['SRCDIR'] = os.path.join(topsrcdir, reldir).replace(os.sep, '/').rstrip('/')
|
||||
d['OBJDIR'] = os.path.join(topobjdir, reldir).replace(os.sep, '/').rstrip('/')
|
||||
d['SRCDIR'] = mozpath.join(topsrcdir, reldir).rstrip('/')
|
||||
d['OBJDIR'] = mozpath.join(topobjdir, reldir).rstrip('/')
|
||||
|
||||
d['CONFIG'] = ReadOnlyDefaultDict(self.config.substs_unicode,
|
||||
global_default=None)
|
||||
|
@ -205,21 +207,21 @@ class MozbuildSandbox(Sandbox):
|
|||
"""
|
||||
if os.path.isabs(path):
|
||||
if not filesystem_absolute:
|
||||
path = os.path.normpath(os.path.join(self.topsrcdir,
|
||||
path = mozpath.normpath(mozpath.join(self.topsrcdir,
|
||||
path[1:]))
|
||||
|
||||
else:
|
||||
if len(self._execution_stack):
|
||||
path = os.path.normpath(os.path.join(
|
||||
os.path.dirname(self._execution_stack[-1]),
|
||||
path = mozpath.normpath(mozpath.join(
|
||||
mozpath.dirname(self._execution_stack[-1]),
|
||||
path))
|
||||
else:
|
||||
path = os.path.normpath(os.path.join(
|
||||
path = mozpath.normpath(mozpath.join(
|
||||
self.topsrcdir, path))
|
||||
|
||||
# realpath() is needed for true security. But, this isn't for security
|
||||
# protection, so it is omitted.
|
||||
normalized_path = os.path.normpath(path)
|
||||
normalized_path = mozpath.normpath(path)
|
||||
if not is_read_allowed(normalized_path, self.config):
|
||||
raise SandboxLoadError(list(self._execution_stack),
|
||||
sys.exc_info()[2], illegal_path=path)
|
||||
|
@ -609,7 +611,7 @@ class BuildReader(object):
|
|||
This is a generator of Sandbox instances. As each mozbuild file is
|
||||
read, a new Sandbox is created. Each created Sandbox is returned.
|
||||
"""
|
||||
path = os.path.join(self.topsrcdir, 'moz.build')
|
||||
path = mozpath.join(self.topsrcdir, 'moz.build')
|
||||
return self.read_mozbuild(path, read_tiers=True,
|
||||
filesystem_absolute=True, metadata={'tier': None})
|
||||
|
||||
|
@ -672,7 +674,7 @@ class BuildReader(object):
|
|||
|
||||
def _read_mozbuild(self, path, read_tiers, filesystem_absolute, descend,
|
||||
metadata):
|
||||
path = os.path.normpath(path)
|
||||
path = mozpath.normpath(path)
|
||||
log(self._log, logging.DEBUG, 'read_mozbuild', {'path': path},
|
||||
'Reading file: {path}')
|
||||
|
||||
|
@ -750,15 +752,15 @@ class BuildReader(object):
|
|||
'parent': sandbox['RELATIVEDIR'],
|
||||
'var': 'DIRS'}
|
||||
|
||||
curdir = os.path.dirname(path)
|
||||
curdir = mozpath.dirname(path)
|
||||
for relpath, child_metadata in recurse_info.items():
|
||||
child_path = os.path.join(curdir, relpath, 'moz.build')
|
||||
child_path = mozpath.join(curdir, relpath, 'moz.build')
|
||||
|
||||
# Ensure we don't break out of the topsrcdir. We don't do realpath
|
||||
# because it isn't necessary. If there are symlinks in the srcdir,
|
||||
# that's not our problem. We're not a hosted application: we don't
|
||||
# need to worry about security too much.
|
||||
child_path = os.path.normpath(child_path)
|
||||
child_path = mozpath.normpath(child_path)
|
||||
if not is_read_allowed(child_path, self.config):
|
||||
raise SandboxValidationError(
|
||||
'Attempting to process file outside of allowed paths: %s' %
|
||||
|
|
|
@ -16,13 +16,15 @@ from mozbuild.backend.configenvironment import ConfigEnvironment
|
|||
from mozbuild.frontend.emitter import TreeMetadataEmitter
|
||||
from mozbuild.frontend.reader import BuildReader
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
||||
log_manager = LoggingManager()
|
||||
log_manager.add_terminal_logging()
|
||||
|
||||
|
||||
test_data_path = os.path.abspath(os.path.dirname(__file__))
|
||||
test_data_path = os.path.join(test_data_path, 'data')
|
||||
test_data_path = mozpath.abspath(mozpath.dirname(__file__))
|
||||
test_data_path = mozpath.join(test_data_path, 'data')
|
||||
|
||||
|
||||
CONFIGS = {
|
||||
|
@ -98,6 +100,16 @@ CONFIGS = {
|
|||
'non_global_defines': [],
|
||||
'substs': [],
|
||||
},
|
||||
'test_config': {
|
||||
'defines': [
|
||||
('foo', 'baz qux'),
|
||||
('baz', 1)
|
||||
],
|
||||
'non_global_defines': [],
|
||||
'substs': [
|
||||
('foo', 'bar baz'),
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,7 +125,7 @@ class BackendTester(unittest.TestCase):
|
|||
objdir = mkdtemp()
|
||||
self.addCleanup(rmtree, objdir)
|
||||
|
||||
srcdir = os.path.join(test_data_path, name)
|
||||
srcdir = mozpath.join(test_data_path, name)
|
||||
config['substs'].append(('top_srcdir', srcdir))
|
||||
return ConfigEnvironment(srcdir, objdir, **config)
|
||||
|
||||
|
@ -135,7 +147,7 @@ class BackendTester(unittest.TestCase):
|
|||
for dirpath, dirnames, filenames in os.walk(topdir):
|
||||
for f in filenames:
|
||||
if f == filename:
|
||||
yield os.path.relpath(os.path.join(dirpath, f), topdir)
|
||||
yield mozpath.relpath(mozpath.join(dirpath, f), topdir)
|
||||
|
||||
def _mozbuild_paths(self, env):
|
||||
return self._tree_paths(env.topsrcdir, 'moz.build')
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/* Comment */
|
||||
#define foo
|
||||
#define foo 42
|
||||
#undef foo
|
||||
#define bar
|
||||
#define bar 42
|
||||
#undef bar
|
||||
|
||||
# undef baz
|
||||
|
||||
#ifdef foo
|
||||
# undef foo
|
||||
# define foo 42
|
||||
# define foo 42
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
#ifdef foo
|
||||
@foo@
|
||||
@bar@
|
|
@ -0,0 +1,6 @@
|
|||
CONFIGURE_SUBST_FILES = [
|
||||
'file',
|
||||
]
|
||||
CONFIGURE_DEFINE_FILES = [
|
||||
'file.h',
|
||||
]
|
|
@ -11,6 +11,8 @@ import mozbuild.backend.configenvironment as ConfigStatus
|
|||
|
||||
from mozbuild.util import ReadOnlyDict
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
||||
class ConfigEnvironment(ConfigStatus.ConfigEnvironment):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -20,7 +22,7 @@ class ConfigEnvironment(ConfigStatus.ConfigEnvironment):
|
|||
if os.path.isabs(self.topsrcdir):
|
||||
top_srcdir = self.topsrcdir.replace(os.sep, '/')
|
||||
else:
|
||||
top_srcdir = os.path.relpath(self.topsrcdir, self.topobjdir).replace(os.sep, '/')
|
||||
top_srcdir = mozpath.relpath(self.topsrcdir, self.topobjdir).replace(os.sep, '/')
|
||||
|
||||
d = dict(self.substs)
|
||||
d['top_srcdir'] = top_srcdir
|
||||
|
@ -62,262 +64,6 @@ zzz = "abc def"''')
|
|||
self.assertEqual(env.substs['ALLEMPTYSUBSTS'], '''FOOBAR =
|
||||
qux =''')
|
||||
|
||||
def test_config_file(self):
|
||||
'''Test the creation of config files.
|
||||
'''
|
||||
with MockedOpen({'file.in': '''#ifdef foo
|
||||
@foo@
|
||||
@bar@
|
||||
'''}):
|
||||
env = ConfigEnvironment('.', '.', substs = [ ('foo', 'bar baz') ])
|
||||
with open('file', 'w') as fh:
|
||||
env.create_config_file(fh)
|
||||
self.assertEqual(open('file', 'r').read(), '''#ifdef foo
|
||||
bar baz
|
||||
@bar@
|
||||
''')
|
||||
|
||||
def test_config_header(self):
|
||||
'''Test the creation of config headers.
|
||||
'''
|
||||
with MockedOpen({'file.in': '''
|
||||
/* Comment */
|
||||
#define foo
|
||||
#define foo 42
|
||||
#undef foo
|
||||
#define bar
|
||||
#define bar 42
|
||||
#undef bar
|
||||
|
||||
# undef baz
|
||||
|
||||
#ifdef foo
|
||||
# undef foo
|
||||
# define foo 42
|
||||
# define foo 42
|
||||
#endif
|
||||
'''}):
|
||||
env = ConfigEnvironment('.', '.', defines = [ ('foo', 'baz qux'), ('baz', 1) ])
|
||||
with open('file', 'w') as fh:
|
||||
env.create_config_header(fh)
|
||||
self.assertEqual(open('file','r').read(), '''
|
||||
/* Comment */
|
||||
#define foo
|
||||
#define foo baz qux
|
||||
#define foo baz qux
|
||||
#define bar
|
||||
#define bar 42
|
||||
/* #undef bar */
|
||||
|
||||
# define baz 1
|
||||
|
||||
#ifdef foo
|
||||
# define foo baz qux
|
||||
# define foo baz qux
|
||||
# define foo baz qux
|
||||
#endif
|
||||
''')
|
||||
|
||||
# Tests for get_relative_srcdir, get_depth, get_input and get_file_srcdir,
|
||||
# depending on various cases of top source directory and top build
|
||||
# directory location.
|
||||
class TestPaths(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.dir = os.path.basename(os.path.abspath(os.curdir))
|
||||
self.absolute = os.path.normpath('/absolute')
|
||||
|
||||
class TestPathsLocalBuildDir(TestPaths):
|
||||
def get_env(self, topsrcdir):
|
||||
env = ConfigEnvironment(topsrcdir = topsrcdir, topobjdir = '.')
|
||||
self.assertEqual(env.get_relative_srcdir('file'), '.')
|
||||
self.assertEqual(env.get_relative_srcdir('dir/file'), 'dir')
|
||||
self.assertEqual(env.get_relative_srcdir('deeply/nested/path/to/file'), 'deeply/nested/path/to')
|
||||
self.assertEqual(env.get_depth('file'), '.')
|
||||
self.assertEqual(env.get_depth('dir/file'), '..')
|
||||
self.assertEqual(env.get_depth('deeply/nested/path/to/file'), '../../../..')
|
||||
return env
|
||||
|
||||
def test_paths_local_build_local_src(self):
|
||||
# topsrcdir = . ; topobjdir = .
|
||||
env = self.get_env('.')
|
||||
self.assertEqual(env.get_input('file'), 'file.in')
|
||||
self.assertEqual(env.get_input('dir/file'), os.path.join('dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('file'), '.')
|
||||
self.assertEqual(env.get_top_srcdir('dir/file'), '..')
|
||||
self.assertEqual(env.get_file_srcdir('file'), '.')
|
||||
self.assertEqual(env.get_file_srcdir('dir/file'), '../dir')
|
||||
|
||||
def test_paths_local_build_parent_src(self):
|
||||
# topsrcdir = .. ; topobjdir = .
|
||||
env = self.get_env('..')
|
||||
self.assertEqual(env.get_input('file'), os.path.join('..', 'file.in'))
|
||||
self.assertEqual(env.get_input('dir/file'), os.path.join('..', 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('file'), '..')
|
||||
self.assertEqual(env.get_top_srcdir('dir/file'), '../..')
|
||||
self.assertEqual(env.get_file_srcdir('file'), '..')
|
||||
self.assertEqual(env.get_file_srcdir('dir/file'), '../../dir')
|
||||
|
||||
def test_paths_local_build_absolute_src(self):
|
||||
# topsrcdir = /absolute ; topobjdir = /absolute
|
||||
env = self.get_env(self.absolute)
|
||||
self.assertEqual(env.get_input('file'), os.path.join(self.absolute, 'file.in'))
|
||||
self.assertEqual(env.get_input('dir/file'), os.path.join(self.absolute, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_input('%s/file' % self.dir), os.path.join(self.absolute, self.dir, 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('file'), '/absolute')
|
||||
self.assertEqual(env.get_top_srcdir('dir/file'), '/absolute')
|
||||
self.assertEqual(env.get_top_srcdir('%s/file' % dir), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('dir/file'), '/absolute/dir')
|
||||
self.assertEqual(env.get_file_srcdir('%s/file' % dir), '/absolute/%s' % dir)
|
||||
|
||||
class TestPathsParentBuildDir(TestPaths):
|
||||
def get_env(self, topsrcdir):
|
||||
env = ConfigEnvironment(topsrcdir = topsrcdir, topobjdir = '..')
|
||||
self.assertEqual(env.get_relative_srcdir('..'), '.')
|
||||
self.assertEqual(env.get_relative_srcdir('file'), self.dir)
|
||||
self.assertEqual(env.get_relative_srcdir('dir/file'), '%s/dir' % self.dir)
|
||||
self.assertEqual(env.get_relative_srcdir('deeply/nested/path/to/file'), '%s/deeply/nested/path/to' % self.dir)
|
||||
self.assertEqual(env.get_depth('../file'), '.')
|
||||
self.assertEqual(env.get_depth('file'), '..')
|
||||
self.assertEqual(env.get_depth('dir/file'), '../..')
|
||||
self.assertEqual(env.get_depth('deeply/nested/path/to/file'), '../../../../..')
|
||||
return env
|
||||
|
||||
def test_paths_parent_build_parent_src(self):
|
||||
# topsrcdir = .. ; topobjdir = ..
|
||||
env = self.get_env('..')
|
||||
self.assertEqual(env.get_input('../file'), os.path.join('..', 'file.in'))
|
||||
self.assertEqual(env.get_input('file'), os.path.join('..', self.dir, 'file.in'))
|
||||
self.assertEqual(env.get_input('dir/file'), os.path.join('..', self.dir, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('../file'), '.')
|
||||
self.assertEqual(env.get_top_srcdir('file'), '..')
|
||||
self.assertEqual(env.get_top_srcdir('dir/file'), '../..')
|
||||
self.assertEqual(env.get_file_srcdir('../file'), '.')
|
||||
self.assertEqual(env.get_file_srcdir('file'), '../%s' % self.dir)
|
||||
self.assertEqual(env.get_file_srcdir('dir/file'), '../../%s/dir' % self.dir)
|
||||
|
||||
def test_paths_parent_build_ancestor_src(self):
|
||||
# topsrcdir = ../.. ; topobjdir = ..
|
||||
env = self.get_env('../..')
|
||||
self.assertEqual(env.get_input('../file'), os.path.join('..', '..', 'file.in'))
|
||||
self.assertEqual(env.get_input('file'), os.path.join('..', '..', self.dir, 'file.in'))
|
||||
self.assertEqual(env.get_input('dir/file'), os.path.join('..', '..', self.dir, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('../file'), '..')
|
||||
self.assertEqual(env.get_top_srcdir('file'), '../..')
|
||||
self.assertEqual(env.get_top_srcdir('dir/file'), '../../..')
|
||||
self.assertEqual(env.get_file_srcdir('../file'), '..')
|
||||
self.assertEqual(env.get_file_srcdir('file'), '../../%s' % self.dir)
|
||||
self.assertEqual(env.get_file_srcdir('dir/file'), '../../../%s/dir' % self.dir)
|
||||
|
||||
def test_paths_parent_build_absolute_src(self):
|
||||
# topsrcdir = /absolute ; topobjdir = ..
|
||||
env = self.get_env(self.absolute)
|
||||
self.assertEqual(env.get_input('../file'), os.path.join(self.absolute, 'file.in'))
|
||||
self.assertEqual(env.get_input('file'), os.path.join(self.absolute, self.dir, 'file.in'))
|
||||
self.assertEqual(env.get_input('dir/file'), os.path.join(self.absolute, self.dir, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('../file'), '/absolute')
|
||||
self.assertEqual(env.get_top_srcdir('file'), '/absolute')
|
||||
self.assertEqual(env.get_top_srcdir('dir/file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('../file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('file'), '/absolute/%s' % self.dir)
|
||||
self.assertEqual(env.get_file_srcdir('dir/file'), '/absolute/%s/dir' % self.dir)
|
||||
|
||||
class TestPathsRelativeBuild(TestPaths):
|
||||
def get_env(self, topsrcdir):
|
||||
env = ConfigEnvironment(topsrcdir = topsrcdir, topobjdir = 'relative')
|
||||
self.assertEqual(env.get_relative_srcdir('relative/file'), '.')
|
||||
self.assertEqual(env.get_relative_srcdir('relative/dir/file'), 'dir')
|
||||
self.assertEqual(env.get_relative_srcdir('relative/deeply/nested/path/to/file'), 'deeply/nested/path/to')
|
||||
self.assertEqual(env.get_depth('relative/file'), '.')
|
||||
self.assertEqual(env.get_depth('relative/dir/file'), '..')
|
||||
self.assertEqual(env.get_depth('relative/deeply/nested/path/to/file'), '../../../..')
|
||||
return env
|
||||
|
||||
def test_paths_relative_build_relative_src(self):
|
||||
# topsrcdir = relative ; topobjdir = relative
|
||||
env = self.get_env('relative')
|
||||
self.assertEqual(env.get_input('relative/file'), os.path.join('relative', 'file.in'))
|
||||
self.assertEqual(env.get_input('relative/dir/file'), os.path.join('relative', 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('relative/file'), '.')
|
||||
self.assertEqual(env.get_top_srcdir('relative/dir/file'), '..')
|
||||
self.assertEqual(env.get_file_srcdir('relative/file'), '.')
|
||||
self.assertEqual(env.get_file_srcdir('relative/dir/file'), '../dir')
|
||||
|
||||
def test_paths_relative_build_local_src(self):
|
||||
# topsrcdir = . ; topobjdir = relative
|
||||
env = self.get_env('.')
|
||||
self.assertEqual(env.get_input('relative/file'), 'file.in')
|
||||
self.assertEqual(env.get_input('relative/dir/file'), os.path.join('dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('relative/file'), '..')
|
||||
self.assertEqual(env.get_top_srcdir('relative/dir/file'), '../..')
|
||||
self.assertEqual(env.get_file_srcdir('relative/file'), '..')
|
||||
self.assertEqual(env.get_file_srcdir('relative/dir/file'), '../../dir')
|
||||
|
||||
def test_paths_relative_build_parent_src(self):
|
||||
# topsrcdir = .. ; topobjdir = relative
|
||||
env = self.get_env('..')
|
||||
self.assertEqual(env.get_input('relative/file'), os.path.join('..', 'file.in'))
|
||||
self.assertEqual(env.get_input('relative/dir/file'), os.path.join('..', 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('relative/file'), '../..')
|
||||
self.assertEqual(env.get_top_srcdir('relative/dir/file'), '../../..')
|
||||
self.assertEqual(env.get_file_srcdir('relative/file'), '../..')
|
||||
self.assertEqual(env.get_file_srcdir('relative/dir/file'), '../../../dir')
|
||||
|
||||
def test_paths_relative_build_absolute_src(self):
|
||||
# topsrcdir = /absolute ; topobjdir = relative
|
||||
env = self.get_env(self.absolute)
|
||||
self.assertEqual(env.get_input('relative/file'), os.path.join(self.absolute, 'file.in'))
|
||||
self.assertEqual(env.get_input('relative/dir/file'), os.path.join(self.absolute, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('relative/file'), '/absolute')
|
||||
self.assertEqual(env.get_top_srcdir('relative/dir/file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('relative/file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('relative/dir/file'), '/absolute/dir')
|
||||
|
||||
class TestPathsAbsoluteBuild(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.absolute_build = os.path.normpath('/absolute/build')
|
||||
|
||||
def get_env(self, topsrcdir):
|
||||
env = ConfigEnvironment(topsrcdir = topsrcdir, topobjdir = self.absolute_build)
|
||||
self.assertEqual(env.get_relative_srcdir('/absolute/build/file'), '.')
|
||||
self.assertEqual(env.get_relative_srcdir('/absolute/build/dir/file'), 'dir')
|
||||
self.assertEqual(env.get_relative_srcdir('/absolute/build/deeply/nested/path/to/file'), 'deeply/nested/path/to')
|
||||
self.assertEqual(env.get_depth('/absolute/build/file'), '.')
|
||||
self.assertEqual(env.get_depth('/absolute/build/dir/file'), '..')
|
||||
self.assertEqual(env.get_depth('/absolute/build/deeply/nested/path/to/file'), '../../../..')
|
||||
return env
|
||||
|
||||
def test_paths_absolute_build_same_src(self):
|
||||
# topsrcdir = /absolute/build ; topobjdir = /absolute/build
|
||||
env = self.get_env(self.absolute_build)
|
||||
self.assertEqual(env.get_input('/absolute/build/file'), os.path.join(self.absolute_build, 'file.in'))
|
||||
self.assertEqual(env.get_input('/absolute/build/dir/file'), os.path.join(self.absolute_build, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('/absolute/build/file'), '/absolute/build')
|
||||
self.assertEqual(env.get_top_srcdir('/absolute/build/dir/file'), '/absolute/build')
|
||||
self.assertEqual(env.get_file_srcdir('/absolute/build/file'), '/absolute/build')
|
||||
self.assertEqual(env.get_file_srcdir('/absolute/build/dir/file'), '/absolute/build/dir')
|
||||
|
||||
def test_paths_absolute_build_ancestor_src(self):
|
||||
# topsrcdir = /absolute ; topobjdir = /absolute/build
|
||||
absolute = os.path.dirname(self.absolute_build)
|
||||
env = self.get_env(absolute)
|
||||
self.assertEqual(env.get_input('/absolute/build/file'), os.path.join(absolute, 'file.in'))
|
||||
self.assertEqual(env.get_input('/absolute/build/dir/file'), os.path.join(absolute, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('/absolute/build/file'), '/absolute')
|
||||
self.assertEqual(env.get_top_srcdir('/absolute/build/dir/file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('/absolute/build/file'), '/absolute')
|
||||
self.assertEqual(env.get_file_srcdir('/absolute/build/dir/file'), '/absolute/dir')
|
||||
|
||||
def test_paths_absolute_build_different_src(self):
|
||||
# topsrcdir = /some/path ; topobjdir = /absolute/build
|
||||
absolute = os.path.normpath('/some/path')
|
||||
env = self.get_env(absolute)
|
||||
self.assertEqual(env.get_input('/absolute/build/file'), os.path.join(absolute, 'file.in'))
|
||||
self.assertEqual(env.get_input('/absolute/build/dir/file'), os.path.join(absolute, 'dir', 'file.in'))
|
||||
self.assertEqual(env.get_top_srcdir('/absolute/build/file'), '/some/path')
|
||||
self.assertEqual(env.get_top_srcdir('/absolute/build/dir/file'), '/some/path')
|
||||
self.assertEqual(env.get_file_srcdir('/absolute/build/file'), '/some/path')
|
||||
self.assertEqual(env.get_file_srcdir('/absolute/build/dir/file'), '/some/path/dir')
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -22,6 +22,8 @@ from mozbuild.frontend.reader import BuildReader
|
|||
|
||||
from mozbuild.test.backend.common import BackendTester
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
||||
class TestRecursiveMakeTraversal(unittest.TestCase):
|
||||
def test_traversal(self):
|
||||
|
@ -152,9 +154,9 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
def test_basic(self):
|
||||
"""Ensure the RecursiveMakeBackend works without error."""
|
||||
env = self._consume('stub0', RecursiveMakeBackend)
|
||||
self.assertTrue(os.path.exists(os.path.join(env.topobjdir,
|
||||
self.assertTrue(os.path.exists(mozpath.join(env.topobjdir,
|
||||
'backend.RecursiveMakeBackend')))
|
||||
self.assertTrue(os.path.exists(os.path.join(env.topobjdir,
|
||||
self.assertTrue(os.path.exists(mozpath.join(env.topobjdir,
|
||||
'backend.RecursiveMakeBackend.pp')))
|
||||
|
||||
def test_output_files(self):
|
||||
|
@ -164,8 +166,8 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
expected = ['', 'dir1', 'dir2']
|
||||
|
||||
for d in expected:
|
||||
out_makefile = os.path.join(env.topobjdir, d, 'Makefile')
|
||||
out_backend = os.path.join(env.topobjdir, d, 'backend.mk')
|
||||
out_makefile = mozpath.join(env.topobjdir, d, 'Makefile')
|
||||
out_backend = mozpath.join(env.topobjdir, d, 'backend.mk')
|
||||
|
||||
self.assertTrue(os.path.exists(out_makefile))
|
||||
self.assertTrue(os.path.exists(out_backend))
|
||||
|
@ -174,7 +176,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure Makefile.in is converted properly."""
|
||||
env = self._consume('stub0', RecursiveMakeBackend)
|
||||
|
||||
p = os.path.join(env.topobjdir, 'Makefile')
|
||||
p = mozpath.join(env.topobjdir, 'Makefile')
|
||||
|
||||
lines = [l.strip() for l in open(p, 'rt').readlines()[1:] if not l.startswith('#')]
|
||||
self.assertEqual(lines, [
|
||||
|
@ -194,7 +196,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure missing Makefile.in results in Makefile creation."""
|
||||
env = self._consume('stub0', RecursiveMakeBackend)
|
||||
|
||||
p = os.path.join(env.topobjdir, 'dir2', 'Makefile')
|
||||
p = mozpath.join(env.topobjdir, 'dir2', 'Makefile')
|
||||
self.assertTrue(os.path.exists(p))
|
||||
|
||||
lines = [l.strip() for l in open(p, 'rt').readlines()]
|
||||
|
@ -206,7 +208,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure backend.mk file is written out properly."""
|
||||
env = self._consume('stub0', RecursiveMakeBackend)
|
||||
|
||||
p = os.path.join(env.topobjdir, 'backend.mk')
|
||||
p = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
|
||||
lines = [l.strip() for l in open(p, 'rt').readlines()[2:]]
|
||||
self.assertEqual(lines, [
|
||||
|
@ -221,8 +223,8 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
|
||||
env = self._consume('stub0', RecursiveMakeBackend)
|
||||
|
||||
makefile_path = os.path.join(env.topobjdir, 'Makefile')
|
||||
backend_path = os.path.join(env.topobjdir, 'backend.mk')
|
||||
makefile_path = mozpath.join(env.topobjdir, 'Makefile')
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
makefile_mtime = os.path.getmtime(makefile_path)
|
||||
backend_mtime = os.path.getmtime(backend_path)
|
||||
|
||||
|
@ -238,7 +240,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure we have make recursion into external make directories."""
|
||||
env = self._consume('external_make_dirs', RecursiveMakeBackend)
|
||||
|
||||
backend_path = os.path.join(env.topobjdir, 'backend.mk')
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
self.assertEqual(lines, [
|
||||
'MOZBUILD_DERIVED := 1',
|
||||
|
@ -252,7 +254,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure substituted config files are produced."""
|
||||
env = self._consume('substitute_config_files', RecursiveMakeBackend)
|
||||
|
||||
p = os.path.join(env.topobjdir, 'foo')
|
||||
p = mozpath.join(env.topobjdir, 'foo')
|
||||
self.assertTrue(os.path.exists(p))
|
||||
lines = [l.strip() for l in open(p, 'rt').readlines()]
|
||||
self.assertEqual(lines, [
|
||||
|
@ -263,7 +265,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure variable passthru is written out correctly."""
|
||||
env = self._consume('variable_passthru', RecursiveMakeBackend)
|
||||
|
||||
backend_path = os.path.join(env.topobjdir, 'backend.mk')
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
|
||||
expected = {
|
||||
|
@ -346,7 +348,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
env = self._consume('exports', RecursiveMakeBackend)
|
||||
|
||||
# EXPORTS files should appear in the dist_include install manifest.
|
||||
m = InstallManifest(path=os.path.join(env.topobjdir,
|
||||
m = InstallManifest(path=mozpath.join(env.topobjdir,
|
||||
'_build_manifests', 'install', 'dist_include'))
|
||||
self.assertEqual(len(m), 7)
|
||||
self.assertIn('foo.h', m)
|
||||
|
@ -357,9 +359,9 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Ensure test manifests get turned into files."""
|
||||
env = self._consume('test-manifests-written', RecursiveMakeBackend)
|
||||
|
||||
tests_dir = os.path.join(env.topobjdir, '_tests')
|
||||
m_master = os.path.join(tests_dir, 'testing', 'mochitest', 'tests', 'mochitest.ini')
|
||||
x_master = os.path.join(tests_dir, 'xpcshell', 'xpcshell.ini')
|
||||
tests_dir = mozpath.join(env.topobjdir, '_tests')
|
||||
m_master = mozpath.join(tests_dir, 'testing', 'mochitest', 'tests', 'mochitest.ini')
|
||||
x_master = mozpath.join(tests_dir, 'xpcshell', 'xpcshell.ini')
|
||||
self.assertTrue(os.path.exists(m_master))
|
||||
self.assertTrue(os.path.exists(x_master))
|
||||
|
||||
|
@ -371,7 +373,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
'[include:xpcshell.ini]',
|
||||
])
|
||||
|
||||
all_tests_path = os.path.join(env.topobjdir, 'all-tests.json')
|
||||
all_tests_path = mozpath.join(env.topobjdir, 'all-tests.json')
|
||||
self.assertTrue(os.path.exists(all_tests_path))
|
||||
|
||||
with open(all_tests_path, 'rt') as fh:
|
||||
|
@ -385,7 +387,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
def test_test_manifest_pattern_matches_recorded(self):
|
||||
"""Pattern matches in test manifests' support-files should be recorded."""
|
||||
env = self._consume('test-manifests-written', RecursiveMakeBackend)
|
||||
m = InstallManifest(path=os.path.join(env.topobjdir,
|
||||
m = InstallManifest(path=mozpath.join(env.topobjdir,
|
||||
'_build_manifests', 'install', 'tests'))
|
||||
|
||||
# This is not the most robust test in the world, but it gets the job
|
||||
|
@ -399,34 +401,34 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
env = self._consume('xpidl', RecursiveMakeBackend)
|
||||
|
||||
# Install manifests should contain entries.
|
||||
install_dir = os.path.join(env.topobjdir, '_build_manifests',
|
||||
install_dir = mozpath.join(env.topobjdir, '_build_manifests',
|
||||
'install')
|
||||
self.assertTrue(os.path.isfile(os.path.join(install_dir, 'dist_idl')))
|
||||
self.assertTrue(os.path.isfile(os.path.join(install_dir, 'xpidl')))
|
||||
self.assertTrue(os.path.isfile(mozpath.join(install_dir, 'dist_idl')))
|
||||
self.assertTrue(os.path.isfile(mozpath.join(install_dir, 'xpidl')))
|
||||
|
||||
m = InstallManifest(path=os.path.join(install_dir, 'dist_idl'))
|
||||
m = InstallManifest(path=mozpath.join(install_dir, 'dist_idl'))
|
||||
self.assertEqual(len(m), 2)
|
||||
self.assertIn('bar.idl', m)
|
||||
self.assertIn('foo.idl', m)
|
||||
|
||||
m = InstallManifest(path=os.path.join(install_dir, 'xpidl'))
|
||||
m = InstallManifest(path=mozpath.join(install_dir, 'xpidl'))
|
||||
self.assertIn('.deps/my_module.pp', m)
|
||||
self.assertIn('xpt/my_module.xpt', m)
|
||||
|
||||
m = InstallManifest(path=os.path.join(install_dir, 'dist_include'))
|
||||
m = InstallManifest(path=mozpath.join(install_dir, 'dist_include'))
|
||||
self.assertIn('foo.h', m)
|
||||
|
||||
p = os.path.join(env.topobjdir, 'config/makefiles/xpidl')
|
||||
p = mozpath.join(env.topobjdir, 'config/makefiles/xpidl')
|
||||
self.assertTrue(os.path.isdir(p))
|
||||
|
||||
self.assertTrue(os.path.isfile(os.path.join(p, 'Makefile')))
|
||||
self.assertTrue(os.path.isfile(mozpath.join(p, 'Makefile')))
|
||||
|
||||
def test_old_install_manifest_deleted(self):
|
||||
# Simulate an install manifest from a previous backend version. Ensure
|
||||
# it is deleted.
|
||||
env = self._get_environment('stub0')
|
||||
purge_dir = os.path.join(env.topobjdir, '_build_manifests', 'install')
|
||||
manifest_path = os.path.join(purge_dir, 'old_manifest')
|
||||
purge_dir = mozpath.join(env.topobjdir, '_build_manifests', 'install')
|
||||
manifest_path = mozpath.join(purge_dir, 'old_manifest')
|
||||
os.makedirs(purge_dir)
|
||||
m = InstallManifest()
|
||||
m.write(path=manifest_path)
|
||||
|
@ -444,12 +446,12 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
m.add_symlink(__file__, 'self')
|
||||
backend.consume(objs)
|
||||
|
||||
man_dir = os.path.join(env.topobjdir, '_build_manifests', 'install')
|
||||
man_dir = mozpath.join(env.topobjdir, '_build_manifests', 'install')
|
||||
self.assertTrue(os.path.isdir(man_dir))
|
||||
|
||||
expected = ['testing']
|
||||
for e in expected:
|
||||
full = os.path.join(man_dir, e)
|
||||
full = mozpath.join(man_dir, e)
|
||||
self.assertTrue(os.path.exists(full))
|
||||
|
||||
m2 = InstallManifest(path=full)
|
||||
|
@ -459,7 +461,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Test that IPDL_SOURCES are written to ipdlsrcs.mk correctly."""
|
||||
env = self._consume('ipdl_sources', RecursiveMakeBackend)
|
||||
|
||||
manifest_path = os.path.join(env.topobjdir,
|
||||
manifest_path = mozpath.join(env.topobjdir,
|
||||
'ipc', 'ipdl', 'ipdlsrcs.mk')
|
||||
lines = [l.strip() for l in open(manifest_path, 'rt').readlines()]
|
||||
|
||||
|
@ -481,7 +483,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Test that DEFINES are written to backend.mk correctly."""
|
||||
env = self._consume('defines', RecursiveMakeBackend)
|
||||
|
||||
backend_path = os.path.join(env.topobjdir, 'backend.mk')
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
|
||||
var = 'DEFINES'
|
||||
|
@ -494,7 +496,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Test that LOCAL_INCLUDES are written to backend.mk correctly."""
|
||||
env = self._consume('local_includes', RecursiveMakeBackend)
|
||||
|
||||
backend_path = os.path.join(env.topobjdir, 'backend.mk')
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
|
||||
expected = [
|
||||
|
@ -509,7 +511,7 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
"""Test that GENERATED_INCLUDES are written to backend.mk correctly."""
|
||||
env = self._consume('generated_includes', RecursiveMakeBackend)
|
||||
|
||||
backend_path = os.path.join(env.topobjdir, 'backend.mk')
|
||||
backend_path = mozpath.join(env.topobjdir, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
|
||||
topobjdir = env.topobjdir.replace('\\', '/')
|
||||
|
@ -530,30 +532,60 @@ class TestRecursiveMakeBackend(BackendTester):
|
|||
print([x for x in os.walk(env.topobjdir)])
|
||||
expected = dict()
|
||||
expected[env.topobjdir] = []
|
||||
expected[os.path.join(env.topobjdir, 'both')] = [
|
||||
expected[mozpath.join(env.topobjdir, 'both')] = [
|
||||
'XPI_NAME = mycrazyxpi',
|
||||
'DIST_SUBDIR = asubdir',
|
||||
final_target_rule
|
||||
]
|
||||
expected[os.path.join(env.topobjdir, 'dist-subdir')] = [
|
||||
expected[mozpath.join(env.topobjdir, 'dist-subdir')] = [
|
||||
'DIST_SUBDIR = asubdir',
|
||||
final_target_rule
|
||||
]
|
||||
expected[os.path.join(env.topobjdir, 'xpi-name')] = [
|
||||
expected[mozpath.join(env.topobjdir, 'xpi-name')] = [
|
||||
'XPI_NAME = mycrazyxpi',
|
||||
final_target_rule
|
||||
]
|
||||
expected[os.path.join(env.topobjdir, 'final-target')] = [
|
||||
expected[mozpath.join(env.topobjdir, 'final-target')] = [
|
||||
'FINAL_TARGET = $(DEPTH)/random-final-target'
|
||||
]
|
||||
for key, expected_rules in expected.iteritems():
|
||||
backend_path = os.path.join(key, 'backend.mk')
|
||||
backend_path = mozpath.join(key, 'backend.mk')
|
||||
lines = [l.strip() for l in open(backend_path, 'rt').readlines()[2:]]
|
||||
found = [str for str in lines if
|
||||
str.startswith('FINAL_TARGET') or str.startswith('XPI_NAME') or
|
||||
str.startswith('DIST_SUBDIR')]
|
||||
self.assertEqual(found, expected_rules)
|
||||
|
||||
def test_config(self):
|
||||
"""Test that CONFIGURE_SUBST_FILES and CONFIGURE_DEFINE_FILES are
|
||||
properly handled."""
|
||||
env = self._consume('test_config', RecursiveMakeBackend)
|
||||
|
||||
self.assertEqual(
|
||||
open(os.path.join(env.topobjdir, 'file'), 'r').readlines(), [
|
||||
'#ifdef foo\n',
|
||||
'bar baz\n',
|
||||
'@bar@\n',
|
||||
])
|
||||
|
||||
self.assertEqual(
|
||||
open(os.path.join(env.topobjdir, 'file.h'), 'r').readlines(), [
|
||||
'/* Comment */\n',
|
||||
'#define foo\n',
|
||||
'#define foo baz qux\n',
|
||||
'#define foo baz qux\n',
|
||||
'#define bar\n',
|
||||
'#define bar 42\n',
|
||||
'/* #undef bar */\n',
|
||||
'\n',
|
||||
'# define baz 1\n',
|
||||
'\n',
|
||||
'#ifdef foo\n',
|
||||
'# define foo baz qux\n',
|
||||
'# define foo baz qux\n',
|
||||
' # define foo baz qux \n',
|
||||
'#endif\n',
|
||||
])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -31,14 +31,16 @@ from mozbuild.frontend.reader import (
|
|||
|
||||
from mozbuild.test.common import MockConfig
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
data_path = os.path.abspath(os.path.dirname(__file__))
|
||||
data_path = os.path.join(data_path, 'data')
|
||||
|
||||
data_path = mozpath.abspath(mozpath.dirname(__file__))
|
||||
data_path = mozpath.join(data_path, 'data')
|
||||
|
||||
|
||||
class TestEmitterBasic(unittest.TestCase):
|
||||
def reader(self, name):
|
||||
config = MockConfig(os.path.join(data_path, name), extra_substs=dict(
|
||||
config = MockConfig(mozpath.join(data_path, name), extra_substs=dict(
|
||||
ENABLE_TESTS='1',
|
||||
BIN_SUFFIX='.prog',
|
||||
))
|
||||
|
@ -121,12 +123,12 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
self.assertIsInstance(objs[1], ConfigFileSubstitution)
|
||||
self.assertIsInstance(objs[2], ConfigFileSubstitution)
|
||||
|
||||
topobjdir = os.path.abspath(reader.config.topobjdir)
|
||||
topobjdir = mozpath.abspath(reader.config.topobjdir)
|
||||
self.assertEqual(objs[1].relpath, 'foo')
|
||||
self.assertEqual(os.path.normpath(objs[1].output_path),
|
||||
os.path.normpath(os.path.join(topobjdir, 'foo')))
|
||||
self.assertEqual(os.path.normpath(objs[2].output_path),
|
||||
os.path.normpath(os.path.join(topobjdir, 'bar')))
|
||||
self.assertEqual(mozpath.normpath(objs[1].output_path),
|
||||
mozpath.normpath(mozpath.join(topobjdir, 'foo')))
|
||||
self.assertEqual(mozpath.normpath(objs[2].output_path),
|
||||
mozpath.normpath(mozpath.join(topobjdir, 'bar')))
|
||||
|
||||
def test_variable_passthru(self):
|
||||
reader = self.reader('variable-passthru')
|
||||
|
@ -300,13 +302,13 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
}
|
||||
|
||||
for o in objs:
|
||||
m = metadata[os.path.basename(o.manifest_relpath)]
|
||||
m = metadata[mozpath.basename(o.manifest_relpath)]
|
||||
|
||||
self.assertTrue(o.path.startswith(o.directory))
|
||||
self.assertEqual(o.flavor, m['flavor'])
|
||||
self.assertEqual(o.dupe_manifest, m.get('dupe', False))
|
||||
|
||||
external_normalized = set(os.path.basename(p) for p in
|
||||
external_normalized = set(mozpath.basename(p) for p in
|
||||
o.external_installs)
|
||||
self.assertEqual(external_normalized, m.get('external', set()))
|
||||
|
||||
|
@ -341,7 +343,7 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
o = objs[0]
|
||||
|
||||
self.assertEqual(o.flavor, 'mochitest')
|
||||
basenames = set(os.path.basename(k) for k in o.installs.keys())
|
||||
basenames = set(mozpath.basename(k) for k in o.installs.keys())
|
||||
self.assertEqual(basenames, {'mochitest.ini', 'test_active.html'})
|
||||
|
||||
def test_ipdl_sources(self):
|
||||
|
|
|
@ -15,19 +15,21 @@ from mozbuild.frontend.reader import BuildReader
|
|||
|
||||
from mozbuild.test.common import MockConfig
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
|
||||
if sys.version_info.major == 2:
|
||||
text_type = 'unicode'
|
||||
else:
|
||||
text_type = 'str'
|
||||
|
||||
data_path = os.path.abspath(os.path.dirname(__file__))
|
||||
data_path = os.path.join(data_path, 'data')
|
||||
data_path = mozpath.abspath(mozpath.dirname(__file__))
|
||||
data_path = mozpath.join(data_path, 'data')
|
||||
|
||||
|
||||
class TestBuildReader(unittest.TestCase):
|
||||
def config(self, name, **kwargs):
|
||||
path = os.path.join(data_path, name)
|
||||
path = mozpath.join(data_path, name)
|
||||
|
||||
return MockConfig(path, **kwargs)
|
||||
|
||||
|
@ -40,7 +42,7 @@ class TestBuildReader(unittest.TestCase):
|
|||
return BuildReader(config)
|
||||
|
||||
def file_path(self, name, *args):
|
||||
return os.path.join(data_path, name, *args)
|
||||
return mozpath.join(data_path, name, *args)
|
||||
|
||||
def test_dirs_traversal_simple(self):
|
||||
reader = self.reader('traversal-simple')
|
||||
|
@ -52,7 +54,7 @@ class TestBuildReader(unittest.TestCase):
|
|||
def test_dirs_traversal_no_descend(self):
|
||||
reader = self.reader('traversal-simple')
|
||||
|
||||
path = os.path.join(reader.topsrcdir, 'moz.build')
|
||||
path = mozpath.join(reader.topsrcdir, 'moz.build')
|
||||
self.assertTrue(os.path.exists(path))
|
||||
|
||||
sandboxes = list(reader.read_mozbuild(path,
|
||||
|
|
|
@ -28,9 +28,10 @@ from mozbuild.frontend.sandbox_symbols import (
|
|||
|
||||
from mozbuild.test.common import MockConfig
|
||||
|
||||
import mozpack.path as mozpath
|
||||
|
||||
test_data_path = os.path.abspath(os.path.dirname(__file__))
|
||||
test_data_path = os.path.join(test_data_path, 'data')
|
||||
test_data_path = mozpath.abspath(mozpath.dirname(__file__))
|
||||
test_data_path = mozpath.join(test_data_path, 'data')
|
||||
|
||||
|
||||
class TestSandbox(unittest.TestCase):
|
||||
|
@ -38,7 +39,7 @@ class TestSandbox(unittest.TestCase):
|
|||
config = None
|
||||
|
||||
if data_path is not None:
|
||||
config = MockConfig(os.path.join(test_data_path, data_path))
|
||||
config = MockConfig(mozpath.join(test_data_path, data_path))
|
||||
else:
|
||||
config = MockConfig()
|
||||
|
||||
|
@ -50,11 +51,11 @@ class TestSandbox(unittest.TestCase):
|
|||
|
||||
self.assertEqual(sandbox['TOPSRCDIR'], config.topsrcdir)
|
||||
self.assertEqual(sandbox['TOPOBJDIR'],
|
||||
os.path.abspath(config.topobjdir))
|
||||
mozpath.abspath(config.topobjdir))
|
||||
self.assertEqual(sandbox['RELATIVEDIR'], '')
|
||||
self.assertEqual(sandbox['SRCDIR'], config.topsrcdir)
|
||||
self.assertEqual(sandbox['OBJDIR'],
|
||||
os.path.abspath(config.topobjdir).replace(os.sep, '/'))
|
||||
mozpath.abspath(config.topobjdir).replace(os.sep, '/'))
|
||||
|
||||
def test_symbol_presence(self):
|
||||
# Ensure no discrepancies between the master symbol table and what's in
|
||||
|
@ -79,7 +80,7 @@ class TestSandbox(unittest.TestCase):
|
|||
self.assertEqual(sandbox['SRCDIR'], '/'.join([config.topsrcdir,
|
||||
'foo/bar']))
|
||||
self.assertEqual(sandbox['OBJDIR'],
|
||||
os.path.abspath('/'.join([config.topobjdir, 'foo/bar'])).replace(os.sep, '/'))
|
||||
mozpath.abspath('/'.join([config.topobjdir, 'foo/bar'])).replace(os.sep, '/'))
|
||||
|
||||
def test_config_access(self):
|
||||
sandbox = self.sandbox()
|
||||
|
@ -225,7 +226,7 @@ add_tier_dir('t1', 'bat', static=True)
|
|||
|
||||
self.assertEqual(sandbox['DIRS'], ['foo', 'bar'])
|
||||
self.assertEqual(sandbox.main_path,
|
||||
os.path.join(sandbox['TOPSRCDIR'], 'moz.build'))
|
||||
mozpath.join(sandbox['TOPSRCDIR'], 'moz.build'))
|
||||
self.assertEqual(len(sandbox.all_paths), 2)
|
||||
|
||||
def test_include_outside_topsrcdir(self):
|
||||
|
@ -234,7 +235,7 @@ add_tier_dir('t1', 'bat', static=True)
|
|||
with self.assertRaises(SandboxLoadError) as se:
|
||||
sandbox.exec_file('relative.build')
|
||||
|
||||
expected = os.path.join(test_data_path, 'moz.build')
|
||||
expected = mozpath.join(test_data_path, 'moz.build')
|
||||
self.assertEqual(se.exception.illegal_path, expected)
|
||||
|
||||
def test_include_error_stack(self):
|
||||
|
@ -252,7 +253,7 @@ add_tier_dir('t1', 'bat', static=True)
|
|||
self.assertEqual(args[1], 'set_unknown')
|
||||
self.assertEqual(args[2], 'ILLEGAL')
|
||||
|
||||
expected_stack = [os.path.join(sandbox.config.topsrcdir, p) for p in [
|
||||
expected_stack = [mozpath.join(sandbox.config.topsrcdir, p) for p in [
|
||||
'moz.build', 'included-1.build', 'included-2.build']]
|
||||
|
||||
self.assertEqual(e.file_stack, expected_stack)
|
||||
|
|
|
@ -28,9 +28,12 @@ def relpath(path, start):
|
|||
return '' if rel == '.' else rel
|
||||
|
||||
|
||||
def abspath(path):
|
||||
return normsep(os.path.abspath(path))
|
||||
|
||||
|
||||
def join(*paths):
|
||||
paths = [normsep(p) for p in paths]
|
||||
return posixpath.join(*paths)
|
||||
return normsep(os.path.join(*paths))
|
||||
|
||||
|
||||
def normpath(path):
|
||||
|
|
Загрузка…
Ссылка в новой задаче