mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1484496: Part 4a - Add JS iterator support to nsISimpleEnumerator. r=mccr8
This patch adds simple stubs to convert between the nsISimpleEnumerator iteration protocol and the JS iteration protocol. Each iterable object is required to have an @@iterator method which returns an object implementing the iterator protocol. The later objects, by convention, also have such a method which returns the object itself. This patch adds both a @@iterator() and entries() methods to nsISimpleEnumerator. The former returns an iterator which returns plain nsISupports objects. The latter accepts an IID and queries each element to that IID before returning it. If any element fails to query, the error is propagated to the caller. Differential Revision: https://phabricator.services.mozilla.com/D3727 --HG-- extra : rebase_source : 340eb43a1c5e6d7ae69fa8ee486d66d31d079b14 extra : histedit_source : f3efc6c265851a563968ee410e4626e0540f55c0
This commit is contained in:
parent
0425e42aa8
commit
c943b2a5c4
14
dom/chrome-webidl/IteratorResult.webidl
Normal file
14
dom/chrome-webidl/IteratorResult.webidl
Normal file
@ -0,0 +1,14 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* A dictionary which represents the result of a call to a next() method on a
|
||||
* JS iterator object.
|
||||
*/
|
||||
dictionary IteratorResult {
|
||||
required boolean done;
|
||||
any value;
|
||||
};
|
@ -34,6 +34,7 @@ WEBIDL_FILES = [
|
||||
'DominatorTree.webidl',
|
||||
'HeapSnapshot.webidl',
|
||||
'InspectorUtils.webidl',
|
||||
'IteratorResult.webidl',
|
||||
'MatchGlob.webidl',
|
||||
'MatchPattern.webidl',
|
||||
'MessageManager.webidl',
|
||||
|
@ -5130,6 +5130,9 @@ nsSimpleEnumerator.prototype =
|
||||
|
||||
return this._items[this._nextIndex++];
|
||||
},
|
||||
[Symbol.iterator]() {
|
||||
return this._items.values();
|
||||
},
|
||||
QueryInterface: function(aIID)
|
||||
{
|
||||
if (Ci.nsISimpleEnumerator.equals(aIID) ||
|
||||
|
@ -214,12 +214,15 @@ MockFilePickerInstance.prototype = {
|
||||
return {
|
||||
index: 0,
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsISimpleEnumerator]),
|
||||
[Symbol.iterator]() {
|
||||
return Array.from(MockFilePicker.returnData, d => d.nsIFile).values();
|
||||
},
|
||||
hasMoreElements() {
|
||||
return this.index < MockFilePicker.returnData.length;
|
||||
},
|
||||
getNext() {
|
||||
if (!MockFilePicker.returnData[this.index].nsIFile) {
|
||||
return null;
|
||||
throw Components.Exception("", Cr.NS_ERROR_FAILURE);
|
||||
}
|
||||
return MockFilePicker.returnData[this.index++].nsIFile;
|
||||
}
|
||||
|
@ -14,8 +14,38 @@
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* A wrapper for an nsISimpleEnumerator instance which implements the
|
||||
* JavaScript iteration protocol.
|
||||
*/
|
||||
[scriptable, uuid(4432e8ae-d4d3-42a6-a4d1-829f1c29512b)]
|
||||
interface nsIJSEnumerator : nsISupports {
|
||||
[symbol]
|
||||
nsIJSEnumerator iterator();
|
||||
|
||||
[implicit_jscontext]
|
||||
jsval next();
|
||||
};
|
||||
|
||||
[scriptable, uuid(796f340d-0a2a-490b-9c60-640765e99782)]
|
||||
interface nsISimpleEnumeratorBase : nsISupports {
|
||||
/**
|
||||
* Returns a JavaScript iterator for all remaining entries in the enumerator.
|
||||
* Each entry is queried only to nsISupports.
|
||||
*/
|
||||
[symbol]
|
||||
nsIJSEnumerator iterator();
|
||||
|
||||
/**
|
||||
* Returns JavaScript iterator for all remaining entries in the enumerator.
|
||||
* Each entry is queried only to the supplied interface. If any element
|
||||
* fails to query to that interface, the error is propagated to the caller.
|
||||
*/
|
||||
nsIJSEnumerator entries(in nsIIDRef aIface);
|
||||
};
|
||||
|
||||
[scriptable, uuid(D1899240-F9D2-11D2-BDD6-000064657374)]
|
||||
interface nsISimpleEnumerator : nsISupports {
|
||||
interface nsISimpleEnumerator : nsISimpleEnumeratorBase {
|
||||
/**
|
||||
* Called to determine whether or not the enumerator has
|
||||
* any elements that can be returned via getNext(). This method
|
||||
@ -27,7 +57,7 @@ interface nsISimpleEnumerator : nsISupports {
|
||||
* @see getNext()
|
||||
* @return true if there are remaining elements in the enumerator.
|
||||
* false if there are no more elements in the enumerator.
|
||||
*/
|
||||
*/
|
||||
boolean hasMoreElements();
|
||||
|
||||
/**
|
||||
|
@ -6,4 +6,82 @@
|
||||
|
||||
#include "nsSimpleEnumerator.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSimpleEnumerator, nsISimpleEnumerator)
|
||||
#include "mozilla/dom/IteratorResultBinding.h"
|
||||
#include "mozilla/dom/RootedDictionary.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace {
|
||||
|
||||
class JSEnumerator final : public nsIJSEnumerator
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIJSENUMERATOR
|
||||
|
||||
explicit JSEnumerator(nsISimpleEnumerator* aEnumerator, const nsID& aIID)
|
||||
: mEnumerator(aEnumerator)
|
||||
, mIID(aIID)
|
||||
{}
|
||||
|
||||
private:
|
||||
~JSEnumerator() = default;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> mEnumerator;
|
||||
const nsID mIID;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
JSEnumerator::Iterator(nsIJSEnumerator** aResult)
|
||||
{
|
||||
RefPtr<JSEnumerator> result(this);
|
||||
result.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
JSEnumerator::Next(JSContext* aCx, JS::MutableHandleValue aResult)
|
||||
{
|
||||
RootedDictionary<IteratorResult> result(aCx);
|
||||
|
||||
nsCOMPtr<nsISupports> elem;
|
||||
if (NS_FAILED(mEnumerator->GetNext(getter_AddRefs(elem)))) {
|
||||
result.mDone = true;
|
||||
} else {
|
||||
result.mDone = false;
|
||||
|
||||
JS::RootedValue value(aCx);
|
||||
MOZ_TRY(nsContentUtils::WrapNative(aCx, elem, &mIID, &value));
|
||||
result.mValue = value;
|
||||
}
|
||||
|
||||
if (!ToJSValue(aCx, result, aResult)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(JSEnumerator, nsIJSEnumerator)
|
||||
|
||||
nsresult
|
||||
nsSimpleEnumerator::Iterator(nsIJSEnumerator **aResult)
|
||||
{
|
||||
auto result = MakeRefPtr<JSEnumerator>(this, NS_GET_IID(nsISupports));
|
||||
result.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSimpleEnumerator::Entries(const nsIID& aIface, nsIJSEnumerator **aResult)
|
||||
{
|
||||
auto result = MakeRefPtr<JSEnumerator>(this, aIface);
|
||||
result.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSimpleEnumerator, nsISimpleEnumerator, nsISimpleEnumeratorBase)
|
||||
|
@ -12,6 +12,7 @@
|
||||
class nsSimpleEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATORBASE
|
||||
|
||||
protected:
|
||||
virtual ~nsSimpleEnumerator() = default;
|
||||
|
@ -108,6 +108,8 @@ public:
|
||||
|
||||
NS_IMETHOD Init(nsLocalFile* aParent, bool aIgnored);
|
||||
|
||||
NS_FORWARD_NSISIMPLEENUMERATORBASE(nsSimpleEnumerator::)
|
||||
|
||||
private:
|
||||
~nsDirEnumeratorUnix() override;
|
||||
|
||||
|
@ -238,6 +238,7 @@ public:
|
||||
nsDriveEnumerator();
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
NS_FORWARD_NSISIMPLEENUMERATORBASE(nsSimpleEnumerator::)
|
||||
nsresult Init();
|
||||
|
||||
NS_IMETHOD GetNextFile(nsIFile** aResult) override
|
||||
@ -694,6 +695,8 @@ private:
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_FORWARD_NSISIMPLEENUMERATORBASE(nsSimpleEnumerator::)
|
||||
|
||||
nsDirEnumerator() : mDir(nullptr)
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user