Bug 807222 part 5. Fix getOwnPropertyNames to work correctly on Window. r=jst

One note: it might be better to change the signature of Enumerate() to
indicate whether we're enumerating just the enumerable properties or
all of them, so we can skip doing this when someone does for...in on
the window.
This commit is contained in:
Boris Zbarsky 2012-11-01 13:51:57 -04:00
parent a7b9d70502
commit 06fca213bc
6 changed files with 104 additions and 4 deletions

View File

@ -50,13 +50,14 @@ function testCompletion(hud) {
is(input.selectionEnd, 8, "end selection is alright");
is(jsterm.completeNode.value.replace(/ /g, ""), "", "'docu' completed");
// Test typing 'window.O' and press tab.
input.value = "window.O";
input.setSelectionRange(8, 8);
// Test typing 'window.Ob' and press tab. Just 'window.O' is
// ambiguous: could be window.Object, window.Option, etc.
input.value = "window.Ob";
input.setSelectionRange(9, 9);
jsterm.complete(jsterm.COMPLETE_FORWARD, testNext);
yield;
is(input.value, "window.Object", "'window.O' tab completion");
is(input.value, "window.Object", "'window.Ob' tab completion");
// Test typing 'document.getElem'.
input.value = "document.getElem";

View File

@ -5612,12 +5612,48 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_OK;
}
struct ResolveGlobalNameClosure
{
JSContext* cx;
JSObject* obj;
bool* retval;
};
static PLDHashOperator
ResolveGlobalName(const nsAString& aName, void* aClosure)
{
ResolveGlobalNameClosure* closure =
static_cast<ResolveGlobalNameClosure*>(aClosure);
JS::Value dummy;
bool ok = JS_LookupUCProperty(closure->cx, closure->obj,
aName.BeginReading(), aName.Length(),
&dummy);
if (!ok) {
*closure->retval = false;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
nsWindowSH::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, bool *_retval)
{
if (!ObjectIsNativeWrapper(cx, obj)) {
*_retval = JS_EnumerateStandardClasses(cx, obj);
if (!*_retval) {
return NS_OK;
}
// Now resolve everything from the namespace manager
nsScriptNameSpaceManager *nameSpaceManager =
nsJSRuntime::GetNameSpaceManager();
if (!nameSpaceManager) {
NS_ERROR("Can't get namespace manager.");
return NS_ERROR_UNEXPECTED;
}
ResolveGlobalNameClosure closure = { cx, obj, _retval };
nameSpaceManager->EnumerateGlobalNames(ResolveGlobalName, &closure);
}
return NS_OK;

View File

@ -802,6 +802,29 @@ nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName,
}
}
struct GlobalNameClosure
{
nsScriptNameSpaceManager::GlobalNameEnumerator enumerator;
void* closure;
};
static PLDHashOperator
EnumerateGlobalName(PLDHashTable*, PLDHashEntryHdr *hdr, uint32_t,
void* aClosure)
{
GlobalNameMapEntry *entry = static_cast<GlobalNameMapEntry *>(hdr);
GlobalNameClosure* closure = static_cast<GlobalNameClosure*>(aClosure);
return closure->enumerator(entry->mKey, closure->closure);
}
void
nsScriptNameSpaceManager::EnumerateGlobalNames(GlobalNameEnumerator aEnumerator,
void* aClosure)
{
GlobalNameClosure closure = { aEnumerator, aClosure };
PL_DHashTableEnumerate(&mGlobalNames, EnumerateGlobalName, &closure);
}
static size_t
SizeOfEntryExcludingThis(PLDHashEntryHdr *aHdr, nsMallocSizeOfFun aMallocSizeOf,
void *aArg)

View File

@ -143,6 +143,12 @@ public:
mozilla::dom::DefineInterface aDefineDOMInterface,
mozilla::dom::PrefEnabled aPrefEnabled);
typedef PLDHashOperator
(* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure);
void EnumerateGlobalNames(GlobalNameEnumerator aEnumerator,
void* aClosure);
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
private:

View File

@ -17,6 +17,7 @@ MOCHITEST_FILES = \
test_gsp-qualified.html \
test_nondomexception.html \
test_screen_orientation.html \
test_window_enumeration.html \
$(NULL)
MOCHITEST_CHROME_FILES = \

View File

@ -0,0 +1,33 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=807222
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 807222</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=807222">Mozilla Bug 807222</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 807222 **/
var expectedProps = [ "Image", "Audio", "Option", "USSDReceivedEvent",
"PerformanceTiming", "CSS2Properties", "SVGElement" ];
var actualProps = Object.getOwnPropertyNames(window);
for (var i = 0; i < expectedProps.length; ++i) {
isnot(actualProps.indexOf(expectedProps[i]), -1,
"getOwnPropertyNames should include " + expectedProps[i]);
}
</script>
</pre>
</body>
</html>