зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central and mozilla-inbound
This commit is contained in:
Коммит
86da6932d3
|
@ -1081,7 +1081,7 @@ nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
|||
nsString newName;
|
||||
accessible->GetName(newName);
|
||||
NS_ConvertUTF16toUTF8 utf8Name(newName);
|
||||
if (!utf8Name.Equals(atkObj->name))
|
||||
if (!atkObj->name || !utf8Name.Equals(atkObj->name))
|
||||
atk_object_set_name(atkObj, utf8Name.get());
|
||||
|
||||
break;
|
||||
|
|
|
@ -635,6 +635,9 @@ nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
|
|||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nsnull;
|
||||
if (!aNode)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
||||
NS_IF_ADDREF(*aAccessible = GetAccessible(node));
|
||||
|
@ -1006,12 +1009,13 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
}
|
||||
|
||||
nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
|
||||
if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation") &&
|
||||
!content->IsFocusable()) { // For presentation only
|
||||
// Only create accessible for role of "presentation" if it is focusable --
|
||||
// in that case we need an accessible in case it gets focused, we
|
||||
// don't want focus ever to be 'lost'
|
||||
return nsnull;
|
||||
if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation")) {
|
||||
// Ignore presentation role if element is focusable (focus event shouldn't
|
||||
// be ever lost and should be sensible).
|
||||
if (content->IsFocusable())
|
||||
roleMapEntry = nsnull;
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (weakFrame.IsAlive() && !newAcc && isHTML) { // HTML accessibles
|
||||
|
|
|
@ -484,18 +484,22 @@ STDMETHODIMP nsAccessibleWrap::get_accKeyboardShortcut(
|
|||
/* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut)
|
||||
{
|
||||
__try {
|
||||
if (!pszKeyboardShortcut)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pszKeyboardShortcut = NULL;
|
||||
nsAccessible *xpAccessible = GetXPAccessibleFor(varChild);
|
||||
if (xpAccessible) {
|
||||
nsAutoString shortcut;
|
||||
nsresult rv = xpAccessible->GetKeyboardShortcut(shortcut);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
if (!xpAccessible || xpAccessible->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
*pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(),
|
||||
shortcut.Length());
|
||||
return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
nsAutoString shortcut;
|
||||
nsresult rv = xpAccessible->GetKeyboardShortcut(shortcut);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
*pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(),
|
||||
shortcut.Length());
|
||||
return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY;
|
||||
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
return E_FAIL;
|
||||
}
|
||||
|
|
|
@ -673,14 +673,19 @@ nsXULTreeGridRowAccessible::GetName(nsAString& aName)
|
|||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsITreeColumns> columns;
|
||||
mTree->GetColumns(getter_AddRefs(columns));
|
||||
if (columns) {
|
||||
nsCOMPtr<nsITreeColumn> primaryColumn;
|
||||
columns->GetPrimaryColumn(getter_AddRefs(primaryColumn));
|
||||
if (primaryColumn)
|
||||
GetCellName(primaryColumn, aName);
|
||||
// XXX: the row name sholdn't be a concatenation of cell names (bug 664384).
|
||||
nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
|
||||
while (column) {
|
||||
if (!aName.IsEmpty())
|
||||
aName.AppendLiteral(" ");
|
||||
|
||||
nsAutoString cellName;
|
||||
GetCellName(column, cellName);
|
||||
aName.Append(cellName);
|
||||
|
||||
column = nsCoreUtils::GetNextSensibleColumn(column);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
<button id="btn_namefromcontent" title="title">1</button>
|
||||
|
||||
<!-- button, no name from content, ARIA role overrides this rule -->
|
||||
<button id="btn_nonamefromcontent" role="presentation">1</button>
|
||||
<button id="btn_nonamefromcontent" role="img">1</button>
|
||||
|
||||
<!-- button, no content, name from @title -->
|
||||
<button id="btn_title" title="title"></button>
|
||||
|
|
|
@ -88,8 +88,7 @@
|
|||
title="title"><img alt="img title" /></a>
|
||||
|
||||
<!-- no name from content, ARIA role overrides this rule -->
|
||||
<a id="nonamefromcontent" href="mozilla.org"
|
||||
role="presentation">1</a>
|
||||
<a id="nonamefromcontent" href="mozilla.org" role="img">1</a>
|
||||
<br/>
|
||||
|
||||
<!-- no content, name from @title -->
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
function tableTester(aID)
|
||||
function tableTester(aID, aIsTable, aCol1ID, aCol2ID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
|
@ -98,7 +98,7 @@
|
|||
this.check = function tableTester_check(aEvent)
|
||||
{
|
||||
var tree = {
|
||||
role: ROLE_TREE_TABLE,
|
||||
role: aIsTable ? ROLE_TABLE : ROLE_TREE_TABLE,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_LIST
|
||||
|
@ -109,15 +109,15 @@
|
|||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row0_col1"
|
||||
name: "row0_" + aCol1ID
|
||||
},
|
||||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row0_col2"
|
||||
name: "row0_" + aCol2ID
|
||||
}
|
||||
],
|
||||
name: "row0_col1"
|
||||
name: "row0_" + aCol1ID + " row0_" + aCol2ID
|
||||
},
|
||||
{
|
||||
role: ROLE_ROW,
|
||||
|
@ -125,15 +125,15 @@
|
|||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row1_col1"
|
||||
name: "row1_" + aCol1ID
|
||||
},
|
||||
{
|
||||
role: ROLE_GRID_CELL,
|
||||
children: [],
|
||||
name: "row1_col2"
|
||||
name: "row1_" + aCol2ID
|
||||
}
|
||||
],
|
||||
name: "row1_col1"
|
||||
name: "row1_" + aCol1ID + " row1_" + aCol2ID
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -152,7 +152,8 @@
|
|||
var gQueue = new eventQueue(EVENT_REORDER);
|
||||
|
||||
gQueue.push(new treeTester("tree"));
|
||||
gQueue.push(new tableTester("table"));
|
||||
gQueue.push(new tableTester("table", true, "t_col1", "t_col2"));
|
||||
gQueue.push(new tableTester("treetable", false, "tt_col1", "tt_col2"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish()
|
||||
}
|
||||
|
@ -170,7 +171,12 @@
|
|||
title="Treegrid row accessible shouldn't inherit name from tree accessible">
|
||||
Mozilla Bug 546812
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=664376"
|
||||
title="Table rows of XUL trees no longer containing cell content as accessible name">
|
||||
Mozilla Bug 664376
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
|
@ -188,8 +194,16 @@
|
|||
|
||||
<tree id="table" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" label="column" primary="true"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
<treecol id="t_col1" flex="1" label="column"/>
|
||||
<treecol id="t_col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<tree id="treetable" flex="1">
|
||||
<treecols>
|
||||
<treecol id="tt_col1" flex="1" label="column" primary="true"/>
|
||||
<treecol id="tt_col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
|
|
@ -57,6 +57,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=529289
|
|||
is(accessibleTable.getCellAt(0,0).firstChild.name, "hi", "no cell");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test gEmptyRoleMap
|
||||
testRole("cell", ROLE_NOTHING);
|
||||
|
||||
|
@ -67,10 +68,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=529289
|
|||
for (a in abstract_roles)
|
||||
testRole(abstract_roles[a], ROLE_SECTION);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// misc roles
|
||||
testRole("scrollbar", ROLE_SCROLLBAR);
|
||||
testRole("dir", ROLE_LIST);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test document role map update
|
||||
var testDoc = getAccessible(document, [nsIAccessibleDocument]);
|
||||
testRole(testDoc, ROLE_DOCUMENT);
|
||||
|
|
|
@ -50,6 +50,7 @@ _TEST_FILES =\
|
|||
$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
|
||||
test_aria_globals.html \
|
||||
test_aria_imgmap.html \
|
||||
test_aria_presentation.html \
|
||||
test_button.xul \
|
||||
test_combobox.xul \
|
||||
test_cssoverflow.html \
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test accessible tree when ARIA role presentation is used</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// Presentation role don't allow accessible.
|
||||
var tree =
|
||||
{ SECTION: [ // container
|
||||
{ TEXT_LEAF: [ ] } // child text of presentation node
|
||||
] };
|
||||
testAccessibleTree("div_cnt", tree);
|
||||
|
||||
// Focusable element, presentation role is ignored.
|
||||
tree =
|
||||
{ SECTION: [ // container
|
||||
{ PUSHBUTTON: [ // button
|
||||
{ TEXT_LEAF: [ ] }
|
||||
] }
|
||||
] };
|
||||
testAccessibleTree("btn_cnt", tree);
|
||||
|
||||
// Presentation table, no table structure is exposed.
|
||||
tree =
|
||||
{ SECTION: [ // container
|
||||
{ TEXT_LEAF: [ ] } // cell text
|
||||
] };
|
||||
testAccessibleTree("tbl_cnt", tree);
|
||||
|
||||
// Focusable table, presentation role is ignored.
|
||||
tree =
|
||||
{ SECTION: [ // container
|
||||
{ TABLE: [ // table
|
||||
{ ROW: [ // tr
|
||||
{ CELL: [ //td
|
||||
{ TEXT_LEAF: [ ] }
|
||||
] }
|
||||
] }
|
||||
] }
|
||||
] };
|
||||
testAccessibleTree("tblfocusable_cnt", tree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=548291"
|
||||
title="Accessible tree of ARIA image maps">
|
||||
Mozilla Bug 548291
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=666504"
|
||||
title="Ignore role presentation on focusable elements">
|
||||
Mozilla Bug 666504
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="div_cnt"><div role="presentation">text</div></div>
|
||||
|
||||
<div id="btn_cnt"><button role="presentation">btn</button></div>
|
||||
|
||||
<div id="tbl_cnt">
|
||||
<table role="presentation">
|
||||
<tr>
|
||||
<td>cell</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tblfocusable_cnt">
|
||||
<table role="presentation" tabindex="0">
|
||||
<tr>
|
||||
<td>cell</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -18,7 +18,11 @@ function nsTreeTreeView()
|
|||
];
|
||||
}
|
||||
|
||||
function nsTreeView() { }
|
||||
function nsTreeView()
|
||||
{
|
||||
this.mTree = null;
|
||||
this.mData = [];
|
||||
}
|
||||
|
||||
nsTreeView.prototype =
|
||||
{
|
||||
|
@ -205,8 +209,6 @@ nsTreeView.prototype =
|
|||
return rowIdx;
|
||||
},
|
||||
|
||||
mTree: null,
|
||||
mData: [],
|
||||
mCyclerStates: [
|
||||
createAtom("cyclerState1"),
|
||||
createAtom("cyclerState2"),
|
||||
|
|
|
@ -36,7 +36,7 @@ function testFile(file, contents, test) {
|
|||
[{ name: "hello", value: "world"},
|
||||
{ name: "myfile",
|
||||
value: contents,
|
||||
fileName: file.name || "",
|
||||
fileName: file.name || "blob",
|
||||
contentType: file.type || "application/octet-stream" }]);
|
||||
testHasRun();
|
||||
}
|
||||
|
|
|
@ -485,6 +485,11 @@ nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
|
|||
rv = file->GetName(filename16);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (filename16.IsEmpty()) {
|
||||
filename16.AssignLiteral("blob");
|
||||
}
|
||||
|
||||
rv = EncodeVal(filename16, filename, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsIVariant.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsclone.h"
|
||||
#include "mozilla/storage.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
|
@ -75,9 +76,10 @@ public:
|
|||
JSAutoStructuredCloneBuffer& aCloneBuffer,
|
||||
const Key& aKey,
|
||||
bool aOverwrite,
|
||||
nsTArray<IndexUpdateInfo>& aIndexUpdateInfo)
|
||||
nsTArray<IndexUpdateInfo>& aIndexUpdateInfo,
|
||||
PRUint64 aOffsetToKeyProp)
|
||||
: AsyncConnectionHelper(aTransaction, aRequest), mObjectStore(aObjectStore),
|
||||
mKey(aKey), mOverwrite(aOverwrite)
|
||||
mKey(aKey), mOverwrite(aOverwrite), mOffsetToKeyProp(aOffsetToKeyProp)
|
||||
{
|
||||
mCloneBuffer.swap(aCloneBuffer);
|
||||
mIndexUpdateInfo.SwapElements(aIndexUpdateInfo);
|
||||
|
@ -111,6 +113,7 @@ private:
|
|||
Key mKey;
|
||||
const bool mOverwrite;
|
||||
nsTArray<IndexUpdateInfo> mIndexUpdateInfo;
|
||||
PRUint64 mOffsetToKeyProp;
|
||||
};
|
||||
|
||||
class GetHelper : public AsyncConnectionHelper
|
||||
|
@ -423,6 +426,41 @@ GenerateRequest(IDBObjectStore* aObjectStore)
|
|||
database->Owner(), aObjectStore->Transaction());
|
||||
}
|
||||
|
||||
JSClass gDummyPropClass = {
|
||||
"dummy", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JS_ConvertStub, JS_FinalizeStub,
|
||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||
};
|
||||
|
||||
JSBool
|
||||
StructuredCloneWriteDummyProp(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter,
|
||||
JSObject* aObj,
|
||||
void* aClosure)
|
||||
{
|
||||
if (JS_GET_CLASS(aCx, aObj) == &gDummyPropClass) {
|
||||
PRUint64* closure = reinterpret_cast<PRUint64*>(aClosure);
|
||||
|
||||
NS_ASSERTION(*closure == 0, "We should not have been here before!");
|
||||
*closure = js_GetSCOffset(aWriter);
|
||||
|
||||
PRUint64 value = 0;
|
||||
return JS_WriteBytes(aWriter, &value, sizeof(value));
|
||||
}
|
||||
|
||||
// try using the runtime callbacks
|
||||
const JSStructuredCloneCallbacks* runtimeCallbacks =
|
||||
aCx->runtime->structuredCloneCallbacks;
|
||||
if (runtimeCallbacks) {
|
||||
return runtimeCallbacks->write(aCx, aWriter, aObj, nsnull);
|
||||
}
|
||||
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
|
@ -840,7 +878,9 @@ IDBObjectStore::ClearStructuredCloneBuffer(JSAutoStructuredCloneBuffer& aBuffer)
|
|||
bool
|
||||
IDBObjectStore::DeserializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval* aValue)
|
||||
jsval* aValue,
|
||||
JSStructuredCloneCallbacks* aCallbacks,
|
||||
void* aClosure)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(),
|
||||
"Should only be deserializing on the main thread!");
|
||||
|
@ -853,14 +893,16 @@ IDBObjectStore::DeserializeValue(JSContext* aCx,
|
|||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
return aBuffer.read(aValue, aCx, nsnull);
|
||||
return aBuffer.read(aValue, aCx, aCallbacks, aClosure);
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
IDBObjectStore::SerializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval aValue)
|
||||
jsval aValue,
|
||||
JSStructuredCloneCallbacks* aCallbacks,
|
||||
void* aClosure)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(),
|
||||
"Should only be serializing on the main thread!");
|
||||
|
@ -868,7 +910,7 @@ IDBObjectStore::SerializeValue(JSContext* aCx,
|
|||
|
||||
JSAutoRequest ar(aCx);
|
||||
|
||||
return aBuffer.write(aCx, aValue, nsnull);
|
||||
return aBuffer.write(aCx, aValue, aCallbacks, aClosure);
|
||||
}
|
||||
|
||||
static inline jsdouble
|
||||
|
@ -890,24 +932,12 @@ SwapBytes(PRUint64 u)
|
|||
|
||||
nsresult
|
||||
IDBObjectStore::ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer,
|
||||
Key& aKey)
|
||||
Key& aKey,
|
||||
PRUint64 aOffsetToKeyProp)
|
||||
{
|
||||
NS_ASSERTION(IsAutoIncrement() && KeyPath().IsEmpty() && aKey.IsInt(),
|
||||
"Don't call me!");
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread");
|
||||
NS_ASSERTION(mKeyPathSerializationOffset, "How did this happen?");
|
||||
|
||||
// The minus 8 dangling off the end here is to account for the null entry
|
||||
// that terminates the buffer
|
||||
const PRUint32 keyPropLen = mKeyPathSerialization.nbytes() -
|
||||
mKeyPathSerializationOffset - sizeof(PRUint64);
|
||||
|
||||
const char* location = nsCRT::memmem((char*)aBuffer.data(),
|
||||
aBuffer.nbytes(),
|
||||
(char*)mKeyPathSerialization.data() +
|
||||
mKeyPathSerializationOffset,
|
||||
keyPropLen);
|
||||
NS_ASSERTION(location, "How did this happen?");
|
||||
|
||||
// This is a duplicate of the js engine's byte munging here
|
||||
union {
|
||||
|
@ -917,16 +947,13 @@ IDBObjectStore::ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer,
|
|||
|
||||
pun.d = SwapBytes(aKey.IntValue());
|
||||
|
||||
memcpy(const_cast<char*>(location) + keyPropLen -
|
||||
sizeof(pun.u), // We're overwriting the last 8 bytes
|
||||
&pun.u, sizeof(PRUint64));
|
||||
memcpy((char*)aBuffer.data() + aOffsetToKeyProp, &pun.u, sizeof(PRUint64));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
IDBObjectStore::IDBObjectStore()
|
||||
: mId(LL_MININT),
|
||||
mAutoIncrement(PR_FALSE),
|
||||
mKeyPathSerializationOffset(0)
|
||||
mAutoIncrement(PR_FALSE)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
}
|
||||
|
@ -942,7 +969,8 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
jsval aKeyVal,
|
||||
JSAutoStructuredCloneBuffer& aCloneBuffer,
|
||||
Key& aKey,
|
||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray)
|
||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray,
|
||||
PRUint64* aOffsetToKeyProp)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
@ -993,9 +1021,10 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
if (!mKeyPath.IsEmpty() && aKey.IsUnset()) {
|
||||
NS_ASSERTION(mAutoIncrement, "Should have bailed earlier!");
|
||||
|
||||
jsval key;
|
||||
ok = JS_NewNumberValue(aCx, kTotallyRandomNumber, &key);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
JSObject* obj = JS_NewObject(aCx, &gDummyPropClass, nsnull, nsnull);
|
||||
NS_ENSURE_TRUE(obj, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
jsval key = OBJECT_TO_JSVAL(obj);
|
||||
|
||||
ok = JS_DefineUCProperty(aCx, JSVAL_TO_OBJECT(aValue), keyPathChars,
|
||||
keyPathLen, key, nsnull, nsnull,
|
||||
|
@ -1003,13 +1032,20 @@ IDBObjectStore::GetAddInfo(JSContext* aCx,
|
|||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
// From this point on we have to try to remove the property.
|
||||
rv = EnsureKeyPathSerializationData(aCx);
|
||||
}
|
||||
|
||||
JSStructuredCloneCallbacks callbacks = {
|
||||
nsnull,
|
||||
StructuredCloneWriteDummyProp,
|
||||
nsnull
|
||||
};
|
||||
*aOffsetToKeyProp = 0;
|
||||
|
||||
// We guard on rv being a success because we need to run the property
|
||||
// deletion code below even if we should not be serializing the value
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
!IDBObjectStore::SerializeValue(aCx, aCloneBuffer, aValue)) {
|
||||
!IDBObjectStore::SerializeValue(aCx, aCloneBuffer, aValue, &callbacks,
|
||||
aOffsetToKeyProp)) {
|
||||
rv = NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -1051,8 +1087,10 @@ IDBObjectStore::AddOrPut(const jsval& aValue,
|
|||
JSAutoStructuredCloneBuffer cloneBuffer;
|
||||
Key key;
|
||||
nsTArray<IndexUpdateInfo> updateInfo;
|
||||
PRUint64 offset;
|
||||
|
||||
nsresult rv = GetAddInfo(aCx, aValue, keyval, cloneBuffer, key, updateInfo);
|
||||
nsresult rv =
|
||||
GetAddInfo(aCx, aValue, keyval, cloneBuffer, key, updateInfo, &offset);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1067,7 +1105,7 @@ IDBObjectStore::AddOrPut(const jsval& aValue,
|
|||
|
||||
nsRefPtr<AddHelper> helper =
|
||||
new AddHelper(mTransaction, request, this, cloneBuffer, key, aOverwrite,
|
||||
updateInfo);
|
||||
updateInfo, offset);
|
||||
|
||||
rv = helper->DispatchToTransactionPool();
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
@ -1076,46 +1114,6 @@ IDBObjectStore::AddOrPut(const jsval& aValue,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
IDBObjectStore::EnsureKeyPathSerializationData(JSContext* aCx)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread");
|
||||
|
||||
if (!mKeyPathSerializationOffset) {
|
||||
JSBool ok;
|
||||
|
||||
JSAutoStructuredCloneBuffer emptyObjectBuffer;
|
||||
JSAutoStructuredCloneBuffer fakeObjectBuffer;
|
||||
|
||||
const jschar* keyPathChars =
|
||||
reinterpret_cast<const jschar*>(mKeyPath.get());
|
||||
const size_t keyPathLen = mKeyPath.Length();
|
||||
|
||||
JSObject* object = JS_NewObject(aCx, nsnull, nsnull, nsnull);
|
||||
NS_ENSURE_TRUE(object, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
ok = emptyObjectBuffer.write(aCx, OBJECT_TO_JSVAL(object));
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
jsval key;
|
||||
// This is just to give us some random marker in the byte stream
|
||||
ok = JS_NewNumberValue(aCx, kTotallyRandomNumber, &key);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
ok = JS_DefineUCProperty(aCx, object, keyPathChars, keyPathLen,
|
||||
key, nsnull, nsnull, JSPROP_ENUMERATE);
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
ok = fakeObjectBuffer.write(aCx, OBJECT_TO_JSVAL(object));
|
||||
NS_ENSURE_TRUE(ok, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
mKeyPathSerialization.swap(fakeObjectBuffer);
|
||||
mKeyPathSerializationOffset = emptyObjectBuffer.nbytes();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBObjectStore)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IDBObjectStore)
|
||||
|
@ -1850,7 +1848,8 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
|||
// Special case where someone put an object into an autoIncrement'ing
|
||||
// objectStore with no key in its keyPath set. We needed to figure out
|
||||
// which row id we would get above before we could set that properly.
|
||||
rv = mObjectStore->ModifyValueForNewKey(mCloneBuffer, mKey);
|
||||
rv = mObjectStore->ModifyValueForNewKey(mCloneBuffer, mKey,
|
||||
mOffsetToKeyProp);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
scoper.Abandon();
|
||||
|
|
|
@ -119,12 +119,16 @@ public:
|
|||
static bool
|
||||
DeserializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval* aValue);
|
||||
jsval* aValue,
|
||||
JSStructuredCloneCallbacks* aCallbacks = nsnull,
|
||||
void* aClosure = nsnull);
|
||||
|
||||
static bool
|
||||
SerializeValue(JSContext* aCx,
|
||||
JSAutoStructuredCloneBuffer& aBuffer,
|
||||
jsval aValue);
|
||||
jsval aValue,
|
||||
JSStructuredCloneCallbacks* aCallbacks = nsnull,
|
||||
void* aClosure = nsnull);
|
||||
|
||||
const nsString& Name() const
|
||||
{
|
||||
|
@ -158,7 +162,8 @@ public:
|
|||
}
|
||||
|
||||
nsresult ModifyValueForNewKey(JSAutoStructuredCloneBuffer& aBuffer,
|
||||
Key& aKey);
|
||||
Key& aKey,
|
||||
PRUint64 aOffsetToKeyProp);
|
||||
|
||||
protected:
|
||||
IDBObjectStore();
|
||||
|
@ -169,7 +174,8 @@ protected:
|
|||
jsval aKeyVal,
|
||||
JSAutoStructuredCloneBuffer& aCloneBuffer,
|
||||
Key& aKey,
|
||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray);
|
||||
nsTArray<IndexUpdateInfo>& aUpdateInfoArray,
|
||||
PRUint64* aOffsetToKeyProp);
|
||||
|
||||
nsresult AddOrPut(const jsval& aValue,
|
||||
const jsval& aKey,
|
||||
|
@ -178,8 +184,6 @@ protected:
|
|||
nsIIDBRequest** _retval,
|
||||
bool aOverwrite);
|
||||
|
||||
nsresult EnsureKeyPathSerializationData(JSContext* aCx);
|
||||
|
||||
private:
|
||||
nsRefPtr<IDBTransaction> mTransaction;
|
||||
|
||||
|
@ -193,13 +197,7 @@ private:
|
|||
PRUint32 mDatabaseId;
|
||||
PRUint32 mStructuredCloneVersion;
|
||||
|
||||
// Used to store a serialized representation of the fake property
|
||||
// entry used to handle autoincrement with keypaths.
|
||||
JSAutoStructuredCloneBuffer mKeyPathSerialization;
|
||||
PRUint32 mKeyPathSerializationOffset;
|
||||
|
||||
nsTArray<nsRefPtr<IDBIndex> > mCreatedIndexes;
|
||||
|
||||
};
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Point.h"
|
||||
|
||||
|
|
|
@ -46,6 +46,13 @@
|
|||
|
||||
using namespace js;
|
||||
|
||||
JS_FRIEND_API(uint64_t)
|
||||
js_GetSCOffset(JSStructuredCloneWriter* writer)
|
||||
{
|
||||
JS_ASSERT(writer);
|
||||
return writer->output().count() * sizeof(uint64_t);
|
||||
}
|
||||
|
||||
namespace js
|
||||
{
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@
|
|||
#include "jsvector.h"
|
||||
#include "jsvalue.h"
|
||||
|
||||
JS_FRIEND_API(uint64_t)
|
||||
js_GetSCOffset(JSStructuredCloneWriter* writer);
|
||||
|
||||
namespace js {
|
||||
|
||||
bool
|
||||
|
@ -73,6 +76,8 @@ struct SCOutput {
|
|||
|
||||
bool extractBuffer(uint64_t **datap, size_t *sizep);
|
||||
|
||||
uint64_t count() { return buf.length(); }
|
||||
|
||||
private:
|
||||
JSContext *cx;
|
||||
js::Vector<uint64_t> buf;
|
||||
|
|
|
@ -127,19 +127,12 @@ const PRInt32 kSizeNotSet = -1;
|
|||
* combo box is toggled to open or close. this is used by Accessibility which presses
|
||||
* that button Programmatically.
|
||||
*/
|
||||
class nsComboButtonListener: public nsIDOMMouseListener
|
||||
class nsComboButtonListener : public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* anEvent) { return PR_FALSE; }
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent) { return PR_FALSE; }
|
||||
NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent) { return PR_FALSE; }
|
||||
NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent) { return PR_FALSE; }
|
||||
NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent) { return PR_FALSE; }
|
||||
NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent) { return PR_FALSE; }
|
||||
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent)
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent*)
|
||||
{
|
||||
mComboBox->ShowDropDown(!mComboBox->IsDroppedDown());
|
||||
return NS_OK;
|
||||
|
@ -155,8 +148,7 @@ class nsComboButtonListener: public nsIDOMMouseListener
|
|||
nsComboboxControlFrame* mComboBox;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsComboButtonListener,
|
||||
nsIDOMMouseListener,
|
||||
NS_IMPL_ISUPPORTS1(nsComboButtonListener,
|
||||
nsIDOMEventListener)
|
||||
|
||||
// static class data member for Bug 32920
|
||||
|
@ -1041,8 +1033,8 @@ nsComboboxControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
|||
// make someone to listen to the button. If its pressed by someone like Accessibility
|
||||
// then open or close the combo box.
|
||||
mButtonListener = new nsComboButtonListener(this);
|
||||
mButtonContent->AddEventListenerByIID(mButtonListener,
|
||||
NS_GET_IID(nsIDOMMouseListener));
|
||||
mButtonContent->AddEventListener(NS_LITERAL_STRING("click"), mButtonListener,
|
||||
PR_FALSE, PR_FALSE);
|
||||
|
||||
mButtonContent->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
|
||||
NS_LITERAL_STRING("button"), PR_FALSE);
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsIStatefulFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsIView;
|
||||
|
@ -283,7 +283,7 @@ protected:
|
|||
|
||||
// make someone to listen to the button. If its programmatically pressed by someone like Accessibility
|
||||
// then open or close the combo box.
|
||||
nsCOMPtr<nsIDOMMouseListener> mButtonListener;
|
||||
nsCOMPtr<nsIDOMEventListener> mButtonListener;
|
||||
|
||||
// static class data member for Bug 32920
|
||||
// only one control can be focused at a time
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
@ -391,7 +390,7 @@ PRBool ShouldProcessMouseClick(nsIDOMEvent* aMouseEvent)
|
|||
// only allow the left button
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
nsCOMPtr<nsIDOMNSUIEvent> uiEvent = do_QueryInterface(aMouseEvent);
|
||||
NS_ENSURE_STATE(uiEvent);
|
||||
NS_ENSURE_TRUE(mouseEvent && uiEvent, PR_FALSE);
|
||||
PRBool defaultPrevented = PR_FALSE;
|
||||
uiEvent->GetPreventDefault(&defaultPrevented);
|
||||
if (defaultPrevented) {
|
||||
|
@ -415,7 +414,7 @@ PRBool ShouldProcessMouseClick(nsIDOMEvent* aMouseEvent)
|
|||
* This is called when our capture button is clicked
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsFileControlFrame::CaptureMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
||||
nsFileControlFrame::CaptureMouseListener::HandleEvent(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
@ -502,30 +501,26 @@ nsFileControlFrame::CaptureMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when our browse button is clicked
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsFileControlFrame::BrowseMouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
NS_ASSERTION(mFrame, "We should have been unregistered");
|
||||
if (!ShouldProcessMouseClick(aMouseEvent))
|
||||
return NS_OK;
|
||||
|
||||
nsHTMLInputElement* input =
|
||||
nsHTMLInputElement::FromContent(mFrame->GetContent());
|
||||
return input ? input->FireAsyncClickHandler() : NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when we receive any registered events on the control.
|
||||
* We've only registered for drop, dragover and click events, and click events
|
||||
* already call MouseClick() for us. Here, we handle file drops.
|
||||
* We've only registered for drop, dragover and click events.
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsFileControlFrame::BrowseMouseListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
NS_ASSERTION(mFrame, "We should have been unregistered");
|
||||
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
if (eventType.EqualsLiteral("click")) {
|
||||
if (!ShouldProcessMouseClick(aEvent))
|
||||
return NS_OK;
|
||||
|
||||
nsHTMLInputElement* input =
|
||||
nsHTMLInputElement::FromContent(mFrame->GetContent());
|
||||
return input ? input->FireAsyncClickHandler() : NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNSUIEvent> uiEvent = do_QueryInterface(aEvent);
|
||||
NS_ENSURE_STATE(uiEvent);
|
||||
PRBool defaultPrevented = PR_FALSE;
|
||||
|
@ -539,8 +534,6 @@ nsFileControlFrame::BrowseMouseListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
if (eventType.EqualsLiteral("dragover")) {
|
||||
// Prevent default if we can accept this drag data
|
||||
aEvent->PreventDefault();
|
||||
|
@ -838,6 +831,5 @@ nsFileControlFrame::ParseAcceptAttribute(AcceptAttrCallback aCallback,
|
|||
////////////////////////////////////////////////////////////
|
||||
// Mouse listener implementation
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsFileControlFrame::MouseListener,
|
||||
nsIDOMMouseListener,
|
||||
NS_IMPL_ISUPPORTS1(nsFileControlFrame::MouseListener,
|
||||
nsIDOMEventListener)
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
#include "nsICapturePicker.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -112,7 +112,7 @@ protected:
|
|||
|
||||
class MouseListener;
|
||||
friend class MouseListener;
|
||||
class MouseListener : public nsIDOMMouseListener {
|
||||
class MouseListener : public nsIDOMEventListener {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
@ -123,16 +123,6 @@ protected:
|
|||
void ForgetFrame() {
|
||||
mFrame = nsnull;
|
||||
}
|
||||
|
||||
// We just want to capture the click events on our browse button
|
||||
// and textfield.
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent) { return NS_OK; }
|
||||
NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent) = 0;
|
||||
NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
|
||||
NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
|
||||
NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
|
||||
|
||||
protected:
|
||||
nsFileControlFrame* mFrame;
|
||||
|
@ -163,17 +153,16 @@ protected:
|
|||
public:
|
||||
CaptureMouseListener(nsFileControlFrame* aFrame) : MouseListener(aFrame),
|
||||
mMode(0) {};
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent);
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
PRUint32 mMode;
|
||||
};
|
||||
|
||||
class BrowseMouseListener: public MouseListener {
|
||||
public:
|
||||
BrowseMouseListener(nsFileControlFrame* aFrame) : MouseListener(aFrame) {};
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
static PRBool IsValidDropData(nsIDOMDragEvent* aEvent);
|
||||
static PRBool IsValidDropData(nsIDOMDragEvent* aEvent);
|
||||
};
|
||||
|
||||
virtual PRBool IsFrameOfType(PRUint32 aFlags) const
|
||||
|
|
|
@ -81,9 +81,7 @@
|
|||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMMouseMotionListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
|
@ -110,9 +108,7 @@ DOMTimeStamp nsListControlFrame::gLastKeyTime = 0;
|
|||
* Frames are not refcounted so they can't be used as event listeners.
|
||||
*****************************************************************************/
|
||||
|
||||
class nsListEventListener : public nsIDOMKeyListener,
|
||||
public nsIDOMMouseListener,
|
||||
public nsIDOMMouseMotionListener
|
||||
class nsListEventListener : public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
nsListEventListener(nsListControlFrame *aFrame)
|
||||
|
@ -121,26 +117,7 @@ public:
|
|||
void SetFrame(nsListControlFrame *aFrame) { mFrame = aFrame; }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsIDOMKeyListener
|
||||
NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
|
||||
NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
|
||||
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
|
||||
|
||||
// nsIDOMMouseListener
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent);
|
||||
|
||||
// nsIDOMMouseMotionListener
|
||||
NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD DragMove(nsIDOMEvent* aMouseEvent);
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
private:
|
||||
nsListControlFrame *mFrame;
|
||||
|
@ -201,17 +178,14 @@ nsListControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
|||
|
||||
mEventListener->SetFrame(nsnull);
|
||||
|
||||
mContent->RemoveEventListenerByIID(static_cast<nsIDOMMouseListener*>
|
||||
(mEventListener),
|
||||
NS_GET_IID(nsIDOMMouseListener));
|
||||
|
||||
mContent->RemoveEventListenerByIID(static_cast<nsIDOMMouseMotionListener*>
|
||||
(mEventListener),
|
||||
NS_GET_IID(nsIDOMMouseMotionListener));
|
||||
|
||||
mContent->RemoveEventListenerByIID(static_cast<nsIDOMKeyListener*>
|
||||
(mEventListener),
|
||||
NS_GET_IID(nsIDOMKeyListener));
|
||||
mContent->RemoveEventListener(NS_LITERAL_STRING("keypress"), mEventListener,
|
||||
PR_FALSE);
|
||||
mContent->RemoveEventListener(NS_LITERAL_STRING("mousedown"), mEventListener,
|
||||
PR_FALSE);
|
||||
mContent->RemoveEventListener(NS_LITERAL_STRING("mouseup"), mEventListener,
|
||||
PR_FALSE);
|
||||
mContent->RemoveEventListener(NS_LITERAL_STRING("mousemove"), mEventListener,
|
||||
PR_FALSE);
|
||||
|
||||
nsFormControlFrame::RegUnRegAccessKey(static_cast<nsIFrame*>(this), PR_FALSE);
|
||||
nsHTMLScrollFrame::DestroyFrom(aDestructRoot);
|
||||
|
@ -1141,17 +1115,14 @@ nsListControlFrame::Init(nsIContent* aContent,
|
|||
if (!mEventListener)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mContent->AddEventListenerByIID(static_cast<nsIDOMMouseListener*>
|
||||
(mEventListener),
|
||||
NS_GET_IID(nsIDOMMouseListener));
|
||||
|
||||
mContent->AddEventListenerByIID(static_cast<nsIDOMMouseMotionListener*>
|
||||
(mEventListener),
|
||||
NS_GET_IID(nsIDOMMouseMotionListener));
|
||||
|
||||
mContent->AddEventListenerByIID(static_cast<nsIDOMKeyListener*>
|
||||
(mEventListener),
|
||||
NS_GET_IID(nsIDOMKeyListener));
|
||||
mContent->AddEventListener(NS_LITERAL_STRING("keypress"), mEventListener,
|
||||
PR_FALSE, PR_FALSE);
|
||||
mContent->AddEventListener(NS_LITERAL_STRING("mousedown"), mEventListener,
|
||||
PR_FALSE, PR_FALSE);
|
||||
mContent->AddEventListener(NS_LITERAL_STRING("mouseup"), mEventListener,
|
||||
PR_FALSE, PR_FALSE);
|
||||
mContent->AddEventListener(NS_LITERAL_STRING("mousemove"), mEventListener,
|
||||
PR_FALSE, PR_FALSE);
|
||||
|
||||
mStartSelectionIndex = kNothingSelected;
|
||||
mEndSelectionIndex = kNothingSelected;
|
||||
|
@ -1910,6 +1881,9 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
|
|||
{
|
||||
NS_ASSERTION(aMouseEvent != nsnull, "aMouseEvent is null.");
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
NS_ENSURE_TRUE(mouseEvent, NS_ERROR_FAILURE);
|
||||
|
||||
UpdateInListState(aMouseEvent);
|
||||
|
||||
mButtonDown = PR_FALSE;
|
||||
|
@ -2121,6 +2095,9 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
{
|
||||
NS_ASSERTION(aMouseEvent != nsnull, "aMouseEvent is null.");
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
NS_ENSURE_TRUE(mouseEvent, NS_ERROR_FAILURE);
|
||||
|
||||
UpdateInListState(aMouseEvent);
|
||||
|
||||
nsEventStates eventStates = mContent->AsElement()->State();
|
||||
|
@ -2188,6 +2165,8 @@ nsresult
|
|||
nsListControlFrame::MouseMove(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
NS_ASSERTION(aMouseEvent, "aMouseEvent is null.");
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
|
||||
NS_ENSURE_TRUE(mouseEvent, NS_ERROR_FAILURE);
|
||||
|
||||
UpdateInListState(aMouseEvent);
|
||||
|
||||
|
@ -2703,53 +2682,25 @@ nsListControlFrame::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
* nsListEventListener
|
||||
*****************************************************************************/
|
||||
|
||||
NS_IMPL_ADDREF(nsListEventListener)
|
||||
NS_IMPL_RELEASE(nsListEventListener)
|
||||
NS_INTERFACE_MAP_BEGIN(nsListEventListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
NS_IMPL_ISUPPORTS1(nsListEventListener, nsIDOMEventListener)
|
||||
|
||||
#define FORWARD_EVENT(_event) \
|
||||
NS_IMETHODIMP \
|
||||
nsListEventListener::_event(nsIDOMEvent* aEvent) \
|
||||
{ \
|
||||
if (mFrame) \
|
||||
return mFrame->nsListControlFrame::_event(aEvent); \
|
||||
return NS_OK; \
|
||||
NS_IMETHODIMP
|
||||
nsListEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
if (eventType.EqualsLiteral("keypress"))
|
||||
return mFrame->nsListControlFrame::KeyPress(aEvent);
|
||||
if (eventType.EqualsLiteral("mousedown"))
|
||||
return mFrame->nsListControlFrame::MouseDown(aEvent);
|
||||
if (eventType.EqualsLiteral("mouseup"))
|
||||
return mFrame->nsListControlFrame::MouseUp(aEvent);
|
||||
if (eventType.EqualsLiteral("mousemove"))
|
||||
return mFrame->nsListControlFrame::MouseMove(aEvent);
|
||||
|
||||
NS_ABORT();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define IGNORE_EVENT(_event) \
|
||||
NS_IMETHODIMP \
|
||||
nsListEventListener::_event(nsIDOMEvent* aEvent) \
|
||||
{ return NS_OK; }
|
||||
|
||||
IGNORE_EVENT(HandleEvent)
|
||||
|
||||
/*================== nsIDOMKeyListener =========================*/
|
||||
|
||||
IGNORE_EVENT(KeyDown)
|
||||
IGNORE_EVENT(KeyUp)
|
||||
FORWARD_EVENT(KeyPress)
|
||||
|
||||
/*=============== nsIDOMMouseListener ======================*/
|
||||
|
||||
FORWARD_EVENT(MouseDown)
|
||||
FORWARD_EVENT(MouseUp)
|
||||
IGNORE_EVENT(MouseClick)
|
||||
IGNORE_EVENT(MouseDblClick)
|
||||
IGNORE_EVENT(MouseOver)
|
||||
IGNORE_EVENT(MouseOut)
|
||||
|
||||
/*=============== nsIDOMMouseMotionListener ======================*/
|
||||
|
||||
FORWARD_EVENT(MouseMove)
|
||||
// XXXbryner does anyone call this, ever?
|
||||
IGNORE_EVENT(DragMove)
|
||||
|
||||
#undef FORWARD_EVENT
|
||||
#undef IGNORE_EVENT
|
||||
|
||||
|
|
|
@ -197,16 +197,12 @@ public:
|
|||
NS_IMETHOD OnOptionSelected(PRInt32 aIndex, PRBool aSelected);
|
||||
NS_IMETHOD OnSetSelectedIndex(PRInt32 aOldIndex, PRInt32 aNewIndex);
|
||||
|
||||
// mouse event listeners (both might destroy |this|)
|
||||
nsresult MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
nsresult MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
|
||||
// mouse motion listeners
|
||||
// mouse event listeners (both )
|
||||
nsresult MouseDown(nsIDOMEvent* aMouseEvent); // might destroy |this|
|
||||
nsresult MouseUp(nsIDOMEvent* aMouseEvent); // might destroy |this|
|
||||
nsresult MouseMove(nsIDOMEvent* aMouseEvent);
|
||||
nsresult DragMove(nsIDOMEvent* aMouseEvent);
|
||||
|
||||
// key listener (might destroy |this|)
|
||||
nsresult KeyPress(nsIDOMEvent* aKeyEvent);
|
||||
nsresult KeyPress(nsIDOMEvent* aKeyEvent); // might destroy |this|
|
||||
|
||||
/**
|
||||
* Returns the options collection for aContent, if any.
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIMenuRollup.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -55,6 +55,11 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
||||
// X.h defines KeyPress
|
||||
#ifdef KeyPress
|
||||
#undef KeyPress
|
||||
#endif
|
||||
|
||||
/**
|
||||
* There are two types that are used:
|
||||
* - dismissable popups such as menus, which should close up when there is a
|
||||
|
@ -296,7 +301,7 @@ private:
|
|||
CloseMenuMode mCloseMenuMode;
|
||||
};
|
||||
|
||||
class nsXULPopupManager : public nsIDOMKeyListener,
|
||||
class nsXULPopupManager : public nsIDOMEventListener,
|
||||
public nsIMenuRollup,
|
||||
public nsIRollupListener,
|
||||
public nsITimerCallback,
|
||||
|
@ -311,6 +316,7 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
// nsIRollupListener
|
||||
NS_IMETHOD Rollup(PRUint32 aCount, nsIContent **aContent);
|
||||
|
@ -622,11 +628,9 @@ public:
|
|||
return HandleKeyboardNavigationInPopup(nsnull, aFrame, aDir);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
|
||||
|
||||
NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
|
||||
NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent);
|
||||
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
|
||||
nsresult KeyUp(nsIDOMKeyEvent* aKeyEvent);
|
||||
nsresult KeyDown(nsIDOMKeyEvent* aKeyEvent);
|
||||
nsresult KeyPress(nsIDOMKeyEvent* aKeyEvent);
|
||||
|
||||
protected:
|
||||
nsXULPopupManager();
|
||||
|
|
|
@ -131,8 +131,7 @@ void nsMenuChainItem::Detach(nsMenuChainItem** aRoot)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS5(nsXULPopupManager,
|
||||
nsIDOMKeyListener,
|
||||
NS_IMPL_ISUPPORTS4(nsXULPopupManager,
|
||||
nsIDOMEventListener,
|
||||
nsIMenuRollup,
|
||||
nsITimerCallback,
|
||||
|
@ -2073,7 +2072,30 @@ nsXULPopupManager::IsValidMenuItem(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXULPopupManager::KeyUp(nsIDOMEvent* aKeyEvent)
|
||||
nsXULPopupManager::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aEvent);
|
||||
NS_ENSURE_TRUE(keyEvent, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsAutoString eventType;
|
||||
keyEvent->GetType(eventType);
|
||||
if (eventType.EqualsLiteral("keyup")) {
|
||||
return KeyUp(keyEvent);
|
||||
}
|
||||
if (eventType.EqualsLiteral("keydown")) {
|
||||
return KeyDown(keyEvent);
|
||||
}
|
||||
if (eventType.EqualsLiteral("keypress")) {
|
||||
return KeyPress(keyEvent);
|
||||
}
|
||||
|
||||
NS_ABORT();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULPopupManager::KeyUp(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
// don't do anything if a menu isn't open or a menubar isn't active
|
||||
if (!mActiveMenuBar) {
|
||||
|
@ -2089,7 +2111,7 @@ nsXULPopupManager::KeyUp(nsIDOMEvent* aKeyEvent)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXULPopupManager::KeyDown(nsIDOMEvent* aKeyEvent)
|
||||
nsXULPopupManager::KeyDown(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
nsMenuChainItem* item = GetTopVisibleMenu();
|
||||
if (item && item->Frame()->IsMenuLocked())
|
||||
|
@ -2107,22 +2129,21 @@ nsXULPopupManager::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
nsMenuBarListener::GetMenuAccessKey(&menuAccessKey);
|
||||
if (menuAccessKey) {
|
||||
PRUint32 theChar;
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
keyEvent->GetKeyCode(&theChar);
|
||||
aKeyEvent->GetKeyCode(&theChar);
|
||||
|
||||
if (theChar == (PRUint32)menuAccessKey) {
|
||||
PRBool ctrl = PR_FALSE;
|
||||
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_CONTROL)
|
||||
keyEvent->GetCtrlKey(&ctrl);
|
||||
aKeyEvent->GetCtrlKey(&ctrl);
|
||||
PRBool alt=PR_FALSE;
|
||||
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_ALT)
|
||||
keyEvent->GetAltKey(&alt);
|
||||
aKeyEvent->GetAltKey(&alt);
|
||||
PRBool shift=PR_FALSE;
|
||||
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_SHIFT)
|
||||
keyEvent->GetShiftKey(&shift);
|
||||
aKeyEvent->GetShiftKey(&shift);
|
||||
PRBool meta=PR_FALSE;
|
||||
if (menuAccessKey != nsIDOMKeyEvent::DOM_VK_META)
|
||||
keyEvent->GetMetaKey(&meta);
|
||||
aKeyEvent->GetMetaKey(&meta);
|
||||
if (!(ctrl || alt || shift || meta)) {
|
||||
// The access key just went down and no other
|
||||
// modifiers are already down.
|
||||
|
@ -2142,7 +2163,7 @@ nsXULPopupManager::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXULPopupManager::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
nsXULPopupManager::KeyPress(nsIDOMKeyEvent* aKeyEvent)
|
||||
{
|
||||
// Don't check prevent default flag -- menus always get first shot at key events.
|
||||
// When a menu is open, the prevent default flag on a keypress is always set, so
|
||||
|
@ -2164,6 +2185,7 @@ nsXULPopupManager::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent = do_QueryInterface(aKeyEvent);
|
||||
NS_ENSURE_TRUE(keyEvent, NS_ERROR_UNEXPECTED);
|
||||
PRUint32 theChar;
|
||||
keyEvent->GetKeyCode(&theChar);
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ function AutocompletePopup(aDocument)
|
|||
stringBundle.GetStringFromName("Autocomplete.label"));
|
||||
this._panel.setAttribute("noautofocus", "true");
|
||||
this._panel.setAttribute("ignorekeys", "true");
|
||||
this._panel.setAttribute("level", "top");
|
||||
|
||||
let mainPopupSet = this._document.getElementById("mainPopupSet");
|
||||
if (mainPopupSet) {
|
||||
|
|
|
@ -51,6 +51,7 @@ const CONSOLEAPI_CLASS_ID = "{b49c18f8-3379-4fc0-8c90-d7772c1a9ff3}";
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/NetworkHelper.jsm");
|
||||
Cu.import("resource:///modules/PropertyPanel.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["HUDService", "ConsoleUtils"];
|
||||
|
||||
|
@ -4174,6 +4175,8 @@ function findCompletionBeginning(aStr)
|
|||
function JSPropertyProvider(aScope, aInputValue)
|
||||
{
|
||||
let obj = unwrap(aScope);
|
||||
// Store the scope object, since obj will be modified later on.
|
||||
let win = obj;
|
||||
|
||||
// Analyse the aInputValue and find the beginning of the last part that
|
||||
// should be completed.
|
||||
|
@ -4212,10 +4215,15 @@ function JSPropertyProvider(aScope, aInputValue)
|
|||
|
||||
// Check if prop is a getter function on obj. Functions can change other
|
||||
// stuff so we can't execute them to get the next object. Stop here.
|
||||
if (obj.__lookupGetter__(prop)) {
|
||||
if (isNonNativeGetter(win, obj, prop)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
obj = obj[prop];
|
||||
}
|
||||
catch (ex) {
|
||||
return null;
|
||||
}
|
||||
obj = obj[prop];
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -4258,10 +4266,16 @@ function isIteratorOrGenerator(aObject)
|
|||
return true;
|
||||
}
|
||||
|
||||
let str = aObject.toString();
|
||||
if (typeof aObject.next == "function" &&
|
||||
str.indexOf("[object Generator") == 0) {
|
||||
return true;
|
||||
try {
|
||||
let str = aObject.toString();
|
||||
if (typeof aObject.next == "function" &&
|
||||
str.indexOf("[object Generator") == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// window.history.next throws in the typeof check above.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4564,8 +4578,7 @@ JSTerm.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Evaluates a string in the sandbox. The string is currently wrapped by a
|
||||
* with(window) { aString } construct, see bug 574033.
|
||||
* Evaluates a string in the sandbox.
|
||||
*
|
||||
* @param string aString
|
||||
* String to evaluate in the sandbox.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: js2; js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -44,7 +45,8 @@ const Cu = Components.utils;
|
|||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = ["PropertyPanel", "PropertyTreeView", "namesAndValuesOf"];
|
||||
var EXPORTED_SYMBOLS = ["PropertyPanel", "PropertyTreeView",
|
||||
"namesAndValuesOf", "isNonNativeGetter"];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//// Helper for PropertyTreeView
|
||||
|
@ -112,11 +114,20 @@ function presentableValueFor(aObject)
|
|||
presentable = aObject.toString();
|
||||
let m = /^\[object (\S+)\]/.exec(presentable);
|
||||
|
||||
if (typeof aObject == "object" && typeof aObject.next == "function" &&
|
||||
m && m[1] == "Generator") {
|
||||
try {
|
||||
if (typeof aObject == "object" && typeof aObject.next == "function" &&
|
||||
m && m[1] == "Generator") {
|
||||
return {
|
||||
type: TYPE_OTHER,
|
||||
display: m[1]
|
||||
};
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// window.history.next throws in the typeof check above.
|
||||
return {
|
||||
type: TYPE_OTHER,
|
||||
display: m[1]
|
||||
type: TYPE_OBJECT,
|
||||
display: m ? m[1] : "Object"
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -148,6 +159,49 @@ function isNativeFunction(aFunction)
|
|||
return typeof aFunction == "function" && !("prototype" in aFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the given property of the provided object is a non-native getter or
|
||||
* not.
|
||||
*
|
||||
* @param object aScope
|
||||
* Scope to use for the check.
|
||||
*
|
||||
* @param object aObject
|
||||
* The object that contains the property.
|
||||
*
|
||||
* @param string aProp
|
||||
* The property you want to check if it is a getter or not.
|
||||
*
|
||||
* @return boolean
|
||||
* True if the given property is a getter, false otherwise.
|
||||
*/
|
||||
function isNonNativeGetter(aScope, aObject, aProp) {
|
||||
if (typeof aObject != "object") {
|
||||
return false;
|
||||
}
|
||||
let desc;
|
||||
while (aObject) {
|
||||
try {
|
||||
if (desc = aScope.Object.getOwnPropertyDescriptor(aObject, aProp)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// Native getters throw here. See bug 520882.
|
||||
if (ex.name == "NS_ERROR_XPC_BAD_CONVERT_JS" ||
|
||||
ex.name == "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO") {
|
||||
return false;
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
aObject = Object.getPrototypeOf(aObject);
|
||||
}
|
||||
if (desc && desc.get && !isNativeFunction(desc.get)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of property name value pairs for the tree.
|
||||
*
|
||||
|
@ -159,7 +213,7 @@ function isNativeFunction(aFunction)
|
|||
function namesAndValuesOf(aObject)
|
||||
{
|
||||
let pairs = [];
|
||||
let value, presentable, getter;
|
||||
let value, presentable;
|
||||
|
||||
let isDOMDocument = aObject instanceof Ci.nsIDOMDocument;
|
||||
|
||||
|
@ -169,11 +223,11 @@ function namesAndValuesOf(aObject)
|
|||
continue;
|
||||
}
|
||||
|
||||
// Also skip non-native getters.
|
||||
// TODO: implement a safer way to skip non-native getters. See bug 647235.
|
||||
getter = aObject.__lookupGetter__ ?
|
||||
aObject.__lookupGetter__(propName) : null;
|
||||
if (getter && !isNativeFunction(getter)) {
|
||||
// Also skip non-native getters. Pass the content window so that
|
||||
// getOwnPropertyDescriptor can work later on.
|
||||
let chromeWindow = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
let contentWindow = chromeWindow.gBrowser.selectedBrowser.contentWindow;
|
||||
if (isNonNativeGetter(contentWindow.wrappedJSObject, aObject, propName)) {
|
||||
value = ""; // Value is never displayed.
|
||||
presentable = {type: TYPE_OTHER, display: "Getter"};
|
||||
}
|
||||
|
|
|
@ -143,6 +143,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_webconsole_bug_585991_autocomplete_keys.js \
|
||||
browser_webconsole_bug_663443_panel_title.js \
|
||||
browser_webconsole_bug_660806_history_nav.js \
|
||||
browser_webconsole_bug_651501_document_body_autocomplete.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that document.body autocompletes in the web console.
|
||||
|
||||
Cu.import("resource://gre/modules/PropertyPanel.jsm");
|
||||
|
||||
function test() {
|
||||
addTab("data:text/html,Web Console autocompletion bug in document.body");
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
}
|
||||
|
||||
var gHUD;
|
||||
|
||||
function onLoad(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, arguments.callee, true);
|
||||
openConsole();
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
gHUD = HUDService.hudReferences[hudId];
|
||||
let jsterm = gHUD.jsterm;
|
||||
let popup = jsterm.autocompletePopup;
|
||||
let completeNode = jsterm.completeNode;
|
||||
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
|
||||
popup._panel.addEventListener("popupshown", function() {
|
||||
popup._panel.removeEventListener("popupshown", arguments.callee, false);
|
||||
|
||||
ok(popup.isOpen, "popup is open");
|
||||
|
||||
let props = namesAndValuesOf(content.wrappedJSObject.document.body).length;
|
||||
is(popup.itemCount, props, "popup.itemCount is correct");
|
||||
|
||||
popup._panel.addEventListener("popuphidden", autocompletePopupHidden, false);
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
}, false);
|
||||
|
||||
jsterm.setInputValue("document.body");
|
||||
EventUtils.synthesizeKey(".", {});
|
||||
}
|
||||
|
||||
function autocompletePopupHidden()
|
||||
{
|
||||
let jsterm = gHUD.jsterm;
|
||||
let popup = jsterm.autocompletePopup;
|
||||
let completeNode = jsterm.completeNode;
|
||||
let inputNode = jsterm.inputNode;
|
||||
|
||||
popup._panel.removeEventListener("popuphidden", arguments.callee, false);
|
||||
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
let inputStr = "document.b";
|
||||
jsterm.setInputValue(inputStr);
|
||||
EventUtils.synthesizeKey("o", {});
|
||||
let testStr = inputStr.replace(/./g, " ") + " ";
|
||||
is(completeNode.value, testStr + "dy", "completeNode is empty");
|
||||
jsterm.setInputValue("");
|
||||
|
||||
// Check the property panel as well.
|
||||
let propPanel = jsterm.openPropertyPanel("Test", content.document);
|
||||
let docProps = 0;
|
||||
for (let prop in content.document) {
|
||||
docProps++;
|
||||
}
|
||||
is (propPanel.treeView.rowCount, docProps, "all document properties shown in propertyPanel");
|
||||
|
||||
let treeRows = propPanel.treeView._rows;
|
||||
is (treeRows[30].display, "body: Object", "found document.body");
|
||||
propPanel.destroy();
|
||||
executeSoon(finishTest);
|
||||
}
|
||||
|
|
@ -807,7 +807,7 @@ UPLOAD_FILES= \
|
|||
$(if $(UPLOAD_EXTRA_FILES), $(foreach f, $(UPLOAD_EXTRA_FILES), $(wildcard $(DIST)/$(f))))
|
||||
|
||||
checksum:
|
||||
mkdir -p `dirname $CHECKSUM_FILE`
|
||||
mkdir -p `dirname $(CHECKSUM_FILE)`
|
||||
@$(PYTHON) $(MOZILLA_DIR)/build/checksums.py \
|
||||
-o $(CHECKSUM_FILE) \
|
||||
-d $(CHECKSUM_ALGORITHM) \
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#ifdef ACCESSIBILITY
|
||||
MOZ_SERVICE(AccessibilityService, nsIAccessibilityService, "@mozilla.org/accessibilityService;1")
|
||||
#endif
|
||||
MOZ_SERVICE(ChromeRegistryService, nsIChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
|
||||
MOZ_SERVICE(ToolkitChromeRegistryService, nsIToolkitChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
|
||||
MOZ_SERVICE(XULChromeRegistryService, nsIXULChromeRegistry, "@mozilla.org/chrome/chrome-registry;1")
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
#include "nsComponentManager.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsNetCID.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче