Merge inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2015-05-18 16:32:50 -04:00
commit 41d95849b2
119 changed files with 1043 additions and 1144 deletions

View File

@ -1,6 +1,8 @@
const Cu = Components.utils;
const Ci = Components.interfaces;
Cu.importGlobalProperties(['File']);
const { Services } = Cu.import("resource://gre/modules/Services.jsm");
// Load a duplicated copy of the jsm to prevent messing with the currently running one
@ -25,7 +27,7 @@ function next() {
let steps = [
function getScreenshot() {
let screenshot = Screenshot.get();
assert.ok(screenshot instanceof Ci.nsIDOMFile,
assert.ok(screenshot instanceof File,
"Screenshot.get() returns a File");
next();
},

View File

@ -1210,6 +1210,9 @@ pref("security.sandbox.content.level", 1);
pref("security.sandbox.content.level", 0);
#endif
// ID (a UUID when set by gecko) that is used as a per profile suffix to a low
// integrity temp directory.
pref("security.sandbox.content.tempDirSuffix", "");
#if defined(MOZ_STACKWALKING)
// This controls the depth of stack trace that is logged when Windows sandbox

View File

@ -40,7 +40,7 @@ def getMarProperties(filename, partial=False):
'%sMarHash' % martype: mar_hash,
}
def getUrlProperties(filename):
def getUrlProperties(filename, package):
# let's create a switch case using name-spaces/dict
# rather than a long if/else with duplicate code
property_conditions = [
@ -57,9 +57,7 @@ def getUrlProperties(filename):
('codeCoverageURL', lambda m: m.endswith('code-coverage-gcno.zip')),
('sdkUrl', lambda m: m.endswith(('sdk.tar.bz2', 'sdk.zip'))),
('testPackagesUrl', lambda m: m.endswith('test_packages.json')),
# packageUrl must be last!
('packageUrl', lambda m: (not m.endswith('.json') and
not m.endswith('tests.zip'))),
('packageUrl', lambda m: m.endswith(package)),
]
url_re = re.compile(r'''^(https?://.*?\.(?:tar\.bz2|dmg|zip|apk|rpm|mar|tar\.gz|json))$''')
properties = {}
@ -102,10 +100,13 @@ if __name__ == '__main__':
parser.add_argument("--upload-files", required=True, nargs="+",
action="store", dest="upload_files",
help="List of files to be uploaded.")
parser.add_argument("--package", required=True,
action="store", dest="package",
help="Filename of the build package")
args = parser.parse_args()
json_data = getMarProperties(args.complete_mar_file)
json_data.update(getUrlProperties(args.upload_output))
json_data.update(getUrlProperties(args.upload_output, args.package))
if args.partial_mar_file:
json_data.update(getMarProperties(args.partial_mar_file, partial=True))
@ -119,6 +120,7 @@ if __name__ == '__main__':
json_data['partialInfo'] = getPartialInfo(json_data)
json_data['uploadFiles'] = args.upload_files
json_data['packageFilename'] = args.package
with open('mach_build_properties.json', 'w') as outfile:
json.dump(json_data, outfile, indent=4)

View File

@ -99,7 +99,7 @@ automation/l10n-check: automation/pretty-l10n-check
automation/update-packaging: automation/pretty-update-packaging
automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) --upload-files $(abspath $(UPLOAD_FILES))
$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) --upload-output $(AUTOMATION_UPLOAD_OUTPUT) --upload-files $(abspath $(UPLOAD_FILES)) --package $(PACKAGE)
# We need the log from make upload to grep it for urls in order to set
# properties.

View File

@ -14,6 +14,8 @@ Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Webapps.jsm");
Cu.importGlobalProperties(['File']);
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
@ -284,7 +286,7 @@ this.ImportExport = {
throw "NoBlobFound";
}
let isFileBlob = aBlob instanceof Ci.nsIDOMFile;
let isFileBlob = aBlob instanceof File;
// We can't QI the DOMFile to nsIFile, so we need to create one.
let zipFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
if (!isFileBlob) {
@ -498,7 +500,7 @@ this.ImportExport = {
throw "NoBlobFound";
}
let isFileBlob = aBlob instanceof Ci.nsIDOMFile;
let isFileBlob = aBlob instanceof File;
// We can't QI the DOMFile to nsIFile, so we need to create one.
let zipFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
if (!isFileBlob) {

View File

@ -177,7 +177,6 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
nsTArray<nsRefPtr<File>>& aFileList)
{
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length()));
nsresult rv;
if (!array) {
return NS_ERROR_OUT_OF_MEMORY;
@ -188,14 +187,12 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
nsRefPtr<File> file = aFileList[i];
nsString filename;
rv = file->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
file->GetName(filename);
str = JS_NewUCStringCopyZ(aCx, filename.get());
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
if (NS_FAILED(rv) ||
!JS_DefineElement(aCx, array, i, str, JSPROP_ENUMERATE)) {
if (!JS_DefineElement(aCx, array, i, str, JSPROP_ENUMERATE)) {
return NS_ERROR_FAILURE;
}
}
@ -217,8 +214,7 @@ ArchiveRequest::GetFileResult(JSContext* aCx,
nsRefPtr<File> file = aFileList[i];
nsString filename;
nsresult rv = file->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
file->GetName(filename);
if (filename == mFilename) {
if (!ToJSValue(aCx, file, aValue)) {

View File

@ -439,22 +439,6 @@ Blob::GetInternalStream(nsIInputStream** aStream)
////////////////////////////////////////////////////////////////////////////
// mozilla::dom::File implementation
NS_IMPL_CYCLE_COLLECTION_CLASS(File)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(File, Blob)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(File, Blob)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(File)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
NS_INTERFACE_MAP_ENTRY(nsIDOMFile)
NS_INTERFACE_MAP_END_INHERITING(Blob)
NS_IMPL_ADDREF_INHERITED(File, Blob)
NS_IMPL_RELEASE_INHERITED(File, Blob)
File::File(nsISupports* aParent, BlobImpl* aImpl)
: Blob(aParent, aImpl)
{
@ -553,17 +537,16 @@ File::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return FileBinding::Wrap(aCx, this, aGivenProto);
}
NS_IMETHODIMP
void
File::GetName(nsAString& aFileName)
{
mImpl->GetName(aFileName);
return NS_OK;
}
NS_IMETHODIMP
File::GetPath(nsAString& aPath)
void
File::GetPath(nsAString& aPath, ErrorResult& aRv)
{
return mImpl->GetPath(aPath);
mImpl->GetPath(aPath, aRv);
}
Date
@ -583,53 +566,16 @@ File::GetLastModified(ErrorResult& aRv)
return mImpl->GetLastModified(aRv);
}
NS_IMETHODIMP
File::GetLastModifiedDate(JSContext* aCx,
JS::MutableHandle<JS::Value> aDate)
{
ErrorResult rv;
Date value = GetLastModifiedDate(rv);
if (rv.Failed()) {
return rv.StealNSResult();
}
if (!value.ToDateObject(aCx, aDate)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
NS_IMETHODIMP
File::GetMozFullPath(nsAString& aFileName)
{
ErrorResult rv;
GetMozFullPath(aFileName, rv);
return rv.StealNSResult();
}
void
File::GetMozFullPath(nsAString& aFilename, ErrorResult& aRv)
{
mImpl->GetMozFullPath(aFilename, aRv);
}
NS_IMETHODIMP
File::GetMozFullPathInternal(nsAString& aFileName)
void
File::GetMozFullPathInternal(nsAString& aFileName, ErrorResult& aRv)
{
ErrorResult rv;
mImpl->GetMozFullPathInternal(aFileName, rv);
return rv.StealNSResult();
}
NS_IMETHODIMP
File::GetMozLastModifiedDate(int64_t* aDate)
{
MOZ_ASSERT(aDate);
ErrorResult rv;
*aDate = GetLastModified(rv);
return rv.StealNSResult();
mImpl->GetMozFullPathInternal(aFileName, aRv);
}
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
@ -817,12 +763,11 @@ BlobImplBase::GetName(nsAString& aName)
aName = mName;
}
nsresult
BlobImplBase::GetPath(nsAString& aPath)
void
BlobImplBase::GetPath(nsAString& aPath, ErrorResult& aRv)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
aPath = mPath;
return NS_OK;
}
void
@ -1321,9 +1266,9 @@ FileList::GetLength(uint32_t* aLength)
}
NS_IMETHODIMP
FileList::Item(uint32_t aIndex, nsIDOMFile **aFile)
FileList::Item(uint32_t aIndex, nsISupports** aFile)
{
nsRefPtr<File> file = Item(aIndex);
nsCOMPtr<nsIDOMBlob> file = Item(aIndex);
file.forget(aFile);
return NS_OK;
}

View File

@ -20,7 +20,7 @@
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h"
#include "nsIDOMFile.h"
#include "nsIDOMBlob.h"
#include "nsIDOMFileList.h"
#include "nsIFile.h"
#include "nsIMutable.h"
@ -157,17 +157,10 @@ private:
};
class File final : public Blob
, public nsIDOMFile
{
friend class Blob;
public:
NS_DECL_NSIDOMFILE
NS_FORWARD_NSIDOMBLOB(Blob::)
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(File, Blob);
// Note: BlobImpl must be a File in order to use this method.
// Check impl->IsFile().
static File*
@ -245,15 +238,18 @@ public:
const ChromeFilePropertyBag& aBag,
ErrorResult& aRv);
// XPCOM GetName is OK
void GetName(nsAString& aName);
int64_t GetLastModified(ErrorResult& aRv);
Date GetLastModifiedDate(ErrorResult& aRv);
void GetPath(nsAString& aName, ErrorResult& aRv);
void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv);
void GetMozFullPathInternal(nsAString& aName, ErrorResult& aRv);
protected:
virtual bool HasFileInterface() const override { return true; }
@ -276,7 +272,7 @@ public:
virtual void GetName(nsAString& aName) = 0;
virtual nsresult GetPath(nsAString& aName) = 0;
virtual void GetPath(nsAString& aName, ErrorResult& aRv) = 0;
virtual int64_t GetLastModified(ErrorResult& aRv) = 0;
@ -404,7 +400,7 @@ public:
virtual void GetName(nsAString& aName) override;
virtual nsresult GetPath(nsAString& aName) override;
virtual void GetPath(nsAString& aName, ErrorResult& aRv) override;
virtual int64_t GetLastModified(ErrorResult& aRv) override;

View File

@ -9,7 +9,6 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "nsIFile.h"
#include "nsIDOMFile.h"
#include "nsITimer.h"
#include "nsCOMPtr.h"
#include "nsIAsyncInputStream.h"

View File

@ -366,8 +366,7 @@ MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
}
// Pre-cache modified date.
int64_t unusedDate;
aRv = blob->GetMozLastModifiedDate(&unusedDate);
blob->GetLastModified(aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}

View File

@ -11,10 +11,10 @@ XPIDL_SOURCES += [
'nsIContentPolicy.idl',
'nsIContentPolicyBase.idl',
'nsIDocumentEncoder.idl',
'nsIDOMBlob.idl',
'nsIDOMDataChannel.idl',
'nsIDOMDOMCursor.idl',
'nsIDOMDOMRequest.idl',
'nsIDOMFile.idl',
'nsIDOMFileList.idl',
'nsIDOMFileReader.idl',
'nsIDOMFormData.idl',

View File

@ -14,6 +14,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/PContentPermission.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/PContentPermissionRequestParent.h"

View File

@ -58,6 +58,7 @@
#include "nsIContentViewer.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/DOMRect.h"
#include <algorithm>
@ -2592,7 +2593,7 @@ nsDOMWindowUtils::GetContainerElement(nsIDOMElement** aResult)
NS_IMETHODIMP
nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
nsIDOMFile **aDOMFile)
nsISupports **aDOMFile)
{
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
@ -2608,8 +2609,8 @@ nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
return NS_ERROR_FAILURE;
}
nsRefPtr<File> file = File::CreateFromFile(innerWindow, aFile);
file.forget(aDOMFile);
nsCOMPtr<nsIDOMBlob> blob = File::CreateFromFile(innerWindow, aFile);
blob.forget(aDOMFile);
return NS_OK;
}
@ -2858,15 +2859,13 @@ nsDOMWindowUtils::GetFilePath(JS::HandleValue aFile, JSContext* aCx,
JSObject* obj = aFile.toObjectOrNull();
nsISupports* nativeObj =
nsContentUtils::XPConnect()->GetNativeOfWrapper(aCx, obj);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(nativeObj);
if (file) {
File* file = nullptr;
if (NS_SUCCEEDED(UNWRAP_OBJECT(File, obj, file))) {
nsString filePath;
nsresult rv = file->GetMozFullPathInternal(filePath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
ErrorResult rv;
file->GetMozFullPathInternal(filePath, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
_retval = filePath;

View File

@ -23,7 +23,6 @@
#include "nsIContentViewer.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMFile.h"
#include "nsPIDOMWindow.h"
#include "nsIWebNavigation.h"
#include "nsIWebProgress.h"

View File

@ -53,25 +53,3 @@ interface nsIDOMBlob : nsISupports
// Return true if this blob is a memory file.
[notxpcom] bool isMemoryFile();
};
// We want to avoid multiple inheritance of nsIDOMBlob so we can downcast from
// nsIDOMBlob to Blob safely. Our chain is:
// - Blob -> nsIDOMBlob
// - File -> nsIDOMFile and Blob
[scriptable, builtinclass, uuid(cc28cf12-f1d4-44ff-843f-9289aa14613b)]
interface nsIDOMFile : nsISupports
{
readonly attribute DOMString name;
readonly attribute DOMString path;
[implicit_jscontext]
readonly attribute jsval lastModifiedDate;
readonly attribute DOMString mozFullPath;
// This performs no security checks!
[noscript] readonly attribute DOMString mozFullPathInternal;
[noscript] readonly attribute int64_t mozLastModifiedDate;
};

View File

@ -5,11 +5,10 @@
#include "nsISupports.idl"
interface nsIDOMFile;
[uuid(283aa7b2-da81-4c72-aea2-9797b440fe34)]
[uuid(57128a85-34de-42db-a252-84dd57724a59)]
interface nsIDOMFileList : nsISupports
{
readonly attribute unsigned long length;
nsIDOMFile item(in unsigned long index);
// returns a DOM File object
nsISupports item(in unsigned long index);
};

View File

@ -26,6 +26,7 @@
using mozilla::dom::StructuredCloneData;
using mozilla::dom::StructuredCloneClosure;
using namespace mozilla;
using namespace mozilla::dom;
bool
nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,

View File

@ -229,7 +229,7 @@ nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject,
// value is destroyed
nsresult result = NS_OK;
PropertyListMapEntry *entry = static_cast<PropertyListMapEntry*>
(PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject, fallible));
(PL_DHashTableAdd(&propertyList->mObjectValueMap, aObject, mozilla::fallible));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
// A nullptr entry->key is the sign that the entry has just been allocated

View File

@ -10,6 +10,7 @@
#include "nsIQueryContentEventResult.h"
#include "nsString.h"
#include "nsRect.h"
#include "Units.h"
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"

View File

@ -172,7 +172,7 @@ ToJSValue(JSContext* aCx,
}
// Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
// nsIDOMFile).
// DOM File).
template <class T>
MOZ_WARN_UNUSED_RESULT
typename EnableIf<!IsBaseOf<nsWrapperCache, T>::value &&

View File

@ -72,14 +72,14 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothOppManager::SendFileBatch final
{
public:
SendFileBatch(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob)
SendFileBatch(const nsAString& aDeviceAddress, Blob* aBlob)
: mDeviceAddress(aDeviceAddress)
{
mBlobs.AppendElement(aBlob);
}
nsString mDeviceAddress;
nsCOMArray<nsIDOMBlob> mBlobs;
nsTArray<nsRefPtr<Blob>> mBlobs;
};
NS_IMETHODIMP
@ -420,7 +420,7 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
bool
BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob)
Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
@ -434,7 +434,7 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
void
BluetoothOppManager::AppendBlobToSend(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob)
Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
@ -794,7 +794,7 @@ BluetoothOppManager::RetrieveSentFileName()
{
mFileName.Truncate();
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(mBlob);
nsRefPtr<File> file = static_cast<Blob*>(mBlob.get())->ToFile();
if (file) {
file->GetName(mFileName);
}

View File

@ -14,13 +14,13 @@
#include "mozilla/ipc/SocketBase.h"
#include "nsCOMArray.h"
class nsIDOMBlob;
class nsIOutputStream;
class nsIInputStream;
class nsIVolumeMountLock;
namespace mozilla {
namespace dom {
class Blob;
class BlobParent;
}
}
@ -55,7 +55,7 @@ public:
bool Listen();
bool SendFile(const nsAString& aDeviceAddress, BlobParent* aActor);
bool SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob);
bool SendFile(const nsAString& aDeviceAddress, Blob* aBlob);
bool StopSendingFile();
bool ConfirmReceivingFile(bool aConfirm);
@ -102,7 +102,7 @@ private:
void NotifyAboutFileChange();
bool AcquireSdcardMountLock();
void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
void AppendBlobToSend(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob);
void AppendBlobToSend(const nsAString& aDeviceAddress, Blob* aBlob);
void DiscardBlobsToSend();
bool ProcessNextBatch();
void ConnectInternal(const nsAString& aDeviceAddress);
@ -199,7 +199,7 @@ private:
nsAutoArrayPtr<uint8_t> mReceivedDataBuffer;
int mCurrentBlobIndex;
nsCOMPtr<nsIDOMBlob> mBlob;
nsRefPtr<Blob> mBlob;
nsTArray<SendFileBatch> mBatches;
/**

View File

@ -1827,7 +1827,7 @@ BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
void
BluetoothServiceBluedroid::SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());

View File

@ -130,7 +130,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable);
virtual void
@ -435,7 +435,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable);
virtual void

View File

@ -11,15 +11,13 @@
#include "BluetoothProfileManagerBase.h"
#include "nsAutoPtr.h"
#include "nsClassHashtable.h"
#include "nsIDOMFile.h"
#include "nsIObserver.h"
#include "nsTObserverArray.h"
#include "nsThreadUtils.h"
class nsIDOMBlob;
namespace mozilla {
namespace dom {
class Blob;
class BlobChild;
class BlobParent;
}
@ -241,7 +239,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void

View File

@ -266,7 +266,7 @@ BluetoothServiceChildProcess::SendFile(
void
BluetoothServiceChildProcess::SendFile(
const nsAString& aDeviceAddress,
nsIDOMBlob* aBlobChild,
Blob* aBlobChild,
BluetoothReplyRunnable* aRunnable)
{
// Parent-process-only method

View File

@ -111,7 +111,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) override;
virtual void

View File

@ -12,15 +12,13 @@
#include "BluetoothProfileManagerBase.h"
#include "nsAutoPtr.h"
#include "nsClassHashtable.h"
#include "nsIDOMFile.h"
#include "nsIObserver.h"
#include "nsTObserverArray.h"
#include "nsThreadUtils.h"
class nsIDOMBlob;
namespace mozilla {
namespace dom {
class Blob;
class BlobChild;
class BlobParent;
}
@ -295,7 +293,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) = 0;
virtual void

View File

@ -316,7 +316,7 @@ BluetoothServiceChildProcess::SendFile(
void
BluetoothServiceChildProcess::SendFile(
const nsAString& aDeviceAddress,
nsIDOMBlob* aBlobChild,
Blob* aBlobChild,
BluetoothReplyRunnable* aRunnable)
{
// Parent-process-only method

View File

@ -140,7 +140,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) override;
virtual void

View File

@ -4161,7 +4161,7 @@ BluetoothDBusService::SendFile(const nsAString& aDeviceAddress,
void
BluetoothDBusService::SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());

View File

@ -174,7 +174,7 @@ public:
virtual void
SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob,
Blob* aBlob,
BluetoothReplyRunnable* aRunnable) override;
virtual void

View File

@ -73,16 +73,17 @@ namespace {
static bool sInShutdown = false;
}
class mozilla::dom::bluetooth::SendFileBatch {
class mozilla::dom::bluetooth::SendFileBatch
{
public:
SendFileBatch(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob)
SendFileBatch(const nsAString& aDeviceAddress, Blob* aBlob)
: mDeviceAddress(aDeviceAddress)
{
mBlobs.AppendElement(aBlob);
}
nsString mDeviceAddress;
nsCOMArray<nsIDOMBlob> mBlobs;
nsTArray<nsRefPtr<Blob>> mBlobs;
};
NS_IMETHODIMP
@ -385,14 +386,14 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<BlobImpl> impl = aActor->GetBlobImpl();
nsCOMPtr<nsIDOMBlob> blob = Blob::Create(nullptr, impl);
nsRefPtr<Blob> blob = Blob::Create(nullptr, impl);
return SendFile(aDeviceAddress, blob.get());
return SendFile(aDeviceAddress, blob);
}
bool
BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob)
Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
@ -406,7 +407,7 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
void
BluetoothOppManager::AppendBlobToSend(const nsAString& aDeviceAddress,
nsIDOMBlob* aBlob)
Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
@ -766,7 +767,7 @@ BluetoothOppManager::RetrieveSentFileName()
{
mFileName.Truncate();
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(mBlob);
nsRefPtr<File> file = mBlob->ToFile();
if (file) {
file->GetName(mFileName);
}

View File

@ -14,13 +14,13 @@
#include "mozilla/ipc/SocketBase.h"
#include "nsCOMArray.h"
class nsIDOMBlob;
class nsIOutputStream;
class nsIInputStream;
class nsIVolumeMountLock;
namespace mozilla {
namespace dom {
class Blob;
class BlobParent;
}
}
@ -51,7 +51,7 @@ public:
bool Listen();
bool SendFile(const nsAString& aDeviceAddress, BlobParent* aActor);
bool SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob);
bool SendFile(const nsAString& aDeviceAddress, Blob* aBlob);
bool StopSendingFile();
bool ConfirmReceivingFile(bool aConfirm);
@ -96,7 +96,7 @@ private:
void NotifyAboutFileChange();
bool AcquireSdcardMountLock();
void SendObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
void AppendBlobToSend(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob);
void AppendBlobToSend(const nsAString& aDeviceAddress, Blob* aBlob);
void DiscardBlobsToSend();
bool ProcessNextBatch();
void ConnectInternal(const nsAString& aDeviceAddress);
@ -193,7 +193,7 @@ private:
nsAutoArrayPtr<uint8_t> mReceivedDataBuffer;
int mCurrentBlobIndex;
nsCOMPtr<nsIDOMBlob> mBlob;
nsRefPtr<Blob> mBlob;
nsTArray<SendFileBatch> mBatches;
/**

View File

@ -6,8 +6,6 @@
#include "InternalResponse.h"
#include "nsIDOMFile.h"
#include "mozilla/dom/InternalHeaders.h"
#include "nsStreamUtils.h"
#include "nsSerializationHelper.h"

View File

@ -647,16 +647,22 @@ HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
const nsAString& aType,
ErrorResult& aRv)
{
nsCOMPtr<nsIDOMFile> file;
nsCOMPtr<nsISupports> file;
aRv = MozGetAsFile(aName, aType, getter_AddRefs(file));
nsRefPtr<File> tmp = static_cast<File*>(file.get());
return tmp.forget();
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(file);
nsRefPtr<Blob> domBlob = static_cast<Blob*>(blob.get());
MOZ_ASSERT(domBlob->IsFile());
return domBlob->ToFile();
}
NS_IMETHODIMP
HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
const nsAString& aType,
nsIDOMFile** aResult)
nsISupports** aResult)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eMozGetAsFile);
@ -672,7 +678,7 @@ HTMLCanvasElement::MozGetAsFile(const nsAString& aName,
nsresult
HTMLCanvasElement::MozGetAsBlobImpl(const nsAString& aName,
const nsAString& aType,
nsIDOMFile** aResult)
nsISupports** aResult)
{
nsCOMPtr<nsIInputStream> stream;
nsAutoString type(aType);
@ -696,7 +702,7 @@ HTMLCanvasElement::MozGetAsBlobImpl(const nsAString& aName,
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(OwnerDoc()->GetScopeObject());
// The File takes ownership of the buffer
nsRefPtr<File> file =
nsCOMPtr<nsIDOMBlob> file =
File::CreateMemoryFile(win, imgData, (uint32_t)imgSize, aName, type,
PR_Now());

View File

@ -237,7 +237,7 @@ protected:
nsAString& aDataURL);
nsresult MozGetAsBlobImpl(const nsAString& aName,
const nsAString& aType,
nsIDOMFile** aResult);
nsISupports** aResult);
void CallPrintCallback();
CanvasContextType mCurrentContextType;

View File

@ -405,7 +405,9 @@ public:
MOZ_ASSERT(blobImpl);
blobImpl->SetPath(Substring(path, 0, uint32_t(length)));
}
*aResult = domFile.forget().downcast<nsIDOMFile>().take();
nsCOMPtr<nsIDOMBlob> blob = domFile.get();
blob.forget(aResult);
LookupAndCacheNext();
return NS_OK;
}
@ -488,23 +490,28 @@ NS_IMPL_ISUPPORTS(DirPickerRecursiveFileEnumerator, nsISimpleEnumerator)
/**
* This may return nullptr if aDomFile's implementation of
* nsIDOMFile::mozFullPathInternal does not successfully return a non-empty
* File::mozFullPathInternal does not successfully return a non-empty
* string that is a valid path. This can happen on Firefox OS, for example,
* where the file picker can create Blobs.
*/
static already_AddRefed<nsIFile>
DOMFileToLocalFile(nsIDOMFile* aDomFile)
DOMFileToLocalFile(File* aDomFile)
{
nsString path;
nsresult rv = aDomFile->GetMozFullPathInternal(path);
if (NS_FAILED(rv) || path.IsEmpty()) {
ErrorResult rv;
aDomFile->GetMozFullPathInternal(path, rv);
if (rv.Failed() || path.IsEmpty()) {
rv.SuppressException();
return nullptr;
}
nsCOMPtr<nsIFile> localFile;
rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(path), true,
getter_AddRefs(localFile));
NS_ENSURE_SUCCESS(rv, nullptr);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
return nullptr;
}
return localFile.forget();
}
@ -532,9 +539,9 @@ public:
nsCOMPtr<nsISupports> tmp;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
mFileList.AppendElement(static_cast<File*>(domFile.get()));
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(tmp);
MOZ_ASSERT(domBlob);
mFileList.AppendElement(static_cast<File*>(domBlob.get()));
mFileListLength = mFileList.Length();
if (mCanceled) {
MOZ_ASSERT(!mInput, "This is bad - how did this happen?");
@ -691,20 +698,23 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
NS_WARN_IF_FALSE(domFile,
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(tmp);
NS_WARN_IF_FALSE(domBlob,
"Null file object from FilePicker's file enumerator?");
if (domFile) {
newFiles.AppendElement(static_cast<File*>(domFile.get()));
if (domBlob) {
newFiles.AppendElement(static_cast<File*>(domBlob.get()));
}
}
} else {
MOZ_ASSERT(mode == static_cast<int16_t>(nsIFilePicker::modeOpen));
nsCOMPtr<nsIDOMFile> domFile;
nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(domFile));
nsCOMPtr<nsISupports> tmp;
nsresult rv = mFilePicker->GetDomfile(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(rv, rv);
if (domFile) {
newFiles.AppendElement(static_cast<File*>(domFile.get()));
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(tmp);
if (blob) {
nsRefPtr<File> file = static_cast<Blob*>(blob.get())->ToFile();
newFiles.AppendElement(file);
}
}
@ -969,7 +979,11 @@ HTMLInputElement::InitFilePicker(FilePickerType aType)
aType != FILE_PICKER_DIRECTORY) {
nsString path;
oldFiles[0]->GetMozFullPathInternal(path);
ErrorResult error;
oldFiles[0]->GetMozFullPathInternal(path, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
nsCOMPtr<nsIFile> localFile;
rv = NS_NewLocalFile(path, false, getter_AddRefs(localFile));
@ -1708,7 +1722,12 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const
// XXX We'd love to assert that this can't happen, but some mochitests
// use SpecialPowers to circumvent our more sane security model.
if (!mFiles.IsEmpty()) {
return mFiles[0]->GetMozFullPath(aValue);
ErrorResult rv;
mFiles[0]->GetMozFullPath(aValue, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
return NS_OK;
}
else {
aValue.Truncate();
@ -1716,8 +1735,10 @@ HTMLInputElement::GetValueInternal(nsAString& aValue) const
#endif
} else {
// Just return the leaf name
if (mFiles.IsEmpty() || NS_FAILED(mFiles[0]->GetName(aValue))) {
if (mFiles.IsEmpty()) {
aValue.Truncate();
} else {
mFiles[0]->GetName(aValue);
}
}
@ -2307,11 +2328,16 @@ HTMLInputElement::FlushFrames()
}
void
HTMLInputElement::MozGetFileNameArray(nsTArray< nsString >& aArray)
HTMLInputElement::MozGetFileNameArray(nsTArray<nsString>& aArray,
ErrorResult& aRv)
{
for (uint32_t i = 0; i < mFiles.Length(); i++) {
nsString str;
mFiles[i]->GetMozFullPathInternal(str);
mFiles[i]->GetMozFullPathInternal(str, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
aArray.AppendElement(str);
}
}
@ -2326,8 +2352,12 @@ HTMLInputElement::MozGetFileNameArray(uint32_t* aLength, char16_t*** aFileNames)
return NS_ERROR_DOM_SECURITY_ERR;
}
ErrorResult rv;
nsTArray<nsString> array;
MozGetFileNameArray(array);
MozGetFileNameArray(array, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
*aLength = array.Length();
char16_t** ret =
@ -2687,7 +2717,11 @@ HTMLInputElement::AfterSetFiles(bool aSetValueChanged)
if (mFiles.IsEmpty()) {
mFirstFilePath.Truncate();
} else {
mFiles[0]->GetMozFullPath(mFirstFilePath);
ErrorResult rv;
mFiles[0]->GetMozFullPath(mFirstFilePath, rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
}
}
#endif

View File

@ -713,7 +713,7 @@ public:
int32_t GetTextLength(ErrorResult& aRv);
void MozGetFileNameArray(nsTArray< nsString >& aFileNames);
void MozGetFileNameArray(nsTArray<nsString>& aFileNames, ErrorResult& aRv);
void MozSetFileNameArray(const Sequence< nsString >& aFileNames, ErrorResult& aRv);
void MozSetFileArray(const Sequence<OwningNonNull<File>>& aFiles);

View File

@ -18,7 +18,6 @@
#include "nsAttrValueInlines.h"
#include "nsISaveAsCharset.h"
#include "nsIFile.h"
#include "nsIDOMFile.h"
#include "nsDirectoryServiceDefs.h"
#include "nsStringStream.h"
#include "nsIURI.h"
@ -451,15 +450,13 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
nsCOMPtr<nsIInputStream> fileStream;
if (aFile) {
nsAutoString filename16;
rv = aFile->GetName(filename16);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
aFile->GetName(filename16);
ErrorResult error;
nsAutoString filepath16;
rv = aFile->GetPath(filepath16);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
aFile->GetPath(filepath16, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
if (!filepath16.IsEmpty()) {

View File

@ -27,7 +27,6 @@
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsError.h"
#include "nsIDOMFile.h"
#include "nsIPrincipal.h"
namespace mozilla {
@ -328,7 +327,7 @@ IDBMutableFile::GetFileId() const
return mFileInfo->Id();
}
already_AddRefed<nsIDOMFile>
already_AddRefed<File>
IDBMutableFile::CreateFileObject(IDBFileHandle* aFileHandle,
MetadataParameters* aMetadataParams)
{
@ -393,12 +392,10 @@ GetFileHelper::GetSuccessResult(JSContext* aCx,
auto fileHandle = static_cast<IDBFileHandle*>(mFileHandle.get());
nsCOMPtr<nsIDOMFile> domFile =
nsRefPtr<File> domFile =
mMutableFile->CreateFileObject(fileHandle, mParams);
nsresult rv =
nsContentUtils::WrapNative(aCx, domFile, &NS_GET_IID(nsIDOMFile), aVal);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (!ToJSValue(aCx, domFile, aVal)) {
return NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR;
}

View File

@ -18,7 +18,6 @@
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
class nsIDOMFile;
class nsPIDOMWindow;
namespace mozilla {
@ -28,6 +27,7 @@ class ErrorResult;
namespace dom {
class DOMRequest;
class File;
class MetadataParameters;
namespace indexedDB {
@ -83,7 +83,7 @@ public:
return mFileInfo;
}
already_AddRefed<nsIDOMFile>
already_AddRefed<File>
CreateFileObject(IDBFileHandle* aFileHandle,
MetadataParameters* aMetadataParams);

View File

@ -334,14 +334,14 @@ StructuredCloneWriteCallback(JSContext* aCx,
nsRefPtr<File> file = blob->ToFile();
if (file) {
int64_t lastModifiedDate;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
file->GetMozLastModifiedDate(&lastModifiedDate)));
ErrorResult rv;
int64_t lastModifiedDate = file->GetLastModified(rv);
MOZ_ALWAYS_TRUE(!rv.Failed());
lastModifiedDate = NativeEndian::swapToLittleEndian(lastModifiedDate);
nsString name;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(file->GetName(name)));
file->GetName(name);
NS_ConvertUTF16toUTF8 convName(name);
uint32_t convNameLength =

View File

@ -17,7 +17,6 @@
#include "mozilla/dom/DOMStringList.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "nsIAppShell.h"
#include "nsIDOMFile.h"
#include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h"
#include "nsTHashtable.h"

View File

@ -94,12 +94,11 @@ function verifyBlob(blob1, blob2, fileId, blobReadHandler)
{
is(blob1 instanceof Components.interfaces.nsIDOMBlob, true,
"Instance of nsIDOMBlob");
is(blob1 instanceof Components.interfaces.nsIDOMFile,
blob2 instanceof Components.interfaces.nsIDOMFile,
"Instance of nsIDOMFile");
is(blob1 instanceof File, blob2 instanceof File,
"Instance of DOM File");
is(blob1.size, blob2.size, "Correct size");
is(blob1.type, blob2.type, "Correct type");
if (blob2 instanceof Components.interfaces.nsIDOMFile) {
if (blob2 instanceof File) {
is(blob1.name, blob2.name, "Correct name");
}
is(utils.getFileId(blob1), fileId, "Correct file id");

View File

@ -39,8 +39,6 @@ interface nsIDOMStyleSheet;
interface nsITransferable;
interface nsIQueryContentEventResult;
interface nsIDOMWindow;
interface nsIDOMBlob;
interface nsIDOMFile;
interface nsIFile;
interface nsIDOMClientRect;
interface nsIURI;
@ -51,7 +49,7 @@ interface nsIJSRAIIHelper;
interface nsIContentPermissionRequest;
interface nsIObserver;
[scriptable, uuid(1a75c351-d115-4d51-94df-731dd1723a1f)]
[scriptable, uuid(34a42cdc-7a04-4e71-8a5c-63e092fba58e)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1445,9 +1443,10 @@ interface nsIDOMWindowUtils : nsISupports {
in AString value2);
/**
* Wrap an nsIFile in an nsIDOMFile
* Wrap an nsIFile in an DOM File
* Returns a File object.
*/
nsIDOMFile wrapDOMFile(in nsIFile aFile);
nsISupports wrapDOMFile(in nsIFile aFile);
/**
* Get the type of the currently focused html input, if any.

View File

@ -16,11 +16,10 @@
*/
interface nsIDOMBlob;
interface nsIDOMFile;
interface nsIVariant;
interface nsIInputStreamCallback;
[uuid(8978d1c5-2981-4678-a1c3-b0b7bae04fbc)]
[uuid(2c984658-2e7c-4774-8ac5-cf1b39f8bec3)]
interface nsIDOMHTMLCanvasElement : nsISupports
{
attribute unsigned long width;
@ -38,7 +37,8 @@ interface nsIDOMHTMLCanvasElement : nsISupports
// Valid calls are
// mozGetAsFile(name); -- defaults to image/png
// mozGetAsFile(name, type); -- uses given type
nsIDOMFile mozGetAsFile(in DOMString name, [optional] in DOMString type);
// The return value is a File object.
nsISupports mozGetAsFile(in DOMString name, [optional] in DOMString type);
// A Mozilla-only extension to get a canvas context backed by double-buffered
// shared memory. Only privileged callers can call this.

View File

@ -2064,8 +2064,8 @@ public:
virtual void
GetName(nsAString& aName) override;
virtual nsresult
GetPath(nsAString& aPath) override;
virtual void
GetPath(nsAString& aPath, ErrorResult& aRv) override;
virtual int64_t
GetLastModified(ErrorResult& aRv) override;
@ -2742,11 +2742,11 @@ RemoteBlobImpl::GetName(nsAString& aName)
mBlobImpl->GetName(aName);
}
nsresult
void
BlobParent::
RemoteBlobImpl::GetPath(nsAString& aPath)
RemoteBlobImpl::GetPath(nsAString& aPath, ErrorResult& aRv)
{
return mBlobImpl->GetPath(aPath);
mBlobImpl->GetPath(aPath, aRv);
}
int64_t

View File

@ -10,6 +10,7 @@
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/Preferences.h"
#include "mozilla/WindowsVersion.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#endif
@ -20,74 +21,100 @@ namespace mozilla {
namespace dom {
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static already_AddRefed<nsIFile>
GetLowIntegrityTemp()
{
MOZ_ASSERT(nsDirectoryService::gService,
"GetLowIntegrityTemp relies on nsDirectoryService being initialized");
// A low integrity temp only currently makes sense for sandbox pref level 1.
if (Preferences::GetInt("security.sandbox.content.level") != 1) {
return nullptr;
}
nsCOMPtr<nsIFile> lowIntegrityTemp;
nsresult rv = nsDirectoryService::gService->Get(NS_WIN_LOW_INTEGRITY_TEMP,
NS_GET_IID(nsIFile),
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
return lowIntegrityTemp.forget();
}
static void
SetUpSandboxEnvironment()
{
MOZ_ASSERT(nsDirectoryService::gService,
"SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
// Setup to use a low integrity temp if available.
nsCOMPtr<nsIFile> lowIntegrityTemp = GetLowIntegrityTemp();
if (!lowIntegrityTemp) {
// A low integrity temp only currently makes sense for Vista or Later and
// sandbox pref level 1.
if (!IsVistaOrLater() ||
Preferences::GetInt("security.sandbox.content.level") != 1) {
return;
}
nsAdoptingString tempDirSuffix =
Preferences::GetString("security.sandbox.content.tempDirSuffix");
if (tempDirSuffix.IsEmpty()) {
NS_WARNING("Low integrity temp suffix pref not set.");
return;
}
// Get the base low integrity Mozilla temp directory.
nsCOMPtr<nsIFile> lowIntegrityTemp;
nsresult rv = nsDirectoryService::gService->Get(NS_WIN_LOW_INTEGRITY_TEMP_BASE,
NS_GET_IID(nsIFile),
getter_AddRefs(lowIntegrityTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Append our profile specific temp name.
rv = lowIntegrityTemp->Append(NS_LITERAL_STRING("Temp-") + tempDirSuffix);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Change the gecko defined temp directory to our low integrity one.
// Undefine returns a failure if the property is not already set.
unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
nsresult rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp);
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, lowIntegrityTemp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Set TEMP and TMP environment variables.
nsAutoString lowIntegrityTempPath;
rv = lowIntegrityTemp->GetPath(lowIntegrityTempPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool setOK = SetEnvironmentVariableW(L"TEMP", lowIntegrityTempPath.get());
NS_WARN_IF_FALSE(setOK, "Failed to set TEMP to low integrity temp path");
setOK = SetEnvironmentVariableW(L"TMP", lowIntegrityTempPath.get());
NS_WARN_IF_FALSE(setOK, "Failed to set TMP to low integrity temp path");
}
#if defined(NIGHTLY_BUILD)
static void
CleanUpSandboxEnvironment()
CleanUpOldSandboxEnvironment()
{
// Remove low integrity temp if it exists.
nsCOMPtr<nsIFile> lowIntegrityTemp = GetLowIntegrityTemp();
if (!lowIntegrityTemp) {
// Temporary code to clean up the old low integrity temp directories.
// The removal of this is tracked by bug 1165818.
nsCOMPtr<nsIFile> lowIntegrityMozilla;
nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOCAL_APPDATA_LOW_DIR,
getter_AddRefs(lowIntegrityMozilla));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Don't check the return value as the directory will only have been created
// if it has been used.
unused << lowIntegrityTemp->Remove(/* aRecursive */ true);
rv = lowIntegrityMozilla->Append(NS_LITERAL_STRING(MOZ_USER_DIR));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsISimpleEnumerator> iter;
rv = lowIntegrityMozilla->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool more;
nsCOMPtr<nsISupports> elem;
while (NS_SUCCEEDED(iter->HasMoreElements(&more)) && more) {
rv = iter->GetNext(getter_AddRefs(elem));
if (NS_FAILED(rv)) {
break;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(elem);
if (!file) {
continue;
}
nsAutoString leafName;
rv = file->GetLeafName(leafName);
if (NS_FAILED(rv)) {
continue;
}
if (leafName.Find(NS_LITERAL_STRING("MozTemp-{")) == 0) {
file->Remove(/* aRecursive */ true);
}
}
}
#endif
#endif
void
ContentProcess::SetAppDir(const nsACString& aPath)
@ -114,8 +141,8 @@ ContentProcess::Init()
void
ContentProcess::CleanUp()
{
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
CleanUpSandboxEnvironment();
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) && defined(NIGHTLY_BUILD)
CleanUpOldSandboxEnvironment();
#endif
mXREEmbed.Stop();
}

View File

@ -8,7 +8,6 @@
#include "nsComponentManagerUtils.h"
#include "nsNetCID.h"
#include "nsIDocument.h"
#include "nsIDOMFile.h"
#include "nsIDOMWindow.h"
#include "nsIFile.h"
#include "nsISimpleEnumerator.h"

View File

@ -7,7 +7,6 @@
#ifndef mozilla_dom_FilePickerParent_h
#define mozilla_dom_FilePickerParent_h
#include "nsIDOMFile.h"
#include "nsIEventTarget.h"
#include "nsIFilePicker.h"
#include "nsCOMArray.h"

View File

@ -901,6 +901,7 @@ MediaFormatReader::Update(TrackType aTrack)
LOGV("Update(%s) ni=%d no=%d", TrackTypeToStr(aTrack), needInput, needOutput);
if (decoder.mDemuxEOS && !decoder.mDemuxEOSServiced) {
decoder.mOutputRequested = true;
decoder.mDecoder->Drain();
decoder.mDemuxEOSServiced = true;
}

View File

@ -113,6 +113,7 @@ GetMediaManagerLog()
}
#define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
using dom::File;
using dom::MediaStreamConstraints;
using dom::MediaTrackConstraintSet;
using dom::MediaTrackConstraints;
@ -264,53 +265,6 @@ private:
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
};
/**
* Invoke the "onSuccess" callback in content. The callback will take a
* DOMBlob in the case of {picture:true}, and a MediaStream in the case of
* {audio:true} or {video:true}. There is a constructor available for each
* form. Do this only on the main thread.
*/
class SuccessCallbackRunnable : public nsRunnable
{
public:
SuccessCallbackRunnable(
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback>& aOnSuccess,
nsCOMPtr<nsIDOMGetUserMediaErrorCallback>& aOnFailure,
nsIDOMFile* aFile, uint64_t aWindowID)
: mFile(aFile)
, mWindowID(aWindowID)
, mManager(MediaManager::GetInstance())
{
mOnSuccess.swap(aOnSuccess);
mOnFailure.swap(aOnFailure);
}
NS_IMETHOD
Run()
{
// Only run if the window is still active.
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> onSuccess = mOnSuccess.forget();
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onFailure = mOnFailure.forget();
if (!(mManager->IsWindowStillActive(mWindowID))) {
return NS_OK;
}
// This is safe since we're on main-thread, and the windowlist can only
// be invalidated from the main-thread (see OnNavigation)
onSuccess->OnSuccess(mFile);
return NS_OK;
}
private:
nsCOMPtr<nsIDOMGetUserMediaSuccessCallback> mOnSuccess;
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> mOnFailure;
nsCOMPtr<nsIDOMFile> mFile;
uint64_t mWindowID;
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
};
/**
* Invoke the GetUserMediaDevices success callback. Wrapped in a runnable
* so that it may be called on the main thread. The error callback is also

View File

@ -112,7 +112,7 @@ protected:
mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling
// This is only modified on MainThread (AllocImpl and DeallocImpl)
nsRefPtr<ICameraControl> mCameraControl;
nsCOMPtr<nsIDOMFile> mLastCapture;
nsRefPtr<dom::File> mLastCapture;
android::sp<android::GonkCameraSource> mCameraSource;

View File

@ -210,7 +210,7 @@ interface nsINfcContentHelper : nsISupports
*
* @param blob
* Raw data of the file to be sent. This object represents a file-like
* (nsIDOMFile) object of immutable, raw data. The blob data needs
* (DOM File) object of immutable, raw data. The blob data needs
* to be 'object wrapped' before calling this interface.
*
* @param sessionToken

View File

@ -89,151 +89,161 @@ this.PushDB.prototype = {
/*
* @param aChannelRecord
* The record to be added.
* @param aSuccessCb
* Callback function to invoke with result ID.
* @param aErrorCb [optional]
* Callback function to invoke when there was an error.
*/
put: function(aChannelRecord, aSuccessCb, aErrorCb) {
put: function(aChannelRecord) {
debug("put()" + JSON.stringify(aChannelRecord));
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
debug("Going to put " + aChannelRecord.channelID);
aStore.put(aChannelRecord).onsuccess = function setTxnResult(aEvent) {
debug("Request successful. Updated record ID: " +
aEvent.target.result);
};
},
aSuccessCb,
aErrorCb
return new Promise((resolve, reject) =>
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
debug("Going to put " + aChannelRecord.channelID);
aStore.put(aChannelRecord).onsuccess = function setTxnResult(aEvent) {
debug("Request successful. Updated record ID: " +
aEvent.target.result);
};
},
resolve,
reject
)
);
},
/*
* @param aChannelID
* The ID of record to be deleted.
* @param aSuccessCb
* Callback function to invoke with result.
* @param aErrorCb [optional]
* Callback function to invoke when there was an error.
*/
delete: function(aChannelID, aSuccessCb, aErrorCb) {
delete: function(aChannelID) {
debug("delete()");
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
debug("Going to delete " + aChannelID);
aStore.delete(aChannelID);
},
aSuccessCb,
aErrorCb
return new Promise((resolve, reject) =>
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
debug("Going to delete " + aChannelID);
aStore.delete(aChannelID);
},
resolve,
reject
)
);
},
clearAll: function clear(aSuccessCb, aErrorCb) {
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function (aTxn, aStore) {
debug("Going to clear all!");
aStore.clear();
},
aSuccessCb,
aErrorCb
clearAll: function clear() {
return new Promise((resolve, reject) =>
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function (aTxn, aStore) {
debug("Going to clear all!");
aStore.clear();
},
resolve,
reject
)
);
},
getByPushEndpoint: function(aPushEndpoint, aSuccessCb, aErrorCb) {
getByPushEndpoint: function(aPushEndpoint) {
debug("getByPushEndpoint()");
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aTxn.result = undefined;
return new Promise((resolve, reject) =>
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aTxn.result = undefined;
let index = aStore.index("pushEndpoint");
index.get(aPushEndpoint).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Fetch successful " + aEvent.target.result);
}
},
aSuccessCb,
aErrorCb
let index = aStore.index("pushEndpoint");
index.get(aPushEndpoint).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Fetch successful " + aEvent.target.result);
}
},
resolve,
reject
)
);
},
getByChannelID: function(aChannelID, aSuccessCb, aErrorCb) {
getByChannelID: function(aChannelID) {
debug("getByChannelID()");
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aTxn.result = undefined;
return new Promise((resolve, reject) =>
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aTxn.result = undefined;
aStore.get(aChannelID).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Fetch successful " + aEvent.target.result);
}
},
aSuccessCb,
aErrorCb
aStore.get(aChannelID).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Fetch successful " + aEvent.target.result);
}
},
resolve,
reject
)
);
},
getByScope: function(aScope, aSuccessCb, aErrorCb) {
getByScope: function(aScope) {
debug("getByScope() " + aScope);
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aTxn.result = undefined;
return new Promise((resolve, reject) =>
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aTxn.result = undefined;
let index = aStore.index("scope");
index.get(aScope).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Fetch successful " + aEvent.target.result);
}
},
aSuccessCb,
aErrorCb
let index = aStore.index("scope");
index.get(aScope).onsuccess = function setTxnResult(aEvent) {
aTxn.result = aEvent.target.result;
debug("Fetch successful " + aEvent.target.result);
}
},
resolve,
reject
)
);
},
getAllChannelIDs: function(aSuccessCb, aErrorCb) {
getAllChannelIDs: function() {
debug("getAllChannelIDs()");
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aStore.mozGetAll().onsuccess = function(event) {
aTxn.result = event.target.result;
}
},
aSuccessCb,
aErrorCb
return new Promise((resolve, reject) =>
this.newTxn(
"readonly",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aStore.mozGetAll().onsuccess = function(event) {
aTxn.result = event.target.result;
}
},
resolve,
reject
)
);
},
drop: function(aSuccessCb, aErrorCb) {
drop: function() {
debug("drop()");
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aStore.clear();
},
aSuccessCb,
aErrorCb
return new Promise((resolve, reject) =>
this.newTxn(
"readwrite",
kPUSHDB_STORE_NAME,
function txnCb(aTxn, aStore) {
aStore.clear();
},
resolve,
reject
)
);
}
};
@ -400,21 +410,31 @@ this.PushService = {
return;
}
this._db.getByScope(scope, function(record) {
this._db.delete(records.channelID, null, function() {
debug("webapps-clear-data: " + scope +
" Could not delete entry " + records.channelID);
this._db.getByScope(scope)
.then(record => {
this._db.delete(records.channelID)
.then(_ => {
// courtesy, but don't establish a connection
// just for it
if (this._ws) {
debug("Had a connection, so telling the server");
this._send("unregister", {channelID: records.channelID});
}
}, err => {
debug("webapps-clear-data: " + scope +
" Could not delete entry " + records.channelID);
// courtesy, but don't establish a connection
// just for it
if (this._ws) {
debug("Had a connection, so telling the server");
this._send("unregister", {channelID: records.channelID});
}
}.bind(this), function() {
// courtesy, but don't establish a connection
// just for it
if (this._ws) {
debug("Had a connection, so telling the server");
this._send("unregister", {channelID: records.channelID});
}
throw "Database error";
});
}, _ => {
debug("webapps-clear-data: Error in getByScope(" + scope + ")");
});
});
break;
}
@ -954,11 +974,12 @@ this.PushService = {
this._beginWSSetup();
return;
}
this._db.getAllChannelIDs(function(channelIDs) {
if (channelIDs.length > 0) {
this._beginWSSetup();
}
}.bind(this));
this._db.getAllChannelIDs()
.then(channelIDs => {
if (channelIDs.length > 0) {
this._beginWSSetup();
}
});
},
/** |delay| should be in milliseconds. */
@ -1354,18 +1375,18 @@ this.PushService = {
debug("Could not get channelID " + aChannelIDFromServer + " from DB");
}
this._db.getByChannelID(aChannelID,
compareRecordVersionAndNotify.bind(this),
recoverNoSuchChannelID.bind(this));
this._db.getByChannelID(aChannelID)
.then(compareRecordVersionAndNotify.bind(this),
err => recoverNoSuchChannelID(err));
},
// Fires a push-register system message to all applications that have
// registration.
_notifyAllAppsRegister: function() {
debug("notifyAllAppsRegister()");
return new Promise((resolve, reject) => {
// records are objects describing the registration as stored in IndexedDB.
this._db.getAllChannelIDs(records => {
// records are objects describing the registration as stored in IndexedDB.
return this._db.getAllChannelIDs()
.then(records => {
let scopes = new Set();
for (let record of records) {
scopes.add(record.scope);
@ -1380,9 +1401,7 @@ this.PushService = {
);
globalMM.broadcastAsyncMessage('pushsubscriptionchanged', scope);
}
resolve();
}, reject);
});
});
},
_notifyApp: function(aPushRecord) {
@ -1428,15 +1447,11 @@ this.PushService = {
_updatePushRecord: function(aPushRecord) {
debug("updatePushRecord()");
let deferred = Promise.defer();
this._db.put(aPushRecord, deferred.resolve, deferred.reject);
return deferred.promise;
return this._db.put(aPushRecord);
},
_dropRegistration: function() {
let deferred = Promise.defer();
this._db.drop(deferred.resolve, deferred.reject);
return deferred.promise;
return this._db.drop();
},
receiveMessage: function(aMessage) {
@ -1474,11 +1489,8 @@ this.PushService = {
},
_register: function(aPageRecord) {
let recordPromise = new Promise((resolve, reject) =>
this._db.getByScope(aPageRecord.scope, resolve, reject));
return recordPromise.then(
pushRecord => {
return this._db.getByScope(aPageRecord.scope)
.then(pushRecord => {
if (pushRecord == null) {
let channelID = this._generateID();
return this._registerWithServer(channelID, aPageRecord);
@ -1603,33 +1615,24 @@ this.PushService = {
_unregister: function(aPageRecord) {
debug("unregisterWithServer()");
let deferred = Promise.defer();
let fail = function(error) {
debug("unregister() fail() error " + error);
deferred.reject(error);
};
if (!aPageRecord.scope) {
fail("NotFoundError");
return deferred.promise;
return Promise.reject("NotFoundError");
}
this._db.getByScope(aPageRecord.scope, function(record) {
// If the endpoint didn't exist, let's just fail.
if (record === undefined) {
fail("NotFoundError");
return;
}
return this._db.getByScope(aPageRecord.scope)
.then(record => {
// If the endpoint didn't exist, let's just fail.
if (record === undefined) {
throw "NotFoundError";
}
this._db.delete(record.channelID, function() {
// Let's be nice to the server and try to inform it, but we don't care
// about the reply.
this._send("unregister", {channelID: record.channelID});
deferred.resolve();
}.bind(this), fail);
}.bind(this), fail);
return deferred.promise;
this._db.delete(record.channelID)
.then(_ =>
// Let's be nice to the server and try to inform it, but we don't care
// about the reply.
this._send("unregister", {channelID: record.channelID})
);
});
},
unregister: function(aPageRecord, aMessageManager) {
@ -1652,23 +1655,19 @@ this.PushService = {
},
_clearAll: function _clearAll() {
return new Promise((resolve, reject) => {
this._db.clearAll(() => resolve(),
() => reject("Database error"));
});
return this._db.clearAll();
},
/**
* Called on message from the child process
*/
_registration: function(aPageRecord) {
return new Promise((resolve, reject) => {
if (!aPageRecord.scope) {
reject("Database error");
return;
}
this._db.getByScope(aPageRecord.scope,
pushRecord => {
if (!aPageRecord.scope) {
return Promise.reject("Database error");
}
return this._db.getByScope(aPageRecord.scope)
.then(pushRecord => {
let registration = null;
if (pushRecord) {
registration = {
@ -1678,11 +1677,10 @@ this.PushService = {
pushCount: pushRecord.pushCount
};
}
resolve(registration);
},
() => reject("Database error")
);
});
return registration;
}, _ => {
throw "Database error";
});
},
registration: function(aPageRecord, aMessageManager) {
@ -1751,8 +1749,9 @@ this.PushService = {
};
}
this._db.getAllChannelIDs(sendHelloMessage.bind(this),
sendHelloMessage.bind(this));
this._db.getAllChannelIDs()
.then(sendHelloMessage.bind(this),
sendHelloMessage.bind(this));
});
},

View File

@ -61,46 +61,6 @@ function after(times, func) {
};
}
/**
* Wraps a Push database in a proxy that returns promises for all asynchronous
* methods. This makes it easier to test the database code with Task.jsm.
*
* @param {PushDB} db A Push database.
* @returns {Proxy} A proxy that traps function property gets and returns
* promisified functions.
*/
function promisifyDatabase(db) {
return new Proxy(db, {
get(target, property) {
let method = target[property];
if (typeof method != 'function') {
return method;
}
return function(...params) {
return new Promise((resolve, reject) => {
method.call(target, ...params, resolve, reject);
});
};
}
});
}
/**
* Clears and closes an open Push database.
*
* @param {PushDB} db A Push database.
* @returns {Promise} A promise that fulfills when the database is closed.
*/
function cleanupDatabase(db) {
return new Promise(resolve => {
function close() {
db.close();
resolve();
}
db.drop(close, close);
});
}
/**
* Defers one or more callbacks until the next turn of the event loop. Multiple
* callbacks are executed in order.

View File

@ -15,9 +15,8 @@ function run_test() {
add_task(function* test_unregister_success() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
yield promiseDB.put({
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield db.put({
channelID,
pushEndpoint: 'https://example.org/update/unregister-success',
scope: 'https://example.com/page/unregister-success',
@ -42,6 +41,6 @@ add_task(function* test_unregister_success() {
});
yield PushNotificationService.clearAll();
let record = yield promiseDB.getByChannelID(channelID);
let record = yield db.getByChannelID(channelID);
ok(!record, 'Unregister did not remove record');
});

View File

@ -20,8 +20,7 @@ function run_test() {
add_task(function* test_notification_ack() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let records = [{
channelID: '21668e05-6da8-42c9-b8ab-9cc3f4d5630c',
pushEndpoint: 'https://example.com/update/1',
@ -39,7 +38,7 @@ add_task(function* test_notification_ack() {
version: 3
}];
for (let record of records) {
yield promiseDB.put(record);
yield db.put(record);
}
let notifyPromise = Promise.all([

View File

@ -18,8 +18,7 @@ function run_test() {
// Should acknowledge duplicate notifications, but not notify apps.
add_task(function* test_notification_duplicate() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let records = [{
channelID: '8d2d9400-3597-4c5a-8a38-c546b0043bcc',
pushEndpoint: 'https://example.org/update/1',
@ -32,7 +31,7 @@ add_task(function* test_notification_duplicate() {
version: 2
}];
for (let record of records) {
yield promiseDB.put(record);
yield db.put(record);
}
let notifyPromise = promiseObserverNotification('push-notification');
@ -72,11 +71,11 @@ add_task(function* test_notification_duplicate() {
yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT,
'Timed out waiting for stale acknowledgement');
let staleRecord = yield promiseDB.getByChannelID(
let staleRecord = yield db.getByChannelID(
'8d2d9400-3597-4c5a-8a38-c546b0043bcc');
strictEqual(staleRecord.version, 2, 'Wrong stale record version');
let updatedRecord = yield promiseDB.getByChannelID(
let updatedRecord = yield db.getByChannelID(
'27d1e393-03ef-4c72-a5e6-9e890dfccad0');
strictEqual(updatedRecord.version, 3, 'Wrong updated record version');
});

View File

@ -18,8 +18,7 @@ function run_test() {
add_task(function* test_notification_error() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let records = [{
channelID: 'f04f1e46-9139-4826-b2d1-9411b0821283',
pushEndpoint: 'https://example.org/update/success-1',
@ -37,7 +36,7 @@ add_task(function* test_notification_error() {
version: 3
}];
for (let record of records) {
yield promiseDB.put(record);
yield db.put(record);
}
let notifyPromise = Promise.all([
@ -56,11 +55,11 @@ add_task(function* test_notification_error() {
PushService.init({
networkInfo: new MockDesktopNetworkInfo(),
db: makeStub(db, {
getByChannelID(prev, channelID, successCb, failureCb) {
getByChannelID(prev, channelID) {
if (channelID == '3c3930ba-44de-40dc-a7ca-8a133ec1a866') {
return failureCb('splines not reticulated');
return Promise.reject('splines not reticulated');
}
return prev.call(this, channelID, successCb, failureCb);
return prev.call(this, channelID);
}
}),
makeWebSocket(uri) {
@ -107,19 +106,19 @@ add_task(function* test_notification_error() {
yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT,
'Timed out waiting for acknowledgements');
let aRecord = yield promiseDB.getByScope('https://example.com/a');
let aRecord = yield db.getByScope('https://example.com/a');
equal(aRecord.channelID, 'f04f1e46-9139-4826-b2d1-9411b0821283',
'Wrong channel ID for record A');
strictEqual(aRecord.version, 2,
'Should return the new version for record A');
let bRecord = yield promiseDB.getByScope('https://example.com/b');
let bRecord = yield db.getByScope('https://example.com/b');
equal(bRecord.channelID, '3c3930ba-44de-40dc-a7ca-8a133ec1a866',
'Wrong channel ID for record B');
strictEqual(bRecord.version, 2,
'Should return the previous version for record B');
let cRecord = yield promiseDB.getByScope('https://example.com/c');
let cRecord = yield db.getByScope('https://example.com/c');
equal(cRecord.channelID, 'b63f7bef-0a0d-4236-b41e-086a69dfd316',
'Wrong channel ID for record C');
strictEqual(cRecord.version, 4,

View File

@ -19,8 +19,7 @@ function run_test() {
add_task(function* test_notification_incomplete() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let records = [{
channelID: '123',
pushEndpoint: 'https://example.org/update/1',
@ -43,7 +42,7 @@ add_task(function* test_notification_incomplete() {
version: 10
}];
for (let record of records) {
promiseDB.put(record);
db.put(record);
}
Services.obs.addObserver(function observe(subject, topic, data) {
@ -102,7 +101,7 @@ add_task(function* test_notification_incomplete() {
yield waitForPromise(notificationDefer.promise, DEFAULT_TIMEOUT,
'Timed out waiting for incomplete notifications');
let storeRecords = yield promiseDB.getAllChannelIDs();
let storeRecords = yield db.getAllChannelIDs();
storeRecords.sort(({pushEndpoint: a}, {pushEndpoint: b}) =>
compareAscending(a, b));
recordsAreEqual(records, storeRecords);

View File

@ -16,9 +16,8 @@ function run_test() {
add_task(function* test_notification_version_string() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
yield promiseDB.put({
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield db.put({
channelID: '6ff97d56-d0c0-43bc-8f5b-61b855e1d93b',
pushEndpoint: 'https://example.org/updates/1',
scope: 'https://example.com/page/1',
@ -66,7 +65,7 @@ add_task(function* test_notification_version_string() {
yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT,
'Timed out waiting for string acknowledgement');
let storeRecord = yield promiseDB.getByChannelID(
let storeRecord = yield db.getByChannelID(
'6ff97d56-d0c0-43bc-8f5b-61b855e1d93b');
strictEqual(storeRecord.version, 4, 'Wrong record version');
});

View File

@ -18,8 +18,7 @@ function run_test() {
add_task(function* test_register_case() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
PushService.init({
networkInfo: new MockDesktopNetworkInfo(),
@ -56,7 +55,7 @@ add_task(function* test_register_case() {
equal(newRecord.scope, 'https://example.net/case',
'Wrong scope in registration record');
let record = yield promiseDB.getByChannelID(newRecord.channelID);
let record = yield db.getByChannelID(newRecord.channelID);
equal(record.pushEndpoint, 'https://example.com/update/case',
'Wrong push endpoint in database record');
equal(record.scope, 'https://example.net/case',

View File

@ -24,15 +24,14 @@ function run_test() {
add_task(function* test_register_flush() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let record = {
channelID: '9bcc7efb-86c7-4457-93ea-e24e6eb59b74',
pushEndpoint: 'https://example.org/update/1',
scope: 'https://example.com/page/1',
version: 2
};
yield promiseDB.put(record);
yield db.put(record);
let notifyPromise = promiseObserverNotification('push-notification');
@ -89,14 +88,14 @@ add_task(function* test_register_flush() {
yield waitForPromise(ackDefer.promise, DEFAULT_TIMEOUT,
'Timed out waiting for acknowledgements');
let prevRecord = yield promiseDB.getByChannelID(
let prevRecord = yield db.getByChannelID(
'9bcc7efb-86c7-4457-93ea-e24e6eb59b74');
equal(prevRecord.pushEndpoint, 'https://example.org/update/1',
'Wrong existing push endpoint');
strictEqual(prevRecord.version, 3,
'Should record version updates sent before register responses');
let registeredRecord = yield promiseDB.getByChannelID(newRecord.channelID);
let registeredRecord = yield db.getByChannelID(newRecord.channelID);
equal(registeredRecord.pushEndpoint, 'https://example.org/update/2',
'Wrong new push endpoint');
ok(!registeredRecord.version, 'Should not record premature updates');

View File

@ -19,8 +19,7 @@ function run_test() {
add_task(function* test_register_invalid_channel() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
PushService._generateID = () => channelID;
PushService.init({
@ -55,6 +54,6 @@ add_task(function* test_register_invalid_channel() {
'Wrong error for invalid channel ID'
);
let record = yield promiseDB.getByChannelID(channelID);
let record = yield db.getByChannelID(channelID);
ok(!record, 'Should not store records for error responses');
});

View File

@ -19,8 +19,7 @@ function run_test() {
add_task(function* test_register_invalid_endpoint() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
PushService._generateID = () => channelID;
PushService.init({
@ -57,6 +56,6 @@ add_task(function* test_register_invalid_endpoint() {
'Wrong error for invalid endpoint'
);
let record = yield promiseDB.getByChannelID(channelID);
let record = yield db.getByChannelID(channelID);
ok(!record, 'Should not store records with invalid endpoints');
});

View File

@ -19,8 +19,7 @@ function run_test() {
add_task(function* test_register_request_queue() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let helloDefer = Promise.defer();
let onHello = after(2, function onHello(request) {

View File

@ -23,7 +23,7 @@ function run_test() {
add_task(function* test_register_rollback() {
let db = new PushDB();
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let handshakes = 0;
let registers = 0;
@ -32,8 +32,8 @@ add_task(function* test_register_rollback() {
PushService.init({
networkInfo: new MockDesktopNetworkInfo(),
db: makeStub(db, {
put(prev, record, successCb, failureCb) {
failureCb('universe has imploded');
put(prev, record) {
return Promise.reject('universe has imploded');
}
}),
makeWebSocket(uri) {

View File

@ -23,8 +23,7 @@ function run_test() {
add_task(function* test_register_success() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
PushService._generateID = () => channelID;
PushService.init({
@ -66,7 +65,7 @@ add_task(function* test_register_success() {
equal(newRecord.scope, 'https://example.org/1',
'Wrong scope in registration record');
let record = yield promiseDB.getByChannelID(channelID);
let record = yield db.getByChannelID(channelID);
equal(record.channelID, channelID,
'Wrong channel ID in database record');
equal(record.pushEndpoint, 'https://example.com/update/1',

View File

@ -26,8 +26,7 @@ add_task(function* test_register_timeout() {
let registers = 0;
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
PushService._generateID = () => channelID;
PushService.init({
@ -90,7 +89,7 @@ add_task(function* test_register_timeout() {
'Wrong error for request timeout'
);
let record = yield promiseDB.getByChannelID(channelID);
let record = yield db.getByChannelID(channelID);
ok(!record, 'Should not store records for timed-out responses');
yield waitForPromise(

View File

@ -15,13 +15,13 @@ function run_test() {
add_task(function* test_registrations_error() {
let db = new PushDB();
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
PushService.init({
networkInfo: new MockDesktopNetworkInfo(),
db: makeStub(db, {
getByScope(prev, scope, successCb, failureCb) {
failureCb('oops');
getByScope(prev, scope) {
return Promise.reject('oops');
}
}),
makeWebSocket(uri) {

View File

@ -15,8 +15,7 @@ function run_test() {
add_task(function* test_registration_success() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let records = [{
channelID: 'bf001fe0-2684-42f2-bc4d-a3e14b11dd5b',
pushEndpoint: 'https://example.com/update/same-manifest/1',
@ -34,7 +33,7 @@ add_task(function* test_registration_success() {
version: 15
}];
for (let record of records) {
yield promiseDB.put(record);
yield db.put(record);
}
PushService.init({

View File

@ -15,9 +15,8 @@ function run_test() {
add_task(function* test_unregister_error() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
yield promiseDB.put({
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield db.put({
channelID: channelID,
pushEndpoint: 'https://example.org/update/failure',
scope: 'https://example.net/page/failure',
@ -56,7 +55,7 @@ add_task(function* test_unregister_error() {
yield PushNotificationService.unregister(
'https://example.net/page/failure');
let result = yield promiseDB.getByChannelID(channelID);
let result = yield db.getByChannelID(channelID);
ok(!result, 'Deleted push record exists');
// Make sure we send a request to the server.

View File

@ -19,8 +19,7 @@ function run_test() {
add_task(function* test_unregister_invalid_json() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
let records = [{
channelID: '87902e90-c57e-4d18-8354-013f4a556559',
pushEndpoint: 'https://example.org/update/1',
@ -33,7 +32,7 @@ add_task(function* test_unregister_invalid_json() {
version: 1
}];
for (let record of records) {
yield promiseDB.put(record);
yield db.put(record);
}
let unregisterDefer = Promise.defer();
@ -62,13 +61,13 @@ add_task(function* test_unregister_invalid_json() {
// _sendRequest().
yield PushNotificationService.unregister(
'https://example.edu/page/1');
let record = yield promiseDB.getByChannelID(
let record = yield db.getByChannelID(
'87902e90-c57e-4d18-8354-013f4a556559');
ok(!record, 'Failed to delete unregistered record');
yield PushNotificationService.unregister(
'https://example.net/page/1');
record = yield promiseDB.getByChannelID(
record = yield db.getByChannelID(
'057caa8f-9b99-47ff-891c-adad18ce603e');
ok(!record,
'Failed to delete unregistered record after receiving invalid JSON');

View File

@ -15,9 +15,8 @@ function run_test() {
add_task(function* test_unregister_success() {
let db = new PushDB();
let promiseDB = promisifyDatabase(db);
do_register_cleanup(() => cleanupDatabase(db));
yield promiseDB.put({
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield db.put({
channelID,
pushEndpoint: 'https://example.org/update/unregister-success',
scope: 'https://example.com/page/unregister-success',
@ -52,7 +51,7 @@ add_task(function* test_unregister_success() {
yield PushNotificationService.unregister(
'https://example.com/page/unregister-success');
let record = yield promiseDB.getByChannelID(channelID);
let record = yield db.getByChannelID(channelID);
ok(!record, 'Unregister did not remove record');
yield waitForPromise(unregisterDefer.promise, DEFAULT_TIMEOUT,

View File

@ -8,7 +8,7 @@ let Cc = Components.classes;
let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.importGlobalProperties(['Blob']);
Cu.importGlobalProperties(['Blob', 'File']);
Cu.import("resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"];
@ -209,7 +209,7 @@ SettingsDB.prototype = {
return "primitive";
} else if (Array.isArray(aObject)) {
return "array";
} else if (aObject instanceof Ci.nsIDOMFile) {
} else if (aObject instanceof File) {
return "file";
} else if (aObject instanceof Ci.nsIDOMBlob) {
return "blob";

View File

@ -8,6 +8,8 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.importGlobalProperties(['File']);
this.EXPORTED_SYMBOLS = ["SettingsRequestManager"];
Cu.import("resource://gre/modules/SettingsDB.jsm");
@ -245,7 +247,7 @@ let SettingsRequestManager = {
if (!aValue || !aValue.constructor) {
return false;
}
return (aValue.constructor.name == "Date") || (aValue instanceof Ci.nsIDOMFile) ||
return (aValue.constructor.name == "Date") || (aValue instanceof File) ||
(aValue instanceof Ci.nsIDOMBlob);
}
// We need to serialize settings objects, otherwise they can change between

View File

@ -45,6 +45,8 @@ partial interface File {
readonly attribute Date lastModifiedDate;
[GetterThrows, ChromeOnly]
readonly attribute DOMString mozFullPath;
readonly attribute DOMString path;
[GetterThrows, ChromeOnly]
readonly attribute DOMString mozFullPath;
};

View File

@ -148,7 +148,7 @@ partial interface HTMLInputElement {
[GetterThrows]
readonly attribute long textLength;
[ChromeOnly]
[Throws, ChromeOnly]
sequence<DOMString> mozGetFileNameArray();
[ChromeOnly, Throws]

View File

@ -18,7 +18,7 @@
#include "cert.h"
#include "certdb.h"
#include "CryptoTask.h"
#include "nsIDOMFile.h"
#include "nsIDOMBlob.h"
#include "nsIWifiService.h"
#include "nsNetUtil.h"
#include "nsServiceManagerUtils.h"

View File

@ -192,13 +192,6 @@ struct RectCornerRadii {
return radii[aCorner];
}
bool operator==(const RectCornerRadii& aOther) const {
for (size_t i = 0; i < RectCorner::Count; i++) {
if (radii[i] != aOther.radii[i]) return false;
}
return true;
}
void Scale(Float aXScale, Float aYScale) {
for (int i = 0; i < RectCorner::Count; i++) {
radii[i].Scale(aXScale, aYScale);
@ -361,16 +354,19 @@ inline bool UserToDevicePixelSnapped(Rect& aRect, const DrawTarget& aDrawTarget,
* This function has the same behavior as UserToDevicePixelSnapped except that
* aRect is not transformed to device space.
*/
inline void MaybeSnapToDevicePixels(Rect& aRect, const DrawTarget& aDrawTarget,
bool aIgnoreScale = false)
inline bool MaybeSnapToDevicePixels(Rect& aRect, const DrawTarget& aDrawTarget,
bool aAllowScaleOr90DegreeRotate = false)
{
if (UserToDevicePixelSnapped(aRect, aDrawTarget, aIgnoreScale)) {
if (UserToDevicePixelSnapped(aRect, aDrawTarget,
aAllowScaleOr90DegreeRotate)) {
// Since UserToDevicePixelSnapped returned true we know there is no
// rotation/skew in 'mat', so we can just use TransformBounds() here.
Matrix mat = aDrawTarget.GetTransform();
mat.Invert();
aRect = mat.TransformBounds(aRect);
return true;
}
return false;
}
} // namespace gfx

View File

@ -712,16 +712,15 @@ SenderHelper::SendTextureSource(GLContext* aGLContext,
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_RECTANGLE, &textureId);
}
gfx::IntSize size = aSource->GetSize();
// By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding
// texture correctly. textureId is used for tracking in DebugGLTextureData.
RefPtr<DataSourceSurface> img =
aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget,
size,
shaderConfig, aFlipY);
if (!IsTextureIdContainsInList(textureId)) {
gfx::IntSize size = aSource->GetSize();
// By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding
// texture correctly. textureId is used for tracking in DebugGLTextureData.
RefPtr<DataSourceSurface> img =
aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget,
size,
shaderConfig, aFlipY);
sTextureIdList.push_back(textureId);
WebSocketHelper::GetSocketManager()->AppendDebugData(
new DebugGLTextureData(aGLContext, aLayerRef, textureTarget,

View File

@ -14,7 +14,6 @@
#include "mozilla/UniquePtr.h"
#include "nsExpirationTracker.h"
#include "nsClassHashtable.h"
#include "gfxUtils.h"
using namespace mozilla;
using namespace mozilla::gfx;
@ -165,56 +164,40 @@ struct BlurCacheKey : public PLDHashEntryHdr {
typedef const BlurCacheKey* KeyTypePointer;
enum { ALLOW_MEMMOVE = true };
IntSize mMinSize;
gfxRect mRect;
gfxIntSize mBlurRadius;
gfxRGBA mShadowColor;
gfxRect mSkipRect;
BackendType mBackend;
RectCornerRadii mCornerRadii;
BlurCacheKey(IntSize aMinimumSize, gfxIntSize aBlurRadius,
RectCornerRadii* aCornerRadii, gfxRGBA aShadowColor,
BackendType aBackend)
: mMinSize(aMinimumSize)
BlurCacheKey(const gfxRect& aRect, const gfxIntSize &aBlurRadius, const gfxRect& aSkipRect, BackendType aBackend)
: mRect(aRect)
, mBlurRadius(aBlurRadius)
, mShadowColor(aShadowColor)
, mSkipRect(aSkipRect)
, mBackend(aBackend)
, mCornerRadii(aCornerRadii ? *aCornerRadii : RectCornerRadii())
{ }
explicit BlurCacheKey(const BlurCacheKey* aOther)
: mMinSize(aOther->mMinSize)
: mRect(aOther->mRect)
, mBlurRadius(aOther->mBlurRadius)
, mShadowColor(aOther->mShadowColor)
, mSkipRect(aOther->mSkipRect)
, mBackend(aOther->mBackend)
, mCornerRadii(aOther->mCornerRadii)
{ }
static PLDHashNumber
HashKey(const KeyTypePointer aKey)
{
PLDHashNumber hash = 0;
hash = AddToHash(hash, aKey->mMinSize.width, aKey->mMinSize.height);
PLDHashNumber hash = HashBytes(&aKey->mRect.x, 4 * sizeof(gfxFloat));
hash = AddToHash(hash, aKey->mBlurRadius.width, aKey->mBlurRadius.height);
hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.r, sizeof(gfxFloat)));
hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.g, sizeof(gfxFloat)));
hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.b, sizeof(gfxFloat)));
hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.a, sizeof(gfxFloat)));
for (int i = 0; i < 4; i++) {
hash = AddToHash(hash, aKey->mCornerRadii[i].width, aKey->mCornerRadii[i].height);
}
hash = AddToHash(hash, HashBytes(&aKey->mSkipRect.x, 4 * sizeof(gfxFloat)));
hash = AddToHash(hash, (uint32_t)aKey->mBackend);
return hash;
}
bool KeyEquals(KeyTypePointer aKey) const
{
if (aKey->mMinSize == mMinSize &&
if (aKey->mRect.IsEqualInterior(mRect) &&
aKey->mBlurRadius == mBlurRadius &&
aKey->mCornerRadii == mCornerRadii &&
aKey->mShadowColor == mShadowColor &&
aKey->mSkipRect.IsEqualInterior(mSkipRect) &&
aKey->mBackend == mBackend) {
return true;
}
@ -231,15 +214,17 @@ struct BlurCacheKey : public PLDHashEntryHdr {
* to the cache entry to be able to be tracked by the nsExpirationTracker.
* */
struct BlurCacheData {
BlurCacheData(SourceSurface* aBlur, IntMargin aExtendDestBy, const BlurCacheKey& aKey)
BlurCacheData(SourceSurface* aBlur, const IntPoint& aTopLeft, const gfxRect& aDirtyRect, const BlurCacheKey& aKey)
: mBlur(aBlur)
, mExtendDest(aExtendDestBy)
, mTopLeft(aTopLeft)
, mDirtyRect(aDirtyRect)
, mKey(aKey)
{}
BlurCacheData(const BlurCacheData& aOther)
: mBlur(aOther.mBlur)
, mExtendDest(aOther.mExtendDest)
, mTopLeft(aOther.mTopLeft)
, mDirtyRect(aOther.mDirtyRect)
, mKey(aOther.mKey)
{ }
@ -249,7 +234,8 @@ struct BlurCacheData {
nsExpirationState mExpirationState;
RefPtr<SourceSurface> mBlur;
IntMargin mExtendDest;
IntPoint mTopLeft;
gfxRect mDirtyRect;
BlurCacheKey mKey;
};
@ -273,18 +259,19 @@ class BlurCache final : public nsExpirationTracker<BlurCacheData,4>
mHashEntries.Remove(aObject->mKey);
}
BlurCacheData* Lookup(const IntSize aMinSize,
BlurCacheData* Lookup(const gfxRect& aRect,
const gfxIntSize& aBlurRadius,
RectCornerRadii* aCornerRadii,
const gfxRGBA& aShadowColor,
BackendType aBackendType)
const gfxRect& aSkipRect,
BackendType aBackendType,
const gfxRect* aDirtyRect)
{
BlurCacheData* blur =
mHashEntries.Get(BlurCacheKey(aMinSize, aBlurRadius,
aCornerRadii, aShadowColor,
aBackendType));
mHashEntries.Get(BlurCacheKey(aRect, aBlurRadius, aSkipRect, aBackendType));
if (blur) {
if (aDirtyRect && !blur->mDirtyRect.Contains(*aDirtyRect)) {
return nullptr;
}
MarkUsed(blur);
}
@ -319,163 +306,52 @@ class BlurCache final : public nsExpirationTracker<BlurCacheData,4>
static BlurCache* gBlurCache = nullptr;
static IntSize
ComputeMinSizeForShadowShape(RectCornerRadii* aCornerRadii,
gfxIntSize aBlurRadius,
IntMargin& aSlice,
const IntSize& aRectSize)
{
float cornerWidth = 0;
float cornerHeight = 0;
if (aCornerRadii) {
RectCornerRadii corners = *aCornerRadii;
for (size_t i = 0; i < 4; i++) {
cornerWidth = std::max(cornerWidth, corners[i].width);
cornerHeight = std::max(cornerHeight, corners[i].height);
}
}
aSlice = IntMargin(ceil(cornerHeight) + aBlurRadius.height,
ceil(cornerWidth) + aBlurRadius.width,
ceil(cornerHeight) + aBlurRadius.height,
ceil(cornerWidth) + aBlurRadius.width);
// Include 1 pixel for the stretchable strip in the middle.
IntSize minSize(aSlice.LeftRight() + 1,
aSlice.TopBottom() + 1);
// If aRectSize is smaller than minSize, the border-image approach won't
// work; there's no way to squeeze parts of the min box-shadow source
// image such that the result looks correct. So we need to adjust minSize
// in such a way that we can later draw it without stretching in the affected
// dimension. We also need to adjust "slice" to ensure that we're not trying
// to slice away more than we have.
if (aRectSize.width < minSize.width) {
minSize.width = aRectSize.width;
aSlice.left = 0;
aSlice.right = 0;
}
if (aRectSize.height < minSize.height) {
minSize.height = aRectSize.height;
aSlice.top = 0;
aSlice.bottom = 0;
}
MOZ_ASSERT(aSlice.LeftRight() <= minSize.width);
MOZ_ASSERT(aSlice.TopBottom() <= minSize.height);
return minSize;
}
void
CacheBlur(DrawTarget& aDT,
const IntSize& aMinSize,
const gfxIntSize& aBlurRadius,
RectCornerRadii* aCornerRadii,
const gfxRGBA& aShadowColor,
IntMargin aExtendDest,
SourceSurface* aBoxShadow)
{
BlurCacheKey key(aMinSize, aBlurRadius, aCornerRadii, aShadowColor, aDT.GetBackendType());
BlurCacheData* data = new BlurCacheData(aBoxShadow, aExtendDest, key);
if (!gBlurCache->RegisterEntry(data)) {
delete data;
}
}
// Blurs a small surface and creates the mask.
static TemporaryRef<SourceSurface>
CreateBlurMask(const IntSize& aRectSize,
RectCornerRadii* aCornerRadii,
gfxIntSize aBlurRadius,
IntMargin& aExtendDestBy,
IntMargin& aSliceBorder,
DrawTarget& aDestDrawTarget)
{
IntMargin slice;
IntSize minSize =
ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, slice, aRectSize);
IntRect minRect(IntPoint(), minSize);
gfxAlphaBoxBlur blur;
gfxContext* blurCtx = blur.Init(ThebesRect(Rect(minRect)), gfxIntSize(),
aBlurRadius, nullptr, nullptr);
if (!blurCtx) {
return nullptr;
}
DrawTarget* blurDT = blurCtx->GetDrawTarget();
ColorPattern black(Color(0.f, 0.f, 0.f, 1.f));
if (aCornerRadii) {
RefPtr<Path> roundedRect =
MakePathForRoundedRect(*blurDT, Rect(minRect), *aCornerRadii);
blurDT->Fill(roundedRect, black);
} else {
blurDT->FillRect(Rect(minRect), black);
}
IntPoint topLeft;
RefPtr<SourceSurface> result = blur.DoBlur(&aDestDrawTarget, &topLeft);
IntRect expandedMinRect(topLeft, result->GetSize());
aExtendDestBy = expandedMinRect - minRect;
aSliceBorder = slice + aExtendDestBy;
MOZ_ASSERT(aSliceBorder.LeftRight() <= expandedMinRect.width);
MOZ_ASSERT(aSliceBorder.TopBottom() <= expandedMinRect.height);
return result.forget();
}
static TemporaryRef<SourceSurface>
CreateBoxShadow(SourceSurface* aBlurMask, const gfxRGBA& aShadowColor)
{
IntSize blurredSize = aBlurMask->GetSize();
gfxPlatform* platform = gfxPlatform::GetPlatform();
RefPtr<DrawTarget> boxShadowDT =
platform->CreateOffscreenContentDrawTarget(blurredSize, SurfaceFormat::B8G8R8A8);
ColorPattern shadowColor(ToDeviceColor(aShadowColor));
boxShadowDT->MaskSurface(shadowColor, aBlurMask, Point(0, 0));
return boxShadowDT->Snapshot();
}
SourceSurface*
GetBlur(DrawTarget& aDT,
const IntSize& aRectSize,
GetCachedBlur(DrawTarget *aDT,
const gfxRect& aRect,
const gfxIntSize& aBlurRadius,
RectCornerRadii* aCornerRadii,
const gfxRGBA& aShadowColor,
IntMargin& aExtendDestBy,
IntMargin& aSlice)
const gfxRect& aSkipRect,
const gfxRect& aDirtyRect,
IntPoint* aTopLeft)
{
if (!gBlurCache) {
gBlurCache = new BlurCache();
}
IntSize minSize =
ComputeMinSizeForShadowShape(aCornerRadii, aBlurRadius, aSlice, aRectSize);
BlurCacheData* cached = gBlurCache->Lookup(minSize, aBlurRadius,
aCornerRadii, aShadowColor,
aDT.GetBackendType());
BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect,
aDT->GetBackendType(),
&aDirtyRect);
if (cached) {
// See CreateBlurMask() for these values
aExtendDestBy = cached->mExtendDest;
aSlice = aSlice + aExtendDestBy;
*aTopLeft = cached->mTopLeft;
return cached->mBlur;
}
return nullptr;
}
RefPtr<SourceSurface> blurMask =
CreateBlurMask(aRectSize, aCornerRadii, aBlurRadius, aExtendDestBy, aSlice, aDT);
if (!blurMask) {
return nullptr;
void
CacheBlur(DrawTarget *aDT,
const gfxRect& aRect,
const gfxIntSize& aBlurRadius,
const gfxRect& aSkipRect,
SourceSurface* aBlur,
const IntPoint& aTopLeft,
const gfxRect& aDirtyRect)
{
// If we already had a cached value with this key, but an incorrect dirty region then just update
// the existing entry
if (BlurCacheData* cached = gBlurCache->Lookup(aRect, aBlurRadius, aSkipRect,
aDT->GetBackendType(),
nullptr)) {
cached->mBlur = aBlur;
cached->mTopLeft = aTopLeft;
cached->mDirtyRect = aDirtyRect;
return;
}
RefPtr<SourceSurface> boxShadow = CreateBoxShadow(blurMask, aShadowColor);
CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow);
return boxShadow;
BlurCacheKey key(aRect, aBlurRadius, aSkipRect, aDT->GetBackendType());
BlurCacheData* data = new BlurCacheData(aBlur, aTopLeft, aDirtyRect, key);
if (!gBlurCache->RegisterEntry(data)) {
delete data;
}
}
void
@ -485,45 +361,8 @@ gfxAlphaBoxBlur::ShutdownBlurCache()
gBlurCache = nullptr;
}
static Rect
RectWithEdgesTRBL(Float aTop, Float aRight, Float aBottom, Float aLeft)
{
return Rect(aLeft, aTop, aRight - aLeft, aBottom - aTop);
}
static void
RepeatOrStretchSurface(DrawTarget& aDT, SourceSurface* aSurface,
const Rect& aDest, const Rect& aSrc)
{
if (!aDT.GetTransform().IsRectilinear() &&
aDT.GetBackendType() != BackendType::CAIRO) {
// Use stretching if possible, since it leads to less seams when the
// destination is transformed. However, don't do this if we're using cairo,
// because if cairo is using pixman it won't render anything for large
// stretch factors because pixman's internal fixed point precision is not
// high enough to handle those scale factors.
aDT.DrawSurface(aSurface, aDest, aSrc);
return;
}
SurfacePattern pattern(aSurface, ExtendMode::REPEAT,
Matrix::Translation(aDest.TopLeft() - aSrc.TopLeft()),
Filter::GOOD, RoundedToInt(aSrc));
aDT.FillRect(aDest, pattern);
}
/***
* We draw a blurred a rectangle by only blurring a smaller rectangle and
* splitting the rectangle into 9 parts.
* First, a small minimum source rect is calculated and used to create a blur
* mask since the actual blurring itself is expensive. Next, we use the mask
* with the given shadow color to create a minimally-sized box shadow of the
* right color. Finally, we cut out the 9 parts from the box-shadow source and
* paint each part in the right place, stretching the non-corner parts to fill
* the space between the corners.
*/
/* static */ void
gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
gfxAlphaBoxBlur::BlurRectangle(gfxContext *aDestinationCtx,
const gfxRect& aRect,
RectCornerRadii* aCornerRadii,
const gfxPoint& aBlurStdDev,
@ -531,103 +370,43 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx,
const gfxRect& aDirtyRect,
const gfxRect& aSkipRect)
{
DrawTarget& destDrawTarget = *aDestinationCtx->GetDrawTarget();
DrawTarget& aDrawTarget = *aDestinationCtx->GetDrawTarget();
gfxIntSize blurRadius = CalculateBlurRadius(aBlurStdDev);
IntRect rect = RoundedToInt(ToRect(aRect));
IntMargin extendDestBy;
IntMargin slice;
IntPoint topLeft;
RefPtr<SourceSurface> surface = GetCachedBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, aDirtyRect, &topLeft);
if (!surface) {
// Create the temporary surface for blurring
gfxAlphaBoxBlur blur;
gfxContext* blurCtx = blur.Init(aRect, gfxIntSize(), blurRadius, &aDirtyRect, &aSkipRect);
if (!blurCtx) {
return;
}
DrawTarget* blurDT = blurCtx->GetDrawTarget();
RefPtr<SourceSurface> boxShadow = GetBlur(destDrawTarget,
rect.Size(), blurRadius,
aCornerRadii, aShadowColor,
extendDestBy, slice);
if (!boxShadow) {
return;
Rect shadowGfxRect = ToRect(aRect);
shadowGfxRect.Round();
ColorPattern black(Color(0.f, 0.f, 0.f, 1.f)); // For masking, so no ToDeviceColor!
if (aCornerRadii) {
RefPtr<Path> roundedRect = MakePathForRoundedRect(*blurDT,
shadowGfxRect,
*aCornerRadii);
blurDT->Fill(roundedRect, black);
} else {
blurDT->FillRect(shadowGfxRect, black);
}
surface = blur.DoBlur(&aDrawTarget, &topLeft);
if (!surface) {
return;
}
CacheBlur(&aDrawTarget, aRect, blurRadius, aSkipRect, surface, topLeft, aDirtyRect);
}
destDrawTarget.PushClipRect(ToRect(aDirtyRect));
// Copy the right parts from boxShadow into destDrawTarget. The middle parts
// will be stretched, border-image style.
Rect srcOuter(Point(), Size(boxShadow->GetSize()));
Rect srcInner = srcOuter;
srcInner.Deflate(Margin(slice));
rect.Inflate(extendDestBy);
Rect dstOuter(rect);
Rect dstInner(rect);
dstInner.Deflate(Margin(slice));
// Corners: top left, top right, bottom left, bottom right
destDrawTarget.DrawSurface(boxShadow,
RectWithEdgesTRBL(dstOuter.Y(), dstInner.X(),
dstInner.Y(), dstOuter.X()),
RectWithEdgesTRBL(srcOuter.Y(), srcInner.X(),
srcInner.Y(), srcOuter.X()));
destDrawTarget.DrawSurface(boxShadow,
RectWithEdgesTRBL(dstOuter.Y(), dstOuter.XMost(),
dstInner.Y(), dstInner.XMost()),
RectWithEdgesTRBL(srcOuter.Y(), srcOuter.XMost(),
srcInner.Y(), srcInner.XMost()));
destDrawTarget.DrawSurface(boxShadow,
RectWithEdgesTRBL(dstInner.YMost(), dstInner.X(),
dstOuter.YMost(), dstOuter.X()),
RectWithEdgesTRBL(srcInner.YMost(), srcInner.X(),
srcOuter.YMost(), srcOuter.X()));
destDrawTarget.DrawSurface(boxShadow,
RectWithEdgesTRBL(dstInner.YMost(), dstOuter.XMost(),
dstOuter.YMost(), dstInner.XMost()),
RectWithEdgesTRBL(srcInner.YMost(), srcOuter.XMost(),
srcOuter.YMost(), srcInner.XMost()));
// Edges: top, left, right, bottom
RepeatOrStretchSurface(destDrawTarget, boxShadow,
RectWithEdgesTRBL(dstOuter.Y(), dstInner.XMost(),
dstInner.Y(), dstInner.X()),
RectWithEdgesTRBL(srcOuter.Y(), srcInner.XMost(),
srcInner.Y(), srcInner.X()));
RepeatOrStretchSurface(destDrawTarget, boxShadow,
RectWithEdgesTRBL(dstInner.Y(), dstInner.X(),
dstInner.YMost(), dstOuter.X()),
RectWithEdgesTRBL(srcInner.Y(), srcInner.X(),
srcInner.YMost(), srcOuter.X()));
RepeatOrStretchSurface(destDrawTarget, boxShadow,
RectWithEdgesTRBL(dstInner.Y(), dstOuter.XMost(),
dstInner.YMost(), dstInner.XMost()),
RectWithEdgesTRBL(srcInner.Y(), srcOuter.XMost(),
srcInner.YMost(), srcInner.XMost()));
RepeatOrStretchSurface(destDrawTarget, boxShadow,
RectWithEdgesTRBL(dstInner.YMost(), dstInner.XMost(),
dstOuter.YMost(), dstInner.X()),
RectWithEdgesTRBL(srcInner.YMost(), srcInner.XMost(),
srcOuter.YMost(), srcInner.X()));
// Middle part
RepeatOrStretchSurface(destDrawTarget, boxShadow,
RectWithEdgesTRBL(dstInner.Y(), dstInner.XMost(),
dstInner.YMost(), dstInner.X()),
RectWithEdgesTRBL(srcInner.Y(), srcInner.XMost(),
srcInner.YMost(), srcInner.X()));
// A note about anti-aliasing and seems between adjacent parts:
// We don't explicitly disable anti-aliasing in the DrawSurface calls above,
// so if there's a transform on destDrawTarget that is not pixel-aligned,
// there will be seams between adjacent parts of the box-shadow. It's hard to
// avoid those without the use of an intermediate surface.
// You might think that we could avoid those by just turning of AA, but there
// is a problem with that: Box-shadow rendering needs to clip out the
// element's border box, and we'd like that clip to have anti-aliasing -
// especially if the element has rounded corners! So we can't do that unless
// we have a way to say "Please anti-alias the clip, but don't antialias the
// destination rect of the DrawSurface call".
// On OS X there is an additional problem with turning off AA: CoreGraphics
// will not just fill the pixels that have their pixel center inside the
// filled shape. Instead, it will fill all the pixels which are partially
// covered by the shape. So for pixels on the edge between two adjacent parts,
// all those pixels will be painted to by both parts, which looks very bad.
destDrawTarget.PopClip();
aDestinationCtx->SetColor(aShadowColor);
Rect dirtyRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
DrawBlur(aDestinationCtx, surface, topLeft, &dirtyRect);
}

View File

@ -304,6 +304,39 @@ gfxGDIFont::Initialize()
mMetrics->maxAdvance = mMetrics->aveCharWidth;
}
// For fonts with USE_TYPO_METRICS set in the fsSelection field,
// let the OS/2 sTypo* metrics override the previous values.
// (see http://www.microsoft.com/typography/otspec/os2.htm#fss)
// Using the equivalent values from oMetrics provides inconsistent
// results with CFF fonts, so we instead rely on OS2Table.
gfxFontEntry::AutoTable os2Table(mFontEntry,
TRUETYPE_TAG('O','S','/','2'));
if (os2Table) {
uint32_t len;
const OS2Table *os2 =
reinterpret_cast<const OS2Table*>(hb_blob_get_data(os2Table,
&len));
if (len >= offsetof(OS2Table, sTypoLineGap) + sizeof(int16_t)) {
const uint16_t kUseTypoMetricsMask = 1 << 7;
if ((uint16_t(os2->fsSelection) & kUseTypoMetricsMask)) {
double ascent = int16_t(os2->sTypoAscender);
double descent = int16_t(os2->sTypoDescender);
double lineGap = int16_t(os2->sTypoLineGap);
mMetrics->maxAscent = ROUND(ascent * mFUnitsConvFactor);
mMetrics->maxDescent = -ROUND(descent * mFUnitsConvFactor);
mMetrics->maxHeight =
mMetrics->maxAscent + mMetrics->maxDescent;
mMetrics->internalLeading =
mMetrics->maxHeight - mMetrics->emHeight;
gfxFloat lineHeight =
ROUND((ascent - descent + lineGap) * mFUnitsConvFactor);
lineHeight = std::max(lineHeight, mMetrics->maxHeight);
mMetrics->externalLeading =
lineHeight - mMetrics->maxHeight;
}
}
}
// Cache the width of a single space.
SIZE size;
GetTextExtentPoint32W(dc.GetDC(), L" ", 1, &size);

View File

@ -69,47 +69,49 @@ class GlobalObject : public NativeObject
*/
static const unsigned STANDARD_CLASS_SLOTS = JSProto_LIMIT * 3;
/* Various function values needed by the engine. */
static const unsigned EVAL = APPLICATION_SLOTS + STANDARD_CLASS_SLOTS;
static const unsigned CREATE_DATAVIEW_FOR_THIS = EVAL + 1;
static const unsigned THROWTYPEERROR = CREATE_DATAVIEW_FOR_THIS + 1;
enum : unsigned {
/* Various function values needed by the engine. */
EVAL = APPLICATION_SLOTS + STANDARD_CLASS_SLOTS,
CREATE_DATAVIEW_FOR_THIS,
THROWTYPEERROR,
/*
* Instances of the internal createArrayFromBuffer function used by the
* typed array code, one per typed array element type.
*/
static const unsigned FROM_BUFFER_UINT8 = THROWTYPEERROR + 1;
static const unsigned FROM_BUFFER_INT8 = FROM_BUFFER_UINT8 + 1;
static const unsigned FROM_BUFFER_UINT16 = FROM_BUFFER_INT8 + 1;
static const unsigned FROM_BUFFER_INT16 = FROM_BUFFER_UINT16 + 1;
static const unsigned FROM_BUFFER_UINT32 = FROM_BUFFER_INT16 + 1;
static const unsigned FROM_BUFFER_INT32 = FROM_BUFFER_UINT32 + 1;
static const unsigned FROM_BUFFER_FLOAT32 = FROM_BUFFER_INT32 + 1;
static const unsigned FROM_BUFFER_FLOAT64 = FROM_BUFFER_FLOAT32 + 1;
static const unsigned FROM_BUFFER_UINT8CLAMPED = FROM_BUFFER_FLOAT64 + 1;
/*
* Instances of the internal createArrayFromBuffer function used by the
* typed array code, one per typed array element type.
*/
FROM_BUFFER_UINT8,
FROM_BUFFER_INT8,
FROM_BUFFER_UINT16,
FROM_BUFFER_INT16,
FROM_BUFFER_UINT32,
FROM_BUFFER_INT32,
FROM_BUFFER_FLOAT32,
FROM_BUFFER_FLOAT64,
FROM_BUFFER_UINT8CLAMPED,
/* One-off properties stored after slots for built-ins. */
static const unsigned ARRAY_ITERATOR_PROTO = FROM_BUFFER_UINT8CLAMPED + 1;
static const unsigned STRING_ITERATOR_PROTO = ARRAY_ITERATOR_PROTO + 1;
static const unsigned LEGACY_GENERATOR_OBJECT_PROTO = STRING_ITERATOR_PROTO + 1;
static const unsigned STAR_GENERATOR_OBJECT_PROTO = LEGACY_GENERATOR_OBJECT_PROTO + 1;
static const unsigned MAP_ITERATOR_PROTO = STAR_GENERATOR_OBJECT_PROTO + 1;
static const unsigned SET_ITERATOR_PROTO = MAP_ITERATOR_PROTO + 1;
static const unsigned COLLATOR_PROTO = SET_ITERATOR_PROTO + 1;
static const unsigned NUMBER_FORMAT_PROTO = COLLATOR_PROTO + 1;
static const unsigned DATE_TIME_FORMAT_PROTO = NUMBER_FORMAT_PROTO + 1;
static const unsigned REGEXP_STATICS = DATE_TIME_FORMAT_PROTO + 1;
static const unsigned WARNED_ONCE_FLAGS = REGEXP_STATICS + 1;
static const unsigned RUNTIME_CODEGEN_ENABLED = WARNED_ONCE_FLAGS + 1;
static const unsigned DEBUGGERS = RUNTIME_CODEGEN_ENABLED + 1;
static const unsigned INTRINSICS = DEBUGGERS + 1;
static const unsigned FLOAT32X4_TYPE_DESCR = INTRINSICS + 1;
static const unsigned FLOAT64X2_TYPE_DESCR = FLOAT32X4_TYPE_DESCR + 1;
static const unsigned INT32X4_TYPE_DESCR = FLOAT64X2_TYPE_DESCR + 1;
static const unsigned FOR_OF_PIC_CHAIN = INT32X4_TYPE_DESCR + 1;
/* One-off properties stored after slots for built-ins. */
ARRAY_ITERATOR_PROTO,
STRING_ITERATOR_PROTO,
LEGACY_GENERATOR_OBJECT_PROTO,
STAR_GENERATOR_OBJECT_PROTO,
MAP_ITERATOR_PROTO,
SET_ITERATOR_PROTO,
COLLATOR_PROTO,
NUMBER_FORMAT_PROTO,
DATE_TIME_FORMAT_PROTO,
REGEXP_STATICS,
WARNED_ONCE_FLAGS,
RUNTIME_CODEGEN_ENABLED,
DEBUGGERS,
INTRINSICS,
FLOAT32X4_TYPE_DESCR,
FLOAT64X2_TYPE_DESCR,
INT32X4_TYPE_DESCR,
FOR_OF_PIC_CHAIN,
/* Total reserved-slot count for global objects. */
static const unsigned RESERVED_SLOTS = FOR_OF_PIC_CHAIN + 1;
/* Total reserved-slot count for global objects. */
RESERVED_SLOTS
};
/*
* The slot count must be in the public API for JSCLASS_GLOBAL_FLAGS, and

View File

@ -28,7 +28,6 @@
#include "mozilla/dom/StructuredCloneTags.h"
#include "mozilla/dom/WindowBinding.h"
#include "nsZipArchive.h"
#include "nsIDOMFile.h"
#include "nsIDOMFileList.h"
#include "nsWindowMemoryReporter.h"
#include "nsDOMClassInfo.h"

View File

@ -3394,8 +3394,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
// 1MB is the default stack size on Windows, so use 900k.
// Windows PGO stack frames have unfortunately gotten pretty large lately. :-(
const size_t kStackQuota = 900 * 1024;
const size_t kTrustedScriptBuffer = (sizeof(size_t) == 8) ? 160 * 1024
: 100 * 1024;
const size_t kTrustedScriptBuffer = (sizeof(size_t) == 8) ? 180 * 1024 //win64
: 120 * 1024; //win32
// The following two configurations are linux-only. Given the numbers above,
// we use 50k and 100k trusted buffers on 32-bit and 64-bit respectively.
#elif defined(DEBUG)

View File

@ -49,7 +49,7 @@
if (Array.isArray(a))
return 'array';
if (a instanceof Ci.nsIDOMFile)
if (a instanceof File)
return 'file';
if (a instanceof Ci.nsIDOMBlob)

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.importGlobalProperties(['Blob']);
Components.utils.importGlobalProperties(['Blob', 'File']);
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -31,7 +31,7 @@ BlobComponent.prototype =
// do some tests
do_check_true(f1 instanceof Ci.nsIDOMBlob, "Should be a DOM Blob");
do_check_true(!(f1 instanceof Ci.nsIDOMFile), "Should not be a DOM File");
do_check_true(!(f1 instanceof File), "Should not be a DOM File");
do_check_true(f1.type == "text/xml", "Wrong type");

View File

@ -36,8 +36,8 @@ FileComponent.prototype =
var f2 = new File(file);
// do some tests
do_check_true(f1 instanceof Ci.nsIDOMFile, "Should be a DOM File");
do_check_true(f2 instanceof Ci.nsIDOMFile, "Should be a DOM File");
do_check_true(f1 instanceof File, "Should be a DOM File");
do_check_true(f2 instanceof File, "Should be a DOM File");
do_check_true(f1.name == "xpcshell.ini", "Should be the right file");
do_check_true(f2.name == "xpcshell.ini", "Should be the right file");

View File

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.importGlobalProperties(['Blob']);
Components.utils.importGlobalProperties(['Blob', 'File']);
const Ci = Components.interfaces;
@ -15,7 +15,7 @@ function run_test() {
// do some tests
do_check_true(f1 instanceof Ci.nsIDOMBlob, "Should be a DOM Blob");
do_check_true(!(f1 instanceof Ci.nsIDOMFile), "Should not be a DOM File");
do_check_true(!(f1 instanceof File), "Should not be a DOM File");
do_check_true(f1.type == "text/xml", "Wrong type");

View File

@ -21,8 +21,8 @@ function run_test() {
var f2 = new File(file);
// do some tests
do_check_true(f1 instanceof Ci.nsIDOMFile, "Should be a DOM File");
do_check_true(f2 instanceof Ci.nsIDOMFile, "Should be a DOM File");
do_check_true(f1 instanceof File, "Should be a DOM File");
do_check_true(f2 instanceof File, "Should be a DOM File");
do_check_true(f1.name == "xpcshell.ini", "Should be the right file");
do_check_true(f2.name == "xpcshell.ini", "Should be the right file");

View File

@ -1478,7 +1478,7 @@ void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,
nsIntRect pxRect =
mVisibleRect.ToOutsidePixels(mFrame->PresContext()->AppUnitsPerDevPixel());
Rect rect(pxRect.x, pxRect.y, pxRect.width, pxRect.height);
MaybeSnapToDevicePixels(rect, aDrawTarget);
MaybeSnapToDevicePixels(rect, aDrawTarget, true);
aDrawTarget.FillRect(rect, color);
}

View File

@ -1,25 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<style type="text/css">
#rear {
width: 500px;
height: 1500px;
box-shadow: 0 0 71px #667;
display: block;
}
</style>
<script>
document.documentElement.scrollTop = 0;
function doTest() {
document.documentElement.scrollTop = 108;
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest);
</script>
</head>
<body>
<div id="rear"></div>
</body>
</html>

View File

@ -1,26 +0,0 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<meta charset="utf-8">
<title>Scrolling shouldn't cause gaps in the shadow</title>
<style type="text/css">
#rear {
width: 500px;
height: 1500px;
box-shadow: 0 0 71px #667;
display: block;
}
</style>
<div id="rear"></div>
<script>
function doTest() {
document.documentElement.scrollTop = 108;
document.documentElement.removeAttribute("class");
}
window.addEventListener("MozReftestInvalidate", doTest);
document.documentElement.scrollTop = 112;
</script>

View File

@ -1923,5 +1923,4 @@ skip-if(!asyncPanZoom) fuzzy-if(B2G,101,887) == 1133905-6-vh-rtl.html 1133905-re
skip-if(B2G||Mulet) == 1150021-1.xul 1150021-1-ref.xul
== 1151145-1.html 1151145-1-ref.html
== 1151306-1.html 1151306-1-ref.html
== 1155828-1.html 1155828-1-ref.html
== 1156129-1.html 1156129-1-ref.html

View File

@ -110,3 +110,44 @@ f.os2_typolinegap = lineheight - (f.os2_typoascent - f.os2_typodescent)
f.hhea_linegap = lineheight - 800
f.generate("markA-lineheight" + str(lineheight) + ".ttf")
# Fonts with known winHeight and typoLineHeight such that winHeight is much
# larger than typoLineHeight.
f = fontforge.font()
typoLineHeight = 2700
winHeight = 6000
n = "MarkA-lineheight" + str(winHeight)
n = n + "-typolineheight" + str(typoLineHeight)
f.fontname = n
f.familyname = n
f.fullname = n
f.copyright = "Copyright (c) 2008-2015 Mozilla Corporation"
g = f.createChar(ord(" "), "space")
g.width = 1000
g = f.createChar(ord("A"), "A")
g.importOutlines("mark-glyph.svg")
g.width = 1500
f.os2_typoascent_add = False
f.os2_typoascent = 800
f.os2_typodescent_add = False
f.os2_typodescent = -200
f.os2_typolinegap = typoLineHeight - (f.os2_typoascent - f.os2_typodescent)
f.hhea_ascent = winHeight / 2
f.hhea_ascent_add = False
f.hhea_descent = winHeight / 2
f.hhea_descent_add = False
f.hhea_linegap = 0
f.os2_winascent = winHeight / 2
f.os2_winascent_add = False
f.os2_windescent = winHeight / 2
f.os2_windescent_add = False
f.os2_use_typo_metrics = True
f.generate("markA-lineheight" + str(winHeight) +
"-typolineheight" + str(typoLineHeight) + ".otf")
f.generate("markA-lineheight" + str(winHeight) +
"-typolineheight" + str(typoLineHeight) + ".ttf")

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